我正在运行 Ansible 2.0,我可以直接运行它,但是我也可能被我的经验测试所欺骗而相信一些不真实的东西,而且我找不到任何文档来告诉我何时应该运行处理程序。
如果处理程序在其任务结束时没有运行,这就是我的难题。我有一个包含 5 个角色的剧本,我想在最后添加一个第 6 个角色,它需要先完成第 4 个角色的处理程序才能启动。
有没有办法运行 Ansible 来依赖于处理程序的完成(即角色完全完成)然后再执行其他操作,或者我使用处理程序的方式错误?
答案1
处理程序执行如下:
- 在戏剧(不是剧本)的结尾
meta: flush_handlers
执行任务时
所以 ”在末尾添加第 6 个角色,该角色需要有第 4 个角色的处理程序“ 你需要:
- 或者将角色分配分成单独的剧目;
或者添加一个元任务并包含第 6 个角色
include_role
模块:roles: - role4 tasks: - meta: flush_handlers - include_role: name: role6
对于您的用例,我建议使用第一种方法,因为该include_role
模块仍然很新,并且在使用时存在一些怪癖(请参阅这个问题)。
此外,请注意处理程序的名称和监听调用是全局的,因此,如果两个处理程序具有相同的名称并且在单个剧目中分配了两个角色,则处于不同角色的两个处理程序将发生冲突。(参考。处理程序:在更改时运行操作)
处理程序 [ ] 由全局唯一名称引用,并由通知程序通知。[ ] 处理程序,它将只运行一次,在特定播放中的所有任务完成后。
处理程序名称和监听主题位于全局命名空间中。
经验证明(运行此 shell 脚本来确认处理程序在剧本结束时执行 - 这里有矛盾的评论和答案):
#!/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"
答案2
处理程序是任务列表,与常规任务并无太大区别,它们由全局唯一名称引用,并由通知程序通知。如果没有通知处理程序,它将不会运行。无论有多少任务通知处理程序,它都只会在特定剧集中的所有任务完成后运行一次。ansible 文档
1) 执行相同操作的处理程序应使用相同的名称。
restart nginx
始终重新启动 nginx,而handler1
不是handler2
2) 处理程序在整个“播放”结束时运行,播放范围仅限于您的部分。
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
有很多方法可以完成相同的任务。处理程序旨在防止多次重新启动同一进程,例如对具有网站、ssl 证书和其他需要重新启动服务的任务的 nginx 服务器进行多次更改。