Browse code

Backport of f722d41 to the stable-2.1 branch

Related to #15915

James Cammarata authored on 2016/08/23 00:03:13
Showing 2 changed files
... ...
@@ -39,6 +39,7 @@ from ansible.inventory.group import Group
39 39
 from ansible.module_utils.facts import Facts
40 40
 from ansible.playbook.helpers import load_list_of_blocks
41 41
 from ansible.playbook.included_file import IncludedFile
42
+from ansible.playbook.task_include import TaskInclude
42 43
 from ansible.plugins import action_loader, connection_loader, filter_loader, lookup_loader, module_loader, test_loader
43 44
 from ansible.template import Templar
44 45
 from ansible.utils.unicode import to_unicode
... ...
@@ -344,21 +345,48 @@ class StrategyBase:
344 344
                                     continue
345 345
                         return None
346 346
 
347
+                    def parent_handler_match(target_handler, handler_name):
348
+                        if target_handler:
349
+                            if isinstance(target_handler, TaskInclude):
350
+                                try:
351
+                                    handler_vars = self._variable_manager.get_vars(loader=self._loader, play=iterator._play, task=target_handler)
352
+                                    templar = Templar(loader=self._loader, variables=handler_vars)
353
+                                    target_handler_name = templar.template(target_handler.name)
354
+                                    if target_handler_name == handler_name:
355
+                                        return True
356
+                                    else:
357
+                                        target_handler_name = templar.template(target_handler.get_name())
358
+                                        if target_handler_name == handler_name:
359
+                                            return True
360
+                                except (UndefinedError, AnsibleUndefinedVariable) as e:
361
+                                    pass
362
+                            return parent_handler_match(target_handler._task_include, handler_name)
363
+                        else:
364
+                            return False
365
+
347 366
                     # Find the handler using the above helper.  First we look up the
348 367
                     # dependency chain of the current task (if it's from a role), otherwise
349 368
                     # we just look through the list of handlers in the current play/all
350 369
                     # roles and use the first one that matches the notify name
351 370
                     target_handler = search_handler_blocks(iterator._play.handlers)
352
-                    if target_handler is None:
353
-                        raise AnsibleError("The requested handler '%s' was not found in any of the known handlers" % handler_name)
354
-
355
-                    if target_handler in self._notified_handlers:
371
+                    if target_handler is not None:
356 372
                         if original_host not in self._notified_handlers[target_handler]:
357 373
                             self._notified_handlers[target_handler].append(original_host)
358 374
                             # FIXME: should this be a callback?
359 375
                             display.vv("NOTIFIED HANDLER %s" % (handler_name,))
360 376
                     else:
361
-                        raise AnsibleError("The requested handler '%s' was not found in the main handlers list" % handler_name)
377
+                        # As there may be more than one handler with the notified name as the
378
+                        # parent, so we just keep track of whether or not we found one at all
379
+                        found = False
380
+                        for target_handler in self._notified_handlers:
381
+                            if parent_handler_match(target_handler, handler_name):
382
+                                self._notified_handlers[target_handler].append(original_host)
383
+                                display.vv("NOTIFIED HANDLER %s" % (target_handler.get_name(),))
384
+                                found = True
385
+
386
+                        # and if none were found, then we raise an error
387
+                        if not found:
388
+                            raise AnsibleError("The requested handler '%s' was not found in the main handlers list" % handler_name)
362 389
 
363 390
                 elif result[0] == 'register_host_var':
364 391
                     # essentially the same as 'set_host_var' below, however we
... ...
@@ -236,7 +236,10 @@ class VariableManager:
236 236
             # sure it sees its defaults above any other roles, as we previously
237 237
             # (v1) made sure each task had a copy of its roles default vars
238 238
             if task and task._role is not None:
239
-                all_vars = combine_vars(all_vars, task._role.get_default_vars(dep_chain=task._block.get_dep_chain()))
239
+                dep_chain = []
240
+                if task._block:
241
+                    dep_chain = task._block.get_dep_chain()
242
+                all_vars = combine_vars(all_vars, task._role.get_default_vars(dep_chain=dep_chain))
240 243
 
241 244
         if host:
242 245
             # next, if a host is specified, we load any vars from group_vars
... ...
@@ -333,7 +336,10 @@ class VariableManager:
333 333
         # vars (which will look at parent blocks/task includes)
334 334
         if task:
335 335
             if task._role:
336
-                all_vars = combine_vars(all_vars, task._role.get_vars(task._block._dep_chain, include_params=False))
336
+                dep_chain = []
337
+                if task._block:
338
+                    dep_chain = task._block.get_dep_chain()
339
+                all_vars = combine_vars(all_vars, task._role.get_vars(dep_chain=dep_chain, include_params=False))
337 340
             all_vars = combine_vars(all_vars, task.get_vars())
338 341
 
339 342
         # next, we merge in the vars cache (include vars) and nonpersistent
... ...
@@ -345,7 +351,10 @@ class VariableManager:
345 345
         # next, we merge in role params and task include params
346 346
         if task:
347 347
             if task._role:
348
-                all_vars = combine_vars(all_vars, task._role.get_role_params(task._block.get_dep_chain()))
348
+                dep_chain = []
349
+                if task._block:
350
+                    dep_chain = task._block.get_dep_chain()
351
+                all_vars = combine_vars(all_vars, task._role.get_role_params(dep_chain=dep_chain))
349 352
 
350 353
             # special case for include tasks, where the include params
351 354
             # may be specified in the vars field for the task, which should