Alternately track listening handlers by uuid if no name is set

Fixes #17846
This commit is contained in:
James Cammarata 2016-11-13 01:26:43 -06:00
parent 527d8307c1
commit 4f06a86161
5 changed files with 85 additions and 19 deletions

View file

@ -147,7 +147,14 @@ class TaskQueueManager:
for listener in listeners: for listener in listeners:
if listener not in self._listening_handlers: if listener not in self._listening_handlers:
self._listening_handlers[listener] = [] self._listening_handlers[listener] = []
# if the handler has a name, we append it to the list of listening
# handlers, otherwise we use the uuid to avoid trampling on other
# nameless listeners
if handler.name:
self._listening_handlers[listener].append(handler.get_name()) self._listening_handlers[listener].append(handler.get_name())
else:
self._listening_handlers[listener].append(handler._uuid)
def load_callbacks(self): def load_callbacks(self):
''' '''

View file

@ -241,6 +241,7 @@ class StrategyBase:
def search_handler_blocks(handler_name, handler_blocks): def search_handler_blocks(handler_name, handler_blocks):
for handler_block in handler_blocks: for handler_block in handler_blocks:
for handler_task in handler_block.block: for handler_task in handler_block.block:
if handler_task.name:
handler_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, task=handler_task) handler_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, task=handler_task)
templar = Templar(loader=self._loader, variables=handler_vars) templar = Templar(loader=self._loader, variables=handler_vars)
try: try:
@ -261,6 +262,11 @@ class StrategyBase:
# set_fact or some other method, and we don't want to error # set_fact or some other method, and we don't want to error
# out unnecessarily # out unnecessarily
continue continue
else:
# if the handler name is not set, we check via the handlers uuid.
# this is mainly used by listening handlers only
if handler_name == handler_task._uuid:
return handler_task
return None return None
def parent_handler_match(target_handler, handler_name): def parent_handler_match(target_handler, handler_name):
@ -415,6 +421,8 @@ class StrategyBase:
listening_handler = search_handler_blocks(listening_handler_name, iterator._play.handlers) listening_handler = search_handler_blocks(listening_handler_name, iterator._play.handlers)
if listening_handler is not None: if listening_handler is not None:
found = True found = True
else:
continue
if original_host not in self._notified_handlers[listening_handler]: if original_host not in self._notified_handlers[listening_handler]:
self._notified_handlers[listening_handler].append(original_host) self._notified_handlers[listening_handler].append(original_host)
display.vv("NOTIFIED HANDLER %s" % (listening_handler_name,)) display.vv("NOTIFIED HANDLER %s" % (listening_handler_name,))

View file

@ -3,6 +3,7 @@
set -eux set -eux
ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario1 ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario1
ansible-playbook test_listening_handlers.yml -i inventory.handlers -v "$@"
[ "$(ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario2 -l A \ [ "$(ansible-playbook test_handlers.yml -i inventory.handlers -v "$@" --tags scenario2 -l A \
| egrep -o 'RUNNING HANDLER \[test_handlers : .*?]')" = "RUNNING HANDLER [test_handlers : test handler]" ] | egrep -o 'RUNNING HANDLER \[test_handlers : .*?]')" = "RUNNING HANDLER [test_handlers : test handler]" ]

View file

@ -18,6 +18,31 @@
- "'handler2_called' in hostvars[inventory_hostname]" - "'handler2_called' in hostvars[inventory_hostname]"
tags: ['scenario1'] tags: ['scenario1']
- name: verify listening handlers
hosts: A
gather_facts: False
connection: local
tasks:
- name: notify some handlers
command: echo foo
notify:
- notify_listen
post_tasks:
- name: assert all defined handlers ran without error
assert:
that:
- "notify_listen_ran_1 is defined"
- "notify_listen_ran_2 is defined"
handlers:
- name: first listening handler has a name
set_fact:
notify_listen_ran_1: True
listen: notify_listen
# second listening handler does not
- set_fact:
notify_listen_ran_2: True
listen: notify_listen
- name: test handlers - name: test handlers
hosts: testgroup hosts: testgroup
gather_facts: False gather_facts: False

View file

@ -0,0 +1,25 @@
---
- name: verify listening handlers
hosts: A
gather_facts: False
connection: local
tasks:
- name: notify some handlers
command: echo foo
notify:
- notify_listen
post_tasks:
- name: assert all defined handlers ran without error
assert:
that:
- "notify_listen_ran_1 is defined"
- "notify_listen_ran_2 is defined"
handlers:
- name: first listening handler has a name
set_fact:
notify_listen_ran_1: True
listen: notify_listen
# second listening handler does not
- set_fact:
notify_listen_ran_2: True
listen: notify_listen