mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Fix any_errors_fatal incorrect implementation in 2.0
Also adds that flag to blocks. Fixes #13744
This commit is contained in:
parent
acf49cf837
commit
1825b4a9c7
5 changed files with 37 additions and 11 deletions
|
@ -151,9 +151,7 @@ class PlaybookExecutor:
|
||||||
# conditions are met, we break out, otherwise we only break out if the entire
|
# conditions are met, we break out, otherwise we only break out if the entire
|
||||||
# batch failed
|
# batch failed
|
||||||
failed_hosts_count = len(self._tqm._failed_hosts) + len(self._tqm._unreachable_hosts)
|
failed_hosts_count = len(self._tqm._failed_hosts) + len(self._tqm._unreachable_hosts)
|
||||||
if new_play.any_errors_fatal and failed_hosts_count > 0:
|
if new_play.max_fail_percentage is not None and \
|
||||||
break
|
|
||||||
elif new_play.max_fail_percentage is not None and \
|
|
||||||
int((new_play.max_fail_percentage)/100.0 * len(batch)) > int((len(batch) - failed_hosts_count) / len(batch) * 100.0):
|
int((new_play.max_fail_percentage)/100.0 * len(batch)) > int((len(batch) - failed_hosts_count) / len(batch) * 100.0):
|
||||||
break
|
break
|
||||||
elif len(batch) == failed_hosts_count:
|
elif len(batch) == failed_hosts_count:
|
||||||
|
|
|
@ -35,6 +35,7 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
_always = FieldAttribute(isa='list', default=[])
|
_always = FieldAttribute(isa='list', default=[])
|
||||||
_delegate_to = FieldAttribute(isa='list')
|
_delegate_to = FieldAttribute(isa='list')
|
||||||
_delegate_facts = FieldAttribute(isa='bool', default=False)
|
_delegate_facts = FieldAttribute(isa='bool', default=False)
|
||||||
|
_any_errors_fatal = FieldAttribute(isa='bool')
|
||||||
|
|
||||||
# for future consideration? this would be functionally
|
# for future consideration? this would be functionally
|
||||||
# similar to the 'else' clause for exceptions
|
# similar to the 'else' clause for exceptions
|
||||||
|
@ -330,6 +331,16 @@ class Block(Base, Become, Conditional, Taggable):
|
||||||
|
|
||||||
return environment
|
return environment
|
||||||
|
|
||||||
|
def _get_attr_any_errors_fatal(self):
|
||||||
|
'''
|
||||||
|
Override for the 'tags' getattr fetcher, used from Base.
|
||||||
|
'''
|
||||||
|
any_errors_fatal = self._attributes['any_errors_fatal']
|
||||||
|
if hasattr(self, '_get_parent_attribute'):
|
||||||
|
if self._get_parent_attribute('any_errors_fatal'):
|
||||||
|
any_errors_fatal = True
|
||||||
|
return any_errors_fatal
|
||||||
|
|
||||||
def filter_tagged_tasks(self, play_context, all_vars):
|
def filter_tagged_tasks(self, play_context, all_vars):
|
||||||
'''
|
'''
|
||||||
Creates a new block, with task lists filtered based on the tags contained
|
Creates a new block, with task lists filtered based on the tags contained
|
||||||
|
|
|
@ -216,14 +216,6 @@ class Task(Base, Conditional, Taggable, Become):
|
||||||
|
|
||||||
return super(Task, self).preprocess_data(new_ds)
|
return super(Task, self).preprocess_data(new_ds)
|
||||||
|
|
||||||
def _load_any_errors_fatal(self, attr, value):
|
|
||||||
'''
|
|
||||||
Exists only to show a deprecation warning, as this attribute is not valid
|
|
||||||
at the task level.
|
|
||||||
'''
|
|
||||||
display.deprecated("Setting any_errors_fatal on a task is no longer supported. This should be set at the play level only")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def post_validate(self, templar):
|
def post_validate(self, templar):
|
||||||
'''
|
'''
|
||||||
Override of base class post_validate, to also do final validation on
|
Override of base class post_validate, to also do final validation on
|
||||||
|
@ -422,3 +414,14 @@ class Task(Base, Conditional, Taggable, Become):
|
||||||
if parent_environment is not None:
|
if parent_environment is not None:
|
||||||
environment = self._extend_value(environment, parent_environment)
|
environment = self._extend_value(environment, parent_environment)
|
||||||
return environment
|
return environment
|
||||||
|
|
||||||
|
def _get_attr_any_errors_fatal(self):
|
||||||
|
'''
|
||||||
|
Override for the 'tags' getattr fetcher, used from Base.
|
||||||
|
'''
|
||||||
|
any_errors_fatal = self._attributes['any_errors_fatal']
|
||||||
|
if hasattr(self, '_get_parent_attribute'):
|
||||||
|
if self._get_parent_attribute('any_errors_fatal'):
|
||||||
|
any_errors_fatal = True
|
||||||
|
return any_errors_fatal
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,8 @@ class StrategyModule(StrategyBase):
|
||||||
else:
|
else:
|
||||||
# handle step if needed, skip meta actions as they are used internally
|
# handle step if needed, skip meta actions as they are used internally
|
||||||
if not self._step or self._take_step(task, host_name):
|
if not self._step or self._take_step(task, host_name):
|
||||||
|
if task.any_errors_fatal:
|
||||||
|
display.warning("Using any_errors_fatal with the free strategy is not supported, as tasks are executed independently on each host")
|
||||||
self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
|
self._tqm.send_callback('v2_playbook_on_task_start', task, is_conditional=False)
|
||||||
self._queue_task(host, task, task_vars, play_context)
|
self._queue_task(host, task, task_vars, play_context)
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,7 @@ class StrategyModule(StrategyBase):
|
||||||
except AnsibleError as e:
|
except AnsibleError as e:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
include_failure = False
|
||||||
if len(included_files) > 0:
|
if len(included_files) > 0:
|
||||||
display.debug("we have included files to process")
|
display.debug("we have included files to process")
|
||||||
noop_task = Task()
|
noop_task = Task()
|
||||||
|
@ -325,6 +326,7 @@ class StrategyModule(StrategyBase):
|
||||||
self._tqm._failed_hosts[host.name] = True
|
self._tqm._failed_hosts[host.name] = True
|
||||||
iterator.mark_host_failed(host)
|
iterator.mark_host_failed(host)
|
||||||
display.error(e, wrap_text=False)
|
display.error(e, wrap_text=False)
|
||||||
|
include_failure = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# finally go through all of the hosts and append the
|
# finally go through all of the hosts and append the
|
||||||
|
@ -338,6 +340,16 @@ class StrategyModule(StrategyBase):
|
||||||
display.debug("done processing included files")
|
display.debug("done processing included files")
|
||||||
|
|
||||||
display.debug("results queue empty")
|
display.debug("results queue empty")
|
||||||
|
|
||||||
|
display.debug("checking for any_errors_fatal")
|
||||||
|
had_failure = include_failure
|
||||||
|
for res in results:
|
||||||
|
if res.is_failed() or res.is_unreachable():
|
||||||
|
had_failure = True
|
||||||
|
break
|
||||||
|
if task and task.any_errors_fatal and had_failure:
|
||||||
|
return False
|
||||||
|
|
||||||
except (IOError, EOFError) as e:
|
except (IOError, EOFError) as e:
|
||||||
display.debug("got IOError/EOFError in task loop: %s" % e)
|
display.debug("got IOError/EOFError in task loop: %s" % e)
|
||||||
# most likely an abort, return failed
|
# most likely an abort, return failed
|
||||||
|
|
Loading…
Reference in a new issue