Related to #15915
James Cammarata authored on 2016/08/23 00:03:13... | ... |
@@ -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 |