Backport of f722d41 to the stable-2.1 branch

Related to #15915
This commit is contained in:
James Cammarata 2016-08-22 10:03:13 -05:00
parent 9478e41394
commit bf929ac532
2 changed files with 45 additions and 8 deletions

View file

@ -39,6 +39,7 @@ from ansible.inventory.group import Group
from ansible.module_utils.facts import Facts from ansible.module_utils.facts import Facts
from ansible.playbook.helpers import load_list_of_blocks from ansible.playbook.helpers import load_list_of_blocks
from ansible.playbook.included_file import IncludedFile 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.plugins import action_loader, connection_loader, filter_loader, lookup_loader, module_loader, test_loader
from ansible.template import Templar from ansible.template import Templar
from ansible.utils.unicode import to_unicode from ansible.utils.unicode import to_unicode
@ -344,21 +345,48 @@ class StrategyBase:
continue continue
return None 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._task_include, handler_name)
else:
return False
# Find the handler using the above helper. First we look up the # Find the handler using the above helper. First we look up the
# dependency chain of the current task (if it's from a role), otherwise # dependency chain of the current task (if it's from a role), otherwise
# we just look through the list of handlers in the current play/all # we just look through the list of handlers in the current play/all
# roles and use the first one that matches the notify name # roles and use the first one that matches the notify name
target_handler = search_handler_blocks(iterator._play.handlers) target_handler = search_handler_blocks(iterator._play.handlers)
if target_handler is None: if target_handler is not 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 original_host not in self._notified_handlers[target_handler]: if original_host not in self._notified_handlers[target_handler]:
self._notified_handlers[target_handler].append(original_host) self._notified_handlers[target_handler].append(original_host)
# FIXME: should this be a callback? # FIXME: should this be a callback?
display.vv("NOTIFIED HANDLER %s" % (handler_name,)) display.vv("NOTIFIED HANDLER %s" % (handler_name,))
else: else:
raise AnsibleError("The requested handler '%s' was not found in the main 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 not found in the main handlers list" % handler_name)
elif result[0] == 'register_host_var': elif result[0] == 'register_host_var':
# essentially the same as 'set_host_var' below, however we # essentially the same as 'set_host_var' below, however we

View file

@ -236,7 +236,10 @@ class VariableManager:
# sure it sees its defaults above any other roles, as we previously # sure it sees its defaults above any other roles, as we previously
# (v1) made sure each task had a copy of its roles default vars # (v1) made sure each task had a copy of its roles default vars
if task and task._role is not None: if task and task._role is not None:
all_vars = combine_vars(all_vars, task._role.get_default_vars(dep_chain=task._block.get_dep_chain())) dep_chain = []
if task._block:
dep_chain = task._block.get_dep_chain()
all_vars = combine_vars(all_vars, task._role.get_default_vars(dep_chain=dep_chain))
if host: if host:
# next, if a host is specified, we load any vars from group_vars # next, if a host is specified, we load any vars from group_vars
@ -333,7 +336,10 @@ class VariableManager:
# vars (which will look at parent blocks/task includes) # vars (which will look at parent blocks/task includes)
if task: if task:
if task._role: if task._role:
all_vars = combine_vars(all_vars, task._role.get_vars(task._block._dep_chain, include_params=False)) dep_chain = []
if task._block:
dep_chain = task._block.get_dep_chain()
all_vars = combine_vars(all_vars, task._role.get_vars(dep_chain=dep_chain, include_params=False))
all_vars = combine_vars(all_vars, task.get_vars()) all_vars = combine_vars(all_vars, task.get_vars())
# next, we merge in the vars cache (include vars) and nonpersistent # next, we merge in the vars cache (include vars) and nonpersistent
@ -345,7 +351,10 @@ class VariableManager:
# next, we merge in role params and task include params # next, we merge in role params and task include params
if task: if task:
if task._role: if task._role:
all_vars = combine_vars(all_vars, task._role.get_role_params(task._block.get_dep_chain())) dep_chain = []
if task._block:
dep_chain = task._block.get_dep_chain()
all_vars = combine_vars(all_vars, task._role.get_role_params(dep_chain=dep_chain))
# special case for include tasks, where the include params # special case for include tasks, where the include params
# may be specified in the vars field for the task, which should # may be specified in the vars field for the task, which should