From ee519e0d0ab831233d3bf1049c81df8e0ca5a0c7 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Tue, 29 May 2018 15:48:32 -0500 Subject: [PATCH] Add a helper to PlayIterator to recursively find the active state (#40847) Also fixes a discovered bug in block rescue detection related to inserting the ansible_failed_{result|task} variables when the rescue is in a nested block. --- lib/ansible/executor/play_iterator.py | 12 ++++++++++++ lib/ansible/plugins/strategy/__init__.py | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/ansible/executor/play_iterator.py b/lib/ansible/executor/play_iterator.py index aaaa59697ba..46c25496a1f 100644 --- a/lib/ansible/executor/play_iterator.py +++ b/lib/ansible/executor/play_iterator.py @@ -514,6 +514,18 @@ class PlayIterator: s = self.get_host_state(host) return self._check_failed_state(s) + def get_active_state(self, state): + ''' + Finds the active state, recursively if necessary when there are child states. + ''' + if state.run_state == self.ITERATING_TASKS and state.tasks_child_state is not None: + return self.get_active_state(state.tasks_child_state) + elif state.run_state == self.ITERATING_RESCUE and state.rescue_child_state is not None: + return self.get_active_state(state.rescue_child_state) + elif state.run_state == self.ITERATING_ALWAYS and state.always_child_state is not None: + return self.get_active_state(state.always_child_state) + return state + def get_original_task(self, host, task): # now a noop because we've changed the way we do caching return (None, None) diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py index e8f6a75edf8..bf423b14602 100644 --- a/lib/ansible/plugins/strategy/__init__.py +++ b/lib/ansible/plugins/strategy/__init__.py @@ -493,7 +493,7 @@ class StrategyBase: if iterator.is_failed(original_host) and state and state.run_state == iterator.ITERATING_COMPLETE: self._tqm._failed_hosts[original_host.name] = True - if state and state.run_state == iterator.ITERATING_RESCUE: + if state and iterator.get_active_state(state).run_state == iterator.ITERATING_RESCUE: self._variable_manager.set_nonpersistent_facts( original_host, dict(