From b47a4a7679ac6f59e0370372d27f8a4d66f89fc5 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 (cherry picked from commit 28d4e52a16c21e5f87acdfe72a7f489611c841c9) --- .../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 60f4f649d..34ad78c43 100644 --- a/tripleo_ansible/ansible_plugins/strategy/tripleo_base.py +++ b/tripleo_ansible/ansible_plugins/strategy/tripleo_base.py @@ -129,6 +129,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 5937fbdc4..149993249 100644 --- a/tripleo_ansible/ansible_plugins/strategy/tripleo_free.py +++ b/tripleo_ansible/ansible_plugins/strategy/tripleo_free.py @@ -229,7 +229,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 d7fa59c20..ff1f8cdb9 100644 --- a/tripleo_ansible/ansible_plugins/strategy/tripleo_linear.py +++ b/tripleo_ansible/ansible_plugins/strategy/tripleo_linear.py @@ -216,6 +216,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, @@ -225,27 +244,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)