我的错误信息:
fatal: [org0.example.com]: FAILED! => {"changed": false, "cmd": "sshpass -d9 /usr/bin/rsync --delay-updates -F --compress --archive '--rsh=/usr/bin/ssh -S none -o Port=22 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' '--out-format=<<CHANGED>>%i %n%L' /Users/liyi/github/Ansible-Fabric-Starter/templates/chaincode ''", "msg": "[Errno 32] Broken pipe", "rc": 32}
网友错误信息:
The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
File "/tmp/ansible_synchronize_payload_vWRlFT/ansible_synchronize_payload.zip/ansible/module_utils/basic.py", line 2563, in run_command
before_communicate_callback(cmd)
File "/tmp/ansible_synchronize_payload_vWRlFT/__main__.py", line 581, in _write_********_to_pipe
os.write(_sshpass_pipe[1], to_bytes(rsync_********) + b'\n')
localhost | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"cmd": "sshpass -d11 /usr/bin/rsync --delay-updates -F --compress --archive '--rsh=/usr/bin/ssh -S none -o Port=9000 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' '--out-format=<<CHANGED>>%i %n%L' /tmp/foo ''",
"invocation": {
"module_args": {
"_local_rsync_password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"_local_rsync_path": "rsync",
"_substitute_controller": false,
"archive": true,
"checksum": false,
"compress": true,
"copy_links": false,
"delete": false,
"dest": "root@localhost:/tmp",
"dest_port": 9000,
"dirs": false,
"existing_only": false,
"group": null,
"link_dest": null,
"links": null,
"mode": "push",
"owner": null,
"partial": false,
"perms": null,
"private_key": null,
"recursive": null,
"rsync_opts": [],
"rsync_path": null,
"rsync_timeout": 0,
"set_remote_user": true,
"src": "/tmp/foo",
"ssh_args": null,
"times": null,
"verify_host": false
}
},
"msg": "[Errno 32] Broken pipe",
"rc": 32
}
当通过Python 2解释器在控件主机上运行Ansible时,似乎会出现此问题。 为避免在命令行中将密码传递给sshpass,它使用管道和Popen(pass_fds =),这仅在Python 3中可用。
我在控制机上运行Ubuntu 18.04 LTS,似乎它仍然使用python2解释器运行Ansible,因此它无法将密码传递给sshpass,并且过程失败。
修补/usr/lib/python2.7/dist-packages/ansible/modules/files/synchronize.py相对简单,以便在命令行而不是使用管道来传递密码。 这是diff(基本文件来自Ansible 2.9.1版):
463,464c463,464
< _sshpass_pipe = os.pipe()
< cmd = ['sshpass', '-d' + to_native(_sshpass_pipe[0], errors='surrogate_or_strict')] + cmd
---
> cmd = ['sshpass', '-p' + rsync_password] + cmd
>
577,592c577
< # If we are using password authentication, write the password into the pipe
< if rsync_password:
< def _write_password_to_pipe(proc):
< os.close(_sshpass_pipe[0])
< try:
< os.write(_sshpass_pipe[1], to_bytes(rsync_password) + b'\n')
< except OSError as exc:
< # Ignore broken pipe errors if the sshpass process has exited.
< if exc.errno != errno.EPIPE or proc.poll() is None:
< raise
<
< (rc, out, err) = module.run_command(
< cmd, pass_fds=_sshpass_pipe,
< before_communicate_callback=_write_password_to_pipe)
< else:
< (rc, out, err) = module.run_command(cmd)
---
> (rc, out, err) = module.run_command(cmd)
我还使用了模块选项rsync_path:rsync以避免远程计算机上的sudo密码出现问题(我在那里不需要提升的特权)。
附言 我认为添加选项以在命令行上将密码传递给sshpass来容纳python2用户可能很好并且非常容易。 如果需要,我可以提供PR。
网友评论