feat(deploy): add NixOS live USB ISO for ATM hardware testing

Add NixOS configuration to build a bootable live USB ISO that runs the
ATM Electron app in kiosk mode on physical hardware (UpBoard). The ISO
boots from squashfs, auto-starts X11/openbox, and launches Electron in
production mode.

Key changes:
- deploy/nixos/live.nix: Live USB module (squashfs+tmpfs, no disk install)
- deploy/nixos/flake.nix: Nix flake with ISO build output
- deploy/nixos/provision-atm.sh: Auto-provision LP credentials via API
- deploy/nixos/build-iso.sh: End-to-end build workflow script
- apps/machine: Fix Electron production mode (ELECTRON_FORCE_PROD),
  Vue Router hash mode for file:// protocol, relative asset paths

Build: cd deploy/nixos && bash build-iso.sh
Test:  qemu-system-x86_64 -enable-kvm -m 2G -cdrom result/iso/*.iso

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-02-18 20:11:23 -05:00
commit 19d43c2939
13 changed files with 1203 additions and 3 deletions

64
deploy/nixos/build-iso.sh Executable file
View file

@ -0,0 +1,64 @@
#!/usr/bin/env bash
# Build a bootable NixOS Live USB ISO for testing the ATM Electron app
# on physical hardware (UpBoard).
#
# Usage: bash build-iso.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
MACHINE_DIR="$REPO_ROOT/apps/machine"
echo "=== Building Lamassu ATM Live USB ISO ==="
# Step 1: Build the Electron app
echo ""
echo "--- Step 1: Building Electron app ---"
cd "$REPO_ROOT"
pnpm run build --filter=@lamassu/machine
# Step 2: Verify build outputs exist
echo ""
echo "--- Step 2: Verifying build outputs ---"
if [ ! -d "$MACHINE_DIR/dist" ]; then
echo "ERROR: $MACHINE_DIR/dist not found. Build failed?"
exit 1
fi
if [ ! -d "$MACHINE_DIR/dist-electron" ]; then
echo "ERROR: $MACHINE_DIR/dist-electron not found. Build failed?"
exit 1
fi
echo "OK: dist/ and dist-electron/ present"
# Step 3: Build the NixOS ISO
echo ""
echo "--- Step 3: Building NixOS ISO (this takes a while) ---"
cd "$SCRIPT_DIR"
export MACHINE_DIR="$MACHINE_DIR"
nix build .#iso --impure --show-trace
# Step 4: Print results
ISO_PATH=$(ls result/iso/*.iso 2>/dev/null | head -1)
if [ -z "$ISO_PATH" ]; then
echo "ERROR: ISO not found in result/iso/"
exit 1
fi
ISO_SIZE=$(du -h "$ISO_PATH" | cut -f1)
echo ""
echo "=== ISO built successfully ==="
echo "File: $ISO_PATH"
echo "Size: $ISO_SIZE"
echo ""
echo "--- Test in QEMU ---"
echo "qemu-system-x86_64 -enable-kvm -m 2G \\"
echo " -bios /usr/share/edk2-ovmf/OVMF_CODE.fd \\"
echo " -cdrom $ISO_PATH -display gtk"
echo ""
echo "--- Write to USB flash drive ---"
echo "sudo dd if=$ISO_PATH of=/dev/sdX bs=4M status=progress oflag=sync"
echo ""
echo "--- After booting, SSH in and configure ---"
echo "ssh lamassu@<atm-ip>"
echo "sudo nano /var/lib/lamassu-atm/.env"
echo "sudo systemctl restart lamassu-atm"