Files
main-desktop/scripts/firstboot.sh
T
ckochandClaude Opus 5 4739fb5e0d Add an unattended-install ISO builder
Boot the stick, pick one GRUB entry, walk away: it wipes the target disk, installs Ubuntu
26.04.1 with the NVIDIA driver and codecs, and runs setup.sh on first boot to install the
apps. build-iso.sh does the image surgery in a container, so the build machine needs nothing
but podman.

The wipe is pinned to one disk serial (the 990 PRO). The Data drive can't match it, and an
unmatched disk stops the install rather than guessing — so the stick can't eat another
machine either. The autoinstall entry is not the GRUB default, so an accidental boot lands in
the ordinary Ubuntu installer.

Verified by running the install in a VM with two virtual NVMe drives carrying the real
serials: unattended start to finish, target partitioned and installed, Data disk byte-for-byte
identical, and late-commands left /opt/main-desktop plus the enabled first-boot service in
place. Testing caught the autoinstall args landing after '---' (where they reach the installed
system instead of the installer, and do nothing), and the first-boot run adding root rather
than ckoch to the docker group, since runuser leaves $USER alone.

setup.sh gains an unattended mode for that first-boot run, waits out the dpkg lock that
Ubuntu's own boot-time upgrades hold, waits for snapd to finish seeding before removing the
Firefox snap, and skips the driver step on machines with no NVIDIA card.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-24 10:01:09 -04:00

39 lines
1.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Runs once, on the first boot after an install from the ISO. Runs setup.sh as the
# desktop user, then takes back the passwordless sudo the installer granted for it.
# Log: /var/log/main-desktop-firstboot.log (and the journal).
set -uo pipefail
LOG=/var/log/main-desktop-firstboot.log
SUDOERS=/etc/sudoers.d/99-main-desktop-firstboot
STAMP=/var/lib/main-desktop-firstboot.done
# Whatever the installer called the account it made — uid 1000 is the desktop user.
USER_NAME=$(id -nu 1000 2>/dev/null || true)
cleanup() {
rm -f "$SUDOERS" # never leave passwordless sudo lying around, pass or fail
systemctl disable main-desktop-firstboot.service >/dev/null 2>&1 || true
: > "$STAMP"
}
trap cleanup EXIT
exec > >(tee -a "$LOG") 2>&1
echo "=== main-desktop first boot: $(date -Is) ==="
if [[ -z $USER_NAME ]]; then
echo "no uid 1000 user found — run /opt/main-desktop/scripts/setup.sh by hand"
exit 1
fi
echo "running setup.sh as $USER_NAME"
if runuser -u "$USER_NAME" -- env HOME="/home/$USER_NAME" UNATTENDED=1 \
bash /opt/main-desktop/scripts/setup.sh; then
echo "=== setup.sh finished $(date -Is) ==="
echo "Log out and back in to pick up the docker and kvm groups."
else
echo "=== setup.sh FAILED (see above) $(date -Is) ==="
echo "Fix whatever it complained about, then re-run it by hand (it's safe to re-run):"
echo " /opt/main-desktop/scripts/setup.sh"
fi