Skip to content

Full Install aborts when the target disk already holds a LUKS partition #137

Description

@mp-c0de

What happened

I chose Full Install / erase the entire disk onto /dev/sda, an internal drive holding an older Linux install with a LUKS-encrypted partition:

sda
├─sda1
└─sda2  crypto_LUKS      <- previous install
sdb
├─sdb1  OMARCHY_202608   <- installer USB
└─sdb2  ARCHISO_EFI

The install failed during Installing Arch + Omarchy. Archinstall raised a SysCallError when

/usr/bin/wipefs --all /dev/sda2

exited 1, and the installer offered to drop to a shell.

From that shell I ran wipefs -a /dev/sda — the whole disk rather than the partition — which cleared the GPT/PMBR and left /dev/sda completely empty. I rebooted the same USB, ran the same Full Install against the same disk, and it completed with no other change.

Environment: ISO label OMARCHY_202608, older Dell laptop, UEFI, AHCI, target /dev/sda, installer USB /dev/sdb.

Why it happens

The full-disk cleanup never clears any on-disk signatures, so the previous install's LUKS header reaches archinstall intact.

orchestrator/phases_impl.py:180-185 runs the cleanup phase:

disk = _install_disk(ctx)
if disk:
    info(f"› cleaning up holders on install disk: {disk}")
    subprocess.run(["omarchy-iso-cleanup-disk", disk], check=True)

omarchy-iso-cleanup-disk unmounts, swapoffs, deactivates LVM, closes open crypt mappings, then blockdev --flushbufs / partprobe / udevadm settle. Every one of those releases a holder; none removes anything written on the disk. A LUKS header on an unopened partition is not a holder, so nothing in the cleanup touches it.

Control then passes to arch.perform_filesystem_operations(), and archinstall's own per-partition wipefs --all becomes the first command to touch that stale header. When it fails, the install is already mid-run and aborts.

So "Full Install = wipe the entire disk" is never actually carried out by Omarchy's own code — it is delegated to archinstall's per-partition wipe, which is the fragile path. The manual wipefs -a /dev/sda works precisely because it addresses the whole disk instead.

Reproduction

Verified on a loop-backed disk (Debian, util-linux 2.38.1, cryptsetup 2.6.1), building the same shape — GPT, a vfat p1, and a LUKS2 p2 — then running the shipped script against it:

--- running omarchy-iso-cleanup-disk (current quattro) ---
   Cleaning up existing holders on install disk: /dev/loop0
--- signatures remaining on the whole disk ---
   loop0  0x200      gpt
   loop0  0x1ffffe00 gpt
   loop0  0x1fe      PMBR
--- signatures remaining on /dev/loop0p2 ---
   loop0p2 0x0    crypto_LUKS 94aa1812-b41d-4c95-9385-6cd2dec6824d
   loop0p2 0x4000 crypto_LUKS 94aa1812-b41d-4c95-9385-6cd2dec6824d

The cleanup completes successfully and the disk is entirely unchanged — both LUKS headers and the whole partition table survive a run whose stated job is to prepare the disk for wiping.

Expected

A user who has explicitly authorised erasing the whole disk should not have to know about /dev/sda vs /dev/sdb, GPT/PMBR metadata, LUKS signatures, lsblk, wipefs, or a root shell. Being told to run wipefs -a by hand is also the most dangerous moment in the whole flow: naming the wrong device there erases the installer USB or a second data disk. The installer already knows exactly which disk the user picked.

Suggested fix

Clear the signatures in omarchy-iso-cleanup-disk itself, after the existing holder-release loops: wipefs -af each partition, then wipefs -af the disk. No new dependency — wipefs is util-linux and demonstrably present, since archinstall's own call to it is what fails.

The script is already double-gated to exactly this case: the orchestrator skips it entirely when ctx.is_protected, and _install_disk() returns a device only when its modification carries wipe: true. Dual-boot, protected and pre-mounted installs never reach it.

PR follows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions