Chunk 1 of the C3 refactor: replace the two-pass install model (archinstall CLI + custom shell dance + chroot bash installer) with a single Python orchestrator that owns phase ordering, using archinstall as a library subsystem. Splits the bash entry point into two: - install.sh: online entry point. Ensures omarchy runtime + base.packages are installed/up to date, then exec's finalize.sh. - finalize.sh: the in-target portion (preflight + packaging + config + login + post-install). Called by install.sh (online) AND by the orchestrator after arch-chroot -u $USER (offline). Adds the orchestrator skeleton under install/orchestrator/: - main.py: entry point, builds + runs the phase list - context.py: InstallContext (parsed configurator JSON + invocation paths) - phases.py: phase state machine (logging + state.json + error wrapping) - phases_impl.py: stubbed phase implementations (filled in by chunks 2-6) - archinstall_adapter.py: thin compat wall around archinstall lib imports (only this module imports from archinstall.*) - ui.py: gum subprocess wrappers so the orchestrator keeps the same styled-terminal UX as the bash installer Updates bin/omarchy-install to dispatch: - --config <json> in args → python -m orchestrator.main (ISO install) - anything else → bash install.sh (online rerun on installed system) Concrete phase logic lands in subsequent chunks. All phases currently raise NotImplementedError; the orchestrator imports cleanly and --help works as a smoke check.
96 lines
3.1 KiB
Python
96 lines
3.1 KiB
Python
"""Omarchy install orchestrator.
|
|
|
|
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
|
|
"""
|
|
|
|
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
|
|
|
|
|
|
def build_phases():
|
|
"""Phase order. Each entry is (display name, callable taking InstallContext).
|
|
|
|
The ordering is the whole point of this orchestrator: package-install
|
|
hooks (limine-mkinitcpio-hook, in particular) and useradd happen at
|
|
points where their prerequisites are guaranteed to be in place.
|
|
"""
|
|
from .phases_impl import (
|
|
prepare_live,
|
|
cleanup_disk,
|
|
partition_and_mount,
|
|
install_base,
|
|
install_bootloader,
|
|
write_limine_config,
|
|
install_early_omarchy_packages,
|
|
create_user,
|
|
install_omarchy_runtime,
|
|
run_chroot_finalizer,
|
|
validate_boot,
|
|
finish,
|
|
)
|
|
|
|
return [
|
|
("Preparing live environment", prepare_live),
|
|
("Cleaning install disk", cleanup_disk),
|
|
("Partitioning + mounting", partition_and_mount),
|
|
("Installing base system", install_base),
|
|
("Installing bootloader", install_bootloader),
|
|
("Writing Limine config", write_limine_config),
|
|
("Installing Omarchy keyring + settings", install_early_omarchy_packages),
|
|
("Creating user", create_user),
|
|
("Installing Omarchy runtime", install_omarchy_runtime),
|
|
("Finalizing in chroot", run_chroot_finalizer),
|
|
("Validating boot setup", validate_boot),
|
|
("Finishing", finish),
|
|
]
|
|
|
|
|
|
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)
|
|
|
|
info(f"Installing Omarchy for {ctx.username} → {ctx.target}")
|
|
|
|
try:
|
|
run(ctx, build_phases())
|
|
except PhaseError:
|
|
error("Installation halted.")
|
|
return 1
|
|
except KeyboardInterrupt:
|
|
error("Installation interrupted.")
|
|
return 130
|
|
|
|
info("Installation complete.")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|