diff --git a/changelogs/fragments/disappearing_hosts.yml b/changelogs/fragments/disappearing_hosts.yml new file mode 100644 index 00000000000000..dee38d14b306b6 --- /dev/null +++ b/changelogs/fragments/disappearing_hosts.yml @@ -0,0 +1,2 @@ +bugfixes: + - handle when host disappears form inventory mid execution. diff --git a/lib/ansible/executor/play_iterator.py b/lib/ansible/executor/play_iterator.py index 0fdcb2fedcccfd..ff780512b99dad 100644 --- a/lib/ansible/executor/play_iterator.py +++ b/lib/ansible/executor/play_iterator.py @@ -473,6 +473,13 @@ def mark_host_failed(self, host): self._host_states[host.name] = s self._play._removed_hosts.append(host.name) + def host_not_in_inventory(self, hostname): + display.debug("marking host %s failed, host not found in inventory: %s" % (hostname)) + s = self._set_failed_state(HostState(blocks=[])) + display.debug("^ failed state is now: %s" % s) + self._host_states[hostname] = s + self._play._removed_hosts.append(hostname) + def get_failed_hosts(self): return dict((host, True) for (host, state) in iteritems(self._host_states) if self._check_failed_state(state)) diff --git a/lib/ansible/executor/task_queue_manager.py b/lib/ansible/executor/task_queue_manager.py index fabc4a92370c24..90d12107a00a92 100644 --- a/lib/ansible/executor/task_queue_manager.py +++ b/lib/ansible/executor/task_queue_manager.py @@ -30,13 +30,10 @@ from ansible.executor.task_result import TaskResult from ansible.module_utils.six import string_types from ansible.module_utils._text import to_text, to_native -from ansible.playbook.block import Block from ansible.playbook.play_context import PlayContext from ansible.plugins.loader import callback_loader, strategy_loader, module_loader from ansible.plugins.callback import CallbackBase from ansible.template import Templar -from ansible.utils.collection_loader import AnsibleCollectionRef -from ansible.utils.helpers import pct_to_int from ansible.vars.hostvars import HostVars from ansible.vars.reserved import warn_if_reserved from ansible.utils.display import Display @@ -193,8 +190,7 @@ def run(self, play): ) play_context = PlayContext(new_play, self.passwords, self._connection_lockfile.fileno()) - if (self._stdout_callback and - hasattr(self._stdout_callback, 'set_play_context')): + if (self._stdout_callback and hasattr(self._stdout_callback, 'set_play_context')): self._stdout_callback.set_play_context(play_context) for callback_plugin in self._callback_plugins: @@ -227,7 +223,11 @@ def run(self, play): # 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) + if host is None: + display.warning("Lost host '%s' from inventory, removing from rest of play execution." % host_name) + iterator.host_not_in_inventory(host_name) + else: + iterator.mark_host_failed(host) self.clear_failed_hosts()