salt.states.cmd

执行任意的命令

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`。

Using the "Stateful" Argument

在这个模板中的很多state功能现在可以允许一个``stateful``参数。如果``sateful``指定为true,那么这将假定命令或脚本将会决定自己的状态,并且遵循一个以下简单描述的协议回传。

  1. :strong:`如果该命令的stdout没有内容的话,就假设未发生改变。`否则,stdout必须是在JSON中,或者`最后`非空行必须是一个被空白符分割键值对key=value字符串(``=``两边都不能有空白符)。

  2. :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,并且其他键值或属性输出将会作为变化的一部分。

  3. 如果有注释,那么它将会作为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.

  4. 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
    

Should I use 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

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:

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.

name

要执行的命令,记住该命令将会在salt-minion的路径和权限下执行。

onlyif

一个用于检查的命令,仅当``onlyif``选项指向的命令返回true时才执行name定义的命令

unless

用于检查的命令,仅当``unless``选项指向的命令返回false时才执行name指向的命令

cwd

执行命令时的当前工作目录,默认是/root

user

以指定用户身份运行命令

group

以指定用户组身份运行命令

shell

用于执行命令的shell,默认shell grain

env

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(':') }}
stateful
The command being executed is expected to return data about executing a state. For more information, see the Using the "Stateful" Argument section.
umask

当命令运行时使用的umask(八进制数)。

output_loglevel
Control the loglevel at which the output from the command is logged. Note that the command being run will still be logged (loglevel: DEBUG) regardless, unless quiet is used for this value.
quiet
The command will be executed quietly, meaning no log entries of the actual command or its return data. This is deprecated as of the 2014.1.0 release, and is being replaced with output_loglevel: quiet.
timeout

如果命令在超时秒数到达时还未终止,发送子进程信号sigterm,并且如果sigterm被忽略,就接着发送sigkill

ignore_timeout

Ignore the timeout of commands, which is useful for running nohup processes.

2015.8.0 新版功能.

creates

Only run if the file specified by creates does not exist.

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.

注解

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.

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://...".
onlyif
Run the named command only if the command passed to the onlyif option returns true
unless
Run the named command only if the command passed to the unless option returns false
cwd

执行命令时的当前工作目录,默认是/root

user
The name of the user to run the command as
group

以指定用户组身份运行命令

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:

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

当命令运行时使用的umask(八进制数)。

stateful
The command being executed is expected to return data about executing a state. For more information, see the Using the "Stateful" Argument section.
timeout

如果命令在超时秒数到达时还未终止,发送子进程信号sigterm,并且如果sigterm被忽略,就接着发送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 does not exist.

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

2016.3.0 新版功能.

Overrides default context variables passed to the template.

defaults

2016.3.0 新版功能.

Default context passed to the template.

output_loglevel
Control the loglevel at which the output from the command is logged. Note that the command being run will still be logged (loglevel: DEBUG) regardless, unless 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.

name

要执行的命令,记住该命令将会在salt-minion的路径和权限下执行。

onlyif

一个用于检查的命令,仅当``onlyif``选项指向的命令返回true时才执行name定义的命令

unless

用于检查的命令,仅当``unless``选项指向的命令返回false时才执行name指向的命令

cwd

执行命令时的当前工作目录,默认是/root

user

以指定用户身份运行命令

group

以指定用户组身份运行命令

shell
The shell to use for execution, defaults to /bin/sh
env

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

当命令运行时使用的umask(八进制数)。

stateful
The command being executed is expected to return data about executing a state. For more information, see the Using the "Stateful" Argument section.
creates

Only run if the file specified by creates does not exist.

2014.7.0 新版功能.

output_loglevel
Control the loglevel at which the output from the command is logged. Note that the command being run will still be logged (loglevel: DEBUG) regardless, unless quiet is used for this value.
use_vt
Use VT utils (saltstack) to stream the command output more interactively to the console and the logs. This is experimental.
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.

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

要执行的命令,记住该命令将会在salt-minion的路径和权限下执行。

onlyif

一个用于检查的命令,仅当``onlyif``选项指向的命令返回true时才执行name定义的命令

unless

用于检查的命令,仅当``unless``选项指向的命令返回false时才执行name指向的命令

cwd

执行命令时的当前工作目录,默认是/root

user

以指定用户身份运行命令

group

以指定用户组身份运行命令

shell

用于执行命令的shell,默认shell grain

env

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

当命令运行时使用的umask(八进制数)。

stateful
The command being executed is expected to return data about executing a state. For more information, see the Using the "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
Control the loglevel at which the output from the command is logged. Note that the command being run will still be logged (loglevel: DEBUG) regardless, unless quiet is used for this value.