无法使用“ failed_when”进行错误处理

时间:2019-04-29 14:58:25

标签: ansible

我希望创建一个可在多台服务器上运行的ansible剧本,以检查是否符合合规性规则。因此,剧本应该检查是否禁用了多个服务以及它们是否已停止。 我确实知道并非所有服务都将在所有计算机上运行或启用。因此,我希望处理剧本中的某些返回码。

我为此任务尝试了failed_when语句。这似乎是一条路,因为它允许设置要处理的RC。

- hosts: server_group1
   remote_user: ansible
   tasks:
  - name: Stop services
    command: /bin/systemctl stop "{{ item }}"
    with_items:
         - cups
         - avahi
         - slapd
         - isc-dhcp-server
         - isc-dhcp-server6
         - nfs-server
         - rpcbind
         - bind9
         - vsftpd
         - dovecot
         - smbd
         - snmpd
         - squid

    register: output
    failed_when: "output.rc != 0 and output.rc != 1"

但是,只有当我使用示例代码中未显示的ignore_errors: True时,循环才起作用。 我确实知道我希望从剧本执行的命令中捕获0和1的RC。但是无论failed_when为何总是产生致命错误,我的剧本也会失败。 我也尝试了不带“”的failed_when行,但这并没有改变。 缺少了一些东西,但我看不到。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

  

因此,剧本应该检查是否禁用了多个服务以及它们是否已停止。

您的剧本没有做任何一件事情。如果某个服务存在,无论它是否正在运行,则在大多数情况下systemctl stop <service>将成功返回。唯一会获得非零退出代码的原因是(a)服务不存在或(b)systemd由于某种原因而无法停止服务。

请注意,调用systemctl stop对是否禁用服务无效;使用您当前的剧本,所有这些服务将在主机下次启动时启动。

如果您的目标不只是检查停止和禁用服务,而是确保停止和禁用服务,则可以执行以下操作:

- name: "Stop services"
  service:
    name: "{{ item }}"
    enabled: false
    state: stopped
  ignore_errors: true
  register: results
  loop:
    - cups
    - avahi
    - slapd
    - isc-dhcp-server
    - isc-dhcp-server6
    - nfs-server
    - rpcbind
    - bind9
    - vsftpd
    - dovecot
    - smbd
    - snmpd
    - squid

您可能在这里想要 ignore_errors: true,因为您要为列表中的每个项目运行任务。

处理错误的另一种方式可能是:

failed_when: >-
  results is failed and
  "Could not find the requested service" not in results.msg|default('')

只有在终止服务的原因是其他而不是目标主机上没有匹配的服务的情况下,任务才会失败。