diff --git a/Changelog.rst b/Changelog.rst index da0e35dd..04f26ef5 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -1,6 +1,14 @@ Change Log ============ +1.6.2 +++++++ + +Fixes +------ + +* Native client proxy initilisation failures were not caught by ``stop_on_errors=False`` - #121. + 1.6.1 +++++++ diff --git a/pssh/clients/native/parallel.py b/pssh/clients/native/parallel.py index 634019d2..0a39321c 100644 --- a/pssh/clients/native/parallel.py +++ b/pssh/clients/native/parallel.py @@ -301,14 +301,15 @@ def _start_tunnel(self, host): allow_agent=self.allow_agent) tunnel.daemon = True tunnel.start() - self._tunnels[host] = tunnel while not tunnel.tunnel_open.is_set(): logger.debug("Waiting for tunnel to become active") sleep(.1) if not tunnel.is_alive(): - msg = "Proxy authentication failed" - logger.error(msg) - raise ProxyError(msg) + msg = "Proxy authentication failed. " \ + "Exception from tunnel client: %s" + logger.error(msg, tunnel.exception) + raise ProxyError(msg, tunnel.exception) + self._tunnels[host] = tunnel return tunnel def _make_ssh_client(self, host): diff --git a/pssh/tunnel.py b/pssh/tunnel.py index ce10b3dc..497ae22c 100644 --- a/pssh/tunnel.py +++ b/pssh/tunnel.py @@ -55,6 +55,7 @@ def __init__(self, host, fw_host, fw_port, user=None, self.retry_delay = retry_delay self.allow_agent = allow_agent self.timeout = timeout + self.exception = None self.tunnel_open = Event() def _read_forward_sock(self): @@ -120,8 +121,13 @@ def _init_tunnel_client(self): self.session = self.client.session def run(self): - self._init_tunnel_client() - self._init_tunnel_sock() + try: + self._init_tunnel_client() + self._init_tunnel_sock() + except Exception as ex: + logger.error("Tunnel initilisation failed with %s", ex) + self.exception = ex + return logger.debug("Hub in run function: %s", get_hub()) try: while True: diff --git a/tests/test_native_parallel_client.py b/tests/test_native_parallel_client.py index 35a5be99..a57a41be 100644 --- a/tests/test_native_parallel_client.py +++ b/tests/test_native_parallel_client.py @@ -39,7 +39,8 @@ from pssh.pssh2_client import ParallelSSHClient, logger as pssh_logger from pssh.exceptions import UnknownHostException, \ AuthenticationException, ConnectionErrorException, SessionError, \ - HostArgumentException, SFTPError, SFTPIOError, Timeout, SCPError + HostArgumentException, SFTPError, SFTPIOError, Timeout, SCPError, \ + ProxyError from .embedded_server.embedded_server import make_socket from .embedded_server.openssh import OpenSSHServer @@ -1387,6 +1388,7 @@ def test_scp_send_dir(self): try: cmds = self.client.scp_send(local_filename, remote_filename) gevent.joinall(cmds, raise_error=True) + time.sleep(.2) self.assertTrue(os.path.isdir(remote_test_dir_abspath)) self.assertTrue(os.path.isfile(remote_file_abspath)) remote_file_data = open(remote_file_abspath, 'r').read() @@ -1507,8 +1509,22 @@ def test_tunnel(self): proxy_host=proxy_host, proxy_port=self.port, num_retries=1, proxy_pkey=self.user_key, timeout=2) - output = client.run_command('echo me', stop_on_errors=False) + output = client.run_command(self.cmd, stop_on_errors=False) self.assertEqual(self.host, list(output.keys())[0]) + del client + server.stop() + + def test_tunnel_init_failure(self): + proxy_host = '127.0.0.20' + client = ParallelSSHClient( + [self.host], port=self.port, pkey=self.user_key, + proxy_host=proxy_host, proxy_port=self.port, num_retries=1, + proxy_pkey=self.user_key, + timeout=2) + output = client.run_command(self.cmd, stop_on_errors=False) + exc = output[self.host].exception + self.assertIsInstance(exc, ProxyError) + self.assertIsInstance(exc.args[1], ConnectionErrorException) # def test_proxy_remote_host_failure_timeout(self): # """Test that timeout setting is passed on to proxy to be used for the