From b729b35e3225bd1283d4dc30f8e07dba76545415 Mon Sep 17 00:00:00 2001 From: Erwin Lang Date: Wed, 26 Apr 2017 01:51:13 +0200 Subject: [PATCH] synchronize: Fix (delegated) local rsync Makes delegated local rsync work even if ansible_host or ansible_ssh_host is set. Makes local rsync work when no ssh is installed. --- lib/ansible/modules/files/synchronize.py | 10 +++++++++- lib/ansible/plugins/action/synchronize.py | 11 ++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/ansible/modules/files/synchronize.py b/lib/ansible/modules/files/synchronize.py index 3afd36ccb09..c4fba95272b 100644 --- a/lib/ansible/modules/files/synchronize.py +++ b/lib/ansible/modules/files/synchronize.py @@ -347,6 +347,14 @@ def substitute_controller(path): return path +def is_rsh_needed(source, dest): + if source.startswith('rsync://') or dest.startswith('rsync://'): + return False + if ':' in source or ':' in dest: + return True + return False + + def main(): module = AnsibleModule( argument_spec = dict( @@ -465,7 +473,7 @@ def main(): if source.startswith('rsync://') and dest.startswith('rsync://'): module.fail_json(msg='either src or dest must be a localhost', rc=1) - if not source.startswith('rsync://') and not dest.startswith('rsync://'): + if is_rsh_needed(source, dest): ssh_cmd = [module.get_bin_path('ssh', required=True), '-S', 'none'] if private_key is not None: ssh_cmd.extend(['-i', private_key]) diff --git a/lib/ansible/plugins/action/synchronize.py b/lib/ansible/plugins/action/synchronize.py index df1bee57673..31a606686e6 100644 --- a/lib/ansible/plugins/action/synchronize.py +++ b/lib/ansible/plugins/action/synchronize.py @@ -216,6 +216,11 @@ class ActionModule(ActionBase): except KeyError: dest_host = dest_host_inventory_vars.get('ansible_ssh_host', inventory_hostname) + dest_host_ids = [hostid for hostid in (dest_host_inventory_vars.get('inventory_hostname'), + dest_host_inventory_vars.get('ansible_host'), + dest_host_inventory_vars.get('ansible_ssh_host')) + if hostid is not None] + localhost_ports = set() for host in C.LOCALHOST: localhost_vars = task_vars['hostvars'].get(host, {}) @@ -231,9 +236,9 @@ class ActionModule(ActionBase): # host rsync puts the files on. This is about *rsync's connection*, # not about the ansible connection to run the module. dest_is_local = False - if not delegate_to and remote_transport is False: + if delegate_to is None and remote_transport is False: dest_is_local = True - elif delegate_to and delegate_to == dest_host: + elif delegate_to is not None and delegate_to in dest_host_ids: dest_is_local = True # CHECK FOR NON-DEFAULT SSH PORT @@ -245,7 +250,7 @@ class ActionModule(ActionBase): # Set use_delegate if we are going to run rsync on a delegated host # instead of localhost use_delegate = False - if dest_host == delegate_to: + if delegate_to is not None and delegate_to in dest_host_ids: # edge case: explicit delegate and dest_host are the same # so we run rsync on the remote machine targeting its localhost # (itself)