models.host

Pydantic boundary specs for the host record (a hosts.json entry).

HostSpec and its family subclasses validate a host dict and build the unchanged runtime UnixHost / EmbeddedHost via to_host(). The specs nest the per-protocol *OptionsSpec``s from ``otto.models.options and reuse their to_runtime() builders; embedded registry-name fields (filesystem / command_frame / loader) resolve through the existing host registries at build time.

class otto.models.host.ToolchainSpec(*, sysroot: Path = PosixPath('/'), lcov: Path = PosixPath('usr/bin/lcov'), gcov: Path = PosixPath('usr/bin/gcov'))

Bases: OttoModel

Toolchain paths: the sysroot directory plus the lcov and gcov binaries.

sysroot : Path
lcov : Path
gcov : Path
to_runtime() Toolchain

Build the runtime Toolchain dataclass from the validated path fields.

class otto.models.host.HostSpec(*, ip: str, element: str, creds: dict[str, str] = <factory>, name: str | None = None, os_type: str = 'unix', os_name: str | None = None, os_version: str | None = None, user: str | None = None, element_id: int | None = None, board: str | None = None, slot: int | None = None, hop: str | None = None, is_virtual: bool = False, default_dest_dir: ~pathlib.Path = PosixPath('.'), max_filename_len: int = 255, resources: set[str] = <factory>, interfaces: dict[str, str] = <factory>, log: ~otto.logger.mode.LogMode = LogMode.NORMAL, log_stdout: bool = True, telnet_options: ~otto.models.options.TelnetOptionsSpec = TelnetOptionsSpec(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={}), snmp: ~otto.models.options.SnmpOptionsSpec | None = None, toolchain: ~otto.models.host.ToolchainSpec = ToolchainSpec(sysroot=PosixPath('/'), lcov=PosixPath('usr/bin/lcov'), gcov=PosixPath('usr/bin/gcov')), command_frame: str | None = None, power_control: dict[str, ~typing.Any] | str | None = None, labs: list[str] = <factory>)

Bases: OttoModel

Abstract boundary spec for a hosts.json host entry.

Holds the fields common to both host families (identity, credentials, telnet/SNMP options, toolchain, power control) and builds the constructor kwargs via _common_host_kwargs(). Concrete subclasses (UnixHostSpec, EmbeddedHostSpec) override to_host() to produce the appropriate runtime class.

ip : str
element : str
creds : dict[str, str]
name : str | None
os_type : str
os_name : str | None
os_version : str | None
user : str | None
element_id : int | None
board : str | None
slot : int | None
hop : str | None
is_virtual : bool
default_dest_dir : Path
max_filename_len : int
resources : set[str]
interfaces : dict[str, str]
log : LogMode
log_stdout : bool
telnet_options : TelnetOptionsSpec
snmp : SnmpOptionsSpec | None
toolchain : ToolchainSpec
command_frame : str | None
power_control : dict[str, Any] | str | None
labs : list[str]
to_host(cls: Any | None = None, *, preferences: dict[str, list[str]] | None = None) RemoteHost

Build the runtime host this spec describes.

Overridden by the concrete family specs (UnixHostSpec, EmbeddedHostSpec), each of which knows the runtime class to construct. The abstract base carries the contract so the storage factory can call spec.to_host(cls) against a HostSpec reference.

class otto.models.host.UnixHostSpec(*, ip: str, element: str, creds: dict[str, str], name: str | None = None, os_type: str = 'unix', os_name: str | None = None, os_version: str | None = None, user: str | None = None, element_id: int | None = None, board: str | None = None, slot: int | None = None, hop: str | None = None, is_virtual: bool = False, default_dest_dir: ~pathlib.Path = PosixPath('.'), max_filename_len: int = 255, resources: set[str] = <factory>, interfaces: dict[str, str] = <factory>, log: ~otto.logger.mode.LogMode = LogMode.NORMAL, log_stdout: bool = True, telnet_options: ~otto.models.options.TelnetOptionsSpec = TelnetOptionsSpec(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={}), snmp: ~otto.models.options.SnmpOptionsSpec | None = None, toolchain: ~otto.models.host.ToolchainSpec = ToolchainSpec(sysroot=PosixPath('/'), lcov=PosixPath('usr/bin/lcov'), gcov=PosixPath('usr/bin/gcov')), command_frame: str | None = None, power_control: dict[str, ~typing.Any] | str | None = None, labs: list[str] = <factory>, hw_version: str | None = None, sw_version: str | None = None, valid_terms: list[str] = <factory>, valid_transfers: list[str] = <factory>, term: str | None = None, transfer: str | None = None, docker_capable: bool = False, ssh_options: ~otto.models.options.SshOptionsSpec = SshOptionsSpec(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=[], remote_forwards=[], socks_forwards=[], extra={}), sftp_options: ~otto.models.options.SftpOptionsSpec = SftpOptionsSpec(env=None, send_env=None, extra={}), scp_options: ~otto.models.options.ScpOptionsSpec = ScpOptionsSpec(preserve=False, recurse=True, block_size=16384, extra={}), ftp_options: ~otto.models.options.FtpOptionsSpec = FtpOptionsSpec(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={}), nc_options: ~otto.models.options.NcOptionsSpec = NcOptionsSpec(exec_name='nc', port=9000, port_strategy='auto', port_cmd=None, listener_check='auto', listener_cmd=None, listener_timeout=30.0))

