Multi-location OS management for localhost, remote SSH, and ARM images/SD cards.
Create a virtual environment and install dependencies:
python3 -m venv env
source env/bin/activate
pip install -r requirements.txtThis project uses a hierarchical configuration system. config.yaml files are automatically discovered and loaded from the following locations:
config.yamlin the project root (Highest Priority)core/**/config.yaml(Base Configuration)plugins/**/config.yaml(Plugin Configuration)
Files are loaded in order of depth (deepest first), meaning:
- A
config.yamlin the project root will override settings fromcore/orplugins/. - Files in
core/orplugins/(usually lower in the directory tree) provide defaults.
Example config.yaml:
# Root config.yaml
serialport:
baudrate: 115200
network:
wifi_ssid: "MyHomeNetwork"If a key is missing for a selected operation, the script prompts for it at runtime.
network:
wifi_ssid: "MyHomeNetwork"
# wifi_password omitted -> prompted when network operation runs-
Overriding a List: Lists are replaced, not merged. Redefining a list in a higher-priority file will completely overwrite the deeper one.
# If core/config.yaml has: # packages: [vim, git] # Root config.yaml: packages: - nano - curl # Result: packages = [nano, curl]
-
Unspecifying a Value (
null): Usenullto explicitly set a value toNone.rtc: addr: null # Disables the address setting, effectively "unsetting" it
To override a value from a lower-precedence config file, simply define the key in your higher-precedence config.yaml.
Original (core/config.yaml):
network:
wifi_ssid: "DefaultSSID"Override (root config.yaml):
network:
wifi_ssid: "MyHomeNetwork"
# To set an explicit empty value, use null
wifi_password: nullResult: wifi_ssid is "MyHomeNetwork", and wifi_password is None.
Use the project-level orchestration runner:
python install.pyThis CLI:
- Loads merged config from
core/**/config.yaml,plugins/**/config.yaml, and rootconfig.yaml - Dynamically discovers available operations from
OperationBasesubclasses undercoreandplugins - Lists orchestration names defined in config
- Provides a
custom (manual operation selection)option to select multiple operations interactively - Runs two phases: gather all required configs first, then execute all selected operations
Custom selection behavior:
- In custom multi-select mode, press Enter with no selected operations to return to the main menu.
Discovery notes:
- New operation classes are discovered automatically if they subclass
OperationBaseand support no-arg construction. - Duplicate operation keys (
moduleName.name) are rejected at startup with a clear error.
Preferred shape:
orchestrations:
genSetup:
hostname: [hostname, username]
region: [timezone]Shorthand shape (also supported):
genSetup:
- hostname:
- hostname
- username
- region:
- timezoneValidation rules:
- If
orchestrationsexists, it must be a mapping. - Each module entry in an explicit orchestration must map to a non-empty string or non-empty list of strings.
- Invalid explicit orchestration entries fail fast with a
ValueErrorthat includes orchestration/module context.