X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=resources%2Flibraries%2Fpython%2Fssh.py;h=5ff1b2d769b705aa15907ac642a14eaf5d3a0166;hb=6e9d38fbad8198f8647e3e71d12b5859490c21f2;hp=5777c3200109906c971f8e0ee929373d3b6e5b4e;hpb=fcee621dda66ed8b218158c36afbf07bd08b23a1;p=csit.git diff --git a/resources/libraries/python/ssh.py b/resources/libraries/python/ssh.py index 5777c32001..5ff1b2d769 100644 --- a/resources/libraries/python/ssh.py +++ b/resources/libraries/python/ssh.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Cisco and/or its affiliates. +# Copyright (c) 2018 Cisco and/or its affiliates. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: @@ -50,7 +50,7 @@ class SSH(object): :param node: Node in topology. :type node: dict - :return: IP address and port for the specified node. + :returns: IP address and port for the specified node. :rtype: int """ @@ -132,21 +132,25 @@ class SSH(object): :rtype: tuple(int, str, str) :raise SSHTimeout: If command is not finished in timeout time. """ - start = time() stdout = StringIO.StringIO() stderr = StringIO.StringIO() try: chan = self._ssh.get_transport().open_session(timeout=5) + peer = self._ssh.get_transport().getpeername() except AttributeError: self._reconnect() chan = self._ssh.get_transport().open_session(timeout=5) + peer = self._ssh.get_transport().getpeername() except SSHException: self._reconnect() chan = self._ssh.get_transport().open_session(timeout=5) + peer = self._ssh.get_transport().getpeername() chan.settimeout(timeout) - logger.trace('exec_command on {0}: {1}' - .format(self._ssh.get_transport().getpeername(), cmd)) + logger.trace('exec_command on {peer} with timeout {timeout}: {cmd}' + .format(peer=peer, timeout=timeout, cmd=cmd)) + + start = time() chan.exec_command(cmd) while not chan.exit_status_ready() and timeout is not None: if chan.recv_ready(): @@ -157,10 +161,11 @@ class SSH(object): if time() - start > timeout: raise SSHTimeout( - 'Timeout exception.\n' - 'Current contents of stdout buffer: {0}\n' - 'Current contents of stderr buffer: {1}\n' - .format(stdout.getvalue(), stderr.getvalue()) + 'Timeout exception during execution of command: {cmd}\n' + 'Current contents of stdout buffer: {stdout}\n' + 'Current contents of stderr buffer: {stderr}\n' + .format(cmd=cmd, stdout=stdout.getvalue(), + stderr=stderr.getvalue()) ) sleep(0.1) @@ -173,14 +178,12 @@ class SSH(object): stderr.write(chan.recv_stderr(self.__MAX_RECV_BUF)) end = time() - logger.trace('exec_command on {0} took {1} seconds'.format( - self._ssh.get_transport().getpeername(), end-start)) + logger.trace('exec_command on {peer} took {total} seconds'. + format(peer=peer, total=end-start)) - logger.trace('chan_recv/_stderr took {} seconds'.format(time()-end)) - - logger.trace('return RC {}'.format(return_code)) - logger.trace('return STDOUT {}'.format(stdout.getvalue())) - logger.trace('return STDERR {}'.format(stderr.getvalue())) + logger.trace('return RC {rc}'.format(rc=return_code)) + logger.trace('return STDOUT {stdout}'.format(stdout=stdout.getvalue())) + logger.trace('return STDERR {stderr}'.format(stderr=stderr.getvalue())) return return_code, stdout.getvalue(), stderr.getvalue() def exec_command_sudo(self, cmd, cmd_input=None, timeout=30): @@ -189,7 +192,7 @@ class SSH(object): :param cmd: Command to be executed. :param cmd_input: Input redirected to the command. :param timeout: Timeout. - :return: return_code, stdout, stderr + :returns: return_code, stdout, stderr :Example: @@ -221,7 +224,7 @@ class SSH(object): :type lxc_params: str :type sudo: bool :type timeout: int - :return: return_code, stdout, stderr + :returns: return_code, stdout, stderr """ command = "lxc-attach {p} --name {n} -- /bin/sh -c '{c}'"\ .format(p=lxc_params, n=lxc_name, c=lxc_cmd) @@ -234,7 +237,7 @@ class SSH(object): """Open interactive terminal on a new channel on the connected Node. :param time_out: Timeout in seconds. - :return: SSH channel with opened terminal. + :returns: SSH channel with opened terminal. .. warning:: Interruptingcow is used here, and it uses signal(SIGALRM) to let the operating system interrupt program @@ -250,7 +253,7 @@ class SSH(object): chan.set_combine_stderr(True) buf = '' - while not buf.endswith((":~$ ", "~]$ ")): + while not buf.endswith((":~$ ", "~]$ ", "~]# ")): try: chunk = chan.recv(self.__MAX_RECV_BUF) if not chunk: @@ -260,6 +263,7 @@ class SSH(object): logger.error('Channel exit status ready') break except socket.timeout: + logger.error('Socket timeout: {0}'.format(buf)) raise Exception('Socket timeout: {0}'.format(buf)) return chan @@ -272,7 +276,7 @@ class SSH(object): :param cmd: Command to be executed. :param prompt: Command prompt, sequence of characters used to indicate readiness to accept commands. - :return: Command output. + :returns: Command output. .. warning:: Interruptingcow is used here, and it uses signal(SIGALRM) to let the operating system interrupt program @@ -293,7 +297,10 @@ class SSH(object): logger.error('Channel exit status ready') break except socket.timeout: - raise Exception('Socket timeout: {0}'.format(buf)) + logger.error('Socket timeout during execution of command: ' + '{0}\nBuffer content:\n{1}'.format(cmd, buf)) + raise Exception('Socket timeout during execution of command: ' + '{0}\nBuffer content:\n{1}'.format(cmd, buf)) tmp = buf.replace(cmd.replace('\n', ''), '') for item in prompt: tmp.replace(item, '') @@ -385,4 +392,4 @@ def exec_cmd_no_error(node, cmd, timeout=600, sudo=False): (ret_code, stdout, stderr) = exec_cmd(node, cmd, timeout=timeout, sudo=sudo) assert_equal(ret_code, 0, 'Command execution failed: "{}"\n{}'. format(cmd, stderr)) - return stdout, stderr + return stdout, stderr \ No newline at end of file