使用Ansible停止可能不存在的服务

时间:2018-08-09 11:05:17

标签: ansible

我正在使用Ansible 2.6.1

我正在尝试确保某些服务未在目标主机上运行。 问题在于某些主机上可能根本不存在该服务。如果是这种情况,Ansible会因为缺少服务而失败并显示错误。服务由Systemd运行。

使用服务模块:

  - name: Stop service
    service:
      name: '{{ target_service }}'
      state: stopped

失败,错误为Could not find the requested service SERVICE: host

尝试使用命令模块:

 - name: Stop service
   command: service {{ target_service }} stop

给出错误:Failed to stop SERVICE.service: Unit SERVICE.service not loaded.

我知道我可以使用ignore_errors: yes,但它也可能隐藏真正的错误。

另一个解决方案是执行2个任务。一种检查服务是否存在,另一种则仅在第一个任务发现有服务但感觉很复杂时才运行。

是否有更简单的方法来确保服务停止并避免错误(如果服务不存在)?

5 个答案:

答案 0 :(得分:2)

我正在使用以下步骤:

- name: Get the list of services
  service_facts:

- name: Stop service
  systemd:
    name: <service_name_here>
    state: stopped
  when: "'<service_name_here>.service' in services"

service_facts 可以在收集事实阶段调用一次。

答案 1 :(得分:1)

以下将在service_stop中注册模块输出;如果模块执行的标准输出不包含 "Could not find the requested service" 并且服务无法根据返回码停止,则模块执行将失败。由于您没有包含整个堆栈跟踪,我假设您发布的错误在标准输出中,您可能需要根据您的错误稍作更改。

- name: Stop service
  register: service_stop
  failed_when: 
    - '"Could not find the requested service" not in service_stop.stdout'
    - service_stop.rc != 0
  service:
    name: '{{ target_service }}'
    state: stopped

答案 2 :(得分:0)

恕我直言,没有简单的方法来确保服务已停止。 Ansible service 模块不检查服务的存在。 (1)多于一个任务,或者(2)需要检查服务是否存在的命令。该命令将特定于操作系统。例如FreeBSD

command: "service -e | grep {{ target_service }} && service {{ target_service }} stop"

答案 3 :(得分:0)

与Vladimir的解决方案相同,但适用于Ubuntu(systemd),并且具有更好的状态处理:

- name: restart {{ target_service }} if exists
  shell: if systemctl is-enabled --quiet {{ target_service }}; then systemctl restart {{ target_service }} && echo restarted ; fi
  register: output
  changed_when: "'restarted' in output.stdout"

它产生3个状态:

  • 服务缺失或禁用-ok
  • 服务存在并已重新启动-changed
  • 服务存在且重新启动失败-failed

答案 4 :(得分:0)

当服务模块出现故障时,检查是否安装了需要停止的服务。这与 this answer 类似,但避免了除非必要的相当冗长的服务事实收集。

- name: Stop a service
  block:
    - name: Attempt to stop the service
      service:
        name:  < service name >
        state: stopped
  rescue:
    - name: Get the list of services
      service_facts:

    - name: Verify that Nagios is not installed
      assert:
        that:
          - "'< service name >.service' not in services"