topology.platforms.shell

topology shell api module.

Classes

class topology.platforms.shell.BaseShell

Base shell class for Topology nodes.

This class represents a base interface for a Topology node shell. This shell is expected to be an interactive shell, where an expect-like mechanism is to be used to find a terminal prompt that signals the end of the terminal response to a command sent to it.

Shells of this kind also represent an actual shell in the node. This means that one of these objects is expected to exist for every one of the shells in the node. These shells are accessible through a connection that may be implemented using a certain command (telnet, or ssh, for example). It may be possible to have several connections to the same shell, so these shells support multiple connections.

The behavior that these connections must follow is this one:

  1. New connections to the shell are created by calling the connect command of the shell with the name of the connection to be created defined in its connection attribute.
  2. Connections can be disconnected by calling the disconnect command of the shell.
  3. Connections can be either connected or disconnected.
  4. Existing disconnected connections can be connected again by calling the connnect command of the shell.
  5. An attempt to connect an already connected shell or to disconnect an already disconnected shell will raise an exception.
  6. These shells will have a default connection that will be used if the connection attribute of the shell methods is set to None.
  7. The default connection will be set to None when the shell is initialized.
  8. If the default connection is None and the connect command is called, it will set the default connection as the connection used in this call. Also, if the previous condition is true and if this connection attribute is set to None, the name of the default connection will be set to ‘0’.
  9. Every time any operation with the shell is attempted, a connection needs to be specified, if this connection is specified to be None, the default connection of the shell will be used.
  10. If any method other than connect and send_command is called with a connection that is not defined yet, an exception will be raised.
  11. If auto_connect is True, calling send_command with a disconnected or nonexistent connection will create and use a new connection. An exception will be raised otherwise.

The behavior of these operations is defined in the following methods, implementations of this class are expected to behave as defined here.

Be aware that the method _register_shell of the node will add two attributes to the shell objects:

  1. _name: name of the shell, the matching key of the node’s dictionary of shells
  2. _node: node object that holds the shell object

The _register_shell method is usually called in the node’s‘ __init__.

Inheritance

Inheritance diagram of BaseShell

connect(*args, connection=None, **kwargs)

Creates a connection to the shell.

Parameters:connection (str) – Name of the connection to be created. If not defined, an attempt to create the default connection will be done. If the default connection is already connected, an exception will be raised. If defined in the call but no default connection has been defined yet, this connection will become the default one. If the connection is already connected, an exception will be raised.
disconnect(*args, connection=None, **kwargs)

Terminates a connection to the shell.

Parameters:connection (str) – Name of the connection to be disconnected. If not defined, the default connection will be disconnected. If the default connection is disconnected, no attempt will be done to define a new default connection, the user will have to either create a new default connection by calling connect or by defining another existing connection as the default one.
execute(command, *args, connection=None, **kwargs)

Executes a command.

If the default connection is not defined, or is disconnected, an exception will be raised.

This is just a convenient method that sends a command to the shell using send_command and returns its response using get_response.

Parameters:
  • command (str) – Command to be sent.
  • connection (str) – Connection to be used to execute this command.
Return type:

str

Returns:

Shell response to the command being sent.

get_response(connection=None, silent=False)

Get a response from the shell connection.

This method can be used to add extra processing to the shell response if needed, cleaning up terminal control codes is an example.

Parameters:
  • connection (str) – Name of the connection to be used to get the response from. If not defined, the default connection will be used.
  • silent (bool) – True to call the connection logger, False otherwise.
Return type:

str

Returns:

Shell response to the previously sent command.

is_connected(connection=None)

Shows if the connection to the shell is active.

Parameters:connection (str) – Name of the connection to check if connected. If not defined, the default connection will be checked.
Return type:bool
Returns:True if there is an active connection to the shell, False otherwise.
send_command(command, matches=None, newline=True, timeout=None, connection=None, silent=False)

Send a command to the shell.

Parameters:
  • command (str) – Command to be sent to the shell.
  • matches (list) – List of strings that may be matched by the shell expect-like mechanism as prompts in the command response.
  • newline (bool) – True to append a newline at the end of the command, False otherwise.
  • timeout (int) – Amount of time to wait until a prompt match is found in the command response.
  • connection (str) – Name of the connection to be used to send the command. If not defined, the default connection will be used.
  • silent (bool) – True to call the connection logger, False otherwise.
class topology.platforms.shell.PExpectShell(prompt, initial_command=None, initial_prompt=None, user=None, user_match='[uU]ser:', password=None, password_match='[pP]assword:', prefix=None, timeout=None, encoding='utf-8', try_filter_echo=True, auto_connect=True, spawn_args=None, errors='ignore', **kwargs)

Implementation of the BaseShell class using pexpect.

This class provides a convenient implementation of the BaseShell using the pexpect package. The only thing needed for child classes is to define the command that will be used to connect to the shell.

