Remote Proxies¶
Remote proxies provide a Pythonic way to communicate with the targets connected via InteractiveSession.
Basically the only requirement is that the remote end is capable of starting PythonShell in the interactive mode.
In this section the proxy management associated interfaces are described. Examples of proxies can be found from Examples of crl.interactivesessions usage.
AutoRecoveringTerminal¶
This module implements pseudo terminal based autorecovering terminal.
-
class
crl.interactivesessions.autorecoveringterminal.
AutoRecoveringTerminal
¶ Automatically recovering terminal in case of listed exception occurs in
run()
or ininitialize()
.For running commands in the terminal of SSH host example.com just use:
>>> from crl.interactivesessions import ( ... AutorecoveringTerminal) >>> from crl.interactivesessions import ( ... SshShell) >>> term = AutoRecoveringTerminal() >>> term.initialize(SshShell( ... 'example.com', 'username', 'password')) >>> term.run('echo hello world!')
-
close
()¶ Close terminal.
Note
Please remember to call
initialize_terminal()
afterclose()
. in order to make the object usable again.
-
initialize
(shells, broken_exceptions=<type 'exceptions.Exception'>, init_broken_exceptions=<type 'exceptions.Exception'>, sleep_between_tries=3, max_tries=3, prepare=<function <lambda>>, finalize=<function <lambda>>, verify=<function <lambda>>)¶ Initialize terminal topology information.
Note
This method does not open the connections. The connections are opened by
initialize_terminal()
. It is up to the use-case when to open the connection and thus connection opening is purposly separated from the topology setting.The connection opening can be also left to
retry_run()
. It opens the connection in the first call. In this fashion the connection opening is not done without a real reason.- Args:
shells (Shell or list of Shells): List of objects derived from
InteractiveSession.Shell
which defines the desired state of the terminal.broken_exceptions (Exception class or list of Exception classes): The exceptions which determines the broken session. If any of these exceptions occurs, the session is automatically recovered. By default, the occurence of any exception triggers the recovery process.
init_broken_exceptions (Eception class or list of exceptions): The exceptions which determines the broken session during init. By default all the exceptions are in this category.
sleep_between_tries (int): seconds to sleep between tries if the exception marking broken session/connection occurs.
max_tries (positive int): maximum number of tries for initialization or for run. If max_tries is 1, then initialization or run is tried only once even if the connection is broken.
prepare (callable): function to be called once initialization of the shell stack is ready.
finalize (callable): function to be called prior the terminal close. verify (callable): function to be called from
auto_setup()
for verifying session. Must raise an exception in broken_exceptions in case the session is broken.
-
initialize_if_needed
()¶ Initialize the session in case verify fails or if the terminal is not initialized already.
-
initialize_terminal
()¶ Initialize terminal connections.
-
set_verify
(verify)¶ Set verify callable. If verify raises any broken_exceptions, the old session will be closed and the new session will be prepared in
initialize_if_needed()
.
-
RunnerTerminal¶
-
class
crl.interactivesessions.runnerterminal.
RunnerTerminal
¶ This is the Python terminal session wrapper for the transparent proxy instances:
remoteproxies._RemoteProxy
andremoteproxies._RecursiveProxy
.Note
This class has Python 2 dependencies.
-
add_handle_to_garbage
(session_id, handle)¶ Adds
crl.interactivesessions.remoteproxies._RemoteProxy
handles (or the derivates of it) into garbage collection. The garbage is cleaned during executions when the treshold MAX_GARBAGE is exceeded.
-
assign_and_run_python
(handle, cmd, timeout=None)¶ Runs a python expression cmd on the remote node and assigns then value to handle. If the value of the expression is an instance of any of the HANDLED_TYPES, then also the value is returned.
Note
The HANDLED_TYPES instances must be serializable and deserializable by picklers and unpicklers.
The return value of the remote call is returned as a python object with two attributes:
isobj: True if the value of the object is returned.
obj: The value of the expression.
If an exception is raised on the remote end, the traceback is logged, and the exception object is raised by this method.
-
close
()¶ Close the terminal session.
Removes any handler modules from the remote end if necessary, and restores the terminal to the original state.
-
create_empty_recursive_proxy
()¶ Creates
remoteproxies._RecursiveProxy
without handle or any other content. This proxy cannot be used but the content of it should be changed by callingremoteproxies._RemoteProxy.set_from_remote_proxy()
.
-
create_empty_remote_proxy
()¶ Creates empty
remoteproxies._RemoteProxy
. Seecreate_empty_recursive_proxy()
.
-
get_proxy_object
(remote_object, local_spec)¶ Creates a proxy object for remote_object.
Args:
remote_object: the name of the remote object to proxy.
- local_spec: a local class object, used to determine which methods
- are available on the remote object. If None, the spec is determined dynamically.
Any method calls and attribute requests for the proxy object will be executed remotely on remote_object.
Calling as_recursive_proxy on the proxy object creates a new
remoteproxies._RecursiveProxy
for the proxied object.Example:
>>> RunnerSession.run_python("a = open('test')") >>> proxy = RunnerTerminal.get_proxy_object('a', file) >>> proxy.readlines() # same as run_python("a.readlines()")
-
get_proxy_object_from_call
(function_name, *args, **kwargs)¶ Calls a remote function, and proxies the return value.
The call is done as in
run_python()
, but the return value is aremoteproxies._RemoteProxy
for the remote return value.
-
get_proxy_or_basic_from_call
(function_name, *args, **kwargs)¶ Calls a remote function, and proxies the return value.
The call is done as in
run_python()
, but the return value is aremoteproxies._RemoteProxy
for the remote return value in case of complex types. But in case the return value is of type int, float or is a string or None then the local copy is created and returned.
-
get_recursive_proxy
(remote_object)¶ Creates a recursive proxy object for remote_object.
Args:
remote_object: the name of the remote object to proxy.
Any attributes, methods and return values produced by a recursive proxy will be recursive proxy objects wrapping that value. The proxied object can be retrieved by calling
remoteproxies._RemoteProxy.as_local_value()
on a remote proxy object. For more details, seeremoteproxies._RecursiveProxy
.
-
import_libraries
(*imports)¶ Import the libraries given as arguments on the remote end.
-
initialize
(session)¶ Initializes the terminal with session. The session has to be a wrapper to
InteractiveSession.InteractiveSession
which implements at least get_session method which returns theInteractiveSession.InteractiveSession
instance.
-
iscallable
(remote_object)¶ Determines whether remote_object is callable or not.
-
static
isproxy
(obj)¶ Returns True if obj is a remote proxy, else False.
-
run
(cmd, timeout=-1, _rerun=False)¶ Run with error handling run of the session.
Note
It is recommended to use
run_python()
instead of this method.
-
run_and_return_handled_python
(handle)¶ Get handle object associated with handle from the remote end in case the handle object is in HANDLED_TYPES
Note
The HANDLED_TYPES instances must be serializable and deserializable by picklers and unpicklers.
The return value of the remote call is returned as a python object with two attributes:
isobj: True if the value of the object is returned.
obj: The value of the expression.
If an exception is raised on the remote end, the traceback is logged, and the exception object is raised by this method.
-
run_python
(cmd, timeout=None)¶ Runs a python expression on the remote node.
The return value of the remote call is returned as a python object.
If an exception is raised on the remote end, the traceback is logged, and the exception object is raised by this method.
-
run_python_call
(function_name, *args, **kwargs)¶ Calls a python function on the remote end.
function_name: a string, describing what function to call.
Any additional arguments given will be passed as arguments to the function on the remote end.
The return value and any exceptions are handled as in
run_python()
.
-
AutoRunnerTerminal¶
-
class
crl.interactivesessions.autorunnerterminal.
AutoRunnerTerminal
¶ Bases:
crl.interactivesessions.runnerterminal.RunnerTerminal
Python terminal session wrapper with the automated recovery feature for the session. This wrapper expects that the session is an instance of
autorecoveringterminal.AutoRecoveringTerminal
.-
initialize
(session, prepare=<function <lambda>>, finalize=<function <lambda>>)¶ This method initializes the terminal in the same fashion than
initialize_with_shells()
but instead of shells the underlying :class:.autorecoveringterminal.AutoRecoveringTerminal` instance should be given as a session.Note
The
autorecoveringterminal.AutoRecoveringTerminal.set_verify()
must be called after this method as the verify is overridden by the default verify.
-
initialize_if_needed
()¶ Initialize the terminal if necessary.
-
initialize_with_shelldicts
(shelldicts, prepare=<function <lambda>>, finalize=<function <lambda>>)¶ This method initializes the terminal in the same fashion than
initialize_with_shells()
but instead of shells the dictionary of shells accepted byshells.shellstack.ShellStack.initialize()
has to be to be given.
-
initialize_with_shells
(shells, prepare=<function <lambda>>, finalize=<function <lambda>>)¶ Initialize the terminal with the
InteractiveSession.Shell
based shells stack or a single shell.Note
The terminal session is not opened by this call. Either call
initialize_if_needed()
directly or use initially empty proxies. The empty proxies can be created via methodsrunnerterminal.RunnerTerminal.create_empty_remote_proxy()
andrunnerterminal.RunnerTerminal.create_empty_recursive_proxy()
The prepare callable should import any required modules and set the proxies. If the empty proxies are used in the initial setup then use
remoteproxies._RemoteProxy.set_from_remote_proxy()
to replace the content.The finalize callable should do any special finalization of the proxies which are set in prepare. For example, if the proxy is managing a temporary file in the remote end, that could be removed in the finalize.
Note
Proxies are automatically invalidated after finalization without any need to do special operations in finalize method. After finalization
runnerexceptions.InvalidProxySession
will be raised in case the remote object is accessed via proxies.The session is not guaranteed to be open when the finalize is called. That is why all possible exceptions are only logged.
-
RunnerTerminal Exceptions¶
-
exception
crl.interactivesessions.runnerexceptions.
InvalidProxySession
¶ This exception is raised by
remoteproxies._RemoteProxy
methods in case the session identifier has been changed. This occurs for example in case the session is recovered but the proxy is not recovered.
-
exception
crl.interactivesessions.runnerexceptions.
RemoteTimeout
(response_id)¶ Exception raised in case remote timeout occurs.
Args:
response_id: The response id to be used in
remoteproxies._RemoteProxy.get_remote_proxy_response()
call for retrieving the response later. Theresponse_wrap(callable): is called with the response and the return value of response_wrap is returned back to the
remoteproxies._RemoteProxy.get_remote_proxy_response()
.
-
exception
crl.interactivesessions.runnerexceptions.
RunnerException
¶
-
exception
crl.interactivesessions.runnerexceptions.
RunnerTerminalSessionBroken
¶ Exception raised in case the
RunnerTerminal.run()
raises an exception. The original exception is embedded into the first argument of the new exception.
-
exception
crl.interactivesessions.runnerexceptions.
RunnerTerminalSessionClosed
¶ Internal exception raised by
RunnerTerminal
in caseRunnerTerminal.run_python()
is called while theRunnerTerminal.close()
is already called or alternatively if the session is not initialized.
-
exception
crl.interactivesessions.runnerexceptions.
RunnerTerminalUnableToDeserialize
¶ Exception raised in case remote object returned is not deserialiazable by the local deserialization methods.
-
exception
crl.interactivesessions.runnerexceptions.
SessionInitializationFailed
¶ This exception is raised by
autorecoveringterminal.AutoRecoveringTerminal
when the initialization of the terminal fails duringautorecoveringterminal.AutoRecoveringTerminal.initialize_terminal()
. The original exception is stored into the first argument of the exception.
Remoteproxies¶
-
class
crl.interactivesessions.remoteproxies.
_RemoteProxy
(session, remote_name, local_spec=None, parent=None, is_remote_owned=True)¶ Bases:
object
Wrapper exposing a remote object as a local one.
Any attribute requests/assignments and method calls are transparently done on a remote object.
A new proxy object for remote_name is created.
Args:
session: a
runnerterminal.RunnerTerminal
instance.remote_name: The name of the remote object to proxy.
local_spec: a local class object, used to determine which methods are available on the remote object. If None, the available methods are determined dynamically.
parent: a reference to parent proxy object of this proxy.
is_remote_owned: If True, then remote object is deleted as well when the proxy is removed from the Python interpreter.
-
as_local_value
()¶ Returns a local copy of the proxied object.
-
as_recursive_proxy
()¶ Returns a
_RecursiveProxy
for the proxied object.
-
get_proxy_handle
()¶ Returns the remote name for the proxied object.
-
get_remote_proxy_response
(remotetimeout, timeout=None)¶ Get remote respose when the call have been timed out. Blocks forever if no timeout in seconds is given. The remotetimeout is a handle which must be an instance of the exception
runnerexceptions.RemoteTimeout
.
-
remote_proxy_autoprepare
()¶ Initialize the proxy session.
-
remote_proxy_use_asynchronous_response
()¶ Set proxy to use asynchronous response without any timeout. In this mode, the proxy returns handle (
runnerexceptions.RemoteTimeout
instance) which then should be passed toget_remote_proxy_response()
to retrieve the actual value of the proxy call. Please see a complete example of the asynchronous mode usage from Running Commands In Background.
-
remote_proxy_use_synchronous_response
()¶ Set proxy to use synchronous response and timeout
-
set_from_remote_proxy
(proxy)¶ Set proxy content from proxy.
Warning
This method nulifies the proxy given as an argument. The reasoning is that it would be really dangerous to keep two proxies with the same handles simultaneously. The
runnerexceptions.InvalidProxySession
is raised when proxy is accessed after this call.
-
set_proxy_spec
(local_spec)¶ Assigns a spec for this proxy object.
-
set_remote_proxy_timeout
(timeout)¶ Set timeout for remote command execution. The negative timeout causes proxy to raise always
runnerexceptions.RemoteTimeout
. If None is set as timeout value, then the default timeout is used. The default timeout is 3600 seconds.Note
The prompt_timeout of
runnerterminal.RunnerTerminal
is added automatically to timeout in case timeout is positive. If timeout is negative then the terminal uses prompt_timeout only.
-
-
class
crl.interactivesessions.remoteproxies.
_RecursiveProxy
(session, remote_name, parent=None, is_remote_owned=None)¶ Bases:
crl.interactivesessions.remoteproxies._RemoteProxy
Wrapper exposing a remote object as a local one.
Any attributes, methods and return values produced by a recursive proxy will be recursive proxy objects wrapping that value. The exceptions are the basic types which are defined in
runnerterminal.RunnerTerminal
in HANDLED_TYPES attribute. The HANDLED_TYPES are returned as local value always. The proxied object can be retrieved by calling_RemoteProxy.as_local_value()
on a remote proxy object.