使用Ansible记住命令的最佳方法是先前成功执行了什么?

时间:2017-01-27 04:14:19

标签: ansible ansible-playbook

使用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

这种方法有效,但有点难看。任何人都可以放弃最佳实践吗?也许设定一些事实?也许是一种全新的方法?

3 个答案:

答案 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的评论中应用默认值逻辑。