From 22b9525aa95df4cef8f75573af8bcc3783847256 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 23 May 2019 10:03:35 -0400 Subject: [PATCH] Preserve ssh error (#56460) * Preserve ssh error * more details on fail * removed redundant caption to errors --- changelogs/fragments/ssh_better_errors.yml | 2 ++ lib/ansible/plugins/connection/ssh.py | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/ssh_better_errors.yml diff --git a/changelogs/fragments/ssh_better_errors.yml b/changelogs/fragments/ssh_better_errors.yml new file mode 100644 index 00000000000..b92f715696c --- /dev/null +++ b/changelogs/fragments/ssh_better_errors.yml @@ -0,0 +1,2 @@ +bugfixes: + - preserve actual ssh error when we cannot connect. diff --git a/lib/ansible/plugins/connection/ssh.py b/lib/ansible/plugins/connection/ssh.py index 1531e41b03c..59c2a8d5cca 100644 --- a/lib/ansible/plugins/connection/ssh.py +++ b/lib/ansible/plugins/connection/ssh.py @@ -413,7 +413,7 @@ def _ssh_retry(func): break # 5 = Invalid/incorrect password from sshpass - except AnsibleAuthenticationFailure as e: + except AnsibleAuthenticationFailure: # Raising this exception, which is subclassed from AnsibleConnectionFailure, prevents further retries raise @@ -686,15 +686,15 @@ class Connection(ConnectionBase): try: fh.write(to_bytes(in_data)) fh.close() - except (OSError, IOError): + except (OSError, IOError) as e: # The ssh connection may have already terminated at this point, with a more useful error # Only raise AnsibleConnectionFailure if the ssh process is still alive time.sleep(0.001) ssh_process.poll() if getattr(ssh_process, 'returncode', None) is None: raise AnsibleConnectionFailure( - 'SSH Error: data could not be sent to remote host "%s". Make sure this host can be reached ' - 'over ssh' % self.host + 'Data could not be sent to remote host "%s". Make sure this host can be reached ' + 'over ssh: %s' % (self.host, to_native(e)), orig_exc=e ) display.debug('Sent initial data (%d bytes)' % len(in_data)) @@ -1030,11 +1030,15 @@ class Connection(ConnectionBase): # If we find a broken pipe because of ControlPersist timeout expiring (see #16731), # we raise a special exception so that we can retry a connection. controlpersist_broken_pipe = b'mux_client_hello_exchange: write packet: Broken pipe' in b_stderr - if p.returncode == 255 and controlpersist_broken_pipe: - raise AnsibleControlPersistBrokenPipeError('SSH Error: data could not be sent because of ControlPersist broken pipe.') + if p.returncode == 255: - if p.returncode == 255 and in_data and checkrc: - raise AnsibleConnectionFailure('SSH Error: data could not be sent to remote host "%s". Make sure this host can be reached over ssh' % self.host) + additional = to_native(b_stderr) + if controlpersist_broken_pipe: + raise AnsibleControlPersistBrokenPipeError('Data could not be sent because of ControlPersist broken pipe: %s' % additional) + + elif in_data and checkrc: + raise AnsibleConnectionFailure('Data could not be sent to remote host "%s". Make sure this host can be reached over ssh: %s' + % (self.host, additional)) return (p.returncode, b_stdout, b_stderr)