summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cammarata <jimi@sngx.net>2016-08-15 13:45:02 -0500
committerJames Cammarata <jimi@sngx.net>2016-08-15 14:09:23 -0500
commita07ae3a2a733b54418aad62d48403b7035210007 (patch)
tree872406604302743b51afb90074c75a77b9aa8495
parentbf8c871801fe75557823cdeb8228da9d18ece599 (diff)
downloadansible-issue_15915_notify_static_include_handlers.tar.gz
Allow notifies to be sent to the top level includes when they were staticissue_15915_notify_static_include_handlers
Since we introduced static includes in 2.1, this broke the functionality where a notify could be sent to a named include statement, triggering all handlers contained within the include. This patch fixes that by adding a search through the parents of a handler for any TaskIncludes which match. Fixes #15915
-rw-r--r--lib/ansible/plugins/strategy/__init__.py38
1 files changed, 34 insertions, 4 deletions
diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py
index d47826cfd8..5b3c461092 100644
--- a/lib/ansible/plugins/strategy/__init__.py
+++ b/lib/ansible/plugins/strategy/__init__.py
@@ -39,6 +39,7 @@ from ansible.inventory.group import Group
from ansible.module_utils.facts import Facts
from ansible.playbook.helpers import load_list_of_blocks
from ansible.playbook.included_file import IncludedFile
+from ansible.playbook.task_include import TaskInclude
from ansible.plugins import action_loader, connection_loader, filter_loader, lookup_loader, module_loader, test_loader
from ansible.template import Templar
from ansible.utils.unicode import to_unicode
@@ -255,6 +256,25 @@ class StrategyBase:
continue
return None
+ def parent_handler_match(target_handler, handler_name):
+ if target_handler:
+ if isinstance(target_handler, TaskInclude):
+ try:
+ handler_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, task=target_handler)
+ templar = Templar(loader=self._loader, variables=handler_vars)
+ target_handler_name = templar.template(target_handler.name)
+ if target_handler_name == handler_name:
+ return True
+ else:
+ target_handler_name = templar.template(target_handler.get_name())
+ if target_handler_name == handler_name:
+ return True
+ except (UndefinedError, AnsibleUndefinedVariable) as e:
+ pass
+ return parent_handler_match(target_handler._parent, handler_name)
+ else:
+ return False
+
passes = 0
while not self._tqm._terminated:
try:
@@ -367,15 +387,25 @@ class StrategyBase:
else:
target_handler = search_handler_blocks(handler_name, iterator._play.handlers)
- if target_handler is None:
- raise AnsibleError("The requested handler '%s' was not found in any of the known handlers" % handler_name)
- if target_handler in self._notified_handlers:
+ if target_handler is not None:
if original_host not in self._notified_handlers[target_handler]:
self._notified_handlers[target_handler].append(original_host)
# FIXME: should this be a callback?
display.vv("NOTIFIED HANDLER %s" % (handler_name,))
else:
- raise AnsibleError("The requested handler '%s' was found in neither the main handlers list nor the listening handlers list" % handler_name)
+ # As there may be more than one handler with the notified name as the
+ # parent, so we just keep track of whether or not we found one at all
+ found = False
+ for target_handler in self._notified_handlers:
+ if parent_handler_match(target_handler, handler_name):
+ self._notified_handlers[target_handler].append(original_host)
+ display.vv("NOTIFIED HANDLER %s" % (target_handler.get_name(),))
+ found = True
+
+ # and if none were found, then we raise an error
+ if not found:
+ raise AnsibleError("The requested handler '%s' was found in neither the main handlers list nor the listening handlers list" % handler_name)
+
if 'add_host' in result_item:
# this task added a new host (add_host module)