Implement run_once
Prior to this patch, run_once was basically ignored. This patch adds tracking on tasks that are tagged with run_once and will only allow it to be invoked once. This means if the run_once task fails, all the other hosts will continue to process their tasks like nothing happened. The play itself will exit if the run_once task fails at the end. For tripleo this means that run_once should not be used for any required tasks within a play but can be used to make sure a task will only run once time for a given play. Change-Id: Iaa1278763d56429b2886371a18477e1f54680e19
This commit is contained in:
parent
f873e31f58
commit
894a853a5e
@ -36,6 +36,13 @@ DOCUMENTATION = '''
|
||||
- Will fail playbook if any hosts have a failure during the
|
||||
execution and any_errors_fatal is true (free does not do this).
|
||||
- Should be backwards compatible for Ansible 2.8
|
||||
- Handles run_once to only invoke the task a single time for a
|
||||
given run. It should be noted that run_once does not ensure the
|
||||
task actually is successful but rather that it is only triggered
|
||||
once time for the host groups. If the task fails, the playbook
|
||||
will fail at the end of the play but there is no assurance that
|
||||
the task will actually complete successfully for a given playbook
|
||||
execution. Other tasks will continue on the other hosts.
|
||||
version_added: "2.9"
|
||||
author: Alex Schultz <aschultz@redhat.com>
|
||||
'''
|
||||
@ -70,6 +77,7 @@ class StrategyModule(StrategyBase):
|
||||
self._play_context = None
|
||||
self._strat_results = []
|
||||
self._workers_free = 0
|
||||
self._run_once_tasks = set()
|
||||
# these were defined in 2.9
|
||||
self._has_hosts_cache = False
|
||||
self._has_hosts_cache_all = False
|
||||
@ -198,13 +206,23 @@ class StrategyModule(StrategyBase):
|
||||
run_once = (templar.template(task.run_once) or action
|
||||
and getattr(action, 'BYPASS_HOST_LOOP', False))
|
||||
|
||||
# TODO(mwhahaha): make it work by caching it across all hosts
|
||||
if run_once:
|
||||
display.warning('tripleo_free run_once does not ensure a task '
|
||||
'is successful for a given playbook but rather '
|
||||
'it is only attempted to execute once.')
|
||||
if action and getattr(action, 'BYPASS_HOST_LOOP', False):
|
||||
raise AnsibleError('Cannot bypass host loop with strategy')
|
||||
else:
|
||||
display.warning("Using run_once does not work with the"
|
||||
"tripleo_free strategy")
|
||||
if task._uuid in self._run_once_tasks:
|
||||
# If the task was previously executed, just drop it
|
||||
# by clearing the blocked host and telling the parent
|
||||
# function to continue.
|
||||
self._debug("Skipping run_once task {} on {}".format(
|
||||
task._uuid, host))
|
||||
del self._blocked_hosts[host_name]
|
||||
raise TripleoFreeContinue()
|
||||
else:
|
||||
self._run_once_tasks.add(task._uuid)
|
||||
|
||||
# handle role deduplication logic
|
||||
if task._role and task._role.has_run(host):
|
||||
|
Loading…
Reference in New Issue
Block a user