使用 Ansible 检查服务是否存在
Check if service exists with Ansible
我有一个 Ansible 剧本,用于将 Java 应用程序部署为 init.d 守护进程。
作为 Ansible 和 Linux 的初学者,我无法根据主机的状态有条件地在主机上执行任务。
也就是说,我有一些主机已经提供了服务,运行 我想在做任何其他事情之前停止它。然后可能会有新的主机,它们还没有这项服务。所以我不能简单地使用 service: name={{service_name}} state=stopped
,因为这在新主机上会失败。
我怎样才能做到这一点?这是我目前所拥有的:
- name: Check if Service Exists
shell: "if chkconfig --list | grep -q my_service; then echo true; else echo false; fi;"
register: service_exists
# This should only execute on hosts where the service is present
- name: Stop Service
service: name={{service_name}} state=stopped
when: service_exists
register: service_stopped
# This too
- name: Remove Old App Folder
command: rm -rf {{app_target_folder}}
when: service_exists
# This should be executed on all hosts, but only after the service has stopped, if it was present
- name: Unpack App Archive
unarchive: src=../target/{{app_tar_name}} dest=/opt
当然我也可以只检查 /etc/init.d 中是否存在包装脚本。这就是我最终得到的结果:
- name: Check if Service Exists
stat: path=/etc/init.d/{{service_name}}
register: service_status
- name: Stop Service
service: name={{service_name}} state=stopped
when: service_status.stat.exists
register: service_stopped
如果 "service" 模块可以处理 "unrecognized service" 错误就好了。
这是我的方法,使用 service
命令而不是检查初始化脚本:
- name: check for apache
shell: "service apache2 status"
register: _svc_apache
failed_when: >
_svc_apache.rc != 0 and ("unrecognized service" not in _svc_apache.stderr)
- name: disable apache
service: name=apache2 state=stopped enabled=no
when: "_svc_apache.rc == 0"
- 检查"service status"的退出代码,当输出包含"unrecognized service"
时接受退出代码0
- 如果退出代码为 0,则该服务已安装(已停止或 运行)
我将 修改为仅使用 service
命令的 return 代码(这适用于 Mint 18.2)
- name: Check if Logstash service exist
shell: service logstash status
register: logstash_status
failed_when: not(logstash_status.rc == 3 or logstash_status.rc == 0)
- name: Check if Logstash service exist
service:
name: logstash
state: stopped
when: logstash_status.rc == 0
请参阅 Ansible 2.5 中新增的 service_facts
模块。
- name: Populate service facts
service_facts:
- debug:
msg: Docker installed!
when: "'docker' in services"
我的几分钱。与上述方法相同,但适用于 kubernetes
检查kublete服务是否运行
- name: "Obtain state of kublet service"
command: systemctl status kubelet.service
register: kubelet_status
failed_when: kubelet_status.rc > 3
如果 kublet 服务不是 运行
,则显示调试信息
- debug:
msg: "{{ kubelet_status.stdout }}"
when: "'running' not in kubelet_status.stdout"
systemd 的另一种方法 ():
- name: Check if cups-browsed service exists
command: systemctl cat cups-browsed
check_mode: no
register: cups_browsed_exists
changed_when: False
failed_when: cups_browsed_exists.rc not in [0, 1]
- name: Stop cups-browsed service
systemd:
name: cups-browsed
state: stopped
when: cups_browsed_exists.rc == 0
这种只使用服务模块的方式对我们有用:
- name: Disable *service_name*
service:
name: *service_name*
enabled: no
state: stopped
register: service_command_output
failed_when: >
service_command_output|failed
and 'unrecognized service' not in service_command_output.msg
and 'Could not find the requested service' not in service_command_output.msg
基于@Maciej 对 RedHat 8 的回答,并将其与对其所做的评论相结合。
这就是我如何在已经安装 Celery 的情况下设法停止它:
- name: Populate service facts
service_facts:
- debug:
msg: httpd installed!
when: ansible_facts.services['httpd.service'] is defined
- name: Stop celery.service
service:
name: celery.service
state: stopped
enabled: true
when: ansible_facts.services['celery.service'] is defined
您可以删除调试语句——它只是为了确认 ansible_facts 正常工作。
我有一个 Ansible 剧本,用于将 Java 应用程序部署为 init.d 守护进程。
作为 Ansible 和 Linux 的初学者,我无法根据主机的状态有条件地在主机上执行任务。
也就是说,我有一些主机已经提供了服务,运行 我想在做任何其他事情之前停止它。然后可能会有新的主机,它们还没有这项服务。所以我不能简单地使用 service: name={{service_name}} state=stopped
,因为这在新主机上会失败。
我怎样才能做到这一点?这是我目前所拥有的:
- name: Check if Service Exists
shell: "if chkconfig --list | grep -q my_service; then echo true; else echo false; fi;"
register: service_exists
# This should only execute on hosts where the service is present
- name: Stop Service
service: name={{service_name}} state=stopped
when: service_exists
register: service_stopped
# This too
- name: Remove Old App Folder
command: rm -rf {{app_target_folder}}
when: service_exists
# This should be executed on all hosts, but only after the service has stopped, if it was present
- name: Unpack App Archive
unarchive: src=../target/{{app_tar_name}} dest=/opt
当然我也可以只检查 /etc/init.d 中是否存在包装脚本。这就是我最终得到的结果:
- name: Check if Service Exists
stat: path=/etc/init.d/{{service_name}}
register: service_status
- name: Stop Service
service: name={{service_name}} state=stopped
when: service_status.stat.exists
register: service_stopped
如果 "service" 模块可以处理 "unrecognized service" 错误就好了。
这是我的方法,使用 service
命令而不是检查初始化脚本:
- name: check for apache
shell: "service apache2 status"
register: _svc_apache
failed_when: >
_svc_apache.rc != 0 and ("unrecognized service" not in _svc_apache.stderr)
- name: disable apache
service: name=apache2 state=stopped enabled=no
when: "_svc_apache.rc == 0"
- 检查"service status"的退出代码,当输出包含"unrecognized service" 时接受退出代码0
- 如果退出代码为 0,则该服务已安装(已停止或 运行)
我将 service
命令的 return 代码(这适用于 Mint 18.2)
- name: Check if Logstash service exist
shell: service logstash status
register: logstash_status
failed_when: not(logstash_status.rc == 3 or logstash_status.rc == 0)
- name: Check if Logstash service exist
service:
name: logstash
state: stopped
when: logstash_status.rc == 0
请参阅 Ansible 2.5 中新增的 service_facts
模块。
- name: Populate service facts
service_facts:
- debug:
msg: Docker installed!
when: "'docker' in services"
我的几分钱。与上述方法相同,但适用于 kubernetes
检查kublete服务是否运行
- name: "Obtain state of kublet service"
command: systemctl status kubelet.service
register: kubelet_status
failed_when: kubelet_status.rc > 3
如果 kublet 服务不是 运行
,则显示调试信息- debug:
msg: "{{ kubelet_status.stdout }}"
when: "'running' not in kubelet_status.stdout"
systemd 的另一种方法 (
- name: Check if cups-browsed service exists
command: systemctl cat cups-browsed
check_mode: no
register: cups_browsed_exists
changed_when: False
failed_when: cups_browsed_exists.rc not in [0, 1]
- name: Stop cups-browsed service
systemd:
name: cups-browsed
state: stopped
when: cups_browsed_exists.rc == 0
这种只使用服务模块的方式对我们有用:
- name: Disable *service_name*
service:
name: *service_name*
enabled: no
state: stopped
register: service_command_output
failed_when: >
service_command_output|failed
and 'unrecognized service' not in service_command_output.msg
and 'Could not find the requested service' not in service_command_output.msg
基于@Maciej 对 RedHat 8 的回答,并将其与对其所做的评论相结合。
这就是我如何在已经安装 Celery 的情况下设法停止它:
- name: Populate service facts
service_facts:
- debug:
msg: httpd installed!
when: ansible_facts.services['httpd.service'] is defined
- name: Stop celery.service
service:
name: celery.service
state: stopped
enabled: true
when: ansible_facts.services['celery.service'] is defined
您可以删除调试语句——它只是为了确认 ansible_facts 正常工作。