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 = ["${sut_dir}/../lab_data"]
libs = ["${sut_dir}/pylib"]
tests = ["${sut_dir}/tests"]
init = ["my_instructions", "my_shared_options"]
# Optional: product preferences applied to every host this repo touches.
# Selector = Python regex matched against the host id; ".*" = all hosts.
# Values win over hosts.json; CLI --term/--transfer win over everything.
[host_preferences.".*"]
ssh_options = { connect_timeout = 5.0, keepalive_interval = 30 }
Variable expansion¶
${sut_dir} 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_preferences].
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[].- [lab]
Optional table selecting the host-source backend — where otto’s hosts come from.
backendnames a registered source (defaults to"json", which readshosts.jsonfrom thelabsdirectories); a[lab.<name>]sub-table holds that backend’s keyword arguments. See Host Database for the full treatment.- 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_preferences]
Optional table of product-wide selector-scoped preferences. Each sub-table key is a Python regex matched against host ids; inner keys are
term,transfer(ordered backend lists) or*_optionstables (per-key option values that win overhosts.json). See Product host preferences in Lab Configuration for the full schema and precedence rules.Migration note:
[host_defaults]was removed; its option tables move under[host_preferences."<selector>".<opt>].- [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 byos_typename. See OS Profiles & Custom Host Classes for the full treatment.- [reservations]
Optional table enabling the reservation gate — otto refuses to start live-lab commands against resources the current user doesn’t hold.
backendnames a registered scheduler source ("none"— the default — disables the gate;"json"reads a reservation file). See Lab Reservations for backends, the file format, and the--as-user/-Rbreak-glass overrides.
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 builds the host source via
build_lab_repository(selected by[lab] backend, defaulting to the built-injsonsource over the mergedlabssearch paths) and loads the lab(s) named by--laborOTTO_LAB. Multiple labs are merged, combining their hosts. The host source is pluggable — see Host Database.Context creation – The global
OttoContextis created with the loaded repos and lab and installed viaset_context(), making hosts available to the zero-argument accessors (get_host,all_hosts) in 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.
Team setup checklist¶
Most of otto’s configuration is a one-time, team-level decision. New contributors then just clone and run. Work through this map once when adopting otto for a team:
Create
.otto/settings.toml—name,version, and thelabs/libs/tests/initpaths (this page, above).Choose a host source — the built-in
jsonsource (commithosts.jsonunder alabsdirectory) is the default; point[lab] backendat a CMDB or inventory API if you have one. See Host Database.Decide on reservation gating — leave it off (
backend = "none", the default) for sandbox labs, or wire[reservations]to your scheduler so otto refuses to clobber a held rack. Tell the team about the--as-userand-R/--skip-reservation-checkbreak-glass overrides before they need them. See Lab Reservations.Register shared code — put instruction/option modules under
libsand list them ininit; auto-import test suites fromtests. See otto run and otto test.Set per-product preferences — optional
[host_preferences]/[os_profiles](this page, above, and Lab Configuration / OS Profiles & Custom Host Classes).Enable tab completion — see Getting Started.
Each backend choice is verifiable: otto ships conformance helpers
(otto.testing.assert_lab_repository_conforms /
assert_reservation_backend_conforms) so a custom host source or reservation
backend can be checked against otto’s contract in your own test suite.