使用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
这种方法有效,但有点难看。任何人都可以放弃最佳实践吗?也许设定一些事实?也许是一种全新的方法?
答案 0 :(得分:3)
在特定目标主机上成功运行命令是事实(使用通用语言),因此最合适的是使用local facts(在Ansible白话中)。
在您的处理程序中将状态保存为/etc/ansible/facts.d
下带有copy
模块和content
参数的JSON文件。
只要您通过常规事实收集过程对主机进行游戏,就会检索并访问它。
然后,您可以使用when
条件控制任务(当事件尚未存在时,您需要包含default
过滤器。)
答案 1 :(得分:2)
理想情况下,使用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选项会导致通知程序即使不是由任务触发也会运行。
答案 2 :(得分:0)
这是我基于@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的评论中应用默认值逻辑。