nixos-install builds with --store /mnt and passes its own substituter as
"auto?trusted=1", which in that context resolves to the target store
itself — so nothing flowed from the ISO and nix fell back to a
full-source bootstrap (gcc/python/bash tarball fetches → offline death).
Host-store simulation (fresh local?root, substituters cleared) proves
"daemon?trusted=1" makes the whole install substitute + build offline:
1125 paths copied, only the per-machine config drvs built locally.
Also drop --offline from the chroot HM build (that flag disables ALL
substituters; plain empty substituters does what we want without it).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`nix flake archive --to` rejects locally-evaluated source paths ("lacks
a signature by a trusted key"); enumerate the archive tree as JSON and
copy with --no-check-sigs instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Offline nixos-install still built from source: the drvs that embed the
user's hostname/username/UUIDs (etc, initrd, toplevel, HM activation)
must be REBUILT, and their builders need tools outside every runtime
closure (etc → python3-minimal, initrd → packing tools). Pin each drv's
inputDerivation into the ISO — the standard nixos-test offline trick.
Also: with no network every substituter query is a DNS retry storm that
ends in a nix goal.cc assertion crash (core dump observed); the installer
now probes connectivity and disables substituters when offline, both on
the live system and inside the nixos-enter HM pre-activation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Found by running the unattended install in an offline QEMU VM:
- compgen is missing from nixpkgs' non-interactive bash (the package
shebang) — replaced with plain glob tests in hardware-db and prewipe
- disko's eval resolves <nixpkgs> via NIX_PATH (a dead channel on the
ISO) and tried channels.nixos.org — export NIX_PATH to the pinned
nixpkgs source and point the flake registry at an empty baked file
- lock nomarchy by path (the source the ISO carries) instead of
git+https: git inputs clone even when narHash is known, which kills
offline installs; `original` keeps the forge URL so a later
`nix flake update` re-resolves normally. Works from dirty-tree ISOs too.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- LUKS2 is the installer default; in exchange the generated config sets
the new nomarchy.system.greeter.autoLogin (greetd initial_session) —
the disk passphrase already gates the machine.
- @snapshots subvolume + nomarchy.system.snapper.enable: hourly/daily
timeline snapshots of / and the nixos-rebuild-snap helper, ported from
the previous iteration (3bdfc35), guarded to no-op on non-BTRFS roots.
- @swap subvolume with a swapfile sized to RAM by default (disko
mkswapfile handles NOCOW); the installer computes the resume offset
and wires boot.resumeDevice + resume_offset for hibernation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ported from the previous iteration's installer (3bdfc35), adapted to the
mkFlake world. gum TUI: disk pick, optional LUKS2, user/hostname/timezone,
DMI → nixos-hardware autodetection (hardware-db.sh). disko partitions
GPT + 1 GiB ESP + BTRFS subvolumes; the generated machine flake lands at
~user/.nomarchy (one mkFlake call, /etc/nixos symlinks to it) and
nixos-install makes it bootable (UEFI/systemd-boot, v1 single disk).
Offline by construction: the target flake.lock is composed from the rev
the ISO was built from (compose-lock.py), `nix flake archive` seeds the
target store, and the ISO pre-builds the template system + desktop.
First boot lands themed: the HM generation is pre-activated in chroot.
mkFlake grows two things for this: hardwareProfile now also takes a list
(autodetection emits several common-* modules), and installed systems get
the standalone home-manager CLI from the pinned input. Unattended mode
(NOMARCHY_UNATTENDED=1 + env) documented in docs/TESTING.md §4.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>