diff --git a/changelogs/fragments/piped-transfer-empty-files.yaml b/changelogs/fragments/piped-transfer-empty-files.yaml new file mode 100644 index 00000000000..756351d0950 --- /dev/null +++ b/changelogs/fragments/piped-transfer-empty-files.yaml @@ -0,0 +1,2 @@ +bugfixes: +- ssh connection - Support empty files with piped transfer_method (https://github.com/ansible/ansible/issues/45426) diff --git a/lib/ansible/plugins/connection/ssh.py b/lib/ansible/plugins/connection/ssh.py index 008f2ebfe93..dc26acb256f 100644 --- a/lib/ansible/plugins/connection/ssh.py +++ b/lib/ansible/plugins/connection/ssh.py @@ -930,13 +930,16 @@ class Connection(ConnectionBase): # we pass sudoable=False to disable pty allocation, which # would end up mixing stdout/stderr and screwing with newlines (returncode, stdout, stderr) = self.exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE), sudoable=False) - out_file = open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') - out_file.write(stdout) - out_file.close() + with open(to_bytes(out_path, errors='surrogate_or_strict'), 'wb+') as out_file: + out_file.write(stdout) else: - in_data = open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb').read() - in_data = to_bytes(in_data, nonstring='passthru') - (returncode, stdout, stderr) = self.exec_command('dd of=%s bs=%s' % (out_path, BUFSIZE), in_data=in_data, sudoable=False) + with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as f: + in_data = to_bytes(f.read(), nonstring='passthru') + if not in_data: + count = ' count=0' + else: + count = '' + (returncode, stdout, stderr) = self.exec_command('dd of=%s bs=%s%s' % (out_path, BUFSIZE, count), in_data=in_data, sudoable=False) # Check the return code and rollover to next method if failed if returncode == 0: