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'},
element='lab',
ssh_options=SshOptions(port=2222, connect_timeout=5),
telnet_options=TelnetOptions(auto_window_resize=True),
)
- class otto.host.options.LocalPortForward(listen_host: str, listen_port: int, dest_host: str, dest_port: int)¶
Bases:
objectAn SSH local port forward: listen locally, send to host:port via the remote.
- class otto.host.options.RemotePortForward(listen_host: str, listen_port: int, dest_host: str, dest_port: int)¶
Bases:
objectAn SSH remote port forward: listen on the remote, send to host:port locally.
- class otto.host.options.SocksForward(listen_host: str, listen_port: int)¶
Bases:
objectA dynamic SOCKS forward listening on the given local address.
- class otto.host.options.SshOptions(port: int = 22, known_hosts: ~typing.Any | None = None, connect_timeout: float | None = None, keepalive_interval: float | None = None, keepalive_count_max: int | None = None, client_keys: list[str] | None = None, client_host_keys: list[str] | None = None, agent_forwarding: bool = False, preferred_auth: str | list[str] | None = None, encryption_algs: list[str] | None = None, server_host_key_algs: list[str] | None = None, compression_algs: list[str] | None = None, local_forwards: list[~otto.host.options.LocalPortForward] = <factory>, remote_forwards: list[~otto.host.options.RemotePortForward] = <factory>, socks_forwards: list[~otto.host.options.SocksForward] = <factory>, extra: dict[str, ~typing.Any] = <factory>, post_connect: ~collections.abc.Callable[[SSHClientConnection], ~collections.abc.Awaitable[None]] | None = 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.- known_hosts : 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 : float | None¶
Seconds to wait for the TCP + SSH handshake.
None= asyncssh default.
- keepalive_interval : float | None¶
Seconds between SSH-level keepalives.
None= asyncssh default (disabled).
- keepalive_count_max : int | None¶
Missed keepalives before asyncssh closes the connection.
None= default.
- client_keys : list[str] | None¶
Private-key paths for public-key auth.
Nonelets asyncssh auto-discover.
- preferred_auth : str | list[str] | None¶
Authentication methods to attempt, in order (e.g.
'publickey,password').
- local_forwards : list[LocalPortForward]¶
Local port forwards to set up after the connection is established.
- remote_forwards : list[RemotePortForward]¶
Remote port forwards to set up after the connection is established.
- socks_forwards : list[SocksForward]¶
Dynamic SOCKS forwards to set up after the connection is established.
- extra : dict[str, 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 : Callable[[SSHClientConnection], Awaitable[None]] | 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: int = 23, write_chunk_size: int = 0, write_chunk_delay: float = 0.0, cols: int = 400, rows: int = 24, encoding: str | bool = False, connect_timeout: float | None = None, echo_negotiation_timeout: float = 3.0, login_prompt: bytes = b':', login: bool = True, single_client_console: bool = False, auto_window_resize: bool = False, extra: dict[str, ~typing.Any] = <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.- write_chunk_size : 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 : float¶
Seconds to pause between chunked writes (see
write_chunk_size). Ignored whenwrite_chunk_sizeis 0.
- cols : int¶
Initial terminal width reported to the remote side. otto historically used 400 to avoid line-wrap artifacts in automation output.
- login_prompt : bytes¶
Byte delimiter that terminates the login/password prompts. Anything ending in a colon matches
login:,Username:,Password:, etc.
- login : 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 : 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.
- class otto.host.options.SftpOptions(env: dict[str, str] | None = None, send_env: list[str] | None = None, extra: dict[str, ~typing.Any] = <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.
- class otto.host.options.ScpOptions(preserve: bool = False, recurse: bool = True, block_size: int = 16384, extra: dict[str, ~typing.Any] = <factory>)¶
Bases:
objectConnection options for
asyncssh.scpfile transfers.Only protocol-level knobs live here; the SSH connection itself is configured via
SshOptions.
- class otto.host.options.FtpOptions(port: int = 21, encoding: str = 'utf-8', socket_timeout: float | None = None, connection_timeout: float | None = None, path_timeout: float | None = None, read_speed_limit: int | None = None, write_speed_limit: int | None = None, ssl: ~typing.Any | None = None, passive_commands: tuple[str, ...] = ('epsv', 'pasv'), extra: dict[str, ~typing.Any] = <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.
-
class otto.host.options.NcOptions(exec_name: str =
'nc', port: int =9000, port_strategy: NcPortStrategy ='auto', port_cmd: str | None =None, listener_check: NcListenerCheck ='auto', listener_cmd: str | None =None, listener_timeout: float =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 : str¶
Netcat executable on both sides (e.g.
nc,ncat,netcat). Listener syntax is assumed to be OpenBSD-style (nc -l PORT).
- port : int¶
Base port for netcat transfers. Used as the scan-start for the ss/netstat/python/proc port-finding strategies.
- port_strategy : NcPortStrategy¶
Strategy for finding free ports on the remote host.
'auto'probes ss → netstat → python → proc and caches the first that works.
- port_cmd : str | None¶
Shell command that prints a free port to stdout. Only used when
port_strategy == 'custom'.
- listener_check : NcListenerCheck¶
Strategy for verifying that a remote
nclistener is ready before sending data.'auto'probes ss → netstat → proc.
- listener_cmd : str | None¶
Shell command (using
{port}as placeholder) that exits 0 when a port is listening. Only used whenlistener_check == 'custom'.
- listener_timeout : 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: int =
69, server_ip: str | None =None, block_size: int =512, timeout: float =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.- server_ip : str | None¶
IP address otto’s TFTP server binds to and the target transfers against.
Noneauto-detects the local IP, as the netcat path does.
-
class otto.host.options.SnmpOptions(oids: tuple[str, ...] =
(), community: str ='public', port: int =161, version: str ='2c', address: str | None =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.- address : str | 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.