See BaseShell.

Parameters:
  • prompt (str) – Regular expression that matches the shell prompt.
  • initial_command (str) – Command that is to be sent at the beginning of the connection.
  • initial_prompt (str) – Regular expression that matches the initial prompt. This value will be used to match the prompt before calling private method _setup_shell().
  • password (str) – Password to be sent at the beginning of the connection.
  • password_match (str) – Regular expression that matches a password prompt.
  • prefix (str) – The prefix to be prepended to all commands sent to this shell.
  • timeout (int) – Default timeout to use in send_command.
  • encoding (str) – Character encoding to use when decoding the shell response.
  • try_filter_echo (bool) – On platforms that doesn’t support some way of turning off the echo of the command try to filter the echo from the output by removing the first line of the output if it match the command.
  • bool (auto_connect) – Enable the automatic creation of a connection when send_command is called if the connection does not exist or is disconnected.
  • spawn_args (dict) – Arguments to be passed to the Pexpect spawn constructor. If this is left as None, then env={'TERM': 'dumb'}, echo=False will be passed as keyword arguments to the spawn constructor.
  • errors (str) – Handling of decoding errors in get_response. The values available are the same ones that the decode method of a bytes object expects in its error keyword argument. Defaults to ignore.

Inheritance

Inheritance diagram of PExpectShell

connect(*args, connection=None, **kwargs)

See BaseShell.connect() for more information.

disconnect(*args, connection=None, **kwargs)

See BaseShell.disconnect() for more information.

get_response(connection=None, silent=False)

See BaseShell.get_response() for more information.

is_connected(connection=None)

See BaseShell.is_connected() for more information.

send_command(command, matches=None, newline=True, timeout=None, connection=None, silent=False, control=False, continuous_timeout=False)

See BaseShell.send_command() for more information.

Parameters:
  • control (bool) – This is to be used with single character commands only. If enabled, the character sent will be interpreted as a control character. Enabling this option makes newline irrelevant. Defaults to False.
  • continuous_timeout (bool) – if true, we will repeat the expect with the same timeout duration as long as the command is still returning output.
class topology.platforms.shell.PExpectBashShell(initial_prompt=['\w+@.+:.+[#$] ', '@~~==::BASH_PROMPT::==~~@'], try_filter_echo=False, delay_after_echo_off=1, **kwargs)

Custom shell class for Bash.

This custom base class will setup the prompt PS1 to the FORCED_PROMPT value of the class and will disable the echo of the device by issuing the stty -echo command. All this is done in the _setup_shell() call, which is overriden by this class.

See PExpectShell.

Parameters:delay_after_echo_off (float) – Number of seconds pexpect should wait after setting echo off before sending another command, this allows bash enough time to properly turn echo off.

Inheritance

Inheritance diagram of PExpectBashShell

class topology.platforms.shell.ShellContext(node, shell_to_use)

Context Manager class for default shell swapping.

This object will handle the swapping of the default shell when in and out of the context.

Parameters:
  • node (BaseNode) – Node to default shell to swap.
  • shell_to_use (str) – Shell to use during the context session.

Inheritance

Inheritance diagram of ShellContext

Exceptions

exception topology.platforms.shell.NonExistingConnectionError(connection)

Exception raised by the shell API when trying to use a non-existent connection.

Inheritance

Inheritance diagram of NonExistingConnectionError

exception topology.platforms.shell.AlreadyConnectedError(connection)

Exception raised by the shell API when trying to create a connection already created.

Inheritance

Inheritance diagram of AlreadyConnectedError

exception topology.platforms.shell.AlreadyDisconnectedError(connection)

Exception raised by the shell API when trying to disconnect an already disconnected connection.

Inheritance

Inheritance diagram of AlreadyDisconnectedError

Variables

topology.platforms.shell.TERM_CODES_REGEX

Regular expression to match terminal control codes.

A terminal control code is a special sequence of characters that sent by some applications to control certain features of the terminal. It is responsibility of the terminal application (driver) to interpret those control codes. However, when using pexpect, the incoming buffer will still have those control codes and will not interpret or do anything with them other than store them. This regular expression allows to remove them as they are unneeded for the purpose of executing commands and parsing their outputs (unless proven otherwise).

\x1b
Match prefix that indicates the next characters are part of a terminal code string.
[E|\[]
Match either E or [.
(\?)?
Match zero or one ?.
([0-9]{1,2}
Match 1 or 2 numerical digits.
(;[0-9]{1,2})?
Match zero or one occurences of the following pattern: ; followed by 1 or 2 numerical digits.
)?
Means the pattern composed by the the last 2 parts above can be found zero or one times.
[m|K|h|H|r]?
Match zero or one occurrences of either m, K, h, H or r.
'\\x1b[E|\\[](\\?)?([0-9]{1,2}(;[0-9]{1,2})?)?[m|K|h|H|r]?'