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:
date > /tmp/salt-run:
cmd.run
Only run if another execution failed, in this case truncate syslog if there is no disk space:
> /var/log/messages:
cmd.run:
- unless: echo 'foo' > /tmp/.test
Note that 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.
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:
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 =).
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.
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:
#!/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:
Run myscript:
cmd.run:
- name: /path/to/myscript
- cwd: /
- stateful: True
Run only if myscript changed something:
cmd.wait:
- name: echo hello
- cwd: /
- watch:
- cmd: Run myscript
Note that if the cmd.wait state also specifies stateful: True it can
then be watched by some other states as well.
cmd.wait is not restricted to watching only cmd states. For example
it can also watch a git state for changes
# Watch for changes to a git repo and rebuild the project on updates
my-project:
git.latest:
- name: git@github.com/repo/foo
- target: /opt/foo
- rev: master
cmd.wait:
- name: make install
- cwd: /opt/foo
- watch:
- git: my-project
cmd.run or cmd.wait?¶These two states are often confused. The important thing to remember about them
is that 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 cmd.wait does just that. cmd.wait
is designed to watch other states, and is
executed when the state it is watching changes. Example:
/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
The map that comes from a pillar cannot be directly consumed by the env option. To use it one must convert it to a list. Example:
printenv:
cmd.run:
- env:
{% for key, value in pillar['keys'].iteritems() %}
- '{{ key }}': '{{ value }}'
{% endfor %}
salt.states.cmd.call(name, func, args=(), kws=None, onlyif=None, unless=None, **kwargs)¶Invoke a pre-defined Python function with arguments specified in the state
declaration. This function is mainly used by the
salt.renderers.pydsl renderer.
The interpretation of onlyif and unless arguments are identical to
those of cmd.run, and all other
arguments(cwd, runas, ...) allowed by cmd.run are allowed here, except that their effects apply
only to the commands specified in onlyif and unless rather than to the
function to be invoked.
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:
{
'name': name
'changes': {'retval': result},
'result': True if result is None else bool(result),
'comment': result if isinstance(result, basestring) else ''
}
salt.states.cmd.mod_watch(name, **kwargs)¶Execute a cmd function based on a watch call
salt.states.cmd.run(name, onlyif=None, unless=None, cwd=None, user=None, group=None, shell=None, env=None, stateful=False, umask=None, output_loglevel='info', quiet=False, timeout=None, **kwargs)¶Run a command if certain circumstances are met. Use cmd.wait if you
want to use the watch requisite.
onlyif option returns trueunless option returns falseA list of environment variables to be set prior to execution. Example:
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 here.
quiet is used for this value.output_loglevel: quiet.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.
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
salt.states.cmd.script(name, source=None, template=None, onlyif=None, unless=None, cwd=None, user=None, group=None, shell=None, env=None, stateful=False, umask=None, timeout=None, **kwargs)¶Download a script from a remote source and execute it. The name can be the source or the source value can be defined.
onlyif option returns trueunless option returns falseA list of environment variables to be set prior to execution. Example:
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 here.
salt.states.cmd.wait(name, onlyif=None, unless=None, cwd=None, user=None, group=None, shell=None, env=(), stateful=False, umask=None, **kwargs)¶Run the given command only if the watch statement calls it
onlyif option returns trueunless option returns falseA list of environment variables to be set prior to execution. Example:
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 here.
salt.states.cmd.wait_call(name, func, args=(), kws=None, onlyif=None, unless=None, stateful=False, **kwargs)¶salt.states.cmd.wait_script(name, source=None, template=None, onlyif=None, unless=None, cwd=None, user=None, group=None, shell=None, env=None, stateful=False, umask=None, **kwargs)¶Download a script from a remote source and execute it only if a watch statement calls it.
onlyif option returns trueunless option returns falseA list of environment variables to be set prior to execution. Example:
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 here.
Current Salt release: 2014.1.7
Docs for previous releases on salt.rtfd.org.