测试代码如下:
(基于Ansible 2.7 , 脚本test.sh的内容即输出$1 $2 $3)
play_source = dict(
name = "Ansible Play",
hosts = '192.168.1.1',
gather_facts = 'no',
vars=dict(ccc='play variable ccc',ddd='play variable ddd'),
tasks = [
dict(block = [
dict(action=dict(module='script', args='/test.sh "{{ddd}}" {{aaa}} "{{fff}}"'),register='x', vars=dict(eee='task variable eee',fff='task variable fff')),
dict(action=dict(module='command', args='uname'))
],
when = 'eee is defined',
rescue = [dict(action=dict(module='debug' ,args=dict(msg="error occur")))],
always = [dict(action=dict(module='shell' ,args='df'))],
vars = dict(aaa='"block variable aaa"',bbb='block variable bbb')
),
dict(action=dict(module='script', args='/test.sh "{{ccc}}" 123 {{x.rc}}'))
]
)
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
tqm = None
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=None,
stdout_callback=results_callback,
)
result = tqm.run(play)
finally:
if tqm is not None:
tqm.cleanup()
shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
callback在ok和skipped中输出result._result
输出结果如下:
on_ok:192.168.1.1
{
"192.168.1.1": {
"changed": true,
"rc": 0,
"stdout": "play variable ddd\r\nblock variable aaa\r\ntask variable fff\r\n",
"stdout_lines": [
"play variable ddd",
"block variable aaa",
"task variable fff"
],
"stderr": "Shared connection to 192.168.1.1 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.1.1 closed."
],
"_ansible_no_log": false
}
}
{'changed': False, 'skip_reason': 'Conditional result was False', '_ansible_no_log': False}
{'changed': False, 'skip_reason': 'Conditional result was False', '_ansible_no_log': False}
on_ok:192.168.1.1
{
"192.168.1.1": {
"changed": true,
"rc": 0,
"stdout": "play variable ccc\r\n123\r\n0\r\n",
"stdout_lines": [
"play variable ccc",
"123",
"0"
],
"stderr": "Shared connection to 192.168.1.1 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.1.1 closed."
],
"_ansible_no_log": false
}
}
关于变量的作用域:
- Play中声明的变量可以被Block和Task直接引用
- Block中声明的变量仅限Block内部使用
- Task中声明的变量仅限Task
- register中声明的变量全局可用
- Block中的when如果要使用变量,block中包含的所有task在执行的时候都会进行判断,甚至包括always里的。例如:上面跳过的task包括
dict(action=dict(module='command', args='uname'))
以及always=[dict(action=dict(module='shell' ,args='df'))]
。因为这两条中没有声明变量eee。但感觉这是个逻辑缺陷???always难道不应该不会被跳过吗? - 猜测Block中的when条件判断是把表达式放到Block的每一个task的play_context中去,而不是把Block作为一个整体来处理。
所以:
block=[
task1,
task2,
],
when = 'condition',
rescue = task3,
always = task4
实际上等同于
try
if condition:
task1
if condition:
task2
except:
if condition:
task3
finally:
if condition:
task4