Repository: ansible/ansible

Issue:
Issues using Ansible synchronize module to Transfer files from Local to Remote host
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME

lib/ansible/modules/file/synchronize.py 

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.4.1.0

  config file = /home/ansbladm/.ansible.cfg

  configured module search path = [u'/home/ansbladm/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']

  ansible python module location = /usr/lib/python2.7/site-packages/ansible

  executable location = /bin/ansible

  python version = 2.7.5 (default, May  3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]
```
##### CONFIGURATION
<!---
ansible-config dump --only-changed

ANSIBLE_PIPELINING(/home/ansbladm/.ansible.cfg) = True

ANSIBLE_SSH_ARGS(/home/ansbladm/.ansible.cfg) =
-->

##### OS / ENVIRONMENT
<!---
Linux CentOS 7
-->

##### SUMMARY
<!--- I wish to copy everything under "/web/Transfer_Files/data/" directory on my localhost where I run my ansible-playbook command onto a remote destination server "remote_server2.com" "/tmp/" directory.

The transfer happens successfully , But i m getting errors and the Playbook fails.

I found the bug to be in the synchronize module where it constructs the rsync command as below.

rsync --delay-updates -F --compress --archive --rsh=ssh -S none /web/Transfer_Files/data/ wlsuser@mybank.intra.com:/tmp

When the command should be without -S none.
Correct rsync command that works is below:

rsync --delay-updates -F --compress --archive --rsh=ssh /web/Transfer_Files/data/ wlsuser@mybank.intra.com:/tmp

Can you please provide a workaround or fix this BUG ??
-->

##### STEPS TO REPRODUCE
<!---
Linux command:
./transfer_files.sh 'perforce_server.com' '/web/platform1212/jdk1.7.0_90' 'remote_server2.com'  '/tmp/' '775'

more transfer_files.sh
ansible-playbook -vvvv site.yml  -i $1,$3 -e "source_file=$2 dest_loc=$4 dest_permission=$5"

more site.yml
- hosts: all[1]
  user: remote_user1
  tasks:
    - synchronize: mode=push src=/web/Transfer_Files/data/ dest="{{ dest_loc }}"
-->

<!--- Paste example playbooks or commands between quotes below -->
```
- hosts: all[1]
  user: remote_user1
  tasks:
    - synchronize: mode=push src=/web/Transfer_Files/data/ dest="{{ dest_loc }}"
```

<!--- You can also paste gist.github.com links for larger files -->

The ansible-playbook run output is shared here: [http://textuploader.com/dhom7](http://textuploader.com/dhom7)

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->

The Linux rsync command is failing causing this ansible module to also fail. 

Ansible tool synchronize module which triggers the unix rsync command as below: 
Below is the sample rsync command constructed and triggered by the synchronize module of ansible.

rsync --delay-updates -F --compress --archive --rsh=ssh -S none /web/Transfer_Files/data/ wlsuser@mybank.intra.com:/tmp

This fails with the below error causing the ansible to fail as well.

rsync: link_stat "/web/Transfer_Files/none" failed: No such file or directory (2)
rsync: failed to set times on "/tmp/.": Not owner (1)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1052) [sender=3.0.9]

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
I did run with -vvvv
<!--- Paste verbatim command output between quotes below -->
```
TASK [synchronize] **********************************************************************************************************************************************************************************

task path: /web/Transfer_Files/site.yml:67

Using module file /usr/python2.7/site-packages/ansible/modules/files/synchronize.py

<remote_server2.com> ESTABLISH LOCAL CONNECTION FOR USER: ansbladm

<remote_server2.com> EXEC /bin/sh -c '/usr/bin/python2 && sleep 0'

The full traceback is:

  File "/tmp/ansible_qedfd6/ansible_module_synchronize.py", line 311, in <module>

    from shlex import quote as shlex_quote

