在Ansible中,Puppet的“除非”是什么意思?


9

背景:在Puppet中,除非已执行命令,否则可以执行该命令:

exec { '/bin/echo root >> /usr/lib/cron/cron.allow':
  path   => '/usr/bin:/usr/sbin:/bin',
  unless => 'grep root /usr/lib/cron/cron.allow 2>/dev/null',
}

目的:执行命令,除非该命令已在Ansible中运行

方法

任务/ main.yml

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu

结果

TASK [ansible-rabbitmq : add vhost sensu] **************************************
fatal: [111.222.333.444]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl",
"add_vhost", "/sensu"], "delta": "0:00:00.210140", "end": 
"2016-07-29 12:55:19.384455", "failed": true, "rc": 2, "start":
"2016-07-29 12:55:19.174315", "stderr": "Error: vhost_already_exists: /sensu", 
"stdout": "Creating vhost \"/sensu\" ...", "stdout_lines": 
["Creating vhost \"/sensu\" ..."], "warnings": []}

讨论区

谷歌搜索unless ansible显示此文档有关when。根据该文档,when添加了一条语句:

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: rabbitmqctl list_vhosts | grep sensu

运行代码导致:

fatal: [192.168.0.9]: FAILED! => {"failed": true, "msg": "The conditional
 check 'rabbitmqctl list_vhosts | grep sensu' failed. The error was: template
 error while templating string: expected token 'end of statement block', got
 'list_vhosts'. String: {% if rabbitmqctl list_vhosts | grep sensu %} True {%
 else %} False {% endif %}\n\nThe error appears to have been in '/etc/ansible
/roles/ansible-rabbitmq/tasks/main.yml': line 10, column 3, but may\nbe
 elsewhere in the file depending on the exact syntax problem.\n\nThe
 offending line appears to be:\n\n\n- name: add vhost sensu\n  ^ here\n"}
  1. 首先,假设when成功了,那么该命令将不会运行,然后看起来更像onlyif在Puppet中
  2. 其次,如果何时成功,应该使用升级标记来模拟一个除非吗?
  3. 使用register。如果该文件丢失或虚拟主机被某个人删除了怎么办?Puppet unless始终执行命令,以便清楚是否需要执行命令。

Answers:


9

我认为您正在寻找的是这样的:

- name: get vhosts
  command: rabbitmqctl list_vhosts
  register: vhosts
  changed_when: false

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: "'/sensu' not in vhosts.stdout"

回复:#3 register不会创建文件。如果要捕获rabbitmqctl list_vhostsvia 的输出register,则内容将与系统的当前状态一样有效。


3

问题是线when: rabbitmqctl list_vhosts | grep sensu。在这里不能使用bash。

您需要将rabbitmqctl list_vhosts | grep sensuin 放在单独的任务中,并注册结果以在when子句中使用它。您可以使用not过滤器获得unless类似行为。

这样的事情应该起作用:

- name: Get rabbitmq vhosts.
  command: rabbitmqctl list_vhosts | grep sensu
  register: rabbitmq_vhosts

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: not 'sensu' in rabbitmq_vhosts.stdout

Get rabbitmq vhosts.在这个例子中就一定会执行。该add vhost sensu只如果字符串意义上并不在注册rabbitmq_vhosts

有关更多信息,请参阅有关条件Jinja过滤器的文档。


问题仍然存在:fatal: [IP]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl", "add_vhost", "/sensu"], "delta": "0:00:00.198681", "end": "2016-07-29 13:43:00.870193", "failed": true, "rc": 2, "start": "2016-07-29 13:43:00.671512", "stderr": "Error: vhost_already_exists: /sensu", "stdout": "Creating vhost \"/sensu\" ...", "stdout_lines": ["Creating vhost \"/sensu\" ..."], "warnings": []}
030 2016年

嗯,可能是我的错。我想这是.stdout我的答案遗漏了。
亨里克·平格尔'16

0

when选项是Ansible关于条件的唯一选择。但是您不能在那里直接定义命令。when期望Jinja表达,并在Ansible对照宿主上评估。因此,您首先需要运行任务以获取结果并注册。

- shell: rabbitmqctl list_vhosts | grep sensu
  register: sensu_vhosts

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: sensu_vhosts.stdout_lines < 1

stdout_lines是shell任务返回的所有行的数组。因此,您可以计算条目数,并且仅在返回0个项目后才运行任务


2
如果/ sensu虚拟主机不存在,则会导致:fatal: [IP]: FAILED! => {"changed": true, "cmd": "rabbitmqctl list_vhosts | grep sensu", "delta": "0:00:00.198769", "end": "2016-07-29 13:45:59.069981", "failed": true, "rc": 1, "start": "2016-07-29 13:45:58.871212", "stderr": "", "stdout": "", "stdout_lines": [], "warnings": []}
030 2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.