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
|
- Will fail playbook if any hosts have a failure during the
|
||||||
execution and any_errors_fatal is true (free does not do this).
|
execution and any_errors_fatal is true (free does not do this).
|
||||||
- Should be backwards compatible for Ansible 2.8
|
- 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"
|
version_added: "2.9"
|
||||||
author: Alex Schultz <aschultz@redhat.com>
|
author: Alex Schultz <aschultz@redhat.com>
|
||||||
'''
|
'''
|
||||||
|
@ -70,6 +77,7 @@ class StrategyModule(StrategyBase):
|
||||||
self._play_context = None
|
self._play_context = None
|
||||||
self._strat_results = []
|
self._strat_results = []
|
||||||
self._workers_free = 0
|
self._workers_free = 0
|
||||||
|
self._run_once_tasks = set()
|
||||||
# these were defined in 2.9
|
# these were defined in 2.9
|
||||||
self._has_hosts_cache = False
|
self._has_hosts_cache = False
|
||||||
self._has_hosts_cache_all = False
|
self._has_hosts_cache_all = False
|
||||||
|
@ -198,13 +206,23 @@ class StrategyModule(StrategyBase):
|
||||||
run_once = (templar.template(task.run_once) or action
|
run_once = (templar.template(task.run_once) or action
|
||||||
and getattr(action, 'BYPASS_HOST_LOOP', False))
|
and getattr(action, 'BYPASS_HOST_LOOP', False))
|
||||||
|
|
||||||
# TODO(mwhahaha): make it work by caching it across all hosts
|
|
||||||
if run_once:
|
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):
|
if action and getattr(action, 'BYPASS_HOST_LOOP', False):
|
||||||
raise AnsibleError('Cannot bypass host loop with strategy')
|
raise AnsibleError('Cannot bypass host loop with strategy')
|
||||||
else:
|
else:
|
||||||
display.warning("Using run_once does not work with the"
|
if task._uuid in self._run_once_tasks:
|
||||||
"tripleo_free strategy")
|
# 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
|
# handle role deduplication logic
|
||||||
if task._role and task._role.has_run(host):
|
if task._role and task._role.has_run(host):
|
||||||
|
|
Loading…
Reference in New Issue