#!/usr/bin/env bash # # Builds the amd64 headless audio-endpoint ISO (mini PC + USB DAC/amp) with # live-build — the same tool tools/build-thin-client-iso.sh # drives, reused here rather than a new toolchain, per # hosts/audio-endpoint/README.md's reasoning. Unlike that image, this one has # no graphical/kiosk stack at all: it boots straight to multi-user.target with # the shared spotify-connect.service running. # # One build per room: unlike the arm64 image (one generic .img, per-room # identity set later via Raspberry Pi Imager), there is no equivalent # post-build customisation tool for a generic x86 ISO, so IMAGE_HOSTNAME below # is baked in at build time — same convention as the thin client's own # THINCLIENT_NAME/IMAGE_HOSTNAME. Re-run this script once per room, changing set -euo pipefail # --------------------------------------------------------------------------- # CONFIGURATION — comes from CoreSystemConfig.json, NOT from this file. # # Rooms are entries in the config's "audio_endpoints" list, so adding a second one is # adding a list entry rather than editing and re-running this script with a different # hostname — which is how per-room images drifted apart before. # # sudo -E tools/build-audio-endpoint-iso-amd64.sh # the only amd64 endpoint # sudo -E tools/build-audio-endpoint-iso-amd64.sh # a specific one # --------------------------------------------------------------------------- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=lib/coreconfig.sh source "${SCRIPT_DIR}/lib/coreconfig.sh" core_select_audio_endpoint amd64 "${1:-}" DEBIAN_RELEASE="$CORE_DEBIAN_RELEASE" IMAGE_HOSTNAME="$CORE_AUDIO_HOSTNAME" # also the Spotify Connect device name # --------------------------------------------------------------------------- # Paths — this script now lives in tools/, so the host directory it drives is # addressed from the repo root rather than relative to the script. # --------------------------------------------------------------------------- AUDIO_ENDPOINT_DIR="${CORE_REPO_ROOT}/hosts/audio-endpoint" SHARED_CONFIGS_DIR="$AUDIO_ENDPOINT_DIR/configs" LIVE_BUILD_DIR="${AUDIO_ENDPOINT_DIR}/live-build-amd64" INCLUDES="${LIVE_BUILD_DIR}/config/includes.chroot" PACKAGE_LIST="${LIVE_BUILD_DIR}/config/package-lists/audio-endpoint.list.chroot" # --------------------------------------------------------------------------- # Sanity checks # --------------------------------------------------------------------------- if [[ $EUID -ne 0 ]]; then echo "Warning: not running as root. 'lb build' needs root to bootstrap and chroot," echo " and will fail partway through. Re-run with: sudo $0" fi if ! command -v lb &> /dev/null; then if [[ $EUID -eq 0 ]]; then echo "--- Installing live-build ---" apt-get update apt-get install -y live-build else echo "live-build is not installed and this script is not running as root." >&2 echo " Install it first: sudo apt-get install live-build" >&2 exit 1 fi fi if [[ ! -f "$PACKAGE_LIST" ]]; then echo "Missing package list: $PACKAGE_LIST" >&2 exit 1 fi for f in spotify-connect.service spotify-connect-start; do if [[ ! -f "$SHARED_CONFIGS_DIR/$f" ]]; then echo "Missing $SHARED_CONFIGS_DIR/$f — is this script running from a full checkout?" >&2 exit 1 fi done # --------------------------------------------------------------------------- # 1. Regenerate includes.chroot from the shared configs/ # --------------------------------------------------------------------------- echo "--- Regenerating $INCLUDES ---" rm -rf "$INCLUDES" install -d \ "$INCLUDES/etc/systemd/system" \ "$INCLUDES/usr/local/bin" install -m 0644 "${SHARED_CONFIGS_DIR}/spotify-connect.service" \ "$INCLUDES/etc/systemd/system/spotify-connect.service" install -m 0755 "${SHARED_CONFIGS_DIR}/spotify-connect-start" \ "$INCLUDES/usr/local/bin/spotify-connect-start" # --------------------------------------------------------------------------- # 2. lb config # --------------------------------------------------------------------------- cd "$LIVE_BUILD_DIR" chmod +x config/hooks/normal/*.hook.chroot if [[ -e .build ]]; then echo "--- Previous build found, running 'lb clean' (package cache is kept) ---" lb clean fi echo "--- Running lb config ---" # live-build auto-discovers config/package-lists/*.list.chroot and # config/hooks/normal/*.hook.chroot; there is no flag to point at them # individually — same convention as hosts/thin-client's own build script. lb config \ --distribution "$DEBIAN_RELEASE" \ --architectures amd64 \ --linux-flavours amd64 \ --archive-areas "main contrib non-free-firmware" \ --binary-images iso-hybrid \ --debian-installer none \ --iso-application "SmartestHome Audio Endpoint" \ --iso-publisher "SmartestHome" \ --iso-volume "smarthome-audio-endpoint" \ --memtest none \ --bootappend-live "boot=live components quiet hostname=${IMAGE_HOSTNAME}" # --------------------------------------------------------------------------- # 3. lb build # --------------------------------------------------------------------------- echo "--- Running lb build (this takes a while and needs network) ---" lb build ISO_PATH="$(find "$LIVE_BUILD_DIR" -maxdepth 1 -name '*.iso' -print -quit)" ISO_PATH="${ISO_PATH:-${LIVE_BUILD_DIR}/live-image-amd64.hybrid.iso}" echo echo "=== Done ===" echo "ISO written to:" echo " ${ISO_PATH}" echo echo "What's in it:" echo " Hostname / Spotify Connect device name: ${IMAGE_HOSTNAME}" echo " No graphical stack — boots straight to multi-user.target" echo " spotify-connect.service — see hosts/audio-endpoint/README.md" echo echo "Next steps:" echo " 1. Write the ISO to a USB stick (dd, Rufus, Balena Etcher, whatever you" echo " normally use) and leave it live-booting from that stick, same as the" echo " thin client — this image does not install itself to disk." echo " 2. Attach the USB DAC/amp and passive speakers, connect Ethernet or" echo " configure Wi-Fi via nmtui after first boot (no display attached, so" echo " do this over SSH — openssh-server is enabled)." echo " 3. First boot checklist (see README.md for the full unverified list):" echo " systemctl status spotify-connect" echo " aplay -l # find the USB DAC's card index — see README's amd64 section" echo " # confirm '${IMAGE_HOSTNAME}' shows up as a Spotify Connect device" echo " 4. Building for another room? Edit IMAGE_HOSTNAME at the top of this" echo " script and re-run — each room needs its own build."