From b2099c7d489ff19d031c6dbb504771f36dd72e0b Mon Sep 17 00:00:00 2001 From: Padreug Date: Mon, 29 Jun 2026 23:47:31 +0200 Subject: [PATCH] fix(deploy): make the live ISO boot cleanly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fresh live boots hit a cascade of activation/unit failures because live.nix shared installed-system config that assumes persistent state: - bitspire-env chowned /var/lib/bitspire/.env to bitspire:bitspire in the default activation order, before `users` runs, so on a fresh boot (no .env yet) it failed with 'invalid user'. Move to the attrset form with deps=["users"]. (Installed systems skip the block since .env exists.) - swapDevices=/var/swapfile lives in the live tmpfs and fails to init — replace with zramSwap for the low-RAM models' OOM cushion. - wg0 needs a provisioned key the live boot lacks; it failed and dragged network-setup down. Drop the interface on live. - display-reset runs `xrandr --output eDP-1`, but the Sintra drives HDMI-1 (no eDP-1) — gate the service off for sintra. Co-Authored-By: Claude Opus 4.8 --- deploy/nixos/live.nix | 49 ++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/deploy/nixos/live.nix b/deploy/nixos/live.nix index 00baabc..7f0a190 100644 --- a/deploy/nixos/live.nix +++ b/deploy/nixos/live.nix @@ -172,19 +172,29 @@ in }; }; - # Install the .env on first boot - system.activationScripts.bitspire-env = '' - mkdir -p /var/lib/bitspire - if [ ! -f /var/lib/bitspire/.env ]; then - cp ${envTemplate} /var/lib/bitspire/.env - chmod 600 /var/lib/bitspire/.env - chown bitspire:bitspire /var/lib/bitspire/.env - fi - ''; + # Install the .env on first boot. Attrset form with deps=["users"] so the + # chown runs AFTER the bitspire user is created. Otherwise on a fresh live + # boot (where /var/lib/bitspire/.env doesn't exist yet) the chown runs in the + # default activation order — before `users` — and fails with + # "chown: invalid user: 'bitspire:bitspire'". The installed system skips this + # block because its .env already exists, which is why only live boots tripped. + system.activationScripts.bitspire-env = { + deps = [ "users" ]; + text = '' + mkdir -p /var/lib/bitspire + if [ ! -f /var/lib/bitspire/.env ]; then + cp ${envTemplate} /var/lib/bitspire/.env + chmod 600 /var/lib/bitspire/.env + chown bitspire:bitspire /var/lib/bitspire/.env + fi + ''; + }; # Reset display output after X starts (required for kexec boots where - # the GPU wasn't reinitialized by BIOS firmware) - systemd.services.display-reset = { + # the GPU wasn't reinitialized by BIOS firmware). Only the eDP-panel models + # (Douro/Tejo) have an eDP-1 output; the Sintra drives HDMI-1, so the + # `xrandr --output eDP-1` here just errors out — skip it there. + systemd.services.display-reset = lib.mkIf (machineModel != "sintra") { description = "Reset eDP display output"; after = [ "display-manager.service" ]; requires = [ "display-manager.service" ]; @@ -198,12 +208,17 @@ in }; }; - # Swap file — Douro/Tejo have only 2GB RAM; without swap the system - # hard-freezes under memory pressure instead of gracefully OOM-killing. - swapDevices = [{ - device = "/var/swapfile"; - size = 1024; # MB - }]; + # Low-RAM models (Douro/Tejo, 2GB) need a swap cushion or they hard-freeze + # under memory pressure. The live system is RAM-rooted, so a /var/swapfile + # lives in tmpfs — pointless, and its init fails on a fresh boot. Use + # compressed RAM swap (zram) instead; no on-disk file required. + zramSwap.enable = true; + + # The wg0 VPN tunnel (declared in configuration.nix) needs a provisioned key + # at /var/lib/wireguard/wg0.key, which a fresh live boot doesn't have — it + # fails and drags network-setup down with it. A live test image doesn't need + # the VPN, so drop the interface entirely. + networking.wireguard.interfaces = lib.mkForce { }; # Clean /tmp on boot to prevent stale Nix build artifacts from filling disk boot.tmp.cleanOnBoot = true;