build-golden.sh

2.8 KB · raw

1#!/usr/bin/env bash2# Bake the golden NixOS qcow2: boot the minimal ISO headless under qemu, drive a3# scripted nixos-install over the serial console, power off. Output is a golden4# disk image; Kiln (or boot-overlay.sh) boots throwaway overlays from it.5#6# Usage: build-golden.sh <nixos.iso> <nina-linux-binary> <out-golden.qcow2>7# Tunables via env: DISK_GB (20), MEM_MB (4096), SMP (2), INSTALL_TIMEOUT (2400)8set -euo pipefail910ISO="${1:?usage: build-golden.sh <iso> <nina-bin> <out.qcow2>}"11NINA="${2:?need nina linux binary}"12OUT="${3:?need output qcow2 path}"13HERE="$(cd "$(dirname "$0")" && pwd)"14DISK_GB="${DISK_GB:-20}"15MEM_MB="${MEM_MB:-4096}"16SMP="${SMP:-2}"17INSTALL_TIMEOUT="${INSTALL_TIMEOUT:-2400}"1819for f in "$ISO" "$NINA"; do [ -f "$f" ] || { echo "missing: $f" >&2; exit 1; }; done2021work="$(mktemp -d)"22trap 'rm -rf "$work"' EXIT2324# Seed media: our config + install script + nina, as an ISO the installer mounts.25seed="$work/seed"26mkdir -p "$seed"27cp "$HERE/configuration.nix" "$seed/configuration.nix"28cp "$HERE/install.sh" "$seed/install.sh"29cp "$NINA" "$seed/nina"30SEED_ISO="$work/seed.iso"31hdiutil makehybrid -quiet -iso -joliet -default-volume-name NINASEED -o "$SEED_ISO" "$seed"3233# Fresh blank disk for the install target.34qemu-img create -f qcow2 "$OUT" "${DISK_GB}G" >/dev/null35echo "golden target: $OUT (${DISK_GB}G)  ·  seed: $SEED_ISO"3637expect -c '38  set timeout 60039  set iso       [lindex $argv 0]40  set seed_iso  [lindex $argv 1]41  set out       [lindex $argv 2]42  set mem       [lindex $argv 3]43  set smp       [lindex $argv 4]44  set install_timeout [lindex $argv 5]4546  spawn qemu-system-x86_64 \47    -machine q35 -accel tcg -cpu max -smp $smp -m $mem \48    -drive file=$out,if=virtio,format=qcow2 \49    -drive file=$iso,media=cdrom,readonly=on \50    -drive file=$seed_iso,media=cdrom,readonly=on \51    -boot d \52    -netdev user,id=n0 -device virtio-net-pci,netdev=n0 \53    -nographic5455  # Reach an installer root shell (autologin on the ISO serial console).56  expect {57    timeout { puts "\n!! no shell prompt from installer"; exit 2 }58    -re {\[root@nixos[^\]]*\]#} {}59    -re {nixos@nixos} { send "sudo -i\r"; exp_continue }60    -re {login:} { send "root\r"; exp_continue }61  }62  send "\r"63  expect -re {\[root@nixos[^\]]*\]#}6465  # Mount seed media and run the installer script.66  send "mkdir -p /mnt-seed && mount /dev/sr1 /mnt-seed && echo NINA_SEED_OK\r"67  expect {68    timeout { puts "\n!! seed mount failed"; exit 3 }69    "NINA_SEED_OK" {}70  }71  send "bash /mnt-seed/install.sh\r"7273  set timeout $install_timeout74  expect {75    timeout { puts "\n!! install timed out"; exit 4 }76    "NINA_INSTALL_DONE" {}77    "NINA_INSTALL_START" { exp_continue }78  }79  # qemu exits when the guest powers off.80  set timeout 12081  expect eof82' "$ISO" "$SEED_ISO" "$OUT" "$MEM_MB" "$SMP" "$INSTALL_TIMEOUT"8384echo "=== golden image built: $OUT ==="85qemu-img info "$OUT" | sed 's/^/  /'