Lab Configuration¶
A lab is a set of hosts described in one or more hosts.json files. Each
file lists every host in a given location; each host entry declares which lab
names it belongs to, so a single file can serve multiple labs and a host can
belong to more than one lab at once. This page is the full per-host schema
reference. For repo-level settings (paths, libs, init modules) see
Repository Setup.
Lab files¶
Each directory listed under the labs key in .otto/settings.toml may
contain a hosts.json file. The file is a JSON array of host objects:
[
{
"ip": "10.10.200.11",
"element": "carrot",
"board": "seed",
"creds": { "vagrant": "vagrant" },
"labs": ["veggies"]
},
{
"ip": "192.0.2.1",
"element": "sprout",
"board": "seed",
"os_type": "zephyr",
"labs": ["embedded"]
}
]
Each entry carries a labs field listing the lab names it belongs to. Pass
--lab veggies (or set OTTO_LAB=veggies) and otto loads every host whose
labs field includes "veggies".
The host id used by get_host(), --list-hosts, and the rest of the CLI
is derived from the element, board, and element_id fields. carrot with board
seed becomes carrot_seed; carrot with board seed and element_id 2
becomes carrot_seed_2.
Per-host fields¶
Required¶
Field |
Type |
Description |
|---|---|---|
|
string |
IP address or DNS name otto will connect to. |
|
string |
Network-element name. Combined with |
|
object |
Map of username → password. At least one entry required for Unix hosts; optional for embedded hosts (RTOS telnet shells typically have no login step). |
|
array of strings |
Lab names this host belongs to. Without this the host is invisible to |
Common optional¶
Field |
Type |
Description |
|---|---|---|
|
string |
Board type, included in the host id when set. |
|
integer |
Disambiguates multiple instances of the same NE; appended to the host id. |
|
string |
Pin a specific user from |
|
string |
Terminal protocol lab pin — must be in the host’s |
|
string |
File-transfer protocol lab pin — must be in the host’s |
|
array of strings |
Ordered list of term backends that may be selected for this host (gates |
|
array of strings |
Ordered list of transfer backends that may be selected for this host (gates |
|
integer |
Physical slot number of the board to which this host belongs. Free-form metadata; not part of the host id. |
|
string |
Host id of an intermediate SSH jump host. Otto opens an SSH tunnel through it and routes all subsequent connections automatically. Hops can chain. |
|
array of strings |
Free-form resource tags used by the reservation backend. |
|
boolean |
|
|
boolean |
Whether to log output to stdout and log files (default |
|
boolean |
Whether to log output to stdout (default |
|
boolean |
|
Host type / OS¶
Field |
Type |
Description |
|---|---|---|
|
string |
Profile selector. Defaults to |
|
string |
Human-readable OS name (e.g. |
|
string |
OS or kernel version string (e.g. |
Embedded-only fields¶
These fields apply only to hosts with an embedded base type (e.g.
os_type: "zephyr" or os_type: "embedded"). See Embedded Hosts for full
details.
Field |
Type |
Description |
|---|---|---|
|
string |
Shell-framing dialect (e.g. |
|
string |
On-device filesystem variant ( |
|
integer |
Maximum filename length accepted by the target filesystem. |
File transfer for embedded hosts uses "console" or "tftp" — see
Embedded Hosts.
Power control¶
The optional power_control block configures a pluggable power controller for
the host. The built-in "command" controller runs configured shell commands on
a controller host in the lab:
Field |
Type |
Description |
|---|---|---|
|
object or string |
Power controller spec. A string selects a registered controller by type name; an object takes the fields below. Omit to leave the host without power control. |
|
string |
Controller type name (e.g. |
|
string |
Host id of the lab host that runs the on/off/status commands. |
|
string |
Shell command to power the host on. Templated with |
|
string |
Shell command to power the host off. Same template variables. |
|
string |
Shell command to query power state (optional). |
|
string |
Substring of |
{
"power_control": {
"type": "command",
"controller": "hypervisor1",
"on_cmd": "virsh start {name}",
"off_cmd": "virsh destroy {name}",
"status_cmd": "virsh domstate {name}",
"status_on": "running"
}
}
See Host capabilities for the Power Control section, runtime API
(host.power(), host.reboot(hard=True)), and how to register a custom
controller (register_power_controller).
SNMP monitoring¶
The optional snmp block configures SNMP polling for a host’s metrics. See
the SNMP section of otto monitor.
Field |
Type |
Description |
|---|---|---|
|
string |
SNMP agent IP address. |
|
integer |
SNMP UDP port. |
|
string |
SNMP community string. |
|
array of strings |
OIDs to poll. |
Per-protocol option tables¶
Each of the following keys accepts an object that overrides individual
protocol fields. They merge per-key with hardcoded dataclass defaults;
product [host_preferences] values are then applied on top (product wins
over the host’s own values). See Host configuration (hosts.json) for the full
connection-options reference.
Key |
Protocol |
|---|---|
|
SSH (term and hop) |
|
Telnet (term, and the embedded console) |
|
SFTP transfer |
|
SCP transfer |
|
FTP transfer |
|
Netcat transfer |
Coverage toolchain¶
The toolchain object points to the cross-toolchain binaries used by the
coverage pipeline. See Coverage Collection.
Field |
Type |
Description |
|---|---|---|
|
string |
Path to the cross-toolchain sysroot. |
|
string |
Path to |
|
string |
Path to the |
Example¶
Two real entries from the test fixture — one Unix host and one Zephyr host:
[
{
"ip": "10.10.200.11",
"element": "carrot",
"os_type": "unix",
"board": "seed",
"term": "ssh",
"transfer": "scp",
"is_virtual": true,
"creds": {
"vagrant": "vagrant",
"test": "Password1"
},
"resources": [
"carrot"
],
"labs": [
"veggies"
]
},
{
"ip": "192.0.2.1",
"element": "sprout",
"os_type": "zephyr",
"os_version": "3.7",
"transfer": "console",
"filesystem": "fat-ram",
"max_filename_len": 32,
"is_virtual": true,
"hop": "basil_seed",
"snmp": {
"address": "10.10.200.14",
"port": 16101,
"community": "public",
"oids": [
"1.3.6.1.2.1.1.3.0",
"1.3.6.1.4.1.63245.1.1.0",
"1.3.6.1.4.1.63245.1.2.0",
"1.3.6.1.4.1.63245.1.3.0",
"1.3.6.1.4.1.63245.1.4.0"
]
},
"resources": [
"sprout"
],
"labs": [
"embedded"
]
}
]
Product host preferences¶
Most products share a common set of connection conventions — a non-standard
SSH port, a longer connect timeout, an alternate nc binary, preferred
terminal or transfer backend. Restating those values on every host entry is
repetitive and error-prone. Move the shared values into
[host_preferences] in .otto/settings.toml.
Migration note:
[host_defaults]was removed; its option tables move under[host_preferences."<selector>".<opt>].
The [host_preferences] block is a map whose keys are Python regexes
matched (re.fullmatch) against each host’s id (e.g. carrot_seed,
router_seed_2). Under each selector, two kinds of values are allowed:
Selection lists (
term,transfer) — an ordered list of preferred backends. Otto picks the first entry that is in the host’s lab-definedvalid_terms/valid_transfersmenu; out-of-menu entries are skipped.Option tables (
ssh_options,telnet_options,sftp_options,scp_options,ftp_options,nc_options) — per-key value overrides.
# .otto/settings.toml
# Selector = Python regex matched against host id (".*" = all hosts).
# Selections (term/transfer) are ordered preferences gated by each host's
# lab menu; option tables are per-key values that win over hosts.json.
[host_preferences.".*"]
term = ["telnet"]
transfer = ["nc"]
ssh_options = { connect_timeout = 5.0, keepalive_interval = 30 }
telnet_options = { cols = 200, echo_negotiation_timeout = 1.0 }
nc_options = { exec_name = "ncat", port_strategy = "proc" }
# Narrower selectors overlay specific host groups.
[host_preferences."router.*"]
telnet_options = { port = 9023 }
Valid option-table names are: ssh_options, telnet_options,
sftp_options, scp_options, ftp_options, nc_options. Unknown keys
raise at startup so typos fail loudly instead of silently no-opping.
Precedence (lowest to highest):
The hardcoded dataclass defaults in
otto.host.options.The host’s own
*_optionstable andterm/transferpin inhosts.json(thevalid_*menu hard-gates selections).[host_preferences]from each repo — product values win overhosts.json. Repos are applied inOTTO_SUT_DIRSorder (later repo wins); within a repo, selectors are applied in definition order (later selector wins on the same key).CLI
--term/--transfer— final word, applied at invocation time.
Merging happens per key at every option-table layer. Setting only
port on a host in hosts.json still inherits connect_timeout from the
product preference, and so on down to the dataclass default.
The merge is performed at host construction time, so the resulting host
carries the fully-resolved *_options instances — nothing has to be
re-resolved at use time.
For the full *_options field reference and per-field semantics, see
Host configuration (hosts.json).
Merging labs¶
Pass multiple lab names to combine them:
otto --lab lab_a,lab_b test TestDevice
Hosts from all labs are merged into a single lab. If two labs define the same host ID, the later lab’s definition wins.
Exploring labs¶
otto --lab my_lab --list-labs # list all available lab names
otto --lab my_lab --list-hosts # list host IDs in the loaded lab
otto --lab my_lab --show-lab # full lab details (use -v for expanded output)