fatal: [remote_server2.com]: FAILED! => {

    "changed": false,

    "cmd": "/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/share/centrifydc/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null --out-format=<<CHANGED>>%i %n%L /web/Transfer_Files/data/ remote_user1@remote_server2.com:/tmp",

    "failed": true,

    "invocation": {

        "module_args": {

            "_local_rsync_path": "rsync",

            "_substitute_controller": false,

            "archive": true,

            "checksum": false,

            "compress": true,

            "copy_links": false,

            "delete": false,

            "dest": "remote_user1@remote_server2.com:/tmp",

            "dest_port": null,

            "dirs": false,

            "existing_only": false,

            "group": null,

            "links": null,

            "mode": "push",

            "owner": null,

            "partial": false,

            "perms": null,

            "private_key": null,

            "recursive": null,

            "rsync_opts": null,

            "rsync_path": null,

            "rsync_timeout": 0,

            "set_remote_user": true,

            "src": "/web/Transfer_Files/data/",

            "ssh_args": null,

            "times": null,

            "verify_host": false

        }

    },

    "msg": "Warning: Permanently added 'remote_server2.com,121.110.43.109' (ECDSA) to the list of known hosts.\r\n\nThis system is for the use by authorized users only. All data contained\non all systems is owned by the company and may be monitored, intercepted,\nrecorded, read, copied, or captured in any manner and disclosed in any\nmanner, by authorized company personnel. Users (authorized or unauthorized)\nhave no explicit or implicit expectation of privacy. Unauthorized or improper\nuse of this system may result in administrative, disciplinary action, civil\nand criminal penalties. Use of this system by any user, authorized or\nunauthorized, constitutes express consent to this monitoring, interception,\nrecording, reading, copying, or capturing and disclosure.\n\nIF YOU DO NOT CONSENT, LOG OFF NOW.\n\n##################################################################\n# *** This Server is using Centrify                          *** #\n# *** Remember to use your Active Directory account          *** #\n# ***    password when logging in                            *** #\n##################################################################\n\nrsync: failed to set times on \"/tmp/.\": Not owner (1)\nrsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1052) [sender=3.0.9]\n",

    "rc": 23

}

        to retry, use: --limit @/web/Transfer_Files/site.retry

 

PLAY RECAP ******************************************************************************************************************************************************************************************

remote_server2.com    : ok=2    changed=1    unreachable=0    failed=1

mybank_server4.com    : ok=5    changed=1    unreachable=0    failed=0
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/files/synchronize.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/files/synchronize.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @tima
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
I have found where the issue lies and updated the original post. Can you please provide the solution or bug-fix ??
From the error message `rsync: failed to set times on "/tmp/.": Not owner (1)`, it looks like a permissions issue on the remote system for `{{ dest_loc }}`
needs_info
@maxamillion the issue is not what you are suspecting. 

The permission error is because of the bug. 

The synchronize module is constructing the rsync command as below:
`rsync --delay-updates -F --compress --archive --rsh=ssh -S none /web/Transfer_Files/data/ wlsuser@mybank.intra.com:/tmp`

The "-S none" is the problem. If i remove "-S none" the playbook works. I dont get permission issue anymore.

-S doesn't take an argument (at least on Ubuntu Linux), so I'd guess it's interpreting none as a source (relative to cwd, which is presumably /web/Transfer_files) is why it is failing. 

You should be able to replicate this issue on CentOS 7 Linux flavor that i m using.


Resolving patch:
diff --git a/lib/ansible/modules/files/synchronize.py b/lib/ansible/modules/files/synchronize.py
--- a/lib/ansible/modules/files/synchronize.py
+++ b/lib/ansible/modules/files/synchronize.py
@@ -481,7 +481,7 @@ def main():
         ssh_cmd_str = ' '.join(shlex_quote(arg) for arg in ssh_cmd)
         if ssh_args:
             ssh_cmd_str += ' %s' % ssh_args
-        cmd.append('--rsh=%s' % ssh_cmd_str)
+        cmd.append('--rsh=\'%s\'' % ssh_cmd_str)
 
     if rsync_path:
         cmd.append('--rsync-path=%s' % rsync_path)


Test patch: