当任务结果产生变化时,通过 notify
通知handler做相应处理。
---
- hosts: all
tasks:
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify:
- handler1
handlers:
- name: handler1
debug:
msg: "I am handler1"
运行结果如下:
TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task1"
}
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
注意:只有task产生变化时,才会触发notify。由于debug语句不产生变化,所以指定 changed_when: true
,强制task1产生变化。
---
- hosts: all
tasks:
- name: task1
debug:
msg: "I am task1"
- name: task2
debug:
msg: "I am task2"
changed_when: true
notify:
- handler2
- handler1
- name: task3
debug:
msg: "I am task3"
handlers:
- name: handler1
debug:
msg: "I am handler1"
- name: handler2
debug:
msg: "I am handler2"
运行结果如下:
TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {
"msg": "I am task1"
}
TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task2"
}
TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => {
"msg": "I am task3"
}
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
RUNNING HANDLER [handler2] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler2"
}
可见:
---
- hosts: all
tasks:
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify:
- handler1
- name: task2
debug:
msg: "I am task2"
changed_when: true
notify:
- handler1
handlers:
- name: handler1
debug:
msg: "I am handler1"
运行结果如下:
TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task1"
}
TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task2"
}
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
可见,若多个task notify同一个handler,该handler只会运行一次。
listen
匹配topic前面的例子,在notify时,是通过handler的 name
来匹配topic的。也可以通过handler的 listen
来匹配:
---
- hosts: all
tasks:
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify:
- task1 changed
- name: task2
debug:
msg: "I am task2"
changed_when: true
notify:
- task2 changed
handlers:
- name: handler1
debug:
msg: "I am handler1"
listen:
- "task2 changed"
- "task1 changed"
运行结果如下:
TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task1"
}
TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task2"
}
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
可见,通过 listen
,一个handler可以监听多个nofiy的topic。
下面的play,运行结果是什么?
---
- hosts: all
tasks:
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify:
- task1 changed
- name: task2
debug:
msg: "I am task2"
changed_when: true
notify:
- task2 changed
handlers:
- name: handler1
debug:
msg: "I am handler1"
listen: "task2 changed"
- name: handler2
debug:
msg: "I am handler2"
listen:
- "task2 changed"
- "task1 changed"
- name: handler3
debug:
msg: "I am handler3"
listen: "task1 changed"
答:运行结果为:
TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task1"
}
TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task2"
}
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
RUNNING HANDLER [handler2] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler2"
}
RUNNING HANDLER [handler3] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler3"
}
前面提到,handler是在所有task运行结束后才运行的。如果想要立即运行handler,可用 meta: flush_handlers
:
---
- hosts: all
tasks:
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify: handler2
- name: flush
meta: flush_handlers
- name: task2
debug:
msg: "I am task2"
changed_when: true
notify: handler1
- name: task3
debug:
msg: "I am task3"
handlers:
- name: handler1
debug:
msg: "I am handler1"
- name: handler2
debug:
msg: "I am handler2"
运行结果如下:
TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task1"
}
TASK [flush] ***************************************************************************************
RUNNING HANDLER [handler2] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler2"
}
TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task2"
}
TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => {
"msg": "I am task3"
}
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
可见,flush之后,handler2立即运行了,而handler1则是在所有task都运行结束之后才运行的。
注意:flush触发运行的handler,如果随后又被notify,还会再次运行:
---
- hosts: all
tasks:
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify: handler1
- name: flush
meta: flush_handlers
- name: task2
debug:
msg: "I am task2"
changed_when: true
notify: handler1
handlers:
- name: handler1
debug:
msg: "I am handler1"
运行结果如下:
TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task1"
}
TASK [flush] ***************************************************************************************
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task2"
}
RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
可见,handler1运行了两次。
---
- hosts: all
vars:
var1: "aaa"
tasks:
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify: handler {{ var1 }}
handlers:
- name: handler {{ var1 }}
debug:
msg: "I am handler1"
运行结果如下:
TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {
"msg": "I am task1"
}
RUNNING HANDLER [handler aaa] **********************************************************************
ok: [192.168.1.55] => {
"msg": "I am handler1"
}
没有问题。但是,这里有个潜在的问题:
---
- hosts: all
#vars:
# var1: "aaa"
tasks:
- name: task0
set_fact:
var1: "aa"
- name: task1
debug:
msg: "I am task1"
changed_when: true
notify: handler {{ var1 }} # 可以识别
handlers:
- name: handler {{ var1 }} # 无法识别
debug:
msg: "I am handler1"
运行结果如下:
TASK [task0] ***************************************************************************************
ok: [192.168.1.55]
TASK [task1] ***************************************************************************************
[WARNING]: Handler 'handler {{ var1 }}' is unusable because it has no listen topics and the name
could not be templated (host-specific variables are not supported in handler names). The error:
'var1' is undefined. 'var1' is undefined
ERROR! The requested handler 'handler aa' was not found in either the main handlers list nor in the listening handlers list
可见,对于动态定义的变量,notify可以识别,而handler命名处无法识别(未定义)。
类似的,如果已定义的变量,如果动态改变其值,notify可以识别,而handler命名处仍然是原值。
所以,最好不要在handler命名处使用变量。
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html