handler - simple - playbooks examples ansible
El manejador ansible no ejecuta mĂșltiples tareas de manejador (4)
Tenemos un rol Ansible que necesita ejecutar tres tareas en el archivo de tareas handlers/main.yml
, pero solo ejecuta la primera tarea. ¿Cómo lo obligo a ejecutar las otras dos tareas? Tengo el indicador de ignore
activado si la primera tarea falla.
El archivo tasks/main.yml
parece a:
- 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
El archivo handlers/main.yml
ve como:
- 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
Solo se ejecuta la primera tarea del controlador (cerrar openfire).
A partir de Ansible 2.2, ahora puede notificar varios manejadores al mismo tiempo utilizando la directiva de 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
Es posible que el manejador llame a otra notificación. También se permiten múltiples llamadas de notificación:
---
- 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
La forma en que el código de ejemplo anterior usa notify
en Ansible no se admite oficialmente, por lo que no me sorprende que no funcione (y me sorprendería si alguna vez realmente funcionara). En su caso particular, usar una tarea en su libro de jugadas o un controlador que simplemente usa state=restarted
para reiniciar el servicio, sería una mejor opción:
- service: name=openfire state=restarted enabled=yes
Sin embargo, si necesita ejecutar varios manejadores como resultado de una operación, la mejor manera de hacerlo sería notificar cada comando por separado en una cadena. Tenga en cuenta que esto casi siempre es indicativo de un problema más profundo ... pero de vez en cuando, he tenido que notificar a otro manejador después de que un manejador determinado haya completado, así:
# 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
Esto debería ser bastante raro, pero no creo que sea una opción tan mala para ciertos escenarios (en mi caso, tuve que importar un volcado de base de datos, luego ejecutar un script de shell después de que se completara, y la mejor manera de hacerlo). La operación idempotent fue notificar al controlador de la import database
lugar de intentar realizar la importación directamente en mi libro de jugadas).
Tal vez sea demasiado tarde, ya que su publicación es de enero, pero ... ¿por qué nombra de manera idéntica a todos los diferentes manejadores? Se supone que los manejadores deben llamarse en las tareas por su name
, por lo que quizás deba nombrarlos de manera diferente. Intenta cambiar el archivo de controladores a algo como esto:
- 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
De todos modos, estoy de acuerdo con Mxx en el punto de que este archivo de controladores es bastante extraño. Debería ser suficiente con un state=restarted
.