summaryrefslogtreecommitdiff
path: root/lib/ansible
diff options
context:
space:
mode:
authorMatt Martz <matt@sivel.net>2018-12-11 09:58:19 -0600
committerBrian Coca <bcoca@users.noreply.github.com>2018-12-11 10:58:19 -0500
commit2a469fd9597ac36099e991a1757193e6d3016e63 (patch)
treeef05cea96df424db851c578765010c7936e1c951 /lib/ansible
parent62b2a08cfbc1aeb5a45d45d9e975d74e194cd8d8 (diff)
downloadansible-2a469fd9597ac36099e991a1757193e6d3016e63.tar.gz
Consolidate handler tracking (#49338)
* Consolidate handler tracking - Remove unused code. ci_complete - unit test fixes. ci_complete - Restore previous behavior of matching a single handler - when notifying a host for a handler, return True if it was added, False otherwise, to reduce copied logic - rename funcitons for clarity. ci_complete - Remove handler logic for static includes which was disabled previously
Diffstat (limited to 'lib/ansible')
-rw-r--r--lib/ansible/executor/task_queue_manager.py26
-rw-r--r--lib/ansible/playbook/handler.py19
-rw-r--r--lib/ansible/plugins/strategy/__init__.py94
-rw-r--r--lib/ansible/plugins/strategy/free.py1
-rw-r--r--lib/ansible/plugins/strategy/linear.py1
5 files changed, 35 insertions, 106 deletions
diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py
index 2474f58f67..08c53413ed 100644
--- a/lib/ansible/executor/task_queue_manager.py
+++ b/lib/ansible/executor/task_queue_manager.py
@@ -90,10 +90,6 @@ class TaskQueueManager:
# a special flag to help us exit cleanly
self._terminated = False
- # this dictionary is used to keep track of notified handlers
- self._notified_handlers = dict()
- self._listening_handlers = dict()
-
# dictionaries to keep track of failed/unreachable hosts
self._failed_hosts = dict()
self._unreachable_hosts = dict()
@@ -120,11 +116,6 @@ class TaskQueueManager:
inventory hostnames for those hosts triggering the handler.
'''
- # Zero the dictionary first by removing any entries there.
- # Proxied dicts don't support iteritems, so we have to use keys()
- self._notified_handlers.clear()
- self._listening_handlers.clear()
-
def _process_block(b):
temp_list = []
for t in b.block:
@@ -137,23 +128,6 @@ class TaskQueueManager:
handler_list = []
for handler_block in play.handlers:
handler_list.extend(_process_block(handler_block))
- # then initialize it with the given handler list
- self.update_handler_list(handler_list)
-
- def update_handler_list(self, handler_list):
- for handler in handler_list:
- if handler._uuid not in self._notified_handlers:
- display.debug("Adding handler %s to notified list" % handler.name)
- self._notified_handlers[handler._uuid] = []
- if handler.listen:
- listeners = handler.listen
- if not isinstance(listeners, list):
- listeners = [listeners]
- for listener in listeners:
- if listener not in self._listening_handlers:
- self._listening_handlers[listener] = []
- display.debug("Adding handler %s to listening list" % handler.name)
- self._listening_handlers[listener].append(handler._uuid)
def load_callbacks(self):
'''
diff --git a/lib/ansible/playbook/handler.py b/lib/ansible/playbook/handler.py
index b0452c577a..cabbd556ab 100644
--- a/lib/ansible/playbook/handler.py
+++ b/lib/ansible/playbook/handler.py
@@ -25,10 +25,12 @@ from ansible.playbook.task import Task
class Handler(Task):
- _listen = FieldAttribute(isa='list')
+ _listen = FieldAttribute(isa='list', default=list)
def __init__(self, block=None, role=None, task_include=None):
- self._flagged_hosts = []
+ self.notified_hosts = []
+
+ self.cached_name = False
super(Handler, self).__init__(block=block, role=role, task_include=task_include)
@@ -41,13 +43,14 @@ class Handler(Task):
t = Handler(block=block, role=role, task_include=task_include)
return t.load_data(data, variable_manager=variable_manager, loader=loader)
- def flag_for_host(self, host):
- # assert instanceof(host, Host)
- if host not in self._flagged_hosts:
- self._flagged_hosts.append(host)
+ def notify_host(self, host):
+ if not self.is_host_notified(host):
+ self.notified_hosts.append(host)
+ return True
+ return False
- def has_triggered(self, host):
- return host in self._flagged_hosts
+ def is_host_notified(self, host):
+ return host in self.notified_hosts
def serialize(self):
result = super(Handler, self).serialize()
diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py
index 7e5583c820..cd4050d8db 100644
--- a/lib/ansible/plugins/strategy/__init__.py
+++ b/lib/ansible/plugins/strategy/__init__.py
@@ -44,7 +44,6 @@ from ansible.module_utils.connection import Connection, ConnectionError
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.playbook.role_include import IncludeRole
from ansible.plugins.loader import action_loader, connection_loader, filter_loader, lookup_loader, module_loader, test_loader
from ansible.template import Templar
from ansible.utils.display import Display
@@ -168,8 +167,6 @@ class StrategyBase:
self._tqm = tqm
self._inventory = tqm.get_inventory()
self._workers = tqm.get_workers()
- self._notified_handlers = tqm._notified_handlers
- self._listening_handlers = tqm._listening_handlers
self._variable_manager = tqm.get_variable_manager()
self._loader = tqm.get_loader()
self._final_q = tqm._final_q
@@ -372,19 +369,21 @@ class StrategyBase:
for handler_block in reversed(handler_blocks):
for handler_task in handler_block.block:
if handler_task.name:
- handler_vars = self._variable_manager.get_vars(play=iterator._play, task=handler_task)
- templar = Templar(loader=self._loader, variables=handler_vars)
+ if not handler_task.cached_name:
+ handler_vars = self._variable_manager.get_vars(play=iterator._play, task=handler_task)
+ templar = Templar(loader=self._loader, variables=handler_vars)
+ handler_task.name = templar.template(handler_task.name)
+ handler_task.cached_name = True
+
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:
+ if handler_task.name == handler_name:
return handler_task
else:
- target_handler_name = templar.template(handler_task.get_name())
- if target_handler_name == handler_name:
+ if handler_task.get_name() == handler_name:
return handler_task
except (UndefinedError, AnsibleUndefinedVariable):
# We skip this handler due to the fact that it may be using
@@ -394,33 +393,6 @@ class StrategyBase:
continue
return None
- def search_handler_blocks_by_uuid(handler_uuid, handler_blocks):
- # iterate in reversed order since last handler loaded with the same name wins
- for handler_block in reversed(handler_blocks):
- for handler_task in handler_block.block:
- if handler_uuid == handler_task._uuid:
- return handler_task
- return None
-
- def parent_handler_match(target_handler, handler_name):
- if target_handler:
- if isinstance(target_handler, (TaskInclude, IncludeRole)) and not getattr(target_handler, 'statically_loaded', True):
- try:
- handler_vars = self._variable_manager.get_vars(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):
- pass
- return parent_handler_match(target_handler._parent, handler_name)
- else:
- return False
-
cur_pass = 0
while True:
try:
@@ -548,31 +520,18 @@ class StrategyBase:
target_handler = search_handler_blocks_by_name(handler_name, iterator._play.handlers)
if target_handler is not None:
found = True
- if target_handler._uuid not in self._notified_handlers:
- self._notified_handlers[target_handler._uuid] = []
- if original_host not in self._notified_handlers[target_handler._uuid]:
- self._notified_handlers[target_handler._uuid].append(original_host)
+ if target_handler.notify_host(original_host):
self._tqm.send_callback('v2_playbook_on_notify', target_handler, original_host)
- else:
- # 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
- for target_handler_uuid in self._notified_handlers:
- target_handler = search_handler_blocks_by_uuid(target_handler_uuid, iterator._play.handlers)
- if target_handler and parent_handler_match(target_handler, handler_name):
- found = True
- if original_host not in self._notified_handlers[target_handler._uuid]:
- self._notified_handlers[target_handler._uuid].append(original_host)
- self._tqm.send_callback('v2_playbook_on_notify', target_handler, original_host)
-
- if handler_name in self._listening_handlers:
- for listening_handler_uuid in self._listening_handlers[handler_name]:
- listening_handler = search_handler_blocks_by_uuid(listening_handler_uuid, iterator._play.handlers)
- if listening_handler is not None:
- found = True
- else:
+
+ for listening_handler_block in iterator._play.handlers:
+ for listening_handler in listening_handler_block.block:
+ listeners = getattr(listening_handler, 'listen', []) or []
+ if handler_name not in listeners:
continue
- if original_host not in self._notified_handlers[listening_handler._uuid]:
- self._notified_handlers[listening_handler._uuid].append(original_host)
+ else:
+ found = True
+
+ if listening_handler.notify_host(original_host):
self._tqm.send_callback('v2_playbook_on_notify', listening_handler, original_host)
# and if none were found, then we raise an error
@@ -877,14 +836,9 @@ class StrategyBase:
# but this may take some work in the iterator and gets tricky when
# we consider the ability of meta tasks to flush handlers
for handler in handler_block.block:
- if handler._uuid in self._notified_handlers and len(self._notified_handlers[handler._uuid]):
+ if handler.notified_hosts:
handler_vars = self._variable_manager.get_vars(play=iterator._play, task=handler)
- templar = Templar(loader=self._loader, variables=handler_vars)
handler_name = handler.get_name()
- try:
- handler_name = templar.template(handler_name)
- except (UndefinedError, AnsibleUndefinedVariable):
- pass
result = self._do_handler_run(handler, handler_name, iterator=iterator, play_context=play_context)
if not result:
break
@@ -898,7 +852,7 @@ class StrategyBase:
# result = False
# break
if notified_hosts is None:
- notified_hosts = self._notified_handlers[handler._uuid]
+ notified_hosts = handler.notified_hosts[:]
notified_hosts = self._filter_notified_hosts(notified_hosts)
@@ -920,7 +874,7 @@ class StrategyBase:
host_results = []
for host in notified_hosts:
- if not handler.has_triggered(host) and (not iterator.is_failed(host) or play_context.force_handlers):
+ if not iterator.is_failed(host) or play_context.force_handlers:
task_vars = self._variable_manager.get_vars(play=iterator._play, host=host, task=handler)
self.add_tqm_variables(task_vars, play=iterator._play)
self._queue_task(host, handler, task_vars, play_context)
@@ -953,7 +907,7 @@ class StrategyBase:
for task in block.block:
task_name = task.get_name()
display.debug("adding task '%s' included in handler '%s'" % (task_name, handler_name))
- self._notified_handlers[task._uuid] = included_file._hosts[:]
+ task.notified_hosts = included_file._hosts[:]
result = self._do_handler_run(
handler=task,
handler_name=task_name,
@@ -971,8 +925,8 @@ class StrategyBase:
continue
# remove hosts from notification list
- self._notified_handlers[handler._uuid] = [
- h for h in self._notified_handlers[handler._uuid]
+ handler.notified_hosts = [
+ h for h in handler.notified_hosts
if h not in notified_hosts]
display.debug("done running handlers, result is: %s" % result)
return result
diff --git a/lib/ansible/plugins/strategy/free.py b/lib/ansible/plugins/strategy/free.py
index bd94338567..104e8afa1c 100644
--- a/lib/ansible/plugins/strategy/free.py
+++ b/lib/ansible/plugins/strategy/free.py
@@ -225,7 +225,6 @@ class StrategyModule(StrategyBase):
variable_manager=self._variable_manager,
loader=self._loader,
)
- self._tqm.update_handler_list([handler for handler_block in handler_blocks for handler in handler_block.block])
else:
new_blocks = self._load_included_file(included_file, iterator=iterator)
except AnsibleError as e:
diff --git a/lib/ansible/plugins/strategy/linear.py b/lib/ansible/plugins/strategy/linear.py
index 0a985ad90d..cf1403d408 100644
--- a/lib/ansible/plugins/strategy/linear.py
+++ b/lib/ansible/plugins/strategy/linear.py
@@ -355,7 +355,6 @@ class StrategyModule(StrategyBase):
variable_manager=self._variable_manager,
loader=self._loader,
)
- self._tqm.update_handler_list([handler for handler_block in handler_blocks for handler in handler_block.block])
else:
new_blocks = self._load_included_file(included_file, iterator=iterator)