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 8b1a07d2d6)
This commit is contained in:
Jimmy McCrory 2017-06-19 15:38:22 -07:00 committed by Jesse Pretorius
parent e9ce8422b4
commit 900e5fee83
2 changed files with 16 additions and 5 deletions

View File

@ -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):

View File

@ -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