mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-06-14 20:29:11 -07:00
Allow handlers to run in between pre_tasks, roles, tasks, and post_tasks.
This commit is contained in:
parent
84781bf185
commit
32fb6c807c
3 changed files with 52 additions and 11 deletions
|
@ -496,15 +496,35 @@ class PlayBook(object):
|
||||||
self.inventory.also_restrict_to(on_hosts)
|
self.inventory.also_restrict_to(on_hosts)
|
||||||
|
|
||||||
for task in play.tasks():
|
for task in play.tasks():
|
||||||
|
|
||||||
|
if task.meta is not None:
|
||||||
|
|
||||||
|
# meta tasks are an internalism and are not valid for end-user playbook usage
|
||||||
|
# here a meta task is a placeholder that signals handlers should be run
|
||||||
|
|
||||||
|
if task.meta == 'flush_handlers':
|
||||||
|
for handler in play.handlers():
|
||||||
|
if len(handler.notified_by) > 0:
|
||||||
|
self.inventory.restrict_to(handler.notified_by)
|
||||||
|
self._run_task(play, handler, True)
|
||||||
|
self.inventory.lift_restriction()
|
||||||
|
for host in handler.notified_by:
|
||||||
|
handler.notified_by.remove(host)
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
hosts_count = len(self._list_available_hosts(play.hosts))
|
hosts_count = len(self._list_available_hosts(play.hosts))
|
||||||
|
|
||||||
# only run the task if the requested tags match
|
# only run the task if the requested tags match
|
||||||
should_run = False
|
should_run = False
|
||||||
for x in self.only_tags:
|
for x in self.only_tags:
|
||||||
|
|
||||||
|
|
||||||
for y in task.tags:
|
for y in task.tags:
|
||||||
if (x==y):
|
if (x==y):
|
||||||
should_run = True
|
should_run = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if should_run:
|
if should_run:
|
||||||
if not self._run_task(play, task, False):
|
if not self._run_task(play, task, False):
|
||||||
# whether no hosts matched is fatal or not depends if it was on the initial step.
|
# whether no hosts matched is fatal or not depends if it was on the initial step.
|
||||||
|
@ -523,12 +543,13 @@ class PlayBook(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# run notify actions
|
# run notify actions
|
||||||
for handler in play.handlers():
|
#for handler in play.handlers():
|
||||||
if len(handler.notified_by) > 0:
|
# if len(handler.notified_by) > 0:
|
||||||
self.inventory.restrict_to(handler.notified_by)
|
# self.inventory.restrict_to(handler.notified_by)
|
||||||
self._run_task(play, handler, True)
|
# self._run_task(play, handler, True)
|
||||||
self.inventory.lift_restriction()
|
# self.inventory.lift_restriction()
|
||||||
handler.notified_by = []
|
# handler.notified_by = []
|
||||||
|
# handler.notified_by = []
|
||||||
|
|
||||||
self.inventory.lift_also_restriction()
|
self.inventory.lift_also_restriction()
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ class Play(object):
|
||||||
# and it auto-extends tasks/handlers/vars_files as appropriate if found
|
# and it auto-extends tasks/handlers/vars_files as appropriate if found
|
||||||
|
|
||||||
if roles is None:
|
if roles is None:
|
||||||
return ds
|
roles = []
|
||||||
if type(roles) != list:
|
if type(roles) != list:
|
||||||
raise errors.AnsibleError("value of 'roles:' must be a list")
|
raise errors.AnsibleError("value of 'roles:' must be a list")
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ class Play(object):
|
||||||
pre_tasks = []
|
pre_tasks = []
|
||||||
for x in pre_tasks:
|
for x in pre_tasks:
|
||||||
new_tasks.append(x)
|
new_tasks.append(x)
|
||||||
|
new_tasks.append(dict(meta='flush_handlers'))
|
||||||
|
|
||||||
# variables if the role was parameterized (i.e. given as a hash)
|
# variables if the role was parameterized (i.e. given as a hash)
|
||||||
has_dict = {}
|
has_dict = {}
|
||||||
|
@ -200,14 +201,17 @@ class Play(object):
|
||||||
if type(post_tasks) != list:
|
if type(post_tasks) != list:
|
||||||
post_tasks = []
|
post_tasks = []
|
||||||
|
|
||||||
|
new_tasks.append(dict(meta='flush_handlers'))
|
||||||
new_tasks.extend(tasks)
|
new_tasks.extend(tasks)
|
||||||
|
new_tasks.append(dict(meta='flush_handlers'))
|
||||||
new_tasks.extend(post_tasks)
|
new_tasks.extend(post_tasks)
|
||||||
|
new_tasks.append(dict(meta='flush_handlers'))
|
||||||
new_handlers.extend(handlers)
|
new_handlers.extend(handlers)
|
||||||
new_vars_files.extend(vars_files)
|
new_vars_files.extend(vars_files)
|
||||||
ds['tasks'] = new_tasks
|
ds['tasks'] = new_tasks
|
||||||
ds['handlers'] = new_handlers
|
ds['handlers'] = new_handlers
|
||||||
ds['vars_files'] = new_vars_files
|
ds['vars_files'] = new_vars_files
|
||||||
|
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
# *************************************************
|
# *************************************************
|
||||||
|
@ -223,6 +227,12 @@ class Play(object):
|
||||||
for x in tasks:
|
for x in tasks:
|
||||||
if not isinstance(x, dict):
|
if not isinstance(x, dict):
|
||||||
raise errors.AnsibleError("expecting dict; got: %s" % x)
|
raise errors.AnsibleError("expecting dict; got: %s" % x)
|
||||||
|
|
||||||
|
if 'meta' in x:
|
||||||
|
if x['meta'] == 'flush_handlers':
|
||||||
|
results.append(Task(self,x))
|
||||||
|
continue
|
||||||
|
|
||||||
task_vars = self.vars.copy()
|
task_vars = self.vars.copy()
|
||||||
task_vars.update(vars)
|
task_vars.update(vars)
|
||||||
if original_file:
|
if original_file:
|
||||||
|
@ -369,7 +379,8 @@ class Play(object):
|
||||||
# gather all the tags in all the tasks into one list
|
# gather all the tags in all the tasks into one list
|
||||||
all_tags = []
|
all_tags = []
|
||||||
for task in self._tasks:
|
for task in self._tasks:
|
||||||
all_tags.extend(task.tags)
|
if not task.meta:
|
||||||
|
all_tags.extend(task.tags)
|
||||||
|
|
||||||
# compare the lists of tags using sets and return the matched and unmatched
|
# compare the lists of tags using sets and return the matched and unmatched
|
||||||
all_tags_set = set(all_tags)
|
all_tags_set = set(all_tags)
|
||||||
|
|
|
@ -22,7 +22,7 @@ import ansible.utils.template as template
|
||||||
class Task(object):
|
class Task(object):
|
||||||
|
|
||||||
__slots__ = [
|
__slots__ = [
|
||||||
'name', 'action', 'only_if', 'when', 'async_seconds', 'async_poll_interval',
|
'name', 'meta', 'action', 'only_if', 'when', 'async_seconds', 'async_poll_interval',
|
||||||
'notify', 'module_name', 'module_args', 'module_vars',
|
'notify', 'module_name', 'module_args', 'module_vars',
|
||||||
'play', 'notified_by', 'tags', 'register',
|
'play', 'notified_by', 'tags', 'register',
|
||||||
'delegate_to', 'first_available_file', 'ignore_errors',
|
'delegate_to', 'first_available_file', 'ignore_errors',
|
||||||
|
@ -33,7 +33,7 @@ class Task(object):
|
||||||
|
|
||||||
# to prevent typos and such
|
# to prevent typos and such
|
||||||
VALID_KEYS = [
|
VALID_KEYS = [
|
||||||
'name', 'action', 'only_if', 'async', 'poll', 'notify',
|
'name', 'meta', 'action', 'only_if', 'async', 'poll', 'notify',
|
||||||
'first_available_file', 'include', 'tags', 'register', 'ignore_errors',
|
'first_available_file', 'include', 'tags', 'register', 'ignore_errors',
|
||||||
'delegate_to', 'local_action', 'transport', 'sudo', 'sudo_user',
|
'delegate_to', 'local_action', 'transport', 'sudo', 'sudo_user',
|
||||||
'sudo_pass', 'when', 'connection', 'environment', 'args',
|
'sudo_pass', 'when', 'connection', 'environment', 'args',
|
||||||
|
@ -43,6 +43,15 @@ class Task(object):
|
||||||
def __init__(self, play, ds, module_vars=None, additional_conditions=None):
|
def __init__(self, play, ds, module_vars=None, additional_conditions=None):
|
||||||
''' constructor loads from a task or handler datastructure '''
|
''' constructor loads from a task or handler datastructure '''
|
||||||
|
|
||||||
|
# meta directives are used to tell things like ansible/playbook to run
|
||||||
|
# operations like handler execution. Meta tasks are not executed
|
||||||
|
# normally.
|
||||||
|
if 'meta' in ds:
|
||||||
|
self.meta = ds['meta']
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.meta = None
|
||||||
|
|
||||||
for x in ds.keys():
|
for x in ds.keys():
|
||||||
|
|
||||||
# code to allow for saying "modulename: args" versus "action: modulename args"
|
# code to allow for saying "modulename: args" versus "action: modulename args"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue