host.options¶
Connection option classes for the network protocols otto speaks.
Each protocol (SSH, Telnet, SFTP, SCP, FTP, netcat) has an *Options
dataclass that holds tunable connection parameters. Default-constructed
instances reproduce otto’s pre-options behavior exactly, so callers who
do not care about configuration can ignore this module.
For SSH, curated fields cover the common knobs and an extra dict
plus a post_connect hook together forward the full power of asyncssh
(kwargs and post-connect method calls like port forwarding).
Example:
host = UnixHost(
ip='10.0.0.1',
creds={'admin': 'secret'},
ne='lab',
ssh_options=SshOptions(port=2222, connect_timeout=5),
telnet_options=TelnetOptions(auto_window_resize=True),
)
- class otto.host.options.LocalPortForward(listen_host, listen_port, dest_host, dest_port)¶
Bases:
objectAn SSH local port forward: listen locally, send to host:port via the remote.
- listen_host : --is-rst--:py:class:`str`¶
- listen_port : --is-rst--:py:class:`int`¶
- dest_host : --is-rst--:py:class:`str`¶
- dest_port : --is-rst--:py:class:`int`¶
- class otto.host.options.RemotePortForward(listen_host, listen_port, dest_host, dest_port)¶
Bases:
objectAn SSH remote port forward: listen on the remote, send to host:port locally.
- listen_host : --is-rst--:py:class:`str`¶
- listen_port : --is-rst--:py:class:`int`¶
- dest_host : --is-rst--:py:class:`str`¶
- dest_port : --is-rst--:py:class:`int`¶
- class otto.host.options.SocksForward(listen_host, listen_port)¶
Bases:
objectA dynamic SOCKS forward listening on the given local address.
- listen_host : --is-rst--:py:class:`str`¶
- listen_port : --is-rst--:py:class:`int`¶
- class otto.host.options.SshOptions(port=22, known_hosts=None, connect_timeout=None, keepalive_interval=None, keepalive_count_max=None, client_keys=None, client_host_keys=None, agent_forwarding=False, preferred_auth=None, encryption_algs=None, server_host_key_algs=None, compression_algs=None, local_forwards=<factory>, remote_forwards=<factory>, socks_forwards=<factory>, extra=<factory>, post_connect=None)¶
Bases:
objectConnection options for asyncssh-backed SSH sessions.
Covers the common connection knobs as curated fields plus two escape hatches (
extraandpost_connect) that together give access to every asyncssh feature.Default-constructed
SshOptions()reproduces otto’s historical behavior: port 22 with host-key verification disabled.- port : --is-rst--:py:class:`int`¶
TCP port for the SSH connection.
- known_hosts : --is-rst--:py:data:`~typing.Any`¶
asyncssh known_hosts.
Nonedisables host-key verification (otto’s historical default). Pass a path, a list of keys, or the string'~/.ssh/known_hosts'to enable checking.
- connect_timeout : --is-rst--:py:class:`float` | :py:obj:`None`¶
Seconds to wait for the TCP + SSH handshake.
None= asyncssh default.
- keepalive_interval : --is-rst--:py:class:`float` | :py:obj:`None`¶
Seconds between SSH-level keepalives.
None= asyncssh default (disabled).
- keepalive_count_max : --is-rst--:py:class:`int` | :py:obj:`None`¶
Missed keepalives before asyncssh closes the connection.
None= default.
- client_keys : --is-rst--:py:class:`list`\ \[:py:class:`str`] | :py:obj:`None`¶
Private-key paths for public-key auth.
Nonelets asyncssh auto-discover.
- client_host_keys : --is-rst--:py:class:`list`\ \[:py:class:`str`] | :py:obj:`None`¶
Host-key paths for host-based auth.
- agent_forwarding : --is-rst--:py:class:`bool`¶
Forward the local SSH agent to the remote side.
- preferred_auth : --is-rst--:py:class:`str` | :py:class:`list`\ \[:py:class:`str`] | :py:obj:`None`¶
Authentication methods to attempt, in order (e.g.
'publickey,password').
- encryption_algs : --is-rst--:py:class:`list`\ \[:py:class:`str`] | :py:obj:`None`¶
Allowed symmetric ciphers.
- server_host_key_algs : --is-rst--:py:class:`list`\ \[:py:class:`str`] | :py:obj:`None`¶
Allowed server host-key algorithms.
- compression_algs : --is-rst--:py:class:`list`\ \[:py:class:`str`] | :py:obj:`None`¶
Allowed compression algorithms.
- local_forwards : --is-rst--:py:class:`list`\ \[:py:class:`~otto.host.options.LocalPortForward`]¶
Local port forwards to set up after the connection is established.
- remote_forwards : --is-rst--:py:class:`list`\ \[:py:class:`~otto.host.options.RemotePortForward`]¶
Remote port forwards to set up after the connection is established.
- socks_forwards : --is-rst--:py:class:`list`\ \[:py:class:`~otto.host.options.SocksForward`]¶
Dynamic SOCKS forwards to set up after the connection is established.
- extra : --is-rst--:py:class:`dict`\ \[:py:class:`str`, :py:data:`~typing.Any`]¶
Arbitrary extra kwargs forwarded directly to
asyncssh.connect().Anything kwarg-shaped on asyncssh’s connect (
config,proxy_command,x509_trusted_certs,gss_host, etc.) can be set here. Values inextraoverride curated fields on conflict.
- post_connect : --is-rst--:py:class:`~collections.abc.Callable`\ \[\[SSHClientConnection], :py:class:`~collections.abc.Awaitable`\ \[:py:obj:`None`]] | :py:obj:`None`¶
Optional async hook called with the freshly opened connection, after the structured forward lists have been applied. Use for anything not expressible as a kwarg or a structured forward — e.g. UNIX-socket forwards, X11, custom subsystems.
- class otto.host.options.TelnetOptions(port=23, write_chunk_size=0, write_chunk_delay=0.0, cols=400, rows=24, encoding=False, connect_timeout=None, echo_negotiation_timeout=3.0, login_prompt=b':', login=True, single_client_console=False, auto_window_resize=False, extra=<factory>)¶
Bases:
objectConnection options for telnetlib3-backed telnet sessions.
Default-constructed
TelnetOptions()reproduces otto’s historical behavior: port 23, bytes mode, cols=400, and a 3-second ECHO negotiation timeout.- port : --is-rst--:py:class:`int`¶
TCP port for the telnet connection.
- write_chunk_size : --is-rst--:py:class:`int`¶
Split each command write into chunks of at most this many bytes.
0(default) writes the whole payload in one call — correct for a host-terminated telnet shell (x86 + E1000). A positive value paces the write so a UART-backed RTOS shell behind a-serial telnet:bridge doesn’t overrun its console RX FIFO on a multi-KBllext load_hexline.
- write_chunk_delay : --is-rst--:py:class:`float`¶
Seconds to pause between chunked writes (see
write_chunk_size). Ignored whenwrite_chunk_sizeis 0.
- cols : --is-rst--:py:class:`int`¶
Initial terminal width reported to the remote side. otto historically used 400 to avoid line-wrap artifacts in automation output.
- rows : --is-rst--:py:class:`int`¶
Initial terminal height reported to the remote side.
- encoding : --is-rst--:py:class:`str` | :py:class:`bool`¶
Text encoding.
False= bytes mode (otto default).
- connect_timeout : --is-rst--:py:class:`float` | :py:obj:`None`¶
Seconds to wait for the telnet TCP handshake.
None= no timeout.
- echo_negotiation_timeout : --is-rst--:py:class:`float`¶
Seconds to wait for the remote to honor
DONT ECHOduring connect.
- login_prompt : --is-rst--:py:class:`bytes`¶
Byte delimiter that terminates the login/password prompts. Anything ending in a colon matches
login:,Username:,Password:, etc.
- login : --is-rst--:py:class:`bool`¶
Whether
connect()performs a telnet login (waits for the login/password prompts and sends credentials). SetFalsefor a shell with no login step — e.g. a bare-metal/RTOS telnet shell — where waiting for alogin:prompt that never arrives would hang the connection.
- single_client_console : --is-rst--:py:class:`bool`¶
When True, this connection targets a single-client console — an RTOS telnet shell that serves one client at a time (e.g. Zephyr
shell_telnetreached over a-serial telnet:bridge). The transport is registered in a process-local set so the embedded test teardown can force-release the slot if a timed-out test left it half-open (seeotto.host.telnet.abort_console_transports()). Unix telnet (multi-session telnetd) leaves this False, so it is never registered or aborted.
- auto_window_resize : --is-rst--:py:class:`bool`¶
When True and stdin is a TTY, install a SIGWINCH handler that sends a NAWS update on every resize so remote TUIs reflow. Off by default; opt in for interactive telnet sessions.
- extra : --is-rst--:py:class:`dict`\ \[:py:class:`str`, :py:data:`~typing.Any`]¶
Extra kwargs forwarded to
telnetlib3.open_connection().
- class otto.host.options.SftpOptions(env=None, send_env=None, extra=<factory>)¶
Bases:
objectConnection options for asyncssh-backed SFTP clients.
SFTP rides on the underlying SSH connection, so connection-level tuning belongs in
SshOptions. These knobs configure the SFTP subsystem itself.- env : --is-rst--:py:class:`dict`\ \[:py:class:`str`, :py:class:`str`] | :py:obj:`None`¶
Environment variables to set in the remote SFTP process.
- send_env : --is-rst--:py:class:`list`\ \[:py:class:`str`] | :py:obj:`None`¶
Local env vars to forward to the remote SFTP process.
- extra : --is-rst--:py:class:`dict`\ \[:py:class:`str`, :py:data:`~typing.Any`]¶
Extra kwargs forwarded to
SSHClientConnection.start_sftp_client().
- class otto.host.options.ScpOptions(preserve=False, recurse=True, block_size=16384, extra=<factory>)¶
Bases:
objectConnection options for
asyncssh.scpfile transfers.Only protocol-level knobs live here; the SSH connection itself is configured via
SshOptions.- preserve : --is-rst--:py:class:`bool`¶
Preserve mtime/atime/mode on transferred files.
- recurse : --is-rst--:py:class:`bool`¶
Recurse into directories.
- block_size : --is-rst--:py:class:`int`¶
Chunk size for SCP transfers. Larger = faster on fast links, more RAM.
- extra : --is-rst--:py:class:`dict`\ \[:py:class:`str`, :py:data:`~typing.Any`]¶
Extra kwargs forwarded to
asyncssh.scp().
- class otto.host.options.FtpOptions(port=21, encoding='utf-8', socket_timeout=None, connection_timeout=None, path_timeout=None, read_speed_limit=None, write_speed_limit=None, ssl=None, passive_commands=('epsv', 'pasv'), extra=<factory>)¶
Bases:
objectConnection options for aioftp-backed FTP clients.
Default-constructed
FtpOptions()reproduces otto’s historical behavior: port 21, UTF-8 encoding, aioftp defaults for everything else.- port : --is-rst--:py:class:`int`¶
TCP port for the FTP control connection.
- encoding : --is-rst--:py:class:`str`¶
Text encoding for FTP commands and paths.
- socket_timeout : --is-rst--:py:class:`float` | :py:obj:`None`¶
Socket-level read/write timeout.
- connection_timeout : --is-rst--:py:class:`float` | :py:obj:`None`¶
Handshake timeout.
- path_timeout : --is-rst--:py:class:`float` | :py:obj:`None`¶
Timeout for path-level operations (list/stat/etc.).
- read_speed_limit : --is-rst--:py:class:`int` | :py:obj:`None`¶
Bytes/sec cap on downloads.
None= unlimited.
- write_speed_limit : --is-rst--:py:class:`int` | :py:obj:`None`¶
Bytes/sec cap on uploads.
None= unlimited.
- ssl : --is-rst--:py:data:`~typing.Any`¶
ssl.SSLContext,True, orNone. Use an SSLContext for FTPS.
- passive_commands : --is-rst--:py:class:`tuple`\ \[:py:class:`str`, :py:data:`...<Ellipsis>`]¶
Passive-mode commands to attempt, in order.
- extra : --is-rst--:py:class:`dict`\ \[:py:class:`str`, :py:data:`~typing.Any`]¶
Extra kwargs forwarded to
aioftp.Client(). aioftp also accepts arbitrarysiosocks_asyncio_kwargswhich can be routed through here.
-
class otto.host.options.NcOptions(exec_name=
'nc', port=9000, port_strategy='auto', port_cmd=None, listener_check='auto', listener_cmd=None, listener_timeout=30.0)¶ Bases:
objectConnection options for netcat-based file transfers.
Bundles all nc-specific knobs that previously lived on
UnixHostinto a single object so thatNcOptions()(with defaults) produces the same behavior as the old individual fields.- exec_name : --is-rst--:py:class:`str`¶
Netcat executable on both sides (e.g.
nc,ncat,netcat). Listener syntax is assumed to be OpenBSD-style (nc -l PORT).
- port : --is-rst--:py:class:`int`¶
Base port for netcat transfers. Used as the scan-start for the ss/netstat/python/proc port-finding strategies.
- port_strategy : --is-rst--:py:data:`~typing.Literal`\ \[``'auto'``, ``'ss'``, ``'netstat'``, ``'python'``, ``'proc'``, ``'custom'``]¶
Strategy for finding free ports on the remote host.
'auto'probes ss → netstat → python → proc and caches the first that works.
- port_cmd : --is-rst--:py:class:`str` | :py:obj:`None`¶
Shell command that prints a free port to stdout. Only used when
port_strategy == 'custom'.
- listener_check : --is-rst--:py:data:`~typing.Literal`\ \[``'auto'``, ``'ss'``, ``'netstat'``, ``'proc'``, ``'custom'``]¶
Strategy for verifying that a remote
nclistener is ready before sending data.'auto'probes ss → netstat → proc.
- listener_cmd : --is-rst--:py:class:`str` | :py:obj:`None`¶
Shell command (using
{port}as placeholder) that exits 0 when a port is listening. Only used whenlistener_check == 'custom'.
- listener_timeout : --is-rst--:py:class:`float`¶
Seconds a remote
nc -llistener may wait for a client before it self-terminates (passed asnc -w), and the ceiling on the post-transfer wait for that listener to exit. Bounds the orphaned-listener hang: if a concurrent process wins a port-collision race, our sender’s bytes land in its listener and ours never gets a client — without this it would block forever. A transfer whose connection is established stays unaffected; this only caps the wait for a client that never arrives.
-
class otto.host.options.TftpOptions(port=
69, server_ip=None, block_size=512, timeout=5.0)¶ Bases:
objectConnection options for TFTP file transfer to an embedded host.
Reserved. TFTP is the deferred
tftpembedded-transfer backend — a faster alternative to consolefstransfer for targets whose firmware has a TFTP client. The backend itself is not yet implemented (EmbeddedFileTransferraisesNotImplementedErrorfortftp); this dataclass exists so lab data and the host API can name the option table now, without a later breaking change when the backend lands.- port : --is-rst--:py:class:`int`¶
UDP port of the TFTP server.
- server_ip : --is-rst--:py:class:`str` | :py:obj:`None`¶
IP address otto’s TFTP server binds to and the target transfers against.
Noneauto-detects the local IP, as the netcat path does.
- block_size : --is-rst--:py:class:`int`¶
TFTP block size (RFC 2348
blksizeoption). 512 is the protocol default; larger blocks reduce round-trips on a reliable link.
- timeout : --is-rst--:py:class:`float`¶
Per-block retransmit timeout, in seconds.
-
class otto.host.options.SnmpOptions(oids=
(), community='public', port=161, version='2c', address=None)¶ Bases:
objectPer-host SNMP polling config — the acquisition half of SNMP monitoring.
Declared in lab data as a host’s
snmpblock; carries only what to poll and how to reach the agent. Presentation for each OID (chart/unit/scale) lives in the monitor module’s descriptor registry, never here. The monitor factory turns this into a liveSnmpClient+SnmpSource.A host carrying an
snmpblock is monitored over SNMP instead of by running shell commands — the way otto reaches an embedded target’s metrics without contending for its single shell session. It is not embedded-only; a Unix host may declare one too.- oids : --is-rst--:py:class:`tuple`\ \[:py:class:`str`, :py:data:`...<Ellipsis>`]¶
OIDs to GET each tick (e.g.
("1.3.6.1.2.1.1.3.0", ...)).
- community : --is-rst--:py:class:`str`¶
SNMP v2c community string.
- port : --is-rst--:py:class:`int`¶
UDP port of the agent (or of a relay standing in for it).
- version : --is-rst--:py:class:`str`¶
SNMP version —
"2c"(default) or"1".
- address : --is-rst--:py:class:`str` | :py:obj:`None`¶
Address otto sends SNMP to.
None(the default) means use the host’s ownip; set it when the agent is reached at a different address than the host’s primary interface — e.g. a relay endpoint, or (future) a named interface from a per-host interface map. Seetodo/multi_interface_hosts.md.