mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-27 04:41:26 -07:00
fix(tasks: synchronize): wrap in sshpass if ssh password was provided (#30743)
* fix(tasks: synchronize): wrap in sshpass if ssh password was provided Closes #16616 * fix(tasks: synchronize): pass rsync password to sshpass via fd * fix(tasks: synchronize): use fail_json instead of AnsibleError * fixup! fix(tasks: synchronize): use fail_json instead of AnsibleError fix python2 handling * feat(module_utils: basic: run_command): add optional arguments `pass_fds` and `before_communicate_callback` * fix(tasks: synchronize): use module.run_command instead of subprocess.Popen * fixup! fix(tasks: synchronize): use module.run_command instead of subprocess.Popen remove unused import * fixup! fixup! fix(tasks: synchronize): use module.run_command instead of subprocess.Popen pass_fds only if they passed to run_command()
This commit is contained in:
parent
7f3c21f628
commit
14037443de
3 changed files with 45 additions and 3 deletions
|
@ -319,8 +319,9 @@ EXAMPLES = '''
|
|||
|
||||
|
||||
import os
|
||||
import errno
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.basic import AnsibleModule, to_bytes
|
||||
from ansible.module_utils.six.moves import shlex_quote
|
||||
|
||||
|
||||
|
@ -365,6 +366,7 @@ def main():
|
|||
private_key=dict(type='path'),
|
||||
rsync_path=dict(type='str'),
|
||||
_local_rsync_path=dict(type='path', default='rsync'),
|
||||
_local_rsync_password=dict(default=None, no_log=True),
|
||||
_substitute_controller=dict(type='bool', default=False),
|
||||
archive=dict(type='bool', default=True),
|
||||
checksum=dict(type='bool', default=False),
|
||||
|
@ -404,6 +406,7 @@ def main():
|
|||
private_key = module.params['private_key']
|
||||
rsync_path = module.params['rsync_path']
|
||||
rsync = module.params.get('_local_rsync_path', 'rsync')
|
||||
rsync_password = module.params.get('_local_rsync_password')
|
||||
rsync_timeout = module.params.get('rsync_timeout', 'rsync_timeout')
|
||||
archive = module.params['archive']
|
||||
checksum = module.params['checksum']
|
||||
|
@ -428,6 +431,16 @@ def main():
|
|||
rsync = module.get_bin_path(rsync, required=True)
|
||||
|
||||
cmd = [rsync, '--delay-updates', '-F']
|
||||
_sshpass_pipe = None
|
||||
if rsync_password:
|
||||
try:
|
||||
module.run_command(["sshpass"])
|
||||
except OSError:
|
||||
module.fail_json(
|
||||
msg="to use rsync connection with passwords, you must install the sshpass program"
|
||||
)
|
||||
_sshpass_pipe = os.pipe()
|
||||
cmd = ['sshpass', '-d' + _sshpass_pipe[0]] + cmd
|
||||
if compress:
|
||||
cmd.append('--compress')
|
||||
if rsync_timeout:
|
||||
|
@ -534,7 +547,24 @@ def main():
|
|||
cmd.append(source)
|
||||
cmd.append(dest)
|
||||
cmdstr = ' '.join(cmd)
|
||||
(rc, out, err) = module.run_command(cmd)
|
||||
|
||||
# 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)
|
||||
|
||||
if rc:
|
||||
return module.fail_json(msg=err, rc=rc, cmd=cmdstr)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue