fix(deploy): multi-model ISO builds and HAL packaging
- Parameterize live.nix by machineModel (douro/tejo) passed via specialArgs - Douro: kernel 5.15 LTS for Bay Trail i915 eDP fix, vt.handoff=7 - Fix HAL packaging: copy dist/ into subdirectory (not flattened) - Add display-reset systemd service for kexec GPU reinitialization - Add --disable-gpu flag for Electron on headless/GPU-less boots - flake.nix: mkLiveConfig helper, per-model ISO outputs (iso-douro/iso-tejo) - build-iso.sh: require model param, write model-specific .env for Vite - flash-douro-usb.sh: GPT+FAT32 ESP layout for Bay Trail UEFI boot Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2605c44ef8
commit
c874d9e2e3
4 changed files with 325 additions and 31 deletions
195
deploy/nixos/flash-douro-usb.sh
Executable file
195
deploy/nixos/flash-douro-usb.sh
Executable file
|
|
@ -0,0 +1,195 @@
|
|||
#!/usr/bin/env bash
|
||||
# Flash a NixOS Live ISO to a USB stick with a proper GPT + FAT32 ESP layout.
|
||||
#
|
||||
# Bay Trail (Douro) UEFI firmware can't boot from raw dd'd ISOs because it
|
||||
# doesn't parse the El Torito EFI boot catalog embedded in ISO9660. This script
|
||||
# creates a standard GPT partition with a FAT32 filesystem containing the
|
||||
# EFI bootloader, kernel, initrd, and NixOS squashfs — which Bay Trail
|
||||
# firmware recognizes natively.
|
||||
#
|
||||
# Usage: sudo bash flash-usb.sh /dev/sdX [path/to/iso]
|
||||
#
|
||||
# If no ISO path is given, uses the most recent build in result/iso/.
|
||||
set -euo pipefail
|
||||
|
||||
USB_DEV="${1:-}"
|
||||
ISO_PATH="${2:-}"
|
||||
|
||||
if [ -z "$USB_DEV" ]; then
|
||||
echo "Usage: sudo bash flash-usb.sh /dev/sdX [path/to/iso]"
|
||||
echo ""
|
||||
echo " /dev/sdX USB device (NOT a partition — e.g. /dev/sdc, not /dev/sdc1)"
|
||||
echo " path/to/iso Optional ISO path (default: result/iso/*.iso)"
|
||||
echo ""
|
||||
echo "WARNING: This will erase ALL data on the target device!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Safety checks
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "ERROR: Must run as root (sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -b "$USB_DEV" ]; then
|
||||
echo "ERROR: $USB_DEV is not a block device"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Don't accidentally wipe a hard drive
|
||||
if echo "$USB_DEV" | grep -qE '^/dev/(sda|nvme|vda)'; then
|
||||
echo "ERROR: $USB_DEV looks like a system drive. Refusing to proceed."
|
||||
echo " Use a removable USB device (e.g. /dev/sdb, /dev/sdc)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find ISO
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ -z "$ISO_PATH" ]; then
|
||||
ISO_PATH=$(ls "$SCRIPT_DIR"/result/iso/*.iso 2>/dev/null | head -1)
|
||||
if [ -z "$ISO_PATH" ]; then
|
||||
echo "ERROR: No ISO found in $SCRIPT_DIR/result/iso/"
|
||||
echo " Build one first: bash build-iso.sh douro"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "$ISO_PATH" ]; then
|
||||
echo "ERROR: ISO not found: $ISO_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ISO_SIZE=$(du -h "$ISO_PATH" | cut -f1)
|
||||
USB_SIZE=$(lsblk -dno SIZE "$USB_DEV" 2>/dev/null || echo "unknown")
|
||||
USB_MODEL=$(lsblk -dno MODEL "$USB_DEV" 2>/dev/null || echo "unknown")
|
||||
|
||||
echo "=== Flash NixOS Live USB ==="
|
||||
echo "ISO: $ISO_PATH ($ISO_SIZE)"
|
||||
echo "Target: $USB_DEV ($USB_SIZE, $USB_MODEL)"
|
||||
echo ""
|
||||
echo "WARNING: ALL data on $USB_DEV will be destroyed!"
|
||||
read -p "Continue? (y/N) " -r
|
||||
if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then
|
||||
echo "Aborted."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Unmount any mounted partitions on the USB
|
||||
echo ""
|
||||
echo "--- Unmounting existing partitions ---"
|
||||
for part in "${USB_DEV}"*; do
|
||||
if mountpoint -q "$part" 2>/dev/null || mount | grep -q "^$part "; then
|
||||
umount "$part" 2>/dev/null || true
|
||||
echo "Unmounted $part"
|
||||
fi
|
||||
done
|
||||
|
||||
# Step 1: Create GPT partition table with a single FAT32 partition
|
||||
echo ""
|
||||
echo "--- Step 1: Creating GPT partition table ---"
|
||||
parted -s "$USB_DEV" mklabel gpt
|
||||
parted -s "$USB_DEV" mkpart ESP fat32 1MiB 100%
|
||||
parted -s "$USB_DEV" set 1 esp on
|
||||
echo "OK: GPT with ESP partition"
|
||||
|
||||
# Wait for kernel to pick up new partition table
|
||||
sleep 2
|
||||
partprobe "$USB_DEV" 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
# Find the partition device (handles both /dev/sdc1 and /dev/nvme0n1p1 styles)
|
||||
PART_DEV="${USB_DEV}1"
|
||||
if [ ! -b "$PART_DEV" ]; then
|
||||
PART_DEV="${USB_DEV}p1"
|
||||
fi
|
||||
if [ ! -b "$PART_DEV" ]; then
|
||||
echo "ERROR: Partition device not found (tried ${USB_DEV}1 and ${USB_DEV}p1)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 2: Format as FAT32
|
||||
# FAT32 volume labels are max 11 chars, so we use a short label.
|
||||
# The kernel finds root by LABEL=nixos-24.05-x86_64 which is on the ISO9660.
|
||||
# But since we're extracting the ISO, we set the label on the FAT32 partition.
|
||||
# NixOS initrd also searches by /nix-store.squashfs file presence.
|
||||
echo ""
|
||||
echo "--- Step 2: Formatting FAT32 ---"
|
||||
mkfs.fat -F32 -n 'NIXOS2405' "$PART_DEV"
|
||||
echo "OK: FAT32 formatted"
|
||||
|
||||
# Step 3: Mount ISO and USB partition
|
||||
echo ""
|
||||
echo "--- Step 3: Mounting ISO and USB ---"
|
||||
MNT_ISO=$(mktemp -d)
|
||||
MNT_USB=$(mktemp -d)
|
||||
mount -o loop,ro "$ISO_PATH" "$MNT_ISO"
|
||||
mount "$PART_DEV" "$MNT_USB"
|
||||
echo "ISO mounted at $MNT_ISO"
|
||||
echo "USB mounted at $MNT_USB"
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo "--- Cleaning up ---"
|
||||
umount "$MNT_USB" 2>/dev/null || true
|
||||
umount "$MNT_ISO" 2>/dev/null || true
|
||||
rmdir "$MNT_ISO" 2>/dev/null || true
|
||||
rmdir "$MNT_USB" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Step 4: Copy EFI boot files (UPPERCASE paths for Bay Trail UEFI compatibility)
|
||||
echo ""
|
||||
echo "--- Step 4: Copying EFI boot files ---"
|
||||
mkdir -p "$MNT_USB/EFI/BOOT"
|
||||
cp "$MNT_ISO/EFI/boot/bootx64.efi" "$MNT_USB/EFI/BOOT/BOOTX64.EFI"
|
||||
cp "$MNT_ISO/EFI/boot/grub.cfg" "$MNT_USB/EFI/BOOT/grub.cfg"
|
||||
cp -r "$MNT_ISO/EFI/boot/grub-theme" "$MNT_USB/EFI/BOOT/grub-theme"
|
||||
cp "$MNT_ISO/EFI/boot/unicode.pf2" "$MNT_USB/EFI/BOOT/unicode.pf2"
|
||||
cp "$MNT_ISO/EFI/boot/efi-background.png" "$MNT_USB/EFI/BOOT/efi-background.png"
|
||||
if [ -f "$MNT_ISO/EFI/boot/refind_x64.efi" ]; then
|
||||
cp "$MNT_ISO/EFI/boot/refind_x64.efi" "$MNT_USB/EFI/BOOT/refind_x64.efi"
|
||||
fi
|
||||
|
||||
# Create the marker file GRUB searches for (search --file /EFI/nixos-installer-image)
|
||||
mkdir -p "$MNT_USB/EFI"
|
||||
touch "$MNT_USB/EFI/nixos-installer-image"
|
||||
echo "OK: EFI boot files copied"
|
||||
|
||||
# Step 5: Copy boot directory (kernel, initrd, grub modules)
|
||||
echo ""
|
||||
echo "--- Step 5: Copying kernel and initrd ---"
|
||||
cp -r "$MNT_ISO/boot" "$MNT_USB/boot"
|
||||
echo "OK: Kernel and initrd copied"
|
||||
|
||||
# Step 6: Fix GRUB config paths (lowercase -> uppercase for our layout)
|
||||
echo ""
|
||||
echo "--- Step 6: Fixing GRUB config paths ---"
|
||||
sed -i 's|/EFI/boot/|/EFI/BOOT/|g' "$MNT_USB/EFI/BOOT/grub.cfg"
|
||||
echo "OK: GRUB paths updated"
|
||||
|
||||
# Step 7: Copy NixOS root filesystem (this is the big one ~2GB)
|
||||
echo ""
|
||||
echo "--- Step 7: Copying NixOS squashfs (this takes a while) ---"
|
||||
cp "$MNT_ISO/nix-store.squashfs" "$MNT_USB/nix-store.squashfs"
|
||||
if [ -f "$MNT_ISO/version.txt" ]; then
|
||||
cp "$MNT_ISO/version.txt" "$MNT_USB/version.txt"
|
||||
fi
|
||||
echo "OK: squashfs copied"
|
||||
|
||||
# Step 8: Sync
|
||||
echo ""
|
||||
echo "--- Step 8: Syncing to disk ---"
|
||||
sync
|
||||
echo "OK: All data written"
|
||||
|
||||
# Cleanup happens via trap
|
||||
echo ""
|
||||
echo "=== USB flash complete ==="
|
||||
echo "Device: $USB_DEV"
|
||||
echo ""
|
||||
echo "Now plug it into the target machine and boot from USB."
|
||||
echo "The GRUB menu should appear with NixOS installer options."
|
||||
echo ""
|
||||
echo "After booting, provision credentials with:"
|
||||
echo " bash provision-atm.sh <atm-ip> 22"
|
||||
Loading…
Add table
Add a link
Reference in a new issue