diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py index ba4970ed662..8373264ef18 100644 --- a/lib/ansible/executor/task_queue_manager.py +++ b/lib/ansible/executor/task_queue_manager.py @@ -236,13 +236,16 @@ class TaskQueueManager: start_at_done = self._start_at_done, ) - # because the TQM may survive multiple play runs, we start by - # marking any hosts as failed in the iterator here which may - # have been marked as failed in previous runs. + # Because the TQM may survive multiple play runs, we start by marking + # any hosts as failed in the iterator here which may have been marked + # as failed in previous runs. Then we clear the internal list of failed + # hosts so we know what failed this round. for host_name in self._failed_hosts.keys(): host = self._inventory.get_host(host_name) iterator.mark_host_failed(host) + self.clear_failed_hosts() + # during initialization, the PlayContext will clear the start_at_task # field to signal that a matching task was found, so check that here # and remember it so we don't try to skip tasks on future plays @@ -251,6 +254,11 @@ class TaskQueueManager: # and run the play using the strategy and cleanup on way out play_return = strategy.run(iterator, play_context) + + # now re-save the hosts that failed from the iterator to our internal list + for host_name in iterator.get_failed_hosts(): + self._failed_hosts[host_name] = True + self._cleanup_processes() return play_return diff --git a/lib/ansible/plugins/strategy/linear.py b/lib/ansible/plugins/strategy/linear.py index 0b8f0318c64..2d3396a3b20 100644 --- a/lib/ansible/plugins/strategy/linear.py +++ b/lib/ansible/plugins/strategy/linear.py @@ -367,7 +367,7 @@ class StrategyModule(StrategyBase): if iterator._play.max_fail_percentage is not None and len(results) > 0: percentage = iterator._play.max_fail_percentage / 100.0 - if (len(iterator.get_failed_hosts()) / len(results)) > percentage: + if (len(self._tqm._failed_hosts) / len(results)) > percentage: for host in hosts_left: # don't double-mark hosts, or the iterator will potentially # fail them out of the rescue/always states