Ansible 中 Puppet 的“unless”对应什么?

Ansible 中 Puppet 的“unless”对应什么?

背景:在 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。如果该文件丢失或虚拟主机已被人为删除,该怎么办?Puppetunless始终会执行命令,因此可以明确命令是否需要执行。

答案1

我认为你正在做的是这样的:

- 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不会创建文件。如果您捕获viaregister的输出,则内容将与系统的当前状态一样有效。rabbitmqctl list_vhostsregister

答案2

问题出在行上when: rabbitmqctl list_vhosts | grep sensu。这里无法使用 bash。

您需要将其放入rabbitmqctl list_vhosts | grep sensu单独的任务中并注册结果以在 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当字符串 sensu 不在已注册的 中时才会被执行rabbitmq_vhosts

请参阅条件语句Jinja 过滤器了解更多信息。

答案3

选项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 个条目时运行任务

相关内容