From 260edc13c58d8349ea10a324fe5786f122505f2c Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Thu, 21 May 2026 20:08:29 -0400 Subject: [PATCH] orchestrator: tear down protected-mode mounts and LUKS mapper on failure --- .../usr/share/omarchy-iso/orchestrator/main.py | 6 +++++- .../omarchy-iso/orchestrator/phases_impl.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/configs/airootfs/usr/share/omarchy-iso/orchestrator/main.py b/configs/airootfs/usr/share/omarchy-iso/orchestrator/main.py index a1135ea..da605a8 100644 --- a/configs/airootfs/usr/share/omarchy-iso/orchestrator/main.py +++ b/configs/airootfs/usr/share/omarchy-iso/orchestrator/main.py @@ -72,11 +72,13 @@ def main() -> int: info(f"Installing Omarchy for {ctx.username} → {ctx.target}") - from .phases_impl import cleanup_bind_mounts + from .phases_impl import cleanup_bind_mounts, cleanup_protected_state + success = False try: try: run(ctx, build_phases(ctx)) + success = True except PhaseError: error("Installation halted.") return 1 @@ -88,6 +90,8 @@ def main() -> int: return 0 finally: cleanup_bind_mounts(ctx) + if not success: + cleanup_protected_state(ctx) if __name__ == "__main__": diff --git a/configs/airootfs/usr/share/omarchy-iso/orchestrator/phases_impl.py b/configs/airootfs/usr/share/omarchy-iso/orchestrator/phases_impl.py index e6ac966..d4b675a 100644 --- a/configs/airootfs/usr/share/omarchy-iso/orchestrator/phases_impl.py +++ b/configs/airootfs/usr/share/omarchy-iso/orchestrator/phases_impl.py @@ -862,6 +862,24 @@ def cleanup_bind_mounts(ctx: InstallContext) -> None: ctx.state["bind_mounts"] = [] +def cleanup_protected_state(ctx: InstallContext) -> None: + """Tear down protected-mode mounts and LUKS mapper after a failed install. + + Idempotent and safe to call multiple times. Successful protected installs + intentionally keep the target mounted until reboot. + """ + if not ctx.is_protected: + return + + subprocess.run(["umount", "-R", str(ctx.target)], check=False, capture_output=True) + if Path("/dev/mapper/omarchy_root").exists(): + subprocess.run( + ["cryptsetup", "close", "omarchy_root"], + check=False, + capture_output=True, + ) + + # ───────────────────────────────────────────────────────────────────────────── # finish: prompt for reboot. Bind mounts are unwound in main()'s finally. # ─────────────────────────────────────────────────────────────────────────────