Open silverwind opened 1 year ago
Hello, @silverwind. I've tried to run playbook as you pointed out and got this error on 'gather facts' task:
fatal: [127.0.0.1]: UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: ssh: connect to host 127.0.0.1 port 1234: Connection refused",
"unreachable": true
}
I reproduced your error with connection: local
. Task failed because you don't have permissions to create files. There is no problems with ports otherwise you would get error on 'gather facts' task as I mentioned earlier. If you add options --ask-become-pass --become
it will work:
ansible-playbook --ask-become-pass --become -i 127.0.0.1, -vvv -e ansible_port=1234 playbook.yml
You need a SSH daemon listening on localhost:1234
. In my case it's a Vagrant VM which has my SSH key installed. --ask-become-pass
should therefore be unnecessary as it authorizes with SSH key, there are no passwords involved.
You should be able to reproduce if you disable gather_facts
, so it goes directly to the synchronize
step, and in that case you don't need anything listening on localhost:1234
to observe the missing rsync option -o Port=1234
in the debug.
Here is a repo to reproduce. There is str.sh
and int.sh
, the only difference between them is that str.sh
passes the port on the command line, while int.sh
passes it via vars
.
As int -o Port=1234
is present:
./int.sh
...
"msg": "ansible_port is type int"
...
fatal: [127.0.0.1]: FAILED! => {"changed": false, "cmd": "/usr/local/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/local/bin/ssh -S none -o Port=1234 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /Users/silverwind/git/ansible-synchronize-port/ 127.0.0.1:/opt/app/", "msg": "ssh: connect to host 127.0.0.1 port 1234: Connection refused\r\nrsync: connection unexpectedly closed (0 bytes received so far) [sender]\nrsync error: unexplained error (code 255) at io.c(231) [sender=3.2.7]\n", "rc": 255}
As str
is it absent (and it goes to localhost:22):
./str.sh
...
"msg": "ansible_port is type str"
...
fatal: [127.0.0.1]: FAILED! => {"changed": false, "cmd": "/usr/local/bin/rsync --delay-updates -F --compress --archive --out-format='<<CHANGED>>%i %n%L' /Users/silverwind/git/ansible-synchronize-port/ /opt/app/", "msg": "rsync: [Receiver] mkdir \"/opt/app\" failed: Permission denied (13)\nrsync error: error in file IO (code 11) at main.c(793) [Receiver=3.2.7]\n", "rc": 11}
I think https://github.com/ansible-collections/ansible.posix/issues/376 is the same root cause where ansible_port
is passed as string.
I suppose difference in how ansible-playbook
choose connection type. With gather_facts: false
connection is local otherwise it's ssh.
There should not be any SSH connection intiated by ansible-core in this playbook. The first connection is from the synchronize
module and I see it actually fails to pass the whole --rsh
argument to rsync
when ansible_port
is str
.
I've tried to run playbook without ansible_port
at all and in this case connection is local.
I believe there is difference between passing ansible_port
in playbook or in cli.
Try to pass ansible_port
like this ansible-playbook -i 127.0.0.1, -vvv -e '{"ansible_port":1234}' playbook.yml
and you will see:
ok: [127.0.0.1] => {
"msg": "ansible_port is type int"
}
but connection is still local.
It should not matter whether connection is local or not. The reproduction demonstrates the the module goes haywire and fails to pass options to rsync as soon as type is str
.
And yeah, there are various workarounds, https://github.com/ansible-collections/ansible.posix/issues/376#issuecomment-1222046195 is another one.
It's matter because module decides whether rsh
is needed or not like this https://github.com/ansible-collections/ansible.posix/blob/main/plugins/modules/synchronize.py#L383. Module doesn't go haywire as soon as type is str
. I've showed it in previous comment.
You are right, if I change 127.0.0.1
to 1.2.3.4
, the bug does not show and the --rsh
option is present even if port is str
.
Interesting that it only triggers when local and port is str
.
SUMMARY
When ansible is launched with
-e ansible_port=1234
, theansible_port
variable will be of typestr
, which is not accepted by the module and no-o Port=1234
is passed down torsync
. If the same variable is defined asint
type, it works as expected.ISSUE TYPE
COMPONENT NAME
ansible.posix.synchronize
ANSIBLE VERSION
COLLECTION VERSION
CONFIGURATION
OS / ENVIRONMENT
macOS 13
STEPS TO REPRODUCE
Run via
ansible-playbook -i 127.0.0.1, -vvv -e ansible_port=1234 playbook.yml
, observe no-o Port=1234
being passed.EXPECTED RESULTS
success
ACTUAL RESULTS
fails as it tries to ssh to localhost port 22: