summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2016-11-13 01:26:43 -0600
committerJames Cammarata <jimi@sngx.net>2016-11-13 01:26:43 -0600
commitdeaae2bcb83068a18c0b418ab7aaae4fef1ea8be (patch)
tree1d2566952efe347bfda77f9e1806d98ef060565c
parent527d8307c133100a3ca585589d590c598608ef07 (diff)
downloadansible-issue_17846_nameless_listening_handlers.tar.gz
Alternately track listening handlers by uuid if no name is setissue_17846_nameless_listening_handlers
Fixes #17846
-rw-r--r--lib/ansible/executor/task_queue_manager.py9
-rw-r--r--lib/ansible/plugins/strategy/__init__.py44
-rwxr-xr-xtest/integration/targets/handlers/runme.sh1
-rw-r--r--test/integration/targets/handlers/test_handlers.yml25
-rw-r--r--test/integration/targets/handlers/test_listening_handlers.yml25
5 files changed, 85 insertions, 19 deletions
diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py
index d738c19ce3..0732cb29ee 100644
--- a/lib/ansible/executor/task_queue_manager.py
+++ b/lib/ansible/executor/task_queue_manager.py
@@ -147,7 +147,14 @@ class TaskQueueManager:
for listener in listeners:
if listener not in self._listening_handlers:
self._listening_handlers[listener] = []
- self._listening_handlers[listener].append(handler.get_name())
+
+ # 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())
+ else:
+ self._listening_handlers[listener].append(handler._uuid)
def load_callbacks(self):
'''
diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py
index 381e60af78..f2cf7844d2 100644
--- a/lib/ansible/plugins/strategy/__init__.py
+++ b/lib/ansible/plugins/strategy/__init__.py
@@ -241,26 +241,32 @@ class StrategyBase:
def search_handler_blocks(handler_name, handler_blocks):
for handler_block in handler_blocks:
for handler_task in handler_block.block:
- handler_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, task=handler_task)
- templar = Templar(loader=self._loader, variables=handler_vars)
- try:
- # first we check with the full result of get_name(), which may
- # include the role name (if the handler is from a role). If that
- # is not found, we resort to the simple name field, which doesn't
- # have anything extra added to it.
- target_handler_name = templar.template(handler_task.name)
- if target_handler_name == handler_name:
- return handler_task
- else:
- target_handler_name = templar.template(handler_task.get_name())
+ if handler_task.name:
+ handler_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, task=handler_task)
+ templar = Templar(loader=self._loader, variables=handler_vars)
+ try:
+ # first we check with the full result of get_name(), which may
+ # include the role name (if the handler is from a role). If that
+ # is not found, we resort to the simple name field, which doesn't
+ # have anything extra added to it.
+ target_handler_name = templar.template(handler_task.name)
if target_handler_name == handler_name:
return handler_task
- except (UndefinedError, AnsibleUndefinedVariable):
- # We skip this handler due to the fact that it may be using
- # a variable in the name that was conditionally included via
- # set_fact or some other method, and we don't want to error
- # out unnecessarily
- continue
+ else:
+ target_handler_name = templar.template(handler_task.get_name())
+ if target_handler_name == handler_name:
+ return handler_task
+ except (UndefinedError, AnsibleUndefinedVariable):
+ # We skip this handler due to the fact that it may be using
+ # a variable in the name that was conditionally included via
+ # set_fact or some other method, and we don't want to error
+ # out unnecessarily
+ 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
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)
if listening_handler is not None:
found = True
+ else:
+ continue
if original_host not in self._notified_handlers[listening_handler]:
self._notified_handlers[listening_handler].append(original_host)
display.vv("NOTIFIED HANDLER %s" % (listening_handler_name,))
diff --git a/test/integration/targets/handlers/runme.sh b/test/integration/targets/handlers/runme.sh
index b1af33b335..9b709de326 100755
--- a/test/integration/targets/handlers/runme.sh
+++ b/test/integration/targets/handlers/runme.sh
@@ -3,6 +3,7 @@
set -eux
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 \
| egrep -o 'RUNNING HANDLER \[test_handlers : .*?]')" = "RUNNING HANDLER [test_handlers : test handler]" ]
diff --git a/test/integration/targets/handlers/test_handlers.yml b/test/integration/targets/handlers/test_handlers.yml
index 87d04b6c90..142eeb387d 100644
--- a/test/integration/targets/handlers/test_handlers.yml
+++ b/test/integration/targets/handlers/test_handlers.yml
@@ -18,6 +18,31 @@
- "'handler2_called' in hostvars[inventory_hostname]"
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
hosts: testgroup
gather_facts: False
diff --git a/test/integration/targets/handlers/test_listening_handlers.yml b/test/integration/targets/handlers/test_listening_handlers.yml
new file mode 100644
index 0000000000..6500f02cfb
--- /dev/null
+++ b/test/integration/targets/handlers/test_listening_handlers.yml
@@ -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