Я использую Ansible 2.0, и я мог бы просто запустить это, но мои эмпирические тесты могли обмануть меня и заставить поверить в то, что не соответствует действительности, и я не могу найти никакой документации, которая сообщала бы мне, когда должны запускаться обработчики.
Если обработчики не запускаются в конце своих задач, это моя загадка. У меня есть playbook с 5 ролями в нем, я хочу добавить 6 ролей в конец, которые должны быть завершены обработчиками 4-й роли, прежде чем она может начаться.
Есть ли способ запустить Ansible, чтобы полагаться на завершение обработчика (то есть на полное выполнение роли), прежде чем делать что-то еще, или я неправильно использую обработчики?
Обработчики выполняются:
meta: flush_handlers
задачаТак "добавить в конец роль 6, в которой должны быть обработчики 4 роли" тебе нужно:
или добавьте метазадачу и включите шестую роль с include_role
модуль:
roles:
- role4
tasks:
- meta: flush_handlers
- include_role:
name: role6
Для вашего случая использования я бы предложил первый метод в качестве include_role
модуль еще очень свежий и при его использовании есть свои особенности (см. этот вопрос на SO).
Более того, обратите внимание, что имена обработчиков и вызовы прослушивания являются глобальными, поэтому два обработчика с разными ролями будут конфликтовать, если у них было одно и то же имя и обе роли были назначены в одной игре. (исх. Обработчики: выполнение операций при изменении)
Обработчики [] упоминаются по глобально уникальному имени и уведомляются уведомителями. [] обработчик, он будет запущен только один раз после того, как все задачи будут выполнены в определенной игре.
Имена обработчиков и темы прослушивания живут в глобальном пространстве имен.
Эмпирическое доказательство (запустите этот сценарий оболочки, чтобы убедиться, что обработчики выполняются в конце игры - здесь были противоречивые комментарии и ответы):
#!/bin/bash
mkdir -p ./sf831880/roles/role1
mkdir -p ./sf831880/roles/role1/handlers
mkdir -p ./sf831880/roles/role1/tasks
mkdir -p ./sf831880/roles/role2
mkdir -p ./sf831880/roles/role2/handlers
mkdir -p ./sf831880/roles/role2/tasks
cat >./sf831880/roles/role1/tasks/main.yml <<TASKS1_END
---
- name: Always true in role1
command: echo role1
notify: handler1
TASKS1_END
cat >./sf831880/roles/role2/tasks/main.yml <<TASKS2_END
---
- name: Always true in role2
command: echo role2
notify: handler2
TASKS2_END
cat >./sf831880/roles/role1/handlers/main.yml <<HANDLERS1_END
---
- name: handler1
debug:
msg: "This is a handler in role1"
HANDLERS1_END
cat >./sf831880/roles/role2/handlers/main.yml <<HANDLERS2_END
---
- name: handler2
debug:
msg: "This is a handler in role2"
HANDLERS2_END
cat >./sf831880/playbook.yml <<PLAYBOOK_END
---
- hosts: localhost
gather_facts: no
connection: local
roles:
- role1
- role2
tasks:
- debug:
msg: "This is a task in a play"
PLAYBOOK_END
ansible-playbook ./sf831880/playbook.yml
Результат:
PLAY [localhost] ***************************************************************
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role2 : Always true in role2] ********************************************
changed: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "This is a task in a play"
}
RUNNING HANDLER [role1 : handler1] *********************************************
ok: [localhost] => {
"msg": "This is a handler in role1"
}
RUNNING HANDLER [role2 : handler2] *********************************************
ok: [localhost] => {
"msg": "This is a handler in role2"
Игра изменена, чтобы содержать meta: flush_handlers
:
---
- hosts: localhost
gather_facts: no
connection: local
roles:
- role1
- role2
tasks:
- meta: flush_handlers
- debug:
msg: "This is a task in a play"
Результат:
PLAY [localhost] ***************************************************************
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role2 : Always true in role2] ********************************************
changed: [localhost]
RUNNING HANDLER [role1 : handler1] *********************************************
ok: [localhost] => {
"msg": "This is a handler in role1"
}
RUNNING HANDLER [role2 : handler2] *********************************************
ok: [localhost] => {
"msg": "This is a handler in role2"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "This is a task in a play"
Обработчики - это списки задач, которые на самом деле не отличаются от обычных задач, на которые ссылаются глобально уникальное имя и которые уведомляются уведомителями. Если ничего не уведомляет обработчик, он не будет запущен. Независимо от того, сколько задач уведомляет обработчик, он будет запущен только один раз после того, как все задачи будут выполнены в конкретной игре. доступный документ
1) Обработчики, которые делают одно и то же, должны называться одинаково.
restart nginx
ВСЕГДА перезапускает nginx, а не handler1
и handler2
2) Обработчики запускаются в КОНЦЕ всего "Play", ограниченного вашими разделами.
3) Я бы использовал register
и when
функции для задач, которые необходимо перезапустить, обратите внимание, что эта переменная должна быть у вас.
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Play 1"
}
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]
TASK [role2 : Always true in role2] ********************************************
changed: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "This is a task in a play"
}
RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
"msg": "This is a handler in role1"
}
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Play 2"
}
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role1 : Always true in role1] ********************************************
changed: [localhost]
TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]
TASK [role2 : Always true in role2] ********************************************
changed: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "This is a task in a play"
}
RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
"msg": "This is a handler in role1"
}
PLAY RECAP *********************************************************************
localhost : ok=20 changed=14 unreachable=0 failed=0
Множество способов выполнить одну и ту же задачу. Обработчики были разработаны для предотвращения перезапуска одного и того же процесса несколько раз, например, нескольких изменений на сервере nginx, на котором есть веб-сайты, сертификаты ssl и другие задачи, требующие перезапуска службы.