CLI Reference¶
Complete reference for all otto command-line options.
Global options¶
These options are available on every otto command:
Option |
Env var |
Default |
Description |
|---|---|---|---|
|
|
(required) |
Lab name(s), comma-separated |
|
|
current dir |
Output directory for logs and artifacts |
|
|
|
Use field or debug products |
|
|
|
Number of days to retain logs |
|
|
|
Logging level |
|
|
|
Rich formatting in log files |
|
|
Show per-line timestamps on the live console (log files are always timestamped) |
|
|
|
Preview without running commands |
|
|
current user |
Check reservations as USERNAME instead of the current user |
|
|
|
Bypass the reservation check entirely (emergency use only) |
|
|
List available lab names and exit |
||
|
List host IDs in the loaded lab and exit |
||
|
Print full lab details and exit |
||
|
|
Nesting depth for |
|
|
Delete the shell-completion cache file and exit |
||
|
Show version and exit |
||
|
Install shell completion and exit |
||
|
Print shell completion script and exit |
||
|
Show help and exit |
Important
Option placement matters. Global options (including --lab/-l) must
appear before the subcommand — they are parsed by the top-level otto
command, not the subcommand. For example:
✅
otto --lab my_lab run deploy --debug❌
otto run deploy --debug --lab my_lab
The same rule applies to --dry-run, --xdir, --log-level, and every
other option listed above. Subcommand-specific options (like --firmware
for a suite, or --interval for monitor) go after the subcommand.
Shell completion¶
After otto --install-completion, tab completion covers the dynamic,
otto-specific values a static shell script couldn’t know: suite and
instruction names, host ids and their per-class verbs, transfer/term
backends, reservation usernames, and — comma-separated lists included —
--lab names and --tests names. It is served from a per-repo cache so the
process answering the keystroke never runs your init modules or test code.
--tests completes by base name and layers a static source scan (the instant
floor) with a pytest-collected set that also includes dynamically-generated
tests; that set warms itself from any real otto test --list-tests run, or
from a one-time bounded collection on the first --tests TAB (see
otto test). --clear-autocomplete-cache drops the cache if it ever goes
stale.
Output directories¶
Most commands create a per-invocation output directory under --xdir
before the command body runs; the run’s log files and artifacts are
written there, and the path is printed at the end of the run
(Output directory: ...):
<xdir>/<command>/<timestamp>_<subcommand>/
<command>is the top-level subcommand (run,test,host, …) and<subcommand>is the leaf — the instruction name, suite name, or host verb. Commands with no distinct leaf (monitor) omit the suffix:monitor/<timestamp>/.<timestamp>is UTC with millisecond precision (YYYYMMDD_HHMMSS_mmm), so directories sort chronologically.Hyphens in command names become underscores (
write-file→write_file).
Read-only commands create no directory: otto cov, otto reservation,
otto schema, and otto init opt out entirely, as do read-only host verbs
such as ls, exists, read-file, is-installed, and is-uninstalled.
Third-party commands control this with the output_dir= flag at
registration — see Extending the otto CLI.
otto init¶
Scaffold a new otto repo, or validate an existing one’s setup. See Getting Started for the full walkthrough.
otto init [--all | --lab | --tests | --instructions] [--name NAME]
[--version X.Y.Z] [--path DIR]
otto init is lab-free: it needs no --lab and no OTTO_SUT_DIRS, and
it never creates an output directory.
Option |
Default |
Description |
|---|---|---|
|
|
Scaffold every missing area without prompting |
|
|
Scaffold the lab area ( |
|
|
Scaffold the tests area (example suite + conftest) |
|
|
Scaffold the instructions area ( |
|
directory name |
Product name for |
|
|
Product version for |
|
current dir |
Repo root to operate on (must already exist) |
With no flags, otto init runs interactively: it prompts to confirm each
missing area (prompting for --name/--version only when
.otto/settings.toml itself is missing). --all scaffolds every missing
area with no prompts. Passing one or more of --lab/--tests/
--instructions scaffolds exactly those areas, plus settings automatically
whenever it’s missing — every other area depends on it.
Areas that already exist are never modified. Instead, otto init validates
them with the same ingestion code otto uses elsewhere and reports each one
✓ or ✗ in a summary table; the command exits with code 1 if any existing
area fails validation. The name used for areas scaffolded on a later run is
read from the existing settings.toml’s name field, falling back to the
directory name.
Every run also prints a “Next steps” list of the commands to run next —
export OTTO_SUT_DIRS=... (skipped if the repo is already listed there),
otto --install-completion, otto --lab example_lab --list-hosts,
otto test --list-suites, otto test TestExample, and otto test --tests test_example_function.
otto run¶
Run registered instructions.
otto run <instruction> [OPTIONS]
otto run --list-instructions
Option |
Description |
|---|---|
|
List all available instructions and exit |
Each instruction defines its own options via Typer annotations. Use
otto run <instruction> --help to see them.
otto test¶
Run registered test suites — or, without a suite name, a suite-less
selection by exact test name (--tests) and/or marker expression (-m).
otto test [PARENT OPTIONS] <Suite> [SUITE OPTIONS]
otto test [PARENT OPTIONS] --tests NAME[,NAME...] [--markers EXPR]
otto test [PARENT OPTIONS] --markers EXPR
otto test --list-suites
otto test --list-tests [--markers EXPR] [<Suite>]
otto test --list-markers
--tests and/or --markers with no suite name select across every suite
and repo that has a match, including plain pytest test_* functions; bare
otto test with neither flag and no suite name prints help. See otto test
for the full selection-run semantics, including how suite Options defaults
are applied.
Parent options (before the suite name)¶
Option |
Default |
Description |
|---|---|---|
|
List test suites with run syntax and exit |
|
|
List the selected tests and exit; narrow with a suite name and/or |
|
|
List the markers available to |
|
|
|
Pytest marker expression (e.g. |
|
|
Run specific tests by exact name across all suites/repos, no suite name needed; |
|
|
Repeat each test N times in one setup/teardown cycle |
|
|
Repeat tests for SECONDS in one setup/teardown cycle |
|
|
Minimum per-test pass rate percent in stability mode (0-100) |
|
auto |
JUnit XML output path |
|
off |
Collect gcov coverage from remotes after the run |
|
|
Override coverage destination (implies |
|
off |
Allow |
|
on |
Delete |
|
off |
Generate an HTML coverage report after the run (implies |
|
|
Override HTML report destination (implies |
|
off |
Allow |
|
|
Title shown in the HTML report header (with |
|
off |
Collect host performance metrics for the entire run |
|
|
Sampling interval for |
|
|
Override monitor data destination ( |
|
all hosts |
Regex restricting which hosts |
Each suite also defines its own options via its Options dataclass — these
flags only exist on that suite’s own subcommand (otto test <Suite> --flag), not on a --tests/-m selection run. Use otto test <Suite> --help to see them. Selection runs default-construct each suite’s
Options; a suite with a required option fails its own tests with a hint
to run the suite form directly.
otto host¶
Run commands, transfer files, log in, and invoke capability verbs on lab hosts.
otto host <HOST_ID> run [--sudo] [--timeout SECS] <COMMANDS...>
otto host <HOST_ID> put <SRC...> <DEST>
otto host <HOST_ID> get <SRC...> <DEST>
otto host <HOST_ID> login
otto host <HOST_ID> reboot [--hard] [--wait] [--timeout SECS]
otto host <HOST_ID> install [--stage-only]
otto host <HOST_ID> power [STATE]
otto host <HOST_ID> ls [PATH] [--all]
otto host --list-hosts
Subcommands¶
All otto host subcommands are synthesized from @cli_exposed host methods
using the same signature-driven mechanism — run, put, get, and login
included. The full set varies by host class; run otto host <HOST_ID> --help
to see what is available for a specific host.
Subcommand |
Description |
|---|---|
|
Execute one or more commands on the host |
|
Upload local files to the host |
|
Download files from the host |
|
Open an interactive shell session on the host |
|
Reboot the host (soft or hard power-cycle) |
|
Power off the host from its own shell |
|
Turn the host on/off or toggle (requires a power controller) |
|
Stage products onto the host without installing |
|
Stage then install products |
|
Uninstall products |
|
Exit 0 if all products are installed |
|
Exit 0 if no products are installed |
|
Exit 0 if a path exists on the host |
|
List directory contents on the host |
|
Create a directory on the host |
|
Remove a path on the host |
|
Copy a path on the host |
|
Move/rename a path on the host |
|
Print a file’s text contents |
|
Write text to a file on the host |
See Host capabilities for class-scoping rules and which verbs each host type exposes.
run options¶
otto host <HOST_ID> run [OPTIONS] COMMANDS...
Option |
Description |
|---|---|
|
One or more shell commands (space-separated, each quoted as needed) |
|
Run every command through |
|
Cumulative timeout in seconds across all commands |
put / get arguments¶
otto host <HOST_ID> put SRC... DEST
otto host <HOST_ID> get SRC... DEST
SRC... is one or more source paths (space-separated); DEST is the
destination directory. For put, sources are local paths; for get, sources
are remote paths.
reboot options¶
otto host <HOST_ID> reboot [--hard] [--wait] [--timeout SECS]
Option |
Default |
Description |
|---|---|---|
|
|
Power-cycle via the power controller instead of an in-shell reboot |
|
|
Block until the host is reachable again after reboot |
|
|
Maximum seconds to wait when |
install options¶
otto host <HOST_ID> install [--stage-only]
Option |
Description |
|---|---|
|
Transfer products but skip the install step |
Host-level options¶
Option |
Description |
|---|---|
|
Host ID to operate on (see |
|
Route through an intermediate SSH hop host |
|
Override the terminal protocol for this session |
|
Override the file transfer protocol for this session |
|
List all available host IDs and exit |
otto monitor¶
Launch the interactive performance dashboard.
otto monitor [OPTIONS]
Option |
Default |
Description |
|---|---|---|
|
all hosts |
Regex matched against host IDs via |
|
|
Collection interval (minimum 1.0) |
|
Load historical data from |
|
|
Persist live data to SQLite for later viewing |
Docker container hosts are excluded from the default monitored fleet.
otto cov¶
Retrieve, reset, and report gcov coverage across the lab’s tiers. For
the full walkthrough, prerequisites (lcov/gcov), and tier recipes,
see the coverage guide.
otto cov get [OPTIONS]
otto cov clean
otto cov report [OUTPUT_DIR...] [OPTIONS]
Subcommand |
Description |
|---|---|
|
Fetch |
|
Zero remote |
|
Assemble every tier — e2e captures, unit harvest, committed manual store — into an HTML report |
otto cov get options¶
Option |
Default |
Description |
|---|---|---|
|
the per-invocation output dir |
Directory for fetched counters and per-board captures |
|
the lab’s sole |
Tier stamped onto each capture; a |
|
none |
Ticket reference; required for a |
|
none |
Free-text note ( |
|
|
Tester name ( |
|
|
Tester email ( |
|
off |
Zero the fetched Unix hosts’ counters after a successful retrieval |
Retrieval requires a git repository (captures are pinned to HEAD);
a dirty working tree is remapped onto committed-code coordinates
automatically.
otto cov report arguments and options¶
Argument |
Description |
|---|---|
|
|
Option |
Default |
Description |
|---|---|---|
|
|
Directory for the generated HTML report ( |
|
|
Title shown in the HTML report header |
|
the configured tiers |
Git-less escape hatch; repeatable. See tier rules below. |
Tiers¶
Tiers are normally declared under [coverage.tiers] in
.otto/settings.toml and loaded automatically — with no --tier
flags, the report uses the configured tiers (or an implicit system
tier when none are configured).
Passing any --tier flag bypasses the declarative model entirely
(settings tiers, the manual store, and unit harvesting are not
consulted) — a git-less fallback for foreign .info files. --tier
is repeatable, and the order of flags is the precedence order —
the first tier is highest precedence and wins row coloring on the
annotated source view.
--tier system(no path) — the implicit tier built by merging the suppliedOUTPUT_DIR.gcdafiles withlcov. Only thesystemtier may omit a path.--tier NAME=PATH— any other tier;PATHmust be a pre-existing lcov-format.infotracefile. A non-systemtier without a path is rejected.Duplicate tier names are rejected.
Examples¶
otto cov get --tier manual --ticket PROJ-123 --note "verified failover"
otto cov report runs/2026-05-16_T1200/ --report ./report
otto cov report run_a/ run_b/ run_c/ --report ./combined
otto cov report runs/ --tier unit=unit.info --tier system --tier manual=manual.info
On success, otto logs the overall coverage percentage, the file count,
and the path to index.html. If no coverage data is found anywhere —
supplied directories, unit harvest, or the manual store — the command
logs an error naming the searched locations and exits non-zero.
Collecting coverage (otto test --cov)¶
otto test --cov collects coverage as part of a test run — it fetches
counters after the suite and produces the same pinned per-board
captures as otto cov get:
Option |
Description |
|---|---|
|
Fetch |
|
Write coverage artifacts to an explicit directory (implies |
|
Allow |
|
Delete stale |
|
Also render the HTML report inline after the run (implies |
|
Explicit destination for the inline HTML report (implies |
See the otto test section above for the full option
table, and the coverage guide for end-to-end examples.
otto docker¶
Build images and orchestrate compose stacks on docker-capable lab hosts.
otto docker build [--repo NAME] [--on HOST] [--rebuild] [<IMAGE>...]
otto docker up [--repo NAME] [--on HOST] [--no-build]
otto docker down [--repo NAME] [--on HOST]
otto docker ps [--on HOST]
Docker subcommands¶
Subcommand |
Description |
|---|---|
|
Build container images |
|
Bring compose stacks up |
|
Tear compose stacks down |
|
List running containers on docker-capable hosts |
Docker options¶
Option |
Applies to |
Description |
|---|---|---|
|
|
Restrict to a single repo by name |
|
all |
Lab host id to operate on (default: all docker-capable hosts) |
|
|
Force rebuild even if a context-hash tag exists |
|
|
Skip the implicit build step before compose up |
|
|
Image names to build (default: all) |
otto reservation¶
Inspect and verify lab reservations.
otto reservation whoami
otto reservation check
Reservation subcommands¶
Subcommand |
Description |
|---|---|
|
Show the resolved reservation identity and backend |
|
Verify the current reservation for the loaded lab |