Bases: HostSpec

Boundary spec for a Unix host entry in hosts.json.

Extends HostSpec with the Unix-specific fields: term/transfer menus and active selections, SSH/SFTP/SCP/FTP/nc option tables, Docker capability, and hardware/software version strings. to_host() resolves the active term and transfer from preferences and builds a UnixHost (or a custom subclass passed as cls).

creds : dict[str, str]
hw_version : str | None
sw_version : str | None
valid_terms : list[str]
valid_transfers : list[str]
term : str | None
transfer : str | None
docker_capable : bool
ssh_options : SshOptionsSpec
sftp_options : SftpOptionsSpec
scp_options : ScpOptionsSpec
ftp_options : FtpOptionsSpec
nc_options : NcOptionsSpec
to_host(cls: type[~otto.host.unix_host.UnixHost] = <class 'otto.host.unix_host.UnixHost'>, *, preferences: dict[str, list[str]] | None = None) UnixHost

Build the runtime host this spec describes.

Overridden by the concrete family specs (UnixHostSpec, EmbeddedHostSpec), each of which knows the runtime class to construct. The abstract base carries the contract so the storage factory can call spec.to_host(cls) against a HostSpec reference.

class otto.models.host.EmbeddedHostSpec(*, ip: str, element: str, creds: dict[str, str] = <factory>, name: str | None = None, os_type: str = 'embedded', os_name: str | None = None, os_version: str | None = None, user: str | None = None, element_id: int | None = None, board: str | None = None, slot: int | None = None, hop: str | None = None, is_virtual: bool = False, default_dest_dir: ~pathlib.Path = PosixPath('.'), max_filename_len: int = 255, resources: set[str] = <factory>, interfaces: dict[str, str] = <factory>, log: ~otto.logger.mode.LogMode = LogMode.NORMAL, log_stdout: bool = True, telnet_options: ~otto.models.options.TelnetOptionsSpec = TelnetOptionsSpec(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={}), snmp: ~otto.models.options.SnmpOptionsSpec | None = None, toolchain: ~otto.models.host.ToolchainSpec = ToolchainSpec(sysroot=PosixPath('/'), lcov=PosixPath('usr/bin/lcov'), gcov=PosixPath('usr/bin/gcov')), command_frame: str | None = None, power_control: dict[str, ~typing.Any] | str | None = None, labs: list[str] = <factory>, valid_terms: list[str] = <factory>, valid_transfers: list[str] = <factory>, term: str | None = None, transfer: str | None = None, filesystem: str | None = None, loader: str | None = None)

Bases: HostSpec

Boundary spec for an embedded host entry in hosts.json.

Extends HostSpec with the embedded-family fields: term/transfer menus and active selections, filesystem and binary loader registry names. to_host() resolves the active term and transfer, looks up the filesystem and loader from their registries, and builds an EmbeddedHost (or a custom subclass passed as cls).

os_type : str
valid_terms : list[str]
valid_transfers : list[str]
term : str | None
transfer : str | None
filesystem : str | None
loader : str | None
to_host(cls: type[~otto.host.embedded_host.EmbeddedHost] = <class 'otto.host.embedded_host.EmbeddedHost'>, *, preferences: dict[str, list[str]] | None = None) EmbeddedHost

Build the runtime host this spec describes.

Overridden by the concrete family specs (UnixHostSpec, EmbeddedHostSpec), each of which knows the runtime class to construct. The abstract base carries the contract so the storage factory can call spec.to_host(cls) against a HostSpec reference.

otto.models.host.HOST_SPEC_RUNTIME_PAIRS : list[tuple[type[HostSpec], type]]

Each host spec paired with the runtime class it builds. Drives the drift guard so a spec field that has no constructor counterpart is caught.