From f56d1242c99f68659e575aa610cdefff73e7707a Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Tue, 14 Aug 2018 16:42:00 +0300 Subject: [PATCH] strategy: linear: Inspect the delegated host on delegated tasks. The purpose of the 'physical_host_addrs' variable was to create a mapping with all the physical hosts and their IP addresses. However, the function was broken because it used the 'physical_host' task variable to obtain the name of the physical host for the running task. As such, the dictionary only contained a single entry. This breaks delegation between hosts, since there was no entry in the dictionary for the delegated host. So if a task targetting containerA on hostA was delegated to containerB on hostB, the IP address of the hostB was not in the dictionary. The connection plugin code then used the 'hostB' hostname to connect to the host instead of its IP. However, if there is no central DNS to translate hostB to an IP or if the deployer did not add such mapping to /etc/hosts we observed the following problem. fatal: [compute00]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname controller00: Name or service not known\r\n", "unreachable": true} In order to fix that, we now examine the delegated host and create the appropriate mappings if the task is delegated. This ensures that the physical_host_addrs variable also contains information for the delegated hosts instead of just the original one. Change-Id: Ic84ad3ccdd8283a4ab3fb3130d4d5e520ab736de --- strategy/linear.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/strategy/linear.py b/strategy/linear.py index e27612f4..f2b6b88f 100644 --- a/strategy/linear.py +++ b/strategy/linear.py @@ -126,13 +126,34 @@ class StrategyModule(LINEAR.StrategyModule): _play_context = copy.deepcopy(play_context) pha = task_vars['physical_host_addrs'] = dict() - physical_host_item = task_vars.get('physical_host') - if physical_host_item: - LINEAR.display.verbose( - u'The "physical_host" variable was found.', - host=host, - caplevel=0 - ) + physical_host_items = [task_vars.get('physical_host')] + if task.delegate_to: + # For delegated tasks, we also need the information from the delegated hosts + for delegated_host in task_vars.get('ansible_delegated_vars', dict()).keys(): + LINEAR.display.verbose( + u'Task is delegated to %s.' % delegated_host, + host=host, + caplevel=0 + ) + delegated_host_info = self._inventory.get_host(u'%s' % delegated_host) + # This checks if we are delegating to a host which does not exist + # in the inventory (possibly using its IP address) + if delegated_host_info is None: + continue + physical_host_vars = delegated_host_info.get_vars() + physical_host_templar = LINEAR.Templar(loader=self._loader, + variables=physical_host_vars) + delegated_physical_host = physical_host_templar.template( + physical_host_vars.get('physical_host')) + if delegated_physical_host: + physical_host_items.append(delegated_physical_host) + LINEAR.display.verbose( + u'Task is delegated to %s. Adding its physical host %s' + % (delegated_host, delegated_physical_host), + host=host, + caplevel=0 + ) + for physical_host_item in physical_host_items: ph = self._inventory.get_host(physical_host_item) if ph: LINEAR.display.verbose(