注解
提示: 本教程建立在:doc:part 1 <states_pt1> 和:doc:`part 2 <states_pt2>`之上,建议从它们开始阅读
这章教程我们将讨论更多 ``sls``文件的扩展模板和配置技巧。
SLS模板块可能需要编程的逻辑或则嵌套的执行。这是通过模块的模板,默认的模块模板系统使用的是`Jinja2`, 我们可以通过更改主配置的:conf_master:`renderer`值来改变这个。
当初始化时所有的状态类型都是通过模板系统获得。使用模板系统只需要简单的添加一些模板标记。SLS模板与模板标记的一个例子,看起来像下面这样。
{% for usr in ['moe','larry','curly'] %}
{{ usr }}:
user.present
{% endfor %}
这个SLS模板文件一次性构造了如下的内容:
moe:
user.present
larry:
user.present
curly:
user.present
这里有个更复杂点的例子:
# Comments in yaml start with a hash symbol.
# Since jinja rendering occurs before yaml parsing, if you want to include jinja
# in the comments you may need to escape them using 'jinja' comments to prevent
# jinja from trying to render something which is not well-defined jinja.
# e.g.
# {# iterate over the Three Stooges using a {% for %}..{% endfor %} loop
# with the iterator variable {{ usr }} becoming the state ID. #}
{% for usr in 'moe','larry','curly' %}
{{ usr }}:
group:
- present
user:
- present
- gid_from_name: True
- require:
- group: {{ usr }}
{% endfor %}
很多时候一个state 在不同的系统上行为要不一样, Salt grains 在模板文本中将可以被应用,`grains`可以被使用在模板内。
apache:
pkg.installed:
{% if grains['os'] == 'RedHat' %}
- name: httpd
{% elif grains['os'] == 'Ubuntu' %}
- name: apache2
{% endif %}
You can use salt['environ.get']('VARNAME')
to use an environment
variable in a Salt state.
MYENVVAR="world" salt-call state.template test.sls
Create a file with contents from an environment variable:
file.managed:
- name: /tmp/hello
- contents: {{ salt['environ.get']('MYENVVAR') }}
Error checking:
{% set myenvvar = salt['environ.get']('MYENVVAR') %}
{% if myenvvar %}
Create a file with contents from an environment variable:
file.managed:
- name: /tmp/hello
- contents: {{ salt['environ.get']('MYENVVAR') }}
{% else %}
Fail - no environment passed in:
test:
A. fail_without_changes
{% endif %}
所有的minion从模板系统中调用可用的模块。他们允许实时在目标机器上搜集数据。同时也允许运行简单shell命令在SLS模块中。
``salt:``一个可用的模块函数在salt模板中,就像下面这样。
moe:
user.present:
- gid: {{ salt['file.group_to_gid']('some_group_that_exists') }}
提示:在上面的例子运行中,some_group_that_exists
必须在状态文件模板引擎处理之前必须存在。
在下面的例子中使用``network.hw_addr``函数取回eth0的MAC地址。
salt['network.hw_addr']('eth0')
在最后,我们将讨论一些不可思议的好技巧在更复杂的state 树中。
A previous example showed how to spread a Salt tree across several files. Similarly, requisites span multiple files by using an Include declaration. For example:
python/python-libs.sls:
python-dateutil:
pkg.installed
python/django.sls:
include:
- python.python-libs
django:
pkg.installed:
- require:
- pkg: python-dateutil
You can modify previous declarations by using an Extend declaration. For example the following modifies the Apache tree to also restart Apache when the vhosts file is changed:
apache/apache.sls:
apache:
pkg.installed
apache/mywebsite.sls:
include:
- apache.apache
extend:
apache:
service:
- running
- watch:
- file: /etc/httpd/extra/httpd-vhosts.conf
/etc/httpd/extra/httpd-vhosts.conf:
file.managed:
- source: salt://apache/httpd-vhosts.conf
对比扩展和`required`or watch
扩展申明申明是有别于``require``or watch
,它是附加,而不是更改必要的组件。
You can override the ID declaration by using a Name declaration. For example, the previous example is a bit more maintainable if rewritten as follows:
apache/mywebsite.sls:
include:
- apache.apache
extend:
apache:
service:
- running
- watch:
- file: mywebsite
mywebsite:
file.managed:
- name: /etc/httpd/extra/httpd-vhosts.conf
- source: salt://apache/httpd-vhosts.conf
Even more powerful is using a Names declaration to override the ID declaration for multiple states at once. This often can remove the need for looping in a template. For example, the first example in this tutorial can be rewritten without the loop:
stooges:
user.present:
- names:
- moe
- larry
- curly
在 第四部分中 我们将讨论如何使用**Salt**的 file_roots
来建立一个工作流程状态提升从开发,测试,生产。