Chunks 2-6 of the C3 refactor. With the adapter in place, the phase
list collapses from 12 stubs to 5 real phases:
prepare_live parse user_*.json into archinstall handlers
arch_install partition + base + bootloader + limine config +
early omarchy + useradd + runtime omarchy (all
inside a single Installer context manager)
run_chroot_finalizer arch-chroot -u $user → finalize.sh
validate_boot halt if /boot/limine.conf, /etc/kernel/cmdline,
or UKI are missing/malformed
finish reboot prompt
Key reordering vs upstream guided.py: write_limine_config runs BETWEEN
add_bootloader and the first add_additional_packages call. By the time
omarchy-limine pulls limine-mkinitcpio-hook (in the runtime package
install), /etc/default/limine and /etc/kernel/cmdline are in place, so
the UKI is built correctly on the first try — no stale-UKI purge,
no follow-up limine-update.
add_additional_packages is split into two calls so /etc/skel is
populated (via omarchy-settings in EARLY_PACKAGES) BEFORE useradd:
EARLY_PACKAGES = base-devel git omarchy-keyring omarchy-settings omarchy-installer
→ installer.create_users(users)
→ runtime: omarchy + omarchy-base.packages
archinstall_adapter.py is the ONLY module that imports from archinstall.
If archinstall's API churns, the blast radius is contained here. Tested
against archinstall 4.3 / Python 3.14.
Limine template lookup tries the new install/assets/limine/ path first
and falls back to the legacy default/limine/ location during the
template-ownership migration (lands in a follow-up chunk).
60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
"""Install context: parsed configurator output, invocation paths, and a
|
|
mutable `state` dict for objects that live across phases (e.g., the
|
|
archinstall config handler and mirror list handler)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
@dataclass
|
|
class InstallContext:
|
|
config_path: Path
|
|
creds_path: Path
|
|
full_name: str
|
|
email: str
|
|
encrypt: bool
|
|
|
|
user_configuration: dict
|
|
user_credentials: dict
|
|
|
|
target: Path = Path("/mnt")
|
|
omarchy_path: Path = Path("/usr/share/omarchy")
|
|
state_dir: Path = Path("/run/omarchy-install")
|
|
log_path: Path = Path("/var/log/omarchy-install.log")
|
|
target_log_path: Path = Path("/mnt/var/log/omarchy-install.log")
|
|
|
|
# Mutable per-run state shared across phases (e.g., 'arch_config_handler',
|
|
# 'mirror_handler'). Phases populate as needed; later phases read.
|
|
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)
|
|
return 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"),
|
|
user_configuration=json.loads(config_path.read_text()),
|
|
user_credentials=json.loads(creds_path.read_text()),
|
|
)
|
|
|
|
@property
|
|
def username(self) -> str:
|
|
return self.user_credentials["users"][0]["username"]
|
|
|
|
|
|
def _read_text(path: str | None) -> str:
|
|
if not path:
|
|
return ""
|
|
p = Path(path)
|
|
if not p.exists():
|
|
return ""
|
|
return p.read_text().strip()
|