cmd state模块管理可执行命令的执行过程,这个state可以告诉命令运行在哪些环境下。
一个简单的例子来执行一个命令:
# Store the current date in a file
date > /tmp/salt-run:
cmd.run
只运行在另一条命令失败的时候,这种情况下可以在没有磁盘空间时截断syslog:
> /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.
touch /tmp/foo:
cmd.run:
- creates: /tmp/foo
注解
The creates
option was added to version 2014.7.0
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.
这意味着如果一个``cmd`` state被另一个state监控的时候,那么这个监控state将总会执行,因为``cmd`` state中的该状态变成了`changed`。
在这个模板中的很多state功能现在可以允许一个``stateful``参数。如果``sateful``指定为true,那么这将假定命令或脚本将会决定自己的状态,并且遵循一个以下简单描述的协议回传。
:strong:`如果该命令的stdout没有内容的话,就假设未发生改变。`否则,stdout必须是在JSON中,或者`最后`非空行必须是一个被空白符分割键值对key=value字符串(``=``两边都不能有空白符)。
:strong:`如果它是JSON那么它必须是一个JSON对象(例如{})。`如果它是键值对key-value那么可以加上引号包含空格。(使用Python的shlex模块解析key=value字符串)
两个特殊的键或属性是默认输出的:
changed: bool (i.e., 'yes', 'no', 'true', 'false', case-insensitive)
comment: str (i.e., any string)
所以,只有是否``changed``是``Then``时才假定命令执行已经改变了state,并且其他键值或属性输出将会作为变化的一部分。
如果有注释,那么它将会作为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.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.
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.
2015.2.0 新版功能.
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
cmd.run
or cmd.wait
?¶注解
Use cmd.run
together with onchanges
instead of cmd.wait
.
这两个states经常会搞混。重点是记住:mod:cmd.run <salt.states.cmd.run> states 在包含它的SLS文件中每次都执行。如果更合理的需求是只是在一些其他state改变的时候才运行,那么 cmd.wait
其他states,并且当监控的state改变时才执行。范例:
/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 does not do anything; all functionality is inside its mod_watch
function, which is called by watch
on changes.
cmd.wait
will be deprecated in future due to the confusion it causes. The
preferred format is using the onchanges Requisite, which
works on cmd.run
as well as on any other state. The example would then look as follows:
/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
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:
printenv:
cmd.run:
- env: {{ salt['pillar.get']('example:key', {}) }}
salt.states.cmd.
call
(name, func, args=(), kws=None, onlyif=None, unless=None, creates=None, output_loglevel='debug', use_vt=False, **kwargs)¶在state声明中调用预定义的Python带参函数。这个功能主要是用于:mod: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.
调用的函数返回值将会像如下方式解读。
如果是字典,那么将会传递到state系统,预计其有一个被其他salt state功能返回的通用结构。
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, string_types) else ''
}
salt.states.cmd.
mod_run_check
(cmd_kwargs, onlyif, unless, group, creates)¶Execute the onlyif and unless logic. Return a result dict if: * group is not available * onlyif failed (onlyif != 0) * unless succeeded (unless == 0) else return True
salt.states.cmd.
mod_watch
(name, **kwargs)¶基于一个监控请求执行的cmd功能
salt.states.cmd.
run
(name, onlyif=None, unless=None, creates=None, cwd=None, user=None, group=None, shell=None, env=None, stateful=False, umask=None, output_loglevel='debug', quiet=False, timeout=None, ignore_timeout=False, use_vt=False, **kwargs)¶Run a command if certain circumstances are met. Use cmd.wait
if you
want to use the watch
requisite.
要执行的命令,记住该命令将会在salt-minion的路径和权限下执行。
一个用于检查的命令,仅当``onlyif``选项指向的命令返回true时才执行name定义的命令
用于检查的命令,仅当``unless``选项指向的命令返回false时才执行name指向的命令
执行命令时的当前工作目录,默认是/root
以指定用户身份运行命令
以指定用户组身份运行命令
用于执行命令的shell,默认shell grain
A list of environment variables to be set prior to execution. Example:
script-foo:
cmd.run:
- env:
- BATCH: 'yes'
警告
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.
Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH':
script-bar:
cmd.run:
- env: "PATH=/some/path:$PATH"
One can still use the existing $PATH by using a bit of 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(':') }}
当命令运行时使用的umask(八进制数)。
quiet
is used for this value.output_loglevel: quiet
.如果命令在超时秒数到达时还未终止,发送子进程信号sigterm,并且如果sigterm被忽略,就接着发送sigkill
Ignore the timeout of commands, which is useful for running nohup processes.
2015.8.0 新版功能.
Only run if the file specified by creates
does not exist.
2014.7.0 新版功能.
注解
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, creates=None, cwd=None, user=None, group=None, shell=None, env=None, stateful=False, umask=None, timeout=None, use_vt=False, output_loglevel='debug', defaults=None, context=None, **kwargs)¶Download a script and execute it with specified arguments.
onlyif
option returns trueunless
option returns false执行命令时的当前工作目录,默认是/root
以指定用户组身份运行命令
A list of environment variables to be set prior to execution. Example:
salt://scripts/foo.sh:
cmd.script:
- env:
- BATCH: 'yes'
警告
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.
Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH':
salt://scripts/bar.sh:
cmd.script:
- env: "PATH=/some/path:$PATH"
One can still use the existing $PATH by using a bit of 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(':') }}
当命令运行时使用的umask(八进制数)。
如果命令在超时秒数到达时还未终止,发送子进程信号sigterm,并且如果sigterm被忽略,就接着发送sigkill
Only run if the file specified by creates
does not exist.
2014.7.0 新版功能.
2016.3.0 新版功能.
Overrides default context variables passed to the template.
2016.3.0 新版功能.
Default context passed to the template.
quiet
is used for this value.salt.states.cmd.
wait
(name, onlyif=None, unless=None, creates=None, cwd=None, user=None, group=None, shell=None, env=(), stateful=False, umask=None, output_loglevel='debug', use_vt=False, **kwargs)¶Run the given command only if the watch statement calls it.
注解
Use cmd.run
with onchange
instead.
要执行的命令,记住该命令将会在salt-minion的路径和权限下执行。
一个用于检查的命令,仅当``onlyif``选项指向的命令返回true时才执行name定义的命令
用于检查的命令,仅当``unless``选项指向的命令返回false时才执行name指向的命令
执行命令时的当前工作目录,默认是/root
以指定用户身份运行命令
以指定用户组身份运行命令
A list of environment variables to be set prior to execution. Example:
script-foo:
cmd.wait:
- env:
- BATCH: 'yes'
警告
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.
Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH':
script-bar:
cmd.wait:
- env: "PATH=/some/path:$PATH"
One can still use the existing $PATH by using a bit of 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(':') }}
当命令运行时使用的umask(八进制数)。
Only run if the file specified by creates
does not exist.
2014.7.0 新版功能.
quiet
is used for this value.salt.states.cmd.
wait_call
(name, func, args=(), kws=None, onlyif=None, unless=None, creates=None, stateful=False, use_vt=False, output_loglevel='debug', **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, use_vt=False, output_loglevel='debug', **kwargs)¶Download a script from a remote source and execute it only if a watch statement calls it.
要执行的命令,记住该命令将会在salt-minion的路径和权限下执行。
一个用于检查的命令,仅当``onlyif``选项指向的命令返回true时才执行name定义的命令
用于检查的命令,仅当``unless``选项指向的命令返回false时才执行name指向的命令
执行命令时的当前工作目录,默认是/root
以指定用户身份运行命令
以指定用户组身份运行命令
用于执行命令的shell,默认shell grain
A list of environment variables to be set prior to execution. Example:
salt://scripts/foo.sh:
cmd.wait_script:
- env:
- BATCH: 'yes'
警告
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.
Variables as values are not evaluated. So $PATH in the following example is a literal '$PATH':
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:
{% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %}
mycommand:
cmd.run:
- name: ls -l /
- env:
- PATH: {{ [current_path, '/my/special/bin']|join(':') }}
当命令运行时使用的umask(八进制数)。
Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental.
quiet
is used for this value.