Ansible处理程序不运行多个处理程序任务

时间:2014-01-27 19:01:35

标签: handler ansible

我们有一个Ansible角色,需要在handlers/main.yml任务文件中运行三个任务,但它只运行第一个任务。如何强制它运行其他两个任务?如果第一个任务失败,我确实有ignore标志。

tasks/main.yml文件如下所示:

- name: openfire | Copy plugins into openfire/plugins
  copy: src={{ srcdir }}/xmpp/{{ item }} dest=${bindir}/openfire/plugins/{{ item }}
  with_items:
   - x.jar
   - y.jar
  sudo: yes
  sudo_user: ${tomcat_user}
  notify: restart openfire

- name: openfire | Copy jars into openfire/lib
  copy: src={{ srcdir }}/xmpp/{{ item }} dest=${bindir}/openfire/lib/{{ item }}
  with_items:
   - a.jar
   - b.jar
  sudo: yes
  sudo_user: ${tomcat_user}
  notify: restart openfire

handlers/main.yml文件如下所示:

- name: restart openfire
  service: name=openfire state=stopped
  ignore_errors: true
  sudo: yes

- name: restart openfire
  file: path=/var/run/openfire.pid state=absent
  sudo: yes

- name: restart openfire
  service: name=openfire state=restarted enabled=yes
  sudo: yes

只运行第一个处理程序任务(关闭openfire)。

4 个答案:

答案 0 :(得分:20)

处理程序可以调用另一个通知。还允许多次通知呼叫:

---
- name: restart something
  command: shutdown.sh 
  notify:
    - wait for stop
    - start something
    - wait for start

- name: wait for stop
  wait_for: port={{port}} state=stopped

- name: start something
  command: startup.sh

- name: wait for start
  wait_for: port={{port}} state=started

答案 1 :(得分:17)

从Ansible 2.2开始,您现在可以使用listen指令同时通知多个处理程序:

- name: stop openfire
  listen: restart openfire
  service: name=openfire state=stopped
  ignore_errors: true
  sudo: yes

- name: remove openfire pid file
  listen: restart openfire
  file: path=/var/run/openfire.pid state=absent
  sudo: yes

- name: restart openfire
  listen: restart openfire
  service: name=openfire state=restarted enabled=yes
  sudo: yes

答案 2 :(得分:9)

也许为时已晚,因为你的帖子是从1月开始的,但是......为什么你要为所有不同的处理程序命名?应该通过name在任务中调用处理程序,因此您可能需要以不同的方式命名它们。尝试将处理程序文件更改为以下内容:

- name: stop openfire
  service: name=openfire state=stopped
  ignore_errors: true
  sudo: yes

- name: remove openfire pid
  file: path=/var/run/openfire.pid state=absent
  sudo: yes

- name: restart openfire
  service: name=openfire state=restarted enabled=yes
  sudo: yes

无论如何,我同意Mxx的观点,即这个处理程序文件很奇怪。使用state=restarted就足够了。

答案 3 :(得分:8)

以上示例代码在Ansible中使用notify的方式尚未获得官方支持,因此我并不感到惊讶它不能正常工作(如果它曾经是这样的话会感到惊讶真的工作)。在您的特定情况下,使用Playbook中的一个任务或仅使用state=restarted重新启动服务的处理程序,将是更好的选择:

- service: name=openfire state=restarted enabled=yes

但是,如果您执行需要在一次操作后运行多个处理程序,那么最好的方法是通知链中的每个单独命令。请注意,这几乎总是表明一个更深层次的问题...但是每隔一段时间,我就必须在某个处理程序完成后通知另一个处理程序,如下所示:

# Inside handlers/main.yml:
- name: import database
  mysql_db: name=database state=import target=/path/to/dump.sql
  notify: run shell script

- name: run shell script
  shell: /path/to/some/shell/script.sh

这应该是非常罕见的,但我不认为某些情况下的选项太糟糕了(在我的情况下,我必须导入数据库转储,然后运行shell脚本)完成,并且使该操作具有幂等性的最佳方法是通知import database处理程序,而不是直接在我的剧本中进行导入。)