-# 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:
: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
"""
format(self._ssh.get_transport().getpeername()))
logger.debug('Connections: {0}'.
format(str(SSH.__existing_connections)))
- except:
+ except RuntimeError as exc:
if attempts > 0:
self._reconnect(attempts-1)
else:
- raise
+ raise exc
def disconnect(self, node):
"""Close SSH connection to the node.
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)
if time() - start > timeout:
raise SSHTimeout(
- 'Timeout exception during execution of command: {0}\n'
- 'Current contents of stdout buffer: {1}\n'
- 'Current contents of stderr buffer: {2}\n'
- .format(cmd, 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)
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('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):
: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:
: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)
def interactive_terminal_open(self, time_out=30):
"""Open interactive terminal on a new channel on the connected Node.
- :param time_out: Timeout in seconds.
- :return: SSH channel with opened terminal.
+ FIXME: Convert or document other possible exceptions, such as
+ socket.error or SSHException.
.. warning:: Interruptingcow is used here, and it uses
signal(SIGALRM) to let the operating system interrupt program
handlers only apply to the main thread, so you cannot use this
from other threads. You must not use this in a program that
uses SIGALRM itself (this includes certain profilers)
+
+ :param time_out: Timeout in seconds.
+ :returns: SSH channel with opened terminal.
+ :raise IOError: If receive attempt results in socket.timeout.
"""
chan = self._ssh.get_transport().open_session()
chan.get_pty()
break
except socket.timeout:
logger.error('Socket timeout: {0}'.format(buf))
- raise Exception('Socket timeout: {0}'.format(buf))
+ # TODO: Find out which exception would callers appreciate here.
+ raise IOError('Socket timeout: {0}'.format(buf))
return chan
def interactive_terminal_exec_command(self, chan, cmd, prompt):
interactive_terminal_open() method has to be called first!
- :param chan: SSH channel with opened terminal.
- :param cmd: Command to be executed.
- :param prompt: Command prompt, sequence of characters used to
- indicate readiness to accept commands.
- :return: Command output.
-
.. warning:: Interruptingcow is used here, and it uses
signal(SIGALRM) to let the operating system interrupt program
execution. This has the following limitations: Python signal
handlers only apply to the main thread, so you cannot use this
from other threads. You must not use this in a program that
uses SIGALRM itself (this includes certain profilers)
+
+ :param chan: SSH channel with opened terminal.
+ :param cmd: Command to be executed.
+ :param prompt: Command prompt, sequence of characters used to
+ indicate readiness to accept commands.
+ :returns: Command output.
+ :raise IOError: If receive attempt results in socket.timeout.
"""
chan.sendall('{c}\n'.format(c=cmd))
buf = ''
except socket.timeout:
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))
+ # TODO: Find out which exception would callers appreciate here.
+ raise IOError('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, '')
def exec_cmd(node, cmd, timeout=600, sudo=False):
"""Convenience function to ssh/exec/return rc, out & err.
+ FIXME: Document :param, :type, :raise and similar.
Returns (rc, stdout, stderr).
"""
if node is None: