deploy: automate a full local reinstall, self-elevating and interactive-safe
./scripts/deploy install <config> localhost now branches on is_live_installer() (checks uname -n): outside a live installer it builds installer-iso, stages its kernel/initrd on the ESP and the iso file on a disk the caller picks (never auto-picked — the wrong disk here is destroyed mid-install), writes a systemd-boot one-shot findiso= entry with homelab.install=<config> on the kernel cmdline, and does a real systemctl reboot (not kexec — terra's kexec-local hang is specifically in kexec's device-shutdown pass, a real ACPI reboot never runs that code at all). installer-iso gains homelab-auto-install.service: once homelab-checkout.service clones the repo, it reads homelab.install= back off /proc/cmdline and re-runs the identical deploy command itself, now genuinely inside the installer, so it takes the disko+nixos-install branch instead of preparing again. The whole reinstall is one command and unattended after the first reboot. Also: every root-requiring path (kexec-local, the new prepare-and-reboot branch, the disko+nixos-install branch) self-elevates via a require_root() helper that re-execs the original invocation under sudo -E, instead of dying and asking the caller to prefix sudo themselves. Uses an absolute script path captured before the script's own cd, so the re-exec is correct regardless of how it was invoked. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -84,14 +84,15 @@ an installer, partitions via disko, installs.
|
||||
Manual alternative (USB ISO): boot installer, `disko` the disk, then
|
||||
`nixos-install --flake .#jupiter`.
|
||||
|
||||
## First install on terra — USB installer (replacing CachyOS)
|
||||
## First install on terra — no-USB findiso reinstall (replacing CachyOS)
|
||||
|
||||
terra is a Ryzen 9 5900X / Radeon RX 6800 XT desktop, currently running
|
||||
CachyOS. Everything is already prepped in this repo: real OS-disk id in
|
||||
`disk-config.nix`, real login pubkey in `common.nix`, terra's age recipient in
|
||||
`.sops.yaml`, its host key pre-generated at `~/.config/homelab/terra/`, and
|
||||
`secrets/terra.yaml` already holds real `darman_password` / `tailscale_authkey`
|
||||
values. Nothing to fill in — just run it.
|
||||
CachyOS with a writable root and systemd-boot. Everything is already prepped
|
||||
in this repo: real OS-disk id in `disk-config.nix`, real login pubkey in
|
||||
`common.nix`, terra's age recipient in `.sops.yaml`, its host key
|
||||
pre-generated at `~/.config/homelab/terra/`, and `secrets/terra.yaml` already
|
||||
holds real `darman_password` / `tailscale_authkey` values. Nothing to fill
|
||||
in — just run it.
|
||||
|
||||
> ⚠️ **`./scripts/deploy kexec-local` does NOT work on terra — do not use it.**
|
||||
> Confirmed on real hardware: the jump hangs completely (kexec's own
|
||||
@@ -101,10 +102,9 @@ values. Nothing to fill in — just run it.
|
||||
> a slow jump). Near-certainly amdgpu: discrete AMD GPUs are known to hang
|
||||
> during kexec's device-shutdown pass with no clean way to hand control back
|
||||
> before the jump — same class of issue as jupiter's `reboot=pci` warm-reboot
|
||||
> workaround, just fatal here instead of merely slow. Untried mitigations
|
||||
> (unbind/`rmmod amdgpu` from a bare VT first, kernel params) might work but
|
||||
> aren't worth the risk of repeating a hard hang on a daily-driver box for a
|
||||
> one-time install — use the USB path below instead.
|
||||
> workaround, just fatal here instead of merely slow. The path below instead
|
||||
> triggers a real ACPI reboot through firmware POST — a materially different
|
||||
> code path that never runs kexec's device-shutdown pass at all.
|
||||
|
||||
> ⚠️ The OS disk (`ata-KINGSTON_SA400S37480G_50026B738072F6C6`) is WIPED. The
|
||||
> dev-data disks (`/mnt/hdd_01` ext4, `/mnt/ssd_01` LVM) and the leftover ntfs
|
||||
@@ -112,32 +112,37 @@ values. Nothing to fill in — just run it.
|
||||
> `lsblk -o NAME,SERIAL,SIZE,MODEL` before proceeding if the box's disks have
|
||||
> changed since `disk-config.nix` was written.
|
||||
|
||||
1. Build the installer ISO and write it to a USB stick (from your laptop —
|
||||
this only needs to be done once; the ISO clones current `master` fresh on
|
||||
every boot, so the same stick stays useful indefinitely):
|
||||
```
|
||||
nix build .#nixosConfigurations.installer-iso.config.system.build.isoImage
|
||||
sudo dd if=result/iso/*.iso of=/dev/sdX bs=4M status=progress conv=fsync
|
||||
```
|
||||
2. Boot terra from the USB stick. It comes up with sshd + DHCP + your laptop
|
||||
pubkey authorized for root, hostname `homelab-installer`, and a
|
||||
`homelab-checkout.service` that clones the (public) repo to
|
||||
`/root/homelab` once network is up. If you ssh in before that finishes,
|
||||
`systemctl status homelab-checkout` tells you; retry with
|
||||
`systemctl restart homelab-checkout` if DHCP was still coming up at boot.
|
||||
3. SSH in (or use the physical console) and run the install directly:
|
||||
```
|
||||
cd /root/homelab
|
||||
./scripts/deploy install terra localhost
|
||||
```
|
||||
`localhost`/`127.0.0.1` skips nixos-anywhere/ssh and runs disko +
|
||||
`nixos-install` directly against `/mnt`. Ships terra's pre-generated host
|
||||
key so `/run/secrets/*` decrypts on boot #1.
|
||||
4. Reboot into NixOS (remove the USB stick first). Then, same as any other
|
||||
host:
|
||||
```
|
||||
ssh darman@terra sudo -v # DO NOT SKIP — see below
|
||||
```
|
||||
One command does the whole thing — no need to `sudo` it yourself, it
|
||||
self-elevates:
|
||||
```
|
||||
./scripts/deploy install terra localhost
|
||||
```
|
||||
`scripts/deploy` detects it isn't already inside a live installer (checks
|
||||
`uname -n`) and instead: builds `installer-iso`'s kernel + initrd + iso image,
|
||||
asks where to stage the iso file (never auto-picks — the wrong disk here is
|
||||
destroyed mid-install; `HOMELAB_INSTALLER_STAGE_DIR` skips the prompt for
|
||||
scripted use), refuses if that resolves to the same disk `disk-config.nix` is
|
||||
about to wipe, copies the kernel/initrd to the ESP, writes a systemd-boot
|
||||
**one-shot** entry (`bootctl set-oneshot` — reverts to the normal default
|
||||
after this one boot, even if it fails) with `findiso=` + `homelab.install=terra`
|
||||
on its kernel cmdline, and reboots — a real `systemctl reboot`, not kexec.
|
||||
|
||||
The booted installer clones the repo (`homelab-checkout.service`, needs
|
||||
network — it's public now, no credentials involved) and then
|
||||
`homelab-auto-install.service` reads `homelab.install=terra` back off
|
||||
`/proc/cmdline` and re-runs the exact same `./scripts/deploy install terra
|
||||
localhost` itself — now genuinely inside the installer, so it takes the
|
||||
disko + `nixos-install` branch instead of preparing again. Ships terra's
|
||||
pre-generated host key first so `/run/secrets/*` decrypts on boot #1. The
|
||||
whole thing is unattended after the initial reboot; ssh into
|
||||
`homelab-installer` (same pubkey as the ISO everywhere else) to watch
|
||||
progress — `journalctl -u homelab-checkout -u homelab-auto-install -f`.
|
||||
|
||||
When it's done, reboot again into the freshly installed NixOS. Then, same as
|
||||
any other host:
|
||||
```
|
||||
ssh darman@terra sudo -v # DO NOT SKIP — see below
|
||||
```
|
||||
|
||||
`darman` is created with `mutableUsers = true`, so `/etc/shadow` is written
|
||||
**once**. If the sops secret wasn't readable at that moment the account gets
|
||||
|
||||
Reference in New Issue
Block a user