diff --git a/lib/ansible/runner/connection_plugins/ssh.py b/lib/ansible/runner/connection_plugins/ssh.py index 8d82a2617e..8dd47b515a 100644 --- a/lib/ansible/runner/connection_plugins/ssh.py +++ b/lib/ansible/runner/connection_plugins/ssh.py @@ -272,7 +272,6 @@ class Connection(object): raise errors.AnsibleError('SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh') while True: rfd, wfd, efd = select.select(rpipes, [], rpipes, 1) - process_over = p.poll() is not None # fail early if the sudo/su password is wrong if self.runner.sudo and sudoable and self.runner.sudo_pass: @@ -288,11 +287,22 @@ class Connection(object): raise errors.AnsibleError('Incorrect su password') if p.stdout in rfd: - stdout += os.read(p.stdout.fileno(), 9000) + dat = os.read(p.stdout.fileno(), 9000) + stdout += dat + if dat == '': + rpipes.remove(p.stdout) if p.stderr in rfd: - stderr += os.read(p.stderr.fileno(), 9000) - if process_over: + dat = os.read(p.stderr.fileno(), 9000) + stderr += dat + if dat == '': + rpipes.remove(p.stderr) + # only break out if we've emptied the pipes, or there is nothing to + # read from and the process has finished. + if (not rpipes or not rfd) and p.poll() is not None: break + # Calling wait while there are still pipes to read can cause a lock + elif not rpipes and p.poll() == None: + p.wait() stdin.close() # close stdin after we read from stdout (see also issue #848) if C.HOST_KEY_CHECKING and not_in_host_file: diff --git a/lib/ansible/runner/connection_plugins/ssh_old.py b/lib/ansible/runner/connection_plugins/ssh_old.py index da91018769..db4fc24fcc 100644 --- a/lib/ansible/runner/connection_plugins/ssh_old.py +++ b/lib/ansible/runner/connection_plugins/ssh_old.py @@ -230,7 +230,6 @@ class Connection(object): rpipes = [p.stdout, p.stderr] while True: rfd, wfd, efd = select.select(rpipes, [], rpipes, 1) - process_over = p.poll() is not None # fail early if the sudo/su password is wrong if self.runner.sudo and sudoable and self.runner.sudo_pass: @@ -246,11 +245,22 @@ class Connection(object): raise errors.AnsibleError('Incorrect su password') if p.stdout in rfd: - stdout += os.read(p.stdout.fileno(), 9000) + dat = os.read(p.stdout.fileno(), 9000) + stdout += dat + if dat == '': + rpipes.remove(p.stdout) if p.stderr in rfd: - stderr += os.read(p.stderr.fileno(), 9000) - if process_over: + dat = os.read(p.stderr.fileno(), 9000) + stderr += dat + if dat == '': + rpipes.remove(p.stderr) + # only break out if we've emptied the pipes, or there is nothing to + # read from and the process has finished. + if (not rpipes or not rfd) and p.poll() is not None: break + # Calling wait while there are still pipes to read can cause a lock + elif not rpipes and p.poll() == None: + p.wait() stdin.close() # close stdin after we read from stdout (see also issue #848) if C.HOST_KEY_CHECKING and not_in_host_file: