feat(deploy): run the tejo from USB (disk-image-tejo-usb) #120

Merged
padreug merged 3 commits from feat/tejo-usb into dev 2026-10-06 17:35:43 +00:00

3 commits

Author SHA1 Message Date
6042d69356 fix(deploy): tejo had no WireGuard address, so it had no way back in
`networking.wireguard.interfaces.wg0.ips` was set in hardware/douro.nix
and hardware/batm3.nix, but hardware/upboard.nix is shared by tejo and
sintra — an address there would be claimed by both machines on the same
/24, so neither got one. tejo therefore evaluated to `wg0.ips = [ ]`:
the interface comes up with no IP and the tunnel is silently dead. On a
machine with no other route in, that is how you lose a box.

Replace the two per-hardware definitions with one `wireguardIpForModel`
table in flake.nix, keyed on model like fiatCodeForModel /
upgradeWindowForModel / nfcReaderForModel, and give tejo 10.0.0.3/24 —
the address it answers on today under its factory Debian.

douro (10.0.0.4/24) and batm3 (10.0.0.5/24) evaluate unchanged; sintra
stays deliberately unlisted, since it is reachable on the LAN and has
never had a tunnel address.

The address is only half of it: the VPS maps peer pubkey to tunnel IP,
so the machine still needs /var/lib/wireguard/wg0.key carried over from
its previous install (or a fresh key added to the VPS peer list). Both
wireguard units are ConditionPathExists-guarded on that key, so a
keyless first boot is clean and the tunnel starts once it is dropped in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-06 19:26:14 +02:00
c3e01c9cd3 feat(deploy): USB-bootable tejo image (disk-image-tejo-usb)
The tejo still runs its factory Debian (ubilinux4, kernel 4.9) on
internal storage and has never had bitspire on it. Rather than flash
that drive, give it the run-from-USB shape douro and batm3 already use:
the stick is the system and the internal install is never touched.

- nixosConfigurations.tejo-usb — tejo-installed + usbBootModule +
  usbBusHardening + usbGrubHybridModule. Evaluates identically to
  sintra-usb, which shares hardware/upboard.nix.
- packages.disk-image-tejo-usb — hybrid table, GRUB, BIOS + UEFI.

NOT the efi/systemd-boot shape douro uses. The tejo is the same Aaeon
UP Board as sintra, whose firmware was found to USB-boot in Legacy/BIOS
mode; systemd-boot is UEFI-only, so a dd'd systemd-boot stick would not
be recognised as bootable at all. The hybrid image boots either path, so
it is also the safe choice if the firmware turns out to differ.

README documents both bootloader shapes and which models take which.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-06 19:18:47 +02:00
81a001c3d3 refactor(deploy): one USB-image helper for both bootloader shapes
disk-image-sintra-usb was a 60-line inline copy of everything
mkUsbDiskImage already does, plus the GRUB/hybrid bits the Aaeon
firmware needs — so the two implementations had already drifted: the
sintra image never picked up the `nofail` /boot that keeps a slow
ESP-USB enumeration out of emergency mode, nor the uas/autosuspend
hardening batm3.nix and douro.nix carry.

- mkUsbDiskImage takes named args with `partitionTableType` ("efi" for
  systemd-boot, "hybrid" for GRUB) and `grubBiosDevice`. The ESP relabel
  is layout-independent: the hybrid table creates the ESP first and
  bios_grub second, so it stays partition 1 either way.
- New `usbGrubHybridModule` + `usbBusHardening` modules. The hardening is
  scoped to the -usb configs rather than hardware/upboard.nix, which
  sintra's eMMC install also reads — no cmdline change on a production
  machine.
- `nixosConfigurations.sintra-usb` is now a named config, so a running
  stick can be updated in place (nix copy + switch-to-configuration)
  like batm3-usb and douro-usb.
- grub.devices is "nodev" in the config and mkForce'd to the build VM's
  disk only for the image: an in-place switch on a live stick has no
  /dev/vda, and GRUB's embedded core.img reads grub.cfg off the
  partition, so the MBR stage needs no per-generation rewrite. Plain
  definition rather than mkForce, since two mkForce lists merge into
  [ "/dev/vda" "nodev" ] instead of replacing.

douro-usb and batm3-usb evaluate to byte-identical kernelParams,
blacklistedKernelModules, fileSystems, bootloader and autoUpgrade
config as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-06 19:17:18 +02:00