golden hour
/opt/saltstack/salt/lib/python3.10/site-packages/salt/states
⬆️ Go Up
Upload
File/Folder
Size
Actions
__init__.py
25 B
Del
OK
__pycache__
-
Del
OK
acme.py
5.08 KB
Del
OK
alias.py
2.49 KB
Del
OK
alternatives.py
6.75 KB
Del
OK
ansiblegate.py
7.93 KB
Del
OK
apache.py
3.95 KB
Del
OK
apache_conf.py
2.72 KB
Del
OK
apache_module.py
2.73 KB
Del
OK
apache_site.py
2.66 KB
Del
OK
aptpkg.py
1.42 KB
Del
OK
archive.py
68.24 KB
Del
OK
artifactory.py
6.84 KB
Del
OK
at.py
7.48 KB
Del
OK
augeas.py
10.57 KB
Del
OK
aws_sqs.py
2.59 KB
Del
OK
azurearm_compute.py
11.78 KB
Del
OK
azurearm_dns.py
26.05 KB
Del
OK
azurearm_network.py
89.12 KB
Del
OK
azurearm_resource.py
28.23 KB
Del
OK
beacon.py
7.58 KB
Del
OK
bigip.py
96.63 KB
Del
OK
blockdev.py
5.13 KB
Del
OK
boto3_elasticache.py
48.01 KB
Del
OK
boto3_elasticsearch.py
32.58 KB
Del
OK
boto3_route53.py
37.54 KB
Del
OK
boto3_sns.py
12.69 KB
Del
OK
boto_apigateway.py
82.83 KB
Del
OK
boto_asg.py
31.93 KB
Del
OK
boto_cfn.py
11.53 KB
Del
OK
boto_cloudfront.py
6.01 KB
Del
OK
boto_cloudtrail.py
13.18 KB
Del
OK
boto_cloudwatch_alarm.py
6.4 KB
Del
OK
boto_cloudwatch_event.py
12.33 KB
Del
OK
boto_cognitoidentity.py
13.69 KB
Del
OK
boto_datapipeline.py
18.5 KB
Del
OK
boto_dynamodb.py
29.32 KB
Del
OK
boto_ec2.py
71.98 KB
Del
OK
boto_elasticache.py
16.75 KB
Del
OK
boto_elasticsearch_domain.py
12.27 KB
Del
OK
boto_elb.py
55.1 KB
Del
OK
boto_elbv2.py
12.19 KB
Del
OK
boto_iam.py
69.16 KB
Del
OK
boto_iam_role.py
27.12 KB
Del
OK
boto_iot.py
25.33 KB
Del
OK
boto_kinesis.py
16.69 KB
Del
OK
boto_kms.py
12.11 KB
Del
OK
boto_lambda.py
35.52 KB
Del
OK
boto_lc.py
11.04 KB
Del
OK
boto_rds.py
26 KB
Del
OK
boto_route53.py
19.49 KB
Del
OK
boto_s3.py
9.32 KB
Del
OK
boto_s3_bucket.py
24.67 KB
Del
OK
boto_secgroup.py
32.62 KB
Del
OK
boto_sns.py
8.92 KB
Del
OK
boto_sqs.py
7.97 KB
Del
OK
boto_vpc.py
62.23 KB
Del
OK
bower.py
8.26 KB
Del
OK
btrfs.py
10.34 KB
Del
OK
cabal.py
5.73 KB
Del
OK
ceph.py
1.9 KB
Del
OK
chef.py
3.76 KB
Del
OK
chocolatey.py
16.15 KB
Del
OK
chronos_job.py
4.6 KB
Del
OK
cimc.py
14.32 KB
Del
OK
cisconso.py
3.14 KB
Del
OK
cloud.py
14.4 KB
Del
OK
cmd.py
40.92 KB
Del
OK
composer.py
8.38 KB
Del
OK
consul.py
5.4 KB
Del
OK
cron.py
23.39 KB
Del
OK
cryptdev.py
6.17 KB
Del
OK
csf.py
9.98 KB
Del
OK
cyg.py
7.05 KB
Del
OK
ddns.py
4.2 KB
Del
OK
debconfmod.py
6.33 KB
Del
OK
dellchassis.py
24.49 KB
Del
OK
disk.py
6.49 KB
Del
OK
docker_container.py
85.27 KB
Del
OK
docker_image.py
16.7 KB
Del
OK
docker_network.py
36.78 KB
Del
OK
docker_volume.py
6.72 KB
Del
OK
drac.py
4.17 KB
Del
OK
dvs.py
26.29 KB
Del
OK
elasticsearch.py
20.38 KB
Del
OK
elasticsearch_index.py
3.25 KB
Del
OK
elasticsearch_index_template.py
3.67 KB
Del
OK
environ.py
5.81 KB
Del
OK
eselect.py
2.27 KB
Del
OK
esxcluster.py
22.4 KB
Del
OK
esxdatacenter.py
4.44 KB
Del
OK
esxi.py
63.07 KB
Del
OK
esxvm.py
20.11 KB
Del
OK
etcd_mod.py
11 KB
Del
OK
ethtool.py
9.88 KB
Del
OK
event.py
2.48 KB
Del
OK
file.py
316.7 KB
Del
OK
firewall.py
1.33 KB
Del
OK
firewalld.py
26.08 KB
Del
OK
gem.py
7.13 KB
Del
OK
git.py
123.85 KB
Del
OK
github.py
27.25 KB
Del
OK
glance_image.py
2.26 KB
Del
OK
glassfish.py
21.47 KB
Del
OK
glusterfs.py
12.21 KB
Del
OK
gnomedesktop.py
7.47 KB
Del
OK
gpg.py
5.28 KB
Del
OK
grafana.py
12.11 KB
Del
OK
grafana4_dashboard.py
17.31 KB
Del
OK
grafana4_datasource.py
6.15 KB
Del
OK
grafana4_org.py
7.73 KB
Del
OK
grafana4_user.py
5.52 KB
Del
OK
grafana_dashboard.py
17.74 KB
Del
OK
grafana_datasource.py
5.31 KB
Del
OK
grains.py
15.57 KB
Del
OK
group.py
9.84 KB
Del
OK
heat.py
9.69 KB
Del
OK
helm.py
10.39 KB
Del
OK
hg.py
6.33 KB
Del
OK
highstate_doc.py
1.41 KB
Del
OK
host.py
8.64 KB
Del
OK
http.py
7.46 KB
Del
OK
icinga2.py
9.07 KB
Del
OK
idem.py
3.91 KB
Del
OK
ifttt.py
2.12 KB
Del
OK
incron.py
5.71 KB
Del
OK
influxdb08_database.py
2.85 KB
Del
OK
influxdb08_user.py
3.39 KB
Del
OK
influxdb_continuous_query.py
2.83 KB
Del
OK
influxdb_database.py
2.11 KB
Del
OK
influxdb_retention_policy.py
4.82 KB
Del
OK
influxdb_user.py
4.84 KB
Del
OK
infoblox_a.py
4.24 KB
Del
OK
infoblox_cname.py
4.19 KB
Del
OK
infoblox_host_record.py
6.59 KB
Del
OK
infoblox_range.py
6.85 KB
Del
OK
ini_manage.py
12.67 KB
Del
OK
ipmi.py
8.42 KB
Del
OK
ipset.py
9.66 KB
Del
OK
iptables.py
27.65 KB
Del
OK
jboss7.py
23.95 KB
Del
OK
jenkins.py
3.36 KB
Del
OK
junos.py
17.78 KB
Del
OK
kapacitor.py
6.46 KB
Del
OK
kernelpkg.py
6.42 KB
Del
OK
keyboard.py
2.01 KB
Del
OK
keystone.py
27.12 KB
Del
OK
keystone_domain.py
2.81 KB
Del
OK
keystone_endpoint.py
4.69 KB
Del
OK
keystone_group.py
3.25 KB
Del
OK
keystone_project.py
3.36 KB
Del
OK
keystone_role.py
2.33 KB
Del
OK
keystone_role_grant.py
4.08 KB
Del
OK
keystone_service.py
2.89 KB
Del
OK
keystone_user.py
3.47 KB
Del
OK
keystore.py
5.67 KB
Del
OK
kmod.py
8.59 KB
Del
OK
kubernetes.py
24.87 KB
Del
OK
layman.py
2.44 KB
Del
OK
ldap.py
19.78 KB
Del
OK
libcloud_dns.py
5.7 KB
Del
OK
libcloud_loadbalancer.py
5.66 KB
Del
OK
libcloud_storage.py
5.13 KB
Del
OK
linux_acl.py
24.42 KB
Del
OK
locale.py
2.52 KB
Del
OK
logadm.py
4.67 KB
Del
OK
logrotate.py
3.86 KB
Del
OK
loop.py
7.74 KB
Del
OK
lvm.py
13.33 KB
Del
OK
lvs_server.py
6.28 KB
Del
OK
lvs_service.py
4.38 KB
Del
OK
lxc.py
22.17 KB
Del
OK
lxd.py
7.88 KB
Del
OK
lxd_container.py
22.25 KB
Del
OK
lxd_image.py
10.59 KB
Del
OK
lxd_profile.py
7.11 KB
Del
OK
mac_assistive.py
1.55 KB
Del
OK
mac_keychain.py
5.59 KB
Del
OK
mac_xattr.py
3.15 KB
Del
OK
macdefaults.py
2.65 KB
Del
OK
macpackage.py
6.76 KB
Del
OK
makeconf.py
6.87 KB
Del
OK
marathon_app.py
4.45 KB
Del
OK
mdadm_raid.py
6.41 KB
Del
OK
memcached.py
3.95 KB
Del
OK
modjk.py
2.84 KB
Del
OK
modjk_worker.py
6.49 KB
Del
OK
module.py
18.64 KB
Del
OK
mongodb_database.py
1.65 KB
Del
OK
mongodb_user.py
6.26 KB
Del
OK
monit.py
2.68 KB
Del
OK
mount.py
50.32 KB
Del
OK
mssql_database.py
3 KB
Del
OK
mssql_login.py
3.64 KB
Del
OK
mssql_role.py
2.37 KB
Del
OK
mssql_user.py
3.51 KB
Del
OK
msteams.py
2.53 KB
Del
OK
mysql_database.py
6.05 KB
Del
OK
mysql_grants.py
8.49 KB
Del
OK
mysql_query.py
13.07 KB
Del
OK
mysql_user.py
9.51 KB
Del
OK
net_napalm_yang.py
9.15 KB
Del
OK
netacl.py
31.92 KB
Del
OK
netconfig.py
33.42 KB
Del
OK
netntp.py
12.51 KB
Del
OK
netsnmp.py
11.33 KB
Del
OK
netusers.py
16.1 KB
Del
OK
network.py
23.97 KB
Del
OK
neutron_network.py
3.96 KB
Del
OK
neutron_secgroup.py
4 KB
Del
OK
neutron_secgroup_rule.py
4.75 KB
Del
OK
neutron_subnet.py
4.29 KB
Del
OK
nexus.py
4.97 KB
Del
OK
nfs_export.py
4.92 KB
Del
OK
nftables.py
19.5 KB
Del
OK
npm.py
11.21 KB
Del
OK
ntp.py
2.12 KB
Del
OK
nxos.py
10.37 KB
Del
OK
nxos_upgrade.py
3.5 KB
Del
OK
openstack_config.py
3.26 KB
Del
OK
openvswitch_bridge.py
4.36 KB
Del
OK
openvswitch_db.py
2.24 KB
Del
OK
openvswitch_port.py
17.24 KB
Del
OK
opsgenie.py
4.07 KB
Del
OK
pagerduty.py
1.89 KB
Del
OK
pagerduty_escalation_policy.py
5.42 KB
Del
OK
pagerduty_schedule.py
6.09 KB
Del
OK
pagerduty_service.py
3.93 KB
Del
OK
pagerduty_user.py
1.18 KB
Del
OK
panos.py
48.13 KB
Del
OK
pbm.py
20.46 KB
Del
OK
pcs.py
36.46 KB
Del
OK
pdbedit.py
3.43 KB
Del
OK
pecl.py
3.65 KB
Del
OK
pip_state.py
38.55 KB
Del
OK
pkg.py
138.08 KB
Del
OK
pkgbuild.py
11.37 KB
Del
OK
pkgng.py
685 B
Del
OK
pkgrepo.py
27.53 KB
Del
OK
portage_config.py
5.01 KB
Del
OK
ports.py
5.65 KB
Del
OK
postgres_cluster.py
4.19 KB
Del
OK
postgres_database.py
6.08 KB
Del
OK
postgres_extension.py
5.68 KB
Del
OK
postgres_group.py
8.52 KB
Del
OK
postgres_initdb.py
2.84 KB
Del
OK
postgres_language.py
3.94 KB
Del
OK
postgres_privileges.py
7.86 KB
Del
OK
postgres_schema.py
4.34 KB
Del
OK
postgres_tablespace.py
6.62 KB
Del
OK
postgres_user.py
9.49 KB
Del
OK
powerpath.py
2.34 KB
Del
OK
probes.py
15.06 KB
Del
OK
process.py
1.32 KB
Del
OK
proxy.py
4.94 KB
Del
OK
pushover.py
3.13 KB
Del
OK
pyenv.py
6.07 KB
Del
OK
pyrax_queues.py
2.97 KB
Del
OK
quota.py
1.4 KB
Del
OK
rabbitmq_cluster.py
1.84 KB
Del
OK
rabbitmq_plugin.py
2.77 KB
Del
OK
rabbitmq_policy.py
4.59 KB
Del
OK
rabbitmq_upstream.py
7.9 KB
Del
OK
rabbitmq_user.py
8.89 KB
Del
OK
rabbitmq_vhost.py
3.04 KB
Del
OK
rbac_solaris.py
6.67 KB
Del
OK
rbenv.py
7.36 KB
Del
OK
rdp.py
1.28 KB
Del
OK
redismod.py
4.76 KB
Del
OK
reg.py
19.22 KB
Del
OK
restconf.py
6.41 KB
Del
OK
rsync.py
4.45 KB
Del
OK
rvm.py
6.56 KB
Del
OK
salt_proxy.py
1.34 KB
Del
OK
saltmod.py
33.12 KB
Del
OK
saltutil.py
8.91 KB
Del
OK
schedule.py
12.47 KB
Del
OK
selinux.py
18.61 KB
Del
OK
serverdensity_device.py
6.41 KB
Del
OK
service.py
37.89 KB
Del
OK
slack.py
4.98 KB
Del
OK
smartos.py
44.83 KB
Del
OK
smtp.py
2.3 KB
Del
OK
snapper.py
7.24 KB
Del
OK
solrcloud.py
4.48 KB
Del
OK
splunk.py
4.32 KB
Del
OK
splunk_search.py
3.17 KB
Del
OK
sqlite3.py
14.7 KB
Del
OK
ssh_auth.py
19.57 KB
Del
OK
ssh_known_hosts.py
7.92 KB
Del
OK
stateconf.py
494 B
Del
OK
status.py
2.21 KB
Del
OK
statuspage.py
17.29 KB
Del
OK
supervisord.py
10.48 KB
Del
OK
svn.py
8.14 KB
Del
OK
sysctl.py
4.11 KB
Del
OK
sysfs.py
2.13 KB
Del
OK
syslog_ng.py
2.97 KB
Del
OK
sysrc.py
2.82 KB
Del
OK
telemetry_alert.py
7.04 KB
Del
OK
test.py
13.09 KB
Del
OK
testinframod.py
1.35 KB
Del
OK
timezone.py
3.42 KB
Del
OK
tls.py
1.81 KB
Del
OK
tomcat.py
9.72 KB
Del
OK
trafficserver.py
8.82 KB
Del
OK
tuned.py
3.32 KB
Del
OK
uptime.py
1.87 KB
Del
OK
user.py
38.63 KB
Del
OK
vagrant.py
11.4 KB
Del
OK
vault.py
3.28 KB
Del
OK
vbox_guest.py
4.05 KB
Del
OK
victorops.py
3.32 KB
Del
OK
virt.py
80.41 KB
Del
OK
virtualenv_mod.py
11.21 KB
Del
OK
webutil.py
3.89 KB
Del
OK
win_certutil.py
4.8 KB
Del
OK
win_dacl.py
7.96 KB
Del
OK
win_dism.py
14.97 KB
Del
OK
win_dns_client.py
8.32 KB
Del
OK
win_firewall.py
6.87 KB
Del
OK
win_iis.py
31.56 KB
Del
OK
win_lgpo.py
24.99 KB
Del
OK
win_lgpo_reg.py
10.96 KB
Del
OK
win_license.py
1.6 KB
Del
OK
win_network.py
14.18 KB
Del
OK
win_path.py
6.39 KB
Del
OK
win_pki.py
5.56 KB
Del
OK
win_powercfg.py
3.79 KB
Del
OK
win_servermanager.py
10.4 KB
Del
OK
win_shortcut.py
7.81 KB
Del
OK
win_smtp_server.py
10.01 KB
Del
OK
win_snmp.py
6.64 KB
Del
OK
win_system.py
13.78 KB
Del
OK
win_wua.py
16.27 KB
Del
OK
win_wusa.py
3.53 KB
Del
OK
winrepo.py
2.74 KB
Del
OK
wordpress.py
4.82 KB
Del
OK
x509.py
27.86 KB
Del
OK
x509_v2.py
64.78 KB
Del
OK
xml.py
1.75 KB
Del
OK
xmpp.py
2.61 KB
Del
OK
zabbix_action.py
9.35 KB
Del
OK
zabbix_host.py
27.25 KB
Del
OK
zabbix_hostgroup.py
5.64 KB
Del
OK
zabbix_mediatype.py
16.89 KB
Del
OK
zabbix_template.py
35.14 KB
Del
OK
zabbix_user.py
17.6 KB
Del
OK
zabbix_usergroup.py
9.64 KB
Del
OK
zabbix_usermacro.py
9.69 KB
Del
OK
zabbix_valuemap.py
8.11 KB
Del
OK
zcbuildout.py
5.16 KB
Del
OK
zenoss.py
2.89 KB
Del
OK
zfs.py
34.48 KB
Del
OK
zk_concurrency.py
5.81 KB
Del
OK
zone.py
46.48 KB
Del
OK
zookeeper.py
11.55 KB
Del
OK
zpool.py
13.4 KB
Del
OK
Edit: cmd.py
""" Execution of arbitrary commands =============================== The cmd state module manages the enforcement of executed commands, this state can tell a command to run under certain circumstances. A simple example to execute a command: .. code-block:: yaml # Store the current date in a file 'date > /tmp/salt-run': cmd.run Only run if another execution failed, in this case truncate syslog if there is no disk space: .. code-block:: yaml '> /var/log/messages/': cmd.run: - unless: echo 'foo' > /tmp/.test && rm -f /tmp/.test Only run if the file specified by ``creates`` does not exist, in this case touch /tmp/foo if it does not exist: .. code-block:: yaml touch /tmp/foo: cmd.run: - creates: /tmp/foo ``creates`` also accepts a list of files, in which case this state will run if **any** of the files do not exist: .. code-block:: yaml "echo 'foo' | tee /tmp/bar > /tmp/baz": cmd.run: - creates: - /tmp/bar - /tmp/baz .. note:: The ``creates`` option was added to the cmd state in version 2014.7.0, and made a global requisite in 3001. Sometimes when running a command that starts up a daemon, the init script doesn't return properly which causes Salt to wait indefinitely for a response. In situations like this try the following: .. code-block:: yaml run_installer: cmd.run: - name: /tmp/installer.bin > /dev/null 2>&1 Salt determines whether the ``cmd`` state is successfully enforced based on the exit code returned by the command. If the command returns a zero exit code, then salt determines that the state was successfully enforced. If the script returns a non-zero exit code, then salt determines that it failed to successfully enforce the state. If a command returns a non-zero exit code but you wish to treat this as a success, then you must place the command in a script and explicitly set the exit code of the script to zero. Please note that the success or failure of the state is not affected by whether a state change occurred nor the stateful argument. When executing a command or script, the state (i.e., changed or not) of the command is unknown to Salt's state system. Therefore, by default, the ``cmd`` state assumes that any command execution results in a changed state. This means that if a ``cmd`` state is watched by another state then the state that's watching will always be executed due to the `changed` state in the ``cmd`` state. .. _stateful-argument: Using the "Stateful" Argument ----------------------------- Many state functions in this module now also accept a ``stateful`` argument. If ``stateful`` is specified to be true then it is assumed that the command or script will determine its own state and communicate it back by following a simple protocol described below: 1. :strong:`If there's nothing in the stdout of the command, then assume no changes.` Otherwise, the stdout must be either in JSON or its `last` non-empty line must be a string of key=value pairs delimited by spaces (no spaces on either side of ``=``). 2. :strong:`If it's JSON then it must be a JSON object (e.g., {}).` If it's key=value pairs then quoting may be used to include spaces. (Python's shlex module is used to parse the key=value string) Two special keys or attributes are recognized in the output:: changed: bool (i.e., 'yes', 'no', 'true', 'false', case-insensitive) comment: str (i.e., any string) So, only if ``changed`` is ``True`` then assume the command execution has changed the state, and any other key values or attributes in the output will be set as part of the changes. 3. :strong:`If there's a comment then it will be used as the comment of the state.` Here's an example of how one might write a shell script for use with a stateful command: .. code-block:: bash #!/bin/bash # echo "Working hard..." # writing the state line echo # an empty line here so the next line will be the last. echo "changed=yes comment='something has changed' whatever=123" And an example SLS file using this module: .. code-block:: yaml Run myscript: cmd.run: - name: /path/to/myscript - cwd: / - stateful: True Run only if myscript changed something: cmd.run: - name: echo hello - cwd: / - onchanges: - cmd: Run myscript Note that if the second ``cmd.run`` state also specifies ``stateful: True`` it can then be watched by some other states as well. 4. :strong:`The stateful argument can optionally include a test_name parameter.` This is used to specify a command to run in test mode. This command should return stateful data for changes that would be made by the command in the name parameter. .. versionadded:: 2015.2.0 .. code-block:: yaml Run myscript: cmd.run: - name: /path/to/myscript - cwd: / - stateful: - test_name: /path/to/myscript test Run masterscript: cmd.script: - name: masterscript - source: salt://path/to/masterscript - cwd: / - stateful: - test_name: masterscript test Should I use :mod:`cmd.run <salt.states.cmd.run>` or :mod:`cmd.wait <salt.states.cmd.wait>`? -------------------------------------------------------------------------------------------- .. note:: Use :mod:`cmd.run <salt.states.cmd.run>` together with :ref:`onchanges <requisites-onchanges>` instead of :mod:`cmd.wait <salt.states.cmd.wait>`. These two states are often confused. The important thing to remember about them is that :mod:`cmd.run <salt.states.cmd.run>` states are run each time the SLS file that contains them is applied. If it is more desirable to have a command that only runs after some other state changes, then :mod:`cmd.wait <salt.states.cmd.wait>` does just that. :mod:`cmd.wait <salt.states.cmd.wait>` is designed to :ref:`watch <requisites-watch>` other states, and is executed when the state it is watching changes. Example: .. code-block:: yaml /usr/local/bin/postinstall.sh: cmd.wait: - watch: - pkg: mycustompkg file.managed: - source: salt://utils/scripts/postinstall.sh mycustompkg: pkg.installed: - require: - file: /usr/local/bin/postinstall.sh ``cmd.wait`` itself do not do anything; all functionality is inside its ``mod_watch`` function, which is called by ``watch`` on changes. The preferred format is using the :ref:`onchanges Requisite <requisites-onchanges>`, which works on ``cmd.run`` as well as on any other state. The example would then look as follows: .. code-block:: yaml /usr/local/bin/postinstall.sh: cmd.run: - onchanges: - pkg: mycustompkg file.managed: - source: salt://utils/scripts/postinstall.sh mycustompkg: pkg.installed: - require: - file: /usr/local/bin/postinstall.sh How do I create an environment from a pillar map? ------------------------------------------------- The map that comes from a pillar can be directly consumed by the env option! To use it, one may pass it like this. Example: .. code-block:: yaml printenv: cmd.run: - env: {{ salt['pillar.get']('example:key', {}) }} """ import copy import logging import os import salt.utils.args import salt.utils.functools import salt.utils.json import salt.utils.platform from salt.exceptions import CommandExecutionError, SaltRenderError log = logging.getLogger(__name__) def _reinterpreted_state(state): """ Re-interpret the state returned by salt.state.run using our protocol. """ ret = state["changes"] state["changes"] = {} state["comment"] = "" out = ret.get("stdout") if not out: if ret.get("stderr"): state["comment"] = ret["stderr"] return state is_json = False try: data = salt.utils.json.loads(out) if not isinstance(data, dict): return _failout( state, "script JSON output must be a JSON object (e.g., {})!" ) is_json = True except ValueError: idx = out.rstrip().rfind("\n") if idx != -1: out = out[idx + 1 :] data = {} try: for item in salt.utils.args.shlex_split(out): key, val = item.split("=") data[key] = val except ValueError: state = _failout( state, "Failed parsing script output! " "Stdout must be JSON or a line of name=value pairs.", ) state["changes"].update(ret) return state changed = _is_true(data.get("changed", "no")) if "comment" in data: state["comment"] = data["comment"] del data["comment"] if changed: for key in ret: data.setdefault(key, ret[key]) # if stdout is the state output in JSON, don't show it. # otherwise it contains the one line name=value pairs, strip it. data["stdout"] = "" if is_json else data.get("stdout", "")[:idx] state["changes"] = data # FIXME: if it's not changed but there's stdout and/or stderr then those # won't be shown as the function output. (though, they will be shown # inside INFO logs). return state def _failout(state, msg): state["comment"] = msg state["result"] = False return state def _is_true(val): if val and str(val).lower() in ("true", "yes", "1"): return True elif str(val).lower() in ("false", "no", "0"): return False raise ValueError("Failed parsing boolean value: {}".format(val)) def wait( name, cwd=None, root=None, runas=None, shell=None, env=(), stateful=False, output_loglevel="debug", hide_output=False, use_vt=False, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Run the given command only if the watch statement calls it. .. note:: Use :mod:`cmd.run <salt.states.cmd.run>` together with :mod:`onchanges </ref/states/requisites#onchanges>` instead of :mod:`cmd.wait <salt.states.cmd.wait>`. name The command to execute, remember that the command will execute with the path and permissions of the salt-minion. cwd The current working directory to execute the command in, defaults to /root root Path to the root of the jail to use. If this parameter is set, the command will run inside a chroot runas The user name to run the command as shell The shell to use for execution, defaults to /bin/sh env A list of environment variables to be set prior to execution. Example: .. code-block:: yaml script-foo: cmd.wait: - env: - BATCH: 'yes' .. warning:: The above illustrates a common PyYAML pitfall, that **yes**, **no**, **on**, **off**, **true**, and **false** are all loaded as boolean ``True`` and ``False`` values, and must be enclosed in quotes to be used as strings. More info on this (and other) PyYAML idiosyncrasies can be found :ref:`here <yaml-idiosyncrasies>`. Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH': .. code-block:: yaml script-bar: cmd.wait: - env: "PATH=/some/path:$PATH" One can still use the existing $PATH by using a bit of Jinja: .. code-block:: jinja {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} mycommand: cmd.run: - name: ls -l / - env: - PATH: {{ [current_path, '/my/special/bin']|join(':') }} .. note:: When using environment variables on Windows, case-sensitivity matters, i.e. Windows uses `Path` as opposed to `PATH` for other systems. stateful The command being executed is expected to return data about executing a state. For more information, see the :ref:`stateful-argument` section. creates Only run if the file specified by ``creates`` do not exist. If you specify a list of files then this state will only run if **any** of the files do not exist. .. versionadded:: 2014.7.0 output_loglevel : debug Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. hide_output : False Suppress stdout and stderr in the state's results. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 use_vt Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. success_retcodes This parameter allows you to specify a list of non-zero return codes that should be considered as successful. If the return code from the command matches any in the list, the state will have a ``True`` result instead of ``False``. .. versionadded:: 2019.2.0 success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 """ # Ignoring our arguments is intentional. return {"name": name, "changes": {}, "result": True, "comment": ""} # Alias "cmd.watch" to "cmd.wait", as this is a common misconfiguration watch = salt.utils.functools.alias_function(wait, "watch") def wait_script( name, source=None, template=None, cwd=None, runas=None, shell=None, env=None, stateful=False, use_vt=False, output_loglevel="debug", hide_output=False, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Download a script from a remote source and execute it only if a watch statement calls it. source The source script being downloaded to the minion, this source script is hosted on the salt master server. If the file is located on the master in the directory named spam, and is called eggs, the source string is salt://spam/eggs template If this setting is applied then the named templating engine will be used to render the downloaded file, currently jinja, mako, and wempy are supported name The command to execute, remember that the command will execute with the path and permissions of the salt-minion. cwd The current working directory to execute the command in, defaults to /root runas The user name to run the command as shell The shell to use for execution, defaults to the shell grain env A list of environment variables to be set prior to execution. Example: .. code-block:: yaml salt://scripts/foo.sh: cmd.wait_script: - env: - BATCH: 'yes' .. warning:: The above illustrates a common PyYAML pitfall, that **yes**, **no**, **on**, **off**, **true**, and **false** are all loaded as boolean ``True`` and ``False`` values, and must be enclosed in quotes to be used as strings. More info on this (and other) PyYAML idiosyncrasies can be found :ref:`here <yaml-idiosyncrasies>`. Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH': .. code-block:: yaml salt://scripts/bar.sh: cmd.wait_script: - env: "PATH=/some/path:$PATH" One can still use the existing $PATH by using a bit of Jinja: .. code-block:: jinja {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} mycommand: cmd.run: - name: ls -l / - env: - PATH: {{ [current_path, '/my/special/bin']|join(':') }} .. note:: When using environment variables on Windows, case-sensitivity matters, i.e. Windows uses `Path` as opposed to `PATH` for other systems. stateful The command being executed is expected to return data about executing a state. For more information, see the :ref:`stateful-argument` section. use_vt Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. output_loglevel : debug Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. hide_output : False Suppress stdout and stderr in the state's results. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 success_retcodes This parameter allows you to specify a list of non-zero return codes that should be considered as successful. If the return code from the command matches any in the list, the state will have a ``True`` result instead of ``False``. .. versionadded:: 2019.2.0 success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 """ # Ignoring our arguments is intentional. return {"name": name, "changes": {}, "result": True, "comment": ""} def run( name, cwd=None, root=None, runas=None, shell=None, env=None, prepend_path=None, stateful=False, output_loglevel="debug", hide_output=False, timeout=None, ignore_timeout=False, use_vt=False, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Run a command if certain circumstances are met. Use ``cmd.wait`` if you want to use the ``watch`` requisite. .. note:: The ``**kwargs`` of ``cmd.run`` are passed down to one of the following exec modules: * ``cmdmod.run_all``: If used with default ``runas`` * ``cmdmod.run_chroot``: If used with non-``root`` value for ``runas`` For more information on what args are available for either of these, refer to the :ref:`cmdmod documentation <cmdmod-module>`. name The command to execute, remember that the command will execute with the path and permissions of the salt-minion. cwd The current working directory to execute the command in, defaults to /root root Path to the root of the jail to use. If this parameter is set, the command will run inside a chroot runas The user name (or uid) to run the command as shell The shell to use for execution, defaults to the shell grain env A list of environment variables to be set prior to execution. Example: .. code-block:: yaml script-foo: cmd.run: - env: - BATCH: 'yes' .. warning:: The above illustrates a common PyYAML pitfall, that **yes**, **no**, **on**, **off**, **true**, and **false** are all loaded as boolean ``True`` and ``False`` values, and must be enclosed in quotes to be used as strings. More info on this (and other) PyYAML idiosyncrasies can be found :ref:`here <yaml-idiosyncrasies>`. Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH': .. code-block:: yaml script-bar: cmd.run: - env: "PATH=/some/path:$PATH" One can still use the existing $PATH by using a bit of Jinja: .. code-block:: jinja {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} mycommand: cmd.run: - name: ls -l / - env: - PATH: {{ [current_path, '/my/special/bin']|join(':') }} .. note:: When using environment variables on Windows, case-sensitivity matters, i.e. Windows uses `Path` as opposed to `PATH` for other systems. prepend_path $PATH segment to prepend (trailing ':' not necessary) to $PATH. This is an easier alternative to the Jinja workaround. .. versionadded:: 2018.3.0 stateful The command being executed is expected to return data about executing a state. For more information, see the :ref:`stateful-argument` section. output_loglevel : debug Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. hide_output : False Suppress stdout and stderr in the state's results. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 timeout If the command has not terminated after timeout seconds, send the subprocess sigterm, and if sigterm is ignored, follow up with sigkill ignore_timeout Ignore the timeout of commands, which is useful for running nohup processes. .. versionadded:: 2015.8.0 creates Only run if the file specified by ``creates`` do not exist. If you specify a list of files then this state will only run if **any** of the files do not exist. .. versionadded:: 2014.7.0 use_vt : False Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. bg : False If ``True``, run command in background and do not await or deliver its results. .. versionadded:: 2016.3.6 success_retcodes This parameter allows you to specify a list of non-zero return codes that should be considered as successful. If the return code from the command matches any in the list, the state will have a ``True`` result instead of ``False``. .. versionadded:: 2019.2.0 success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 .. note:: cmd.run supports the usage of ``reload_modules``. This functionality allows you to force Salt to reload all modules. You should only use ``reload_modules`` if your cmd.run does some sort of installation (such as ``pip``), if you do not reload the modules future items in your state which rely on the software being installed will fail. .. code-block:: yaml getpip: cmd.run: - name: /usr/bin/python /usr/local/sbin/get-pip.py - unless: which pip - require: - pkg: python - file: /usr/local/sbin/get-pip.py - reload_modules: True """ ### NOTE: The keyword arguments in **kwargs are passed directly to the ### ``cmd.run_all`` function and cannot be removed from the function ### definition, otherwise the use of unsupported arguments in a ### ``cmd.run`` state will result in a traceback. ret = {"name": name, "changes": {}, "result": False, "comment": ""} test_name = None if not isinstance(stateful, list): stateful = stateful is True elif isinstance(stateful, list) and "test_name" in stateful[0]: test_name = stateful[0]["test_name"] if __opts__["test"] and test_name: name = test_name # Need the check for None here, if env is not provided then it falls back # to None and it is assumed that the environment is not being overridden. if env is not None and not isinstance(env, (list, dict)): ret["comment"] = "Invalidly-formatted 'env' parameter. See documentation." return ret cmd_kwargs = copy.deepcopy(kwargs) cmd_kwargs.update( { "cwd": cwd, "root": root, "runas": runas, "use_vt": use_vt, "shell": shell or __grains__["shell"], "env": env, "prepend_path": prepend_path, "output_loglevel": output_loglevel, "hide_output": hide_output, "success_retcodes": success_retcodes, "success_stdout": success_stdout, "success_stderr": success_stderr, } ) if __opts__["test"] and not test_name: ret["result"] = None ret["comment"] = 'Command "{}" would have been executed'.format(name) ret["changes"] = {"cmd": name} return _reinterpreted_state(ret) if stateful else ret if cwd and not os.path.isdir(cwd): ret["comment"] = 'Desired working directory "{}" is not available'.format(cwd) return ret # Wow, we passed the test, run this sucker! try: run_cmd = "cmd.run_all" if not root else "cmd.run_chroot" cmd_all = __salt__[run_cmd]( cmd=name, timeout=timeout, python_shell=True, **cmd_kwargs ) except Exception as err: # pylint: disable=broad-except ret["comment"] = str(err) return ret ret["changes"] = cmd_all ret["result"] = not bool(cmd_all["retcode"]) ret["comment"] = 'Command "{}" run'.format(name) # Ignore timeout errors if asked (for nohups) and treat cmd as a success if ignore_timeout: trigger = "Timed out after" if ret["changes"].get("retcode") == 1 and trigger in ret["changes"].get( "stdout" ): ret["changes"]["retcode"] = 0 ret["result"] = True if stateful: ret = _reinterpreted_state(ret) if __opts__["test"] and cmd_all["retcode"] == 0 and ret["changes"]: ret["result"] = None return ret def script( name, source=None, template=None, cwd=None, runas=None, password=None, shell=None, env=None, stateful=False, timeout=None, use_vt=False, output_loglevel="debug", hide_output=False, defaults=None, context=None, success_retcodes=None, success_stdout=None, success_stderr=None, **kwargs ): """ Download a script and execute it with specified arguments. source The location of the script to download. If the file is located on the master in the directory named spam, and is called eggs, the source string is salt://spam/eggs template If this setting is applied then the named templating engine will be used to render the downloaded file. Currently jinja, mako, and wempy are supported name Either "cmd arg1 arg2 arg3..." (cmd is not used) or a source "salt://...". cwd The current working directory to execute the command in, defaults to /root runas Specify an alternate user to run the command. The default behavior is to run as the user under which Salt is running. If running on a Windows minion you must also use the ``password`` argument, and the target user account must be in the Administrators group. .. note:: For Windows users, specifically Server users, it may be necessary to specify your runas user using the User Logon Name instead of the legacy logon name. Traditionally, logons would be in the following format. ``Domain/user`` In the event this causes issues when executing scripts, use the UPN format which looks like the following. ``user@domain.local`` More information <https://github.com/saltstack/salt/issues/55080> password .. versionadded:: 3000 Windows only. Required when specifying ``runas``. This parameter will be ignored on non-Windows platforms. shell The shell to use for execution. The default is set in grains['shell'] env A list of environment variables to be set prior to execution. Example: .. code-block:: yaml salt://scripts/foo.sh: cmd.script: - env: - BATCH: 'yes' .. warning:: The above illustrates a common PyYAML pitfall, that **yes**, **no**, **on**, **off**, **true**, and **false** are all loaded as boolean ``True`` and ``False`` values, and must be enclosed in quotes to be used as strings. More info on this (and other) PyYAML idiosyncrasies can be found :ref:`here <yaml-idiosyncrasies>`. Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH': .. code-block:: yaml salt://scripts/bar.sh: cmd.script: - env: "PATH=/some/path:$PATH" One can still use the existing $PATH by using a bit of Jinja: .. code-block:: jinja {% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %} mycommand: cmd.run: - name: ls -l / - env: - PATH: {{ [current_path, '/my/special/bin']|join(':') }} .. note:: When using environment variables on Windows, case-sensitivity matters, i.e. Windows uses `Path` as opposed to `PATH` for other systems. saltenv : ``base`` The Salt environment to use stateful The command being executed is expected to return data about executing a state. For more information, see the :ref:`stateful-argument` section. timeout If the command has not terminated after timeout seconds, send the subprocess sigterm, and if sigterm is ignored, follow up with sigkill args String of command line args to pass to the script. Only used if no args are specified as part of the `name` argument. To pass a string containing spaces in YAML, you will need to doubly-quote it: "arg1 'arg two' arg3" creates Only run if the file specified by ``creates`` do not exist. If you specify a list of files then this state will only run if **any** of the files do not exist. .. versionadded:: 2014.7.0 use_vt Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental. context .. versionadded:: 2016.3.0 Overrides default context variables passed to the template. defaults .. versionadded:: 2016.3.0 Default context passed to the template. output_loglevel : debug Control the loglevel at which the output from the command is logged to the minion log. .. note:: The command being run will still be logged at the ``debug`` loglevel regardless, unless ``quiet`` is used for this value. hide_output : False Suppress stdout and stderr in the state's results. .. note:: This is separate from ``output_loglevel``, which only handles how Salt logs to the minion log. .. versionadded:: 2018.3.0 success_retcodes This parameter allows you to specify a list of non-zero return codes that should be considered as successful. If the return code from the command matches any in the list, the state will have a ``True`` result instead of ``False``. .. versionadded:: 2019.2.0 success_stdout: This parameter will allow a list of strings that when found in standard out should be considered a success. If stdout returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 success_stderr: This parameter will allow a list of strings that when found in standard error should be considered a success. If stderr returned from the run matches any in the provided list, the return code will be overridden with zero. .. versionadded:: 3004 """ test_name = None if not isinstance(stateful, list): stateful = stateful is True elif isinstance(stateful, list) and "test_name" in stateful[0]: test_name = stateful[0]["test_name"] if __opts__["test"] and test_name: name = test_name ret = {"name": name, "changes": {}, "result": False, "comment": ""} # Need the check for None here, if env is not provided then it falls back # to None and it is assumed that the environment is not being overridden. if env is not None and not isinstance(env, (list, dict)): ret["comment"] = "Invalidly-formatted 'env' parameter. See documentation." return ret if context and not isinstance(context, dict): ret[ "comment" ] = "Invalidly-formatted 'context' parameter. Must be formed as a dict." return ret if defaults and not isinstance(defaults, dict): ret[ "comment" ] = "Invalidly-formatted 'defaults' parameter. Must be formed as a dict." return ret if runas and salt.utils.platform.is_windows() and not password: ret["comment"] = "Must supply a password if runas argument is used on Windows." return ret tmpctx = defaults if defaults else {} if context: tmpctx.update(context) cmd_kwargs = copy.deepcopy(kwargs) cmd_kwargs.update( { "runas": runas, "password": password, "shell": shell or __grains__["shell"], "env": env, "cwd": cwd, "template": template, "timeout": timeout, "output_loglevel": output_loglevel, "hide_output": hide_output, "use_vt": use_vt, "context": tmpctx, "saltenv": __env__, "success_retcodes": success_retcodes, "success_stdout": success_stdout, "success_stderr": success_stderr, } ) run_check_cmd_kwargs = { "cwd": cwd, "runas": runas, "shell": shell or __grains__["shell"], } # Change the source to be the name arg if it is not specified if source is None: source = name # If script args present split from name and define args if not cmd_kwargs.get("args", None) and len(name.split()) > 1: cmd_kwargs.update({"args": name.split(" ", 1)[1]}) if __opts__["test"] and not test_name: ret["result"] = None ret["comment"] = "Command '{}' would have been executed".format(name) return _reinterpreted_state(ret) if stateful else ret if cwd and not os.path.isdir(cwd): ret["comment"] = 'Desired working directory "{}" is not available'.format(cwd) return ret # Wow, we passed the test, run this sucker! try: cmd_all = __salt__["cmd.script"](source, python_shell=True, **cmd_kwargs) except (CommandExecutionError, SaltRenderError, OSError) as err: ret["comment"] = str(err) return ret ret["changes"] = cmd_all if kwargs.get("retcode", False): ret["result"] = not bool(cmd_all) else: ret["result"] = not bool(cmd_all["retcode"]) if ret.get("changes", {}).get("cache_error"): ret["comment"] = "Unable to cache script {} from saltenv '{}'".format( source, __env__ ) else: ret["comment"] = "Command '{}' run".format(name) if stateful: ret = _reinterpreted_state(ret) if __opts__["test"] and cmd_all["retcode"] == 0 and ret["changes"]: ret["result"] = None return ret def call( name, func, args=(), kws=None, output_loglevel="debug", hide_output=False, use_vt=False, **kwargs ): """ Invoke a pre-defined Python function with arguments specified in the state declaration. This function is mainly used by the :mod:`salt.renderers.pydsl` renderer. In addition, the ``stateful`` argument has no effects here. The return value of the invoked function will be interpreted as follows. If it's a dictionary then it will be passed through to the state system, which expects it to have the usual structure returned by any salt state function. Otherwise, the return value (denoted as ``result`` in the code below) is expected to be a JSON serializable object, and this dictionary is returned: .. code-block:: python { 'name': name 'changes': {'retval': result}, 'result': True if result is None else bool(result), 'comment': result if isinstance(result, str) else '' } """ ret = {"name": name, "changes": {}, "result": False, "comment": ""} cmd_kwargs = { "cwd": kwargs.get("cwd"), "runas": kwargs.get("user"), "shell": kwargs.get("shell") or __grains__["shell"], "env": kwargs.get("env"), "use_vt": use_vt, "output_loglevel": output_loglevel, "hide_output": hide_output, } if not kws: kws = {} result = func(*args, **kws) if isinstance(result, dict): ret.update(result) return ret else: # result must be JSON serializable else we get an error ret["changes"] = {"retval": result} ret["result"] = True if result is None else bool(result) if isinstance(result, str): ret["comment"] = result return ret def wait_call( name, func, args=(), kws=None, stateful=False, use_vt=False, output_loglevel="debug", hide_output=False, **kwargs ): # Ignoring our arguments is intentional. return {"name": name, "changes": {}, "result": True, "comment": ""} def mod_watch(name, **kwargs): """ Execute a cmd function based on a watch call .. note:: This state exists to support special handling of the ``watch`` :ref:`requisite <requisites>`. It should not be called directly. Parameters for this function should be set by the state being triggered. """ if kwargs["sfun"] in ("wait", "run", "watch"): if kwargs.get("stateful"): kwargs.pop("stateful") return _reinterpreted_state(run(name, **kwargs)) return run(name, **kwargs) elif kwargs["sfun"] == "wait_script" or kwargs["sfun"] == "script": if kwargs.get("stateful"): kwargs.pop("stateful") return _reinterpreted_state(script(name, **kwargs)) return script(name, **kwargs) elif kwargs["sfun"] == "wait_call" or kwargs["sfun"] == "call": if kwargs.get("func"): func = kwargs.pop("func") return call(name, func, **kwargs) else: return { "name": name, "changes": {}, "comment": "cmd.{0[sfun]} needs a named parameter func".format(kwargs), "result": False, } return { "name": name, "changes": {}, "comment": ( "cmd.{0[sfun]} does not work with the watch requisite, " "please use cmd.wait or cmd.wait_script".format(kwargs) ), "result": False, }
Save