使用 Ansible 记住命令之前成功执行的最佳方法是什么?
With Ansible what is the best way of remembering a command has executed successfully previously?
使用command module,如果该命令创建了一个文件,您可以检查该文件是否存在。如果是这样,它会阻止命令再次执行。
- command: touch ~/myfile
args:
creates: ~/myfile
但是,如果该命令没有创建文件,那么它会再次执行运行。
为了避免第二次执行,我创建了一些关于更改(通知)的随机文件,如下所示:
- command: dothisonceonly # this does not create a file
args:
creates: ~/somefile
notify: done
然后处理程序:
- name: done
command: touch ~/somefile
这种方法可行,但有点难看。任何人都可以放弃最佳实践吗?也许设置一些事实?也许是一种全新的方法?
一个命令在特定目标主机上运行成功是事实(通俗地说),所以最合适的是使用local facts(Ansible 白话)。
在您的处理程序中,使用 copy
模块和 content
参数将状态保存为 /etc/ansible/facts.d
下的 JSON 文件。
只要您 运行 通过常规 fact-gathering 流程与主机对战,它就会被检索和访问。
然后你可以用when
条件来控制任务(你需要包括default
过滤器来过滤没有事实存在的情况)。
理想情况下,使用 Ansible 检查第一个命令更改的状态,而不是使用文件作为代理。原因是检查某物的实际状态提供了更好的不变性,因为它在每次通过时都经过测试。
如果有理由不使用该方法。然后注册命令的结果并使用它而不是通知程序来触发文件的创建。
- command: dothisonceonly # this does not create a file
creates: ~/somefile
register: result
- file:
path: ~/somefile
state: touch
when: result|succeeded
如果您想知道这里发生了什么,请添加:
- debug: var=result
请注意通知者,他们 运行 在播放结束时。这意味着如果一个通知程序被一个任务触发但随后播放失败,则通知程序将不会是 运行。相反,有一些 Ansible 选项会导致通知程序 运行,即使不是由任务触发也是如此。
这是我根据@techraf
的回答实际实现的
- command: echo 'phew'
register: itworks
notify: Done itworks
when: ansible_local.itworks | d(0) == 0
和处理程序:
- name: Done itworks
copy:
content: '{{ itworks }}'
dest: /etc/ansible/facts.d/itworks.fact
文档:
http://docs.ansible.com/ansible/playbooks_variables.html#local-facts-facts-d
感谢@techraf 这很好用并且坚持事实。
编辑
在@techraf 的评论中应用了默认值逻辑。
使用command module,如果该命令创建了一个文件,您可以检查该文件是否存在。如果是这样,它会阻止命令再次执行。
- command: touch ~/myfile
args:
creates: ~/myfile
但是,如果该命令没有创建文件,那么它会再次执行运行。
为了避免第二次执行,我创建了一些关于更改(通知)的随机文件,如下所示:
- command: dothisonceonly # this does not create a file
args:
creates: ~/somefile
notify: done
然后处理程序:
- name: done
command: touch ~/somefile
这种方法可行,但有点难看。任何人都可以放弃最佳实践吗?也许设置一些事实?也许是一种全新的方法?
一个命令在特定目标主机上运行成功是事实(通俗地说),所以最合适的是使用local facts(Ansible 白话)。
在您的处理程序中,使用 copy
模块和 content
参数将状态保存为 /etc/ansible/facts.d
下的 JSON 文件。
只要您 运行 通过常规 fact-gathering 流程与主机对战,它就会被检索和访问。
然后你可以用when
条件来控制任务(你需要包括default
过滤器来过滤没有事实存在的情况)。
理想情况下,使用 Ansible 检查第一个命令更改的状态,而不是使用文件作为代理。原因是检查某物的实际状态提供了更好的不变性,因为它在每次通过时都经过测试。
如果有理由不使用该方法。然后注册命令的结果并使用它而不是通知程序来触发文件的创建。
- command: dothisonceonly # this does not create a file
creates: ~/somefile
register: result
- file:
path: ~/somefile
state: touch
when: result|succeeded
如果您想知道这里发生了什么,请添加:
- debug: var=result
请注意通知者,他们 运行 在播放结束时。这意味着如果一个通知程序被一个任务触发但随后播放失败,则通知程序将不会是 运行。相反,有一些 Ansible 选项会导致通知程序 运行,即使不是由任务触发也是如此。
这是我根据@techraf
的回答实际实现的- command: echo 'phew'
register: itworks
notify: Done itworks
when: ansible_local.itworks | d(0) == 0
和处理程序:
- name: Done itworks
copy:
content: '{{ itworks }}'
dest: /etc/ansible/facts.d/itworks.fact
文档:
http://docs.ansible.com/ansible/playbooks_variables.html#local-facts-facts-d
感谢@techraf 这很好用并且坚持事实。
编辑
在@techraf 的评论中应用了默认值逻辑。