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:
parent
c8e5bf9ee1
commit
19d43c2939
13 changed files with 1203 additions and 3 deletions
181
deploy/nixos/live.nix
Normal file
181
deploy/nixos/live.nix
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
# Lamassu ATM Live USB Configuration
|
||||
# Bootable ISO for testing on physical hardware (UpBoard) without installing to disk.
|
||||
# Builds with: nix build .#iso
|
||||
#
|
||||
# Does NOT import hardware/upboard.nix (its fileSystems conflict with live boot).
|
||||
# Instead, duplicates only the hardware-relevant kernel modules and GPU config.
|
||||
|
||||
{ config, lib, pkgs, pkgs-unstable, nixpkgs, ... }:
|
||||
|
||||
let
|
||||
# Pre-built Electron app copied into the Nix store.
|
||||
# Build first: pnpm run build --filter=@lamassu/machine
|
||||
# Requires --impure: reads MACHINE_DIR env var to find build artifacts (dist/ is gitignored)
|
||||
machineDir = builtins.getEnv "MACHINE_DIR";
|
||||
atm-app = assert machineDir != ""
|
||||
|| throw "MACHINE_DIR env var must be set (use build-iso.sh or: export MACHINE_DIR=/path/to/apps/machine)";
|
||||
pkgs.runCommand "lamassu-atm-app" { } ''
|
||||
mkdir -p $out
|
||||
cp -r ${builtins.path { path = machineDir + "/dist"; name = "dist"; }} $out/dist
|
||||
cp -r ${builtins.path { path = machineDir + "/dist-electron"; name = "dist-electron"; }} $out/dist-electron
|
||||
cp ${builtins.path { path = machineDir + "/package.json"; name = "package.json"; }} $out/package.json
|
||||
'';
|
||||
|
||||
# .env template with regtest defaults pointing to the dev machine
|
||||
envTemplate = pkgs.writeText "lamassu-atm-env" ''
|
||||
# Lamassu ATM Live USB Configuration
|
||||
# Edit this file and restart: sudo systemctl restart lamassu-atm
|
||||
#
|
||||
# Dev machine LAN address (adjust to your network)
|
||||
VITE_RELAY_URL=ws://192.168.1.190:7777
|
||||
VITE_LIGHTNING_PUB_API_URL=http://192.168.1.190:1776
|
||||
VITE_EXTENSION_API_URL=http://192.168.1.190:1777
|
||||
|
||||
# Lightning.Pub credentials (fill in after boot)
|
||||
VITE_LIGHTNING_PUB_PUBKEY=
|
||||
VITE_ATM_PRIVATE_KEY=
|
||||
VITE_ADMIN_TOKEN=
|
||||
VITE_APP_ID=
|
||||
VITE_APP_TOKEN=
|
||||
VITE_LINKING_TOKEN=
|
||||
|
||||
# Machine configuration
|
||||
VITE_LAMASSU_MACHINE_MODEL=sintra
|
||||
VITE_LAMASSU_FIAT_CODE=USD
|
||||
|
||||
# Hardware (uncomment and set for real hardware)
|
||||
# VITE_LAMASSU_VALIDATOR_DEVICE=/dev/ttyUSB0
|
||||
# VITE_LAMASSU_DISPENSER_DEVICE=/dev/ttyUSB1
|
||||
# VITE_LAMASSU_CASSETTES=
|
||||
|
||||
# Force production mode when running via `electron /path`
|
||||
ELECTRON_FORCE_PROD=1
|
||||
|
||||
# Display
|
||||
DISPLAY=:0
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
# NixOS ISO image builder (nixpkgs path passed via specialArgs from flake.nix)
|
||||
"${nixpkgs}/nixos/modules/installer/cd-dvd/iso-image.nix"
|
||||
"${nixpkgs}/nixos/modules/profiles/all-hardware.nix"
|
||||
|
||||
# Reuse kiosk config (X11, openbox, users, networking)
|
||||
./configuration.nix
|
||||
|
||||
# Reuse ATM systemd service module
|
||||
./lamassu-atm.nix
|
||||
];
|
||||
|
||||
# ISO image settings
|
||||
isoImage = {
|
||||
isoName = "lamassu-atm-live.iso";
|
||||
makeEfiBootable = true;
|
||||
makeBiosBootable = true;
|
||||
squashfsCompression = "zstd -Xcompression-level 6";
|
||||
};
|
||||
|
||||
# No fileSystems override needed — iso-image.nix handles squashfs + tmpfs root.
|
||||
# We don't import hardware/upboard.nix, so there are no conflicting disk mounts.
|
||||
|
||||
# Boot: UpBoard-relevant kernel modules (from hardware/upboard.nix) without disk mounts
|
||||
boot = {
|
||||
initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
"sdhci_pci"
|
||||
"i915"
|
||||
"squashfs"
|
||||
"iso9660"
|
||||
"loop"
|
||||
];
|
||||
|
||||
kernelModules = [
|
||||
"kvm-intel"
|
||||
"i2c-dev"
|
||||
"spi-dev"
|
||||
];
|
||||
|
||||
kernelParams = [
|
||||
"i915.enable_psr=0"
|
||||
"quiet"
|
||||
"splash"
|
||||
];
|
||||
};
|
||||
|
||||
# Intel GPU support (from hardware/upboard.nix)
|
||||
# NB: nixos-24.05 uses hardware.opengl, not hardware.graphics
|
||||
hardware = {
|
||||
opengl = {
|
||||
enable = true;
|
||||
extraPackages = with pkgs; [
|
||||
intel-media-driver
|
||||
vaapiIntel
|
||||
vaapiVdpau
|
||||
libvdpau-va-gl
|
||||
];
|
||||
};
|
||||
enableRedistributableFirmware = true;
|
||||
cpu.intel.updateMicrocode = true;
|
||||
};
|
||||
|
||||
# Performance governor for responsive kiosk
|
||||
powerManagement = {
|
||||
enable = true;
|
||||
cpuFreqGovernor = "performance";
|
||||
};
|
||||
|
||||
# Disable suspend/hibernate
|
||||
systemd.targets = {
|
||||
sleep.enable = false;
|
||||
suspend.enable = false;
|
||||
hibernate.enable = false;
|
||||
hybrid-sleep.enable = false;
|
||||
};
|
||||
|
||||
# Enable the ATM service with live USB paths
|
||||
services.lamassu-atm = {
|
||||
enable = true;
|
||||
appDir = "${atm-app}";
|
||||
};
|
||||
|
||||
# Allow unprivileged user namespaces (Electron sandbox needs this)
|
||||
boot.kernel.sysctl."kernel.unprivileged_userns_clone" = 1;
|
||||
|
||||
# Override the systemd service for live USB environment
|
||||
systemd.services.lamassu-atm = {
|
||||
serviceConfig = {
|
||||
EnvironmentFile = lib.mkForce "/var/lib/lamassu-atm/.env";
|
||||
# Electron needs --no-sandbox in the live/testing environment
|
||||
ExecStart = lib.mkForce "${pkgs-unstable.electron}/bin/electron --no-sandbox --disable-gpu-sandbox ${atm-app}";
|
||||
# Disable all security hardening that conflicts with Electron
|
||||
NoNewPrivileges = lib.mkForce false;
|
||||
ProtectSystem = lib.mkForce false;
|
||||
ProtectHome = lib.mkForce false;
|
||||
PrivateTmp = lib.mkForce false;
|
||||
};
|
||||
};
|
||||
|
||||
# Install the .env template on first boot
|
||||
system.activationScripts.lamassu-env = ''
|
||||
mkdir -p /var/lib/lamassu-atm
|
||||
if [ ! -f /var/lib/lamassu-atm/.env ]; then
|
||||
cp ${envTemplate} /var/lib/lamassu-atm/.env
|
||||
chmod 600 /var/lib/lamassu-atm/.env
|
||||
chown lamassu:lamassu /var/lib/lamassu-atm/.env
|
||||
fi
|
||||
'';
|
||||
|
||||
# Allow SSH with password for initial setup on the live system
|
||||
services.openssh.settings.PasswordAuthentication = lib.mkForce true;
|
||||
|
||||
# Serial port udev rules (from hardware/upboard.nix)
|
||||
services.udev.extraRules = lib.mkAfter ''
|
||||
KERNEL=="ttyS[0-9]*", MODE="0666"
|
||||
KERNEL=="ttyUSB[0-9]*", MODE="0666"
|
||||
KERNEL=="ttyACM[0-9]*", MODE="0666"
|
||||
'';
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue