Repository Setup¶
Otto discovers your project through a .otto/settings.toml file at the
repository root. This page explains every setting and what happens during
project initialization.
The settings file¶
Create .otto/settings.toml in your repo root:
name = "my_project"
version = "1.0.0"
labs = ["${sutDir}/../lab_data"]
libs = ["${sutDir}/pylib"]
tests = ["${sutDir}/tests"]
init = ["my_instructions", "my_shared_options"]
# Optional: connection defaults applied to every host this repo touches.
[host_defaults.ssh_options]
connect_timeout = 5.0
keepalive_interval = 30
Variable expansion¶
${sutDir} is replaced with the absolute path to the repo root at load
time. Use it to keep paths relative and portable. Expansion runs
inside every settings table, including string values nested under
[host_defaults].
Field reference¶
- name
Required. Product or repository name. Displayed in CLI panels and log output.
- version
Required. Semantic version string (e.g.
"1.0.0").- labs
List of directory paths to search for lab JSON files. When you pass
--lab my_lab, otto looks in these directories for a file matching that name. Defaults to[].- libs
List of Python package directories to add to
sys.pathat startup. This is where you put your instruction modules, shared options, and helper libraries. Defaults to[].- tests
List of directories to scan for
test_*.pyfiles. Each matching file is imported at startup, which triggers@register_suite()decorators and makes suites available asotto testsubcommands. Defaults to[].- init
List of Python module names (dot-separated) to import at startup. Use this to register instructions (
@command()) and shared option classes. These modules must be importable from one of thelibsdirectories. Defaults to[].- [host_defaults]
Optional table of per-protocol option defaults applied to every host loaded from this repo’s
labs. See Repo-level host defaults in Lab Configuration for the full schema and precedence rules.- [os_profiles]
Optional table of named OS-profile bundles. Each
[os_profiles.<name>]sub-table must contain abasekey naming a registered host class (e.g."unix","zephyr", or a class registered by aninitmodule) and may contain any default field values to bundle with that profile. Profiles are registered into the global OS-profile registry so lab-data entries can select them byosTypename. See OS Profiles & Custom Host Classes for the full treatment.
What happens at startup¶
When you run any otto command, the following initialization sequence
occurs:
Environment parsing – Otto reads
OTTO_SUT_DIRSto find repo root directories.Repo discovery – For each path in
OTTO_SUT_DIRS, otto creates aRepoobject and reads its.otto/settings.toml.Apply settings – For each repo, otto:
Adds
libsdirectories tosys.pathImports modules listed in
init(this registers instructions)Auto-imports all
test_*.pyfiles fromtestsdirectories (this registers suites)
Lab loading – Otto collects all
labssearch paths from every repo and loads the lab(s) specified by--laborOTTO_LAB. Multiple labs are merged, combining their hosts.Config module creation – The global
ConfigModuleis created with the loaded repos and lab, making hosts available to all commands.
Multiple repos¶
Otto supports multiple repos simultaneously. Set OTTO_SUT_DIRS to a
comma-separated list:
export OTTO_SUT_DIRS=/path/to/repo1,/path/to/repo2
Each repo has its own settings, libs, tests, and lab search paths. They are all merged at startup – instructions and suites from every repo appear in the CLI, and lab search paths from all repos are combined.
Lab files¶
Each directory listed under labs holds a hosts.json file describing the
hosts at that location. The full per-host schema — every field, the
connection-option tables, repo-level host defaults, and how labs merge — lives
in Lab Configuration.