From 28d4e52a16c21e5f87acdfe72a7f489611c841c9 Mon Sep 17 00:00:00 2001 From: Alex Schultz Date: Thu, 16 Jul 2020 13:44:03 -0600 Subject: [PATCH] Allow any_errors_fatal to be dynamic Currently any_errors_fatal cannot be dynamic value based on the current task vars. This change attempts to evaulate the provided value and verifies it's a boolean when using it to handle the any_errors_fatal logic. Related Upstream: https://github.com/ansible/ansible/pull/70694 Related-Bug: #1887702 Change-Id: I31cf042b72aad5cdd2c7c1ae8bc319eca372acff --- .../ansible_plugins/strategy/tripleo_base.py | 8 ++++ .../ansible_plugins/strategy/tripleo_free.py | 2 +- .../strategy/tripleo_linear.py | 40 ++++++++++--------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/tripleo_ansible/ansible_plugins/strategy/tripleo_base.py b/tripleo_ansible/ansible_plugins/strategy/tripleo_base.py index 50469523c..5fbc932c3 100644 --- a/tripleo_ansible/ansible_plugins/strategy/tripleo_base.py +++ b/tripleo_ansible/ansible_plugins/strategy/tripleo_base.py @@ -127,6 +127,14 @@ class TripleoBase(StrategyBase): failures[role] = 1 return failures + def _get_task_errors_fatal(self, task, templar): + """Return parsed any_errors_fatal from a task""" + return task.get_validated_value('any_errors_fatal', + task._valid_attrs['any_errors_fatal'], + templar.template( + task.any_errors_fatal), + None) + def process_includes(self, host_results, noop=False): """Handle includes diff --git a/tripleo_ansible/ansible_plugins/strategy/tripleo_free.py b/tripleo_ansible/ansible_plugins/strategy/tripleo_free.py index ec8d9f7c0..050c8d645 100644 --- a/tripleo_ansible/ansible_plugins/strategy/tripleo_free.py +++ b/tripleo_ansible/ansible_plugins/strategy/tripleo_free.py @@ -227,7 +227,7 @@ class StrategyModule(BASE.TripleoBase): self._blocked_hosts[host_name] = False else: if not self._step or self._take_step(task, host_name): - if task.any_errors_fatal: + if self._get_task_errors_fatal(task, templar): display.warning('any_errors_fatal only stops any future ' 'tasks running on the host that fails ' 'with the tripleo_free strategy.') diff --git a/tripleo_ansible/ansible_plugins/strategy/tripleo_linear.py b/tripleo_ansible/ansible_plugins/strategy/tripleo_linear.py index 5985e0c16..2eccecac1 100644 --- a/tripleo_ansible/ansible_plugins/strategy/tripleo_linear.py +++ b/tripleo_ansible/ansible_plugins/strategy/tripleo_linear.py @@ -214,6 +214,25 @@ class StrategyModule(BASE.TripleoBase): and not task._role._metadata.allow_duplicates): raise TripleoLinearNoHostTask() + # todo handle steps like in linear + # build get_vars call params + vars_params = {'play': self._iterator._play, + 'host': host, + 'task': task} + # if we have >= 2.9 we can use the hosts cache + if self._has_hosts_cache: + vars_params['_hosts'] = self._hosts_cache + if self._has_hosts_cache_all: + vars_params['_hosts_all'] = self._hosts_cache_all + + task_vars = self._variable_manager.get_vars(**vars_params) + + self.add_tqm_variables(task_vars, play=self._iterator._play) + templar = Templar(loader=self._loader, variables=task_vars) + + run_once = (templar.template(task.run_once) or action + and getattr(action, 'BYPASS_HOST_LOOP', False)) + if task.action == 'meta': results.extend(self._execute_meta(task, self._play_context, @@ -223,27 +242,10 @@ class StrategyModule(BASE.TripleoBase): 'reset_connection', 'end_host')): run_once = True - if (task.any_errors_fatal or run_once and not task.ignore_errors): + if (self._get_task_errors_fatal(task, templar) + or run_once and not task.ignore_errors): self._any_errors_fatal = True else: - # todo handle steps like in linear - # build get_vars call params - vars_params = {'play': self._iterator._play, - 'host': host, - 'task': task} - # if we have >= 2.9 we can use the hosts cache - if self._has_hosts_cache: - vars_params['_hosts'] = self._hosts_cache - if self._has_hosts_cache_all: - vars_params['_hosts_all'] = self._hosts_cache_all - - task_vars = self._variable_manager.get_vars(**vars_params) - - self.add_tqm_variables(task_vars, play=self._iterator._play) - templar = Templar(loader=self._loader, variables=task_vars) - - run_once = (templar.template(task.run_once) or action - and getattr(action, 'BYPASS_HOST_LOOP', False)) self._send_task_callback(task, templar) self._blocked_hosts[host.get_name()] = True self._queue_task(host, task, task_vars, self._play_context)