From 900e5fee83f169d6477a9a95b54327a3caaf3952 Mon Sep 17 00:00:00 2001 From: Jimmy McCrory Date: Mon, 19 Jun 2017 15:38:22 -0700 Subject: [PATCH] Fix delegation to containers between hosts Tasks which delegate from a container to a container on a separate host currently fail because the 'physical_host_addr' variable, which those tasks use to connect to a physical host, is exclusively set as the address of the originating container's physical host. Assign a new host variable, 'physical_host_addrs', which contains a mapping of each physical host and its address, so the tasks can now lookup of the correct address to use depending on the target container. Change-Id: If594914df53efacc6d5bba148f4f46280f5a117d (cherry picked from commit 8b1a07d2d60cb5e0a48fc152f1eee8a3bc051902) --- connection/ssh.py | 5 +++-- strategy/linear.py | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/connection/ssh.py b/connection/ssh.py index 5109f9a0..705d1309 100644 --- a/connection/ssh.py +++ b/connection/ssh.py @@ -64,8 +64,9 @@ class Connection(SSH.Connection): def set_host_overrides(self, host, hostvars=None): if self._container_check() or self._chroot_check(): - physical_host_addr = hostvars.get('physical_host_addr', - self.physical_host) + physical_host_addrs = hostvars.get('physical_host_addrs', {}) + physical_host_addr = physical_host_addrs.get(self.physical_host, + self.physical_host) self.host = self._play_context.remote_addr = physical_host_addr def _exec_command(self, cmd, in_data=None, sudoable=True): diff --git a/strategy/linear.py b/strategy/linear.py index dd3486ae..3452761a 100644 --- a/strategy/linear.py +++ b/strategy/linear.py @@ -104,6 +104,9 @@ class StrategyModule(LINEAR.StrategyModule): def _queue_task(self, host, task, task_vars, play_context): """Queue a task to be sent to the worker. + Set a host variable, 'physical_host_addrs', containing a dictionary of + each physical host and its 'ansible_host' variable. + Modify the playbook_context to disable pipelining and use the paramiko transport method when a task is being delegated. """ @@ -112,9 +115,16 @@ class StrategyModule(LINEAR.StrategyModule): return _play_context = copy.deepcopy(play_context) - if 'physical_host' in host.vars: - physical_host = self._inventory.get_host_variables(host.vars['physical_host']) - host.set_variable('physical_host_addr', physical_host['ansible_host']) + + groups = self._inventory.get_group_dict() + physical_hosts = groups.get('hosts', groups.get('all', {})) + physical_host_addrs = {} + for physical_host in physical_hosts: + physical_host_vars = self._inventory.get_host_variables(physical_host) + physical_host_addr = physical_host_vars.get('ansible_host', physical_host) + physical_host_addrs[physical_host] = physical_host_addr + host.set_variable('physical_host_addrs', physical_host_addrs) + if task.delegate_to: # If a task uses delegation change the play_context # to use paramiko with pipelining disabled for this