installer: move hibernation into orchestrator

This commit is contained in:
Ryan Hughes committed 2026-05-23 14:05:15 -04:00
1 parent c7b8d4b584
commit 3a51e875b6
3 files changed
+115 -53

No files matched your search

@@ -197,10 +197,11 @@ weights = [
('Starting installation', 1, 2, 2),
('Preparing live environment', 2, 6, 5),
('Verifying protected mounts', 6, 8, 3),
('Installing Arch + Omarchy', 8, 82, 60),
('Installing base system', 8, 82, 60),
('Configuring protected boot', 82, 86, 8),
('Finalizing in chroot', 86, 98, 90),
('Installing Arch + Omarchy', 8, 86, 95),
('Installing base system', 8, 84, 85),
('Configuring protected boot', 84, 86, 8),
('Configuring hibernation', 86, 88, 5),
('Finalizing in chroot', 88, 98, 10),
('Configuring login', 98, 99, 3),
('Validating protected boot setup', 99, 100, 5),
('Validating boot setup', 99, 100, 5),
@@ -34,6 +34,7 @@ def build_phases(ctx: InstallContext):
arch_install_base,
verify_protected_mounts,
configure_protected_boot,
configure_hibernation,
run_chroot_finalizer,
configure_login,
validate_boot_full,
@@ -46,6 +47,7 @@ def build_phases(ctx: InstallContext):
("Verifying protected mounts", verify_protected_mounts),
("Installing base system", arch_install_base),
("Configuring protected boot", configure_protected_boot),
("Configuring hibernation", configure_hibernation),
("Finalizing in chroot", run_chroot_finalizer),
("Configuring login", configure_login),
("Validating protected boot setup", validate_boot_protected),
@@ -54,6 +56,7 @@ def build_phases(ctx: InstallContext):
return [
("Preparing live environment", prepare_live),
("Installing Arch + Omarchy", arch_install_full),
("Configuring hibernation", configure_hibernation),
("Finalizing in chroot", run_chroot_finalizer),
("Configuring login", configure_login),
("Validating boot setup", validate_boot_full),
@@ -134,41 +134,45 @@ def arch_install_full(ctx: InstallContext) -> None:
if config.mirror_config:
installer.set_mirrors(mirror_handler, config.mirror_config, on_target=False)
info("› installing base system (mkinitcpio deferred to final Limine UKI build)")
installer.minimal_installation(
optional_repositories=(
config.mirror_config.optional_repositories
if config.mirror_config else []
),
mkinitcpio=False,
hostname=config.hostname,
locale_config=config.locale_config,
pacman_config=config.pacman_config,
)
_mask_mkinitcpio_pacman_hooks(ctx)
try:
info("› installing base system (mkinitcpio deferred to final Limine UKI build)")
installer.minimal_installation(
optional_repositories=(
config.mirror_config.optional_repositories
if config.mirror_config else []
),
mkinitcpio=False,
hostname=config.hostname,
locale_config=config.locale_config,
pacman_config=config.pacman_config,
)
if config.mirror_config:
installer.set_mirrors(mirror_handler, config.mirror_config, on_target=True)
if config.mirror_config:
installer.set_mirrors(mirror_handler, config.mirror_config, on_target=True)
if config.swap and config.swap.enabled:
installer.setup_swap(algo=config.swap.algorithm)
if config.swap and config.swap.enabled:
installer.setup_swap(algo=config.swap.algorithm)
info(f"› installing early Omarchy packages: {', '.join(EARLY_PACKAGES)}")
installer.add_additional_packages(EARLY_PACKAGES)
info(f"› installing early Omarchy packages: {', '.join(EARLY_PACKAGES)}")
installer.add_additional_packages(EARLY_PACKAGES)
if arch.bootloader_enabled(config):
if not arch.is_limine(config):
raise RuntimeError(
"Omarchy full-disk installs only support Limine bootloader setup"
)
info("› installing bootloader (Limine)")
_install_limine_omarchy(ctx, installer, config)
if arch.bootloader_enabled(config):
if not arch.is_limine(config):
raise RuntimeError(
"Omarchy full-disk installs only support Limine bootloader setup"
)
info("› installing bootloader (Limine)")
_install_limine_omarchy(ctx, installer, config)
info("› writing Limine config (so limine-mkinitcpio-hook fires correctly)")
_write_limine_defaults_from_config(ctx, installer, config)
info("› writing Limine config (so limine-mkinitcpio-hook fires correctly)")
_write_limine_defaults_from_config(ctx, installer, config)
info("› creating user (with /etc/skel populated)")
if config.auth_config and config.auth_config.users:
installer.create_users(config.auth_config.users)
info("› creating user (with /etc/skel populated)")
if config.auth_config and config.auth_config.users:
installer.create_users(config.auth_config.users)
finally:
_unmask_mkinitcpio_pacman_hooks(ctx)
info("› installing Omarchy runtime + omarchy-base.packages")
installer.add_additional_packages(_runtime_package_list(ctx))
@@ -398,6 +402,32 @@ def _limine_template(ctx: InstallContext, filename: str) -> Path:
raise RuntimeError(f"Limine template {filename} not found. Searched:\n {searched}")
def _mask_mkinitcpio_pacman_hooks(ctx: InstallContext) -> None:
"""Temporarily suppress mkinitcpio pacman hooks between base and runtime.
The final Limine UKI build happens after all boot config is known. Pacman
would otherwise rebuild initramfs during the base linux transaction and
again when early settings/plymouth packages land.
"""
hooks_dir = ctx.target / "etc" / "pacman.d" / "hooks"
hooks_dir.mkdir(parents=True, exist_ok=True)
for name in ("90-mkinitcpio-install.hook", "60-mkinitcpio-remove.hook"):
path = hooks_dir / name
path.unlink(missing_ok=True)
path.symlink_to("/dev/null")
def _unmask_mkinitcpio_pacman_hooks(ctx: InstallContext) -> None:
hooks_dir = ctx.target / "etc" / "pacman.d" / "hooks"
for name in ("90-mkinitcpio-install.hook", "60-mkinitcpio-remove.hook"):
path = hooks_dir / name
try:
if path.is_symlink() and path.readlink() == Path("/dev/null"):
path.unlink()
except OSError:
pass
def _runtime_package_list(ctx: InstallContext) -> list[str]:
"""omarchy + every package in install/omarchy-base.packages that isn't
already in EARLY_PACKAGES."""
@@ -488,30 +518,34 @@ def arch_install_base(ctx: InstallContext) -> None:
if config.mirror_config:
installer.set_mirrors(mirror_handler, config.mirror_config, on_target=False)
info("› installing base system (mkinitcpio deferred to configure_protected_boot)")
installer.minimal_installation(
optional_repositories=(
config.mirror_config.optional_repositories
if config.mirror_config else []
),
mkinitcpio=False,
hostname=config.hostname,
locale_config=config.locale_config,
pacman_config=config.pacman_config,
)
_mask_mkinitcpio_pacman_hooks(ctx)
try:
info("› installing base system (mkinitcpio deferred to configure_protected_boot)")
installer.minimal_installation(
optional_repositories=(
config.mirror_config.optional_repositories
if config.mirror_config else []
),
mkinitcpio=False,
hostname=config.hostname,
locale_config=config.locale_config,
pacman_config=config.pacman_config,
)
if config.mirror_config:
installer.set_mirrors(mirror_handler, config.mirror_config, on_target=True)
if config.mirror_config:
installer.set_mirrors(mirror_handler, config.mirror_config, on_target=True)
if config.swap and config.swap.enabled:
installer.setup_swap(algo=config.swap.algorithm)
if config.swap and config.swap.enabled:
installer.setup_swap(algo=config.swap.algorithm)
info(f"› installing early Omarchy packages: {', '.join(EARLY_PACKAGES)}")
installer.add_additional_packages(EARLY_PACKAGES)
info(f"› installing early Omarchy packages: {', '.join(EARLY_PACKAGES)}")
installer.add_additional_packages(EARLY_PACKAGES)
info("› creating user (with /etc/skel populated)")
if config.auth_config and config.auth_config.users:
installer.create_users(config.auth_config.users)
info("› creating user (with /etc/skel populated)")
if config.auth_config and config.auth_config.users:
installer.create_users(config.auth_config.users)
finally:
_unmask_mkinitcpio_pacman_hooks(ctx)
info("› installing Omarchy runtime + omarchy-base.packages")
installer.add_additional_packages(_runtime_package_list(ctx))
@@ -789,6 +823,30 @@ def _register_efibootmgr_entry(
)
def configure_hibernation(ctx: InstallContext) -> None:
"""Configure swap/resume in the target as root before user finalization.
Hibernation is system boot configuration, not per-user setup. Keep it out
of finalize.sh so the finalizer stays focused on user/session defaults.
The final Limine UKI build still happens later in limine-snapper.sh, after
this writes the resume hook and kernel cmdline drop-in.
"""
setup = ctx.target / "usr" / "bin" / "omarchy-hibernation-setup"
if not setup.exists():
_debug_log(ctx, "skipping hibernation: /usr/bin/omarchy-hibernation-setup is not installed")
return
subprocess.run([
"arch-chroot", str(ctx.target),
"env",
"OMARCHY_INSTALL_MODE=offline",
"OMARCHY_CHROOT_INSTALL=1",
"OMARCHY_PATH=/usr/share/omarchy",
"OMARCHY_INSTALL_LOG_FILE=/var/log/omarchy-install.log",
"/usr/bin/omarchy-hibernation-setup", "--force", "--no-rebuild",
], check=True)
def _install_debug_enabled() -> bool:
return os.environ.get("OMARCHY_INSTALL_DEBUG") == "1" or Path("/usr/share/omarchy-iso/install-debug").exists()