orchestrator: switch wrapper interface from CLI args to env vars to avoid archinstall argparse collision

This commit is contained in:
Ryan Hughes committed 2026-05-21 19:40:31 -04:00
1 parent 8dad5a7436
commit 22f94e6da6
3 files changed
+39 -34

No files matched your search

@@ -6,10 +6,24 @@
set -eEo pipefail
# Patch archinstall BEFORE Python loads it. orchestrator/main.py top-level
# imports archinstall_adapter, which top-level imports archinstall.*; patching
# inside a phase would be too late (bytecode already loaded).
# Patch archinstall BEFORE Python loads it. phases_impl.py imports
# archinstall_adapter, which imports archinstall.*; patching inside a phase
# would be too late (bytecode already loaded).
omarchy-iso-patch-archinstall
# Parse our args; convert to env vars before exec'ing Python so archinstall's
# own argparse (which runs at module import time inside the orchestrator)
# doesn't choke on flags it doesn't recognize.
while [[ $# -gt 0 ]]; do
case $1 in
--config) export OMARCHY_INSTALL_CONFIG="$2"; shift 2 ;;
--creds) export OMARCHY_INSTALL_CREDS="$2"; shift 2 ;;
--full-name-file) export OMARCHY_INSTALL_FULL_NAME_FILE="$2"; shift 2 ;;
--email-file) export OMARCHY_INSTALL_EMAIL_FILE="$2"; shift 2 ;;
--encrypt-file) export OMARCHY_INSTALL_ENCRYPT_FILE="$2"; shift 2 ;;
*) echo "omarchy-iso-install: unknown arg $1" >&2; exit 2 ;;
esac
done
cd /usr/share/omarchy-iso
exec python -m orchestrator.main "$@"
exec python -m orchestrator.main
@@ -5,6 +5,7 @@ archinstall config handler and mirror list handler)."""
from __future__ import annotations
import json
import os
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
@@ -32,16 +33,21 @@ class InstallContext:
state: dict[str, Any] = field(default_factory=dict)
@classmethod
def from_args(cls, args) -> "InstallContext":
config_path = Path(args.config)
creds_path = Path(args.creds)
def from_env(cls) -> "InstallContext":
config_str = os.environ.get("OMARCHY_INSTALL_CONFIG")
creds_str = os.environ.get("OMARCHY_INSTALL_CREDS")
if not config_str or not creds_str:
raise RuntimeError("OMARCHY_INSTALL_CONFIG and OMARCHY_INSTALL_CREDS must be set")
config_path = Path(config_str)
creds_path = Path(creds_str)
user_configuration = json.loads(config_path.read_text())
ctx = cls(
config_path=config_path,
creds_path=creds_path,
full_name=_read_text(args.full_name_file),
email=_read_text(args.email_file),
encrypt=_read_text(args.encrypt_file).lower() in ("true", "yes", "1"),
full_name=_read_text(os.environ.get("OMARCHY_INSTALL_FULL_NAME_FILE")),
email=_read_text(os.environ.get("OMARCHY_INSTALL_EMAIL_FILE")),
encrypt=_read_text(os.environ.get("OMARCHY_INSTALL_ENCRYPT_FILE")).lower() in ("true", "yes", "1"),
user_configuration=user_configuration,
user_credentials=json.loads(creds_path.read_text()),
)
@@ -3,22 +3,14 @@
Single tool that owns the full install phase ordering, with archinstall used as
a library subsystem (not as the top-level installer).
Usage (typically invoked by bin/omarchy-install on the live ISO):
omarchy-install \\
--config user_configuration.json \\
--creds user_credentials.json \\
--full-name-file user_full_name.txt \\
--email-file user_email_address.txt \\
--encrypt-file user_encrypt_installation.txt
The live-ISO wrapper consumes CLI args and passes configuration paths via
OMARCHY_INSTALL_* environment variables before Python starts. This keeps
archinstall's import-time CLI parsing from seeing Omarchy-specific flags.
"""
from __future__ import annotations
import argparse
import sys
from . import archinstall_adapter as arch
from .context import InstallContext
from .phases import PhaseError, run
from .ui import error, info
@@ -71,19 +63,12 @@ def build_phases(ctx: InstallContext):
]
def parse_args(argv):
p = argparse.ArgumentParser(prog="omarchy-install")
p.add_argument("--config", required=True, help="archinstall user_configuration.json")
p.add_argument("--creds", required=True, help="archinstall user_credentials.json")
p.add_argument("--full-name-file", help="text file with the user's full name")
p.add_argument("--email-file", help="text file with the user's email address")
p.add_argument("--encrypt-file", help="text file holding 'true' if root encryption enabled")
return p.parse_args(argv)
def main(argv=None) -> int:
args = parse_args(argv or sys.argv[1:])
ctx = InstallContext.from_args(args)
def main() -> int:
try:
ctx = InstallContext.from_env()
except RuntimeError as e:
error(f"Configuration error: {e}")
return 2
info(f"Installing Omarchy for {ctx.username} → {ctx.target}")