magicciv/scripts/dev-setup/bluefin.sh
Natalie 6cd36704f7 feat(@projects/@magic-civilization): add audio & sprite rendering capabilities
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-17 12:00:30 -07:00

164 lines
6.2 KiB
Bash
Executable file

#!/usr/bin/env bash
# Bluefin / rpm-ostree / bootc dev-environment setup for Magic Civilization
#
# Installs the Linux-host packages that this project's tooling needs
# but that are NOT in the base ublue/bluefin image:
#
# - weston — Wayland compositor used by the headless
# Godot screenshot pipeline + Phase Gate proof
# scenes (runs flatpak Godot inside a weston
# session so viewport capture produces real
# pixels instead of the dummy-driver null).
# - vulkan-tools — vulkaninfo / vkcube; diagnostic binaries for
# probing the installed Vulkan stack.
# - mesa-vulkan-drivers — always present on ublue; redeclared here so
# this script is a complete dev-deps manifest.
#
# Idempotent: re-running is a no-op once packages are installed. Uses
# `rpm-ostree install --apply-live` so the packages are usable in the
# current boot without waiting for reboot. PERSISTENCE across reboots
# comes from layering in the bootc image
# (`~/Code/bootc-bluefin/containerfiles/Containerfile.desktop-core`);
# this script runs the transient install for fast iteration.
#
# Usage:
# ./run setup:bluefin # install missing packages
# ./run setup:bluefin --check # exit 0 if all present, 1 otherwise
#
# Safe to run as your normal user — internally escalates with `sudo -n`
# for the one rpm-ostree call. If passwordless sudo is not configured,
# you'll be prompted for a password once.
set -uo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
DIM='\033[2m'
NC='\033[0m'
REQUIRED_PACKAGES=(
weston
vulkan-tools
mesa-vulkan-drivers
)
CHECK_ONLY=false
for arg in "$@"; do
case "$arg" in
--check) CHECK_ONLY=true ;;
--help|-h)
echo "Usage: $0 [--check]"
echo " (no args) Install missing packages via rpm-ostree --apply-live"
echo " --check Exit 0 if all packages are installed, 1 otherwise"
exit 0
;;
*) echo "Unknown argument: $arg"; exit 2 ;;
esac
done
# ── Preconditions ────────────────────────────────────────────────────
if ! command -v rpm-ostree &>/dev/null; then
echo -e "${RED}This script targets bootc / rpm-ostree systems (Bluefin, Silverblue, Kinoite).${NC}"
echo -e "${DIM}For plain Fedora/CentOS use: sudo dnf install ${REQUIRED_PACKAGES[*]}${NC}"
exit 2
fi
# ── Inventory which packages are missing ────────────────────────────
missing=()
present=()
for pkg in "${REQUIRED_PACKAGES[@]}"; do
if rpm -q "$pkg" &>/dev/null; then
present+=("$pkg")
else
missing+=("$pkg")
fi
done
echo -e "${BLUE}Magic Civilization — Bluefin dev-setup${NC}"
echo -e "${DIM}required: ${REQUIRED_PACKAGES[*]}${NC}"
if [ ${#present[@]} -gt 0 ]; then
echo -e " ${GREEN}present${NC} ${present[*]}"
fi
if [ ${#missing[@]} -eq 0 ]; then
echo -e " ${GREEN}all required packages already installed — nothing to do${NC}"
exit 0
fi
echo -e " ${YELLOW}missing${NC} ${missing[*]}"
if [ "$CHECK_ONLY" = "true" ]; then
echo -e "${YELLOW}--check mode: ${#missing[@]} package(s) missing${NC}"
exit 1
fi
# ── Install missing via rpm-ostree --apply-live ─────────────────────
# Use --allow-inactive so rpm-ostree accepts the "already requested but
# not applied" state from a prior partial run and just applies live this
# time. --apply-live makes the current boot see the new binaries without
# reboot; the same packages still need to be added to
# ~/Code/bootc-bluefin/containerfiles/Containerfile.desktop-core for
# persistence across the next bootc image rebuild.
echo ""
echo -e "${BLUE}Installing missing packages (rpm-ostree --apply-live)…${NC}"
echo -e "${DIM}This requires sudo — you may be prompted once.${NC}"
echo ""
if sudo -n true 2>/dev/null; then
SUDO="sudo"
else
SUDO="sudo" # will prompt interactively
fi
# `rpm-ostree install` refuses if the package is "already requested" in a
# previous partial run that didn't finish apply-live. Handle both cases.
for pkg in "${missing[@]}"; do
if rpm-ostree status --json 2>/dev/null | grep -q "\"$pkg\""; then
echo -e " ${DIM}$pkg already staged — apply-live will pick it up${NC}"
fi
done
set +e
$SUDO rpm-ostree install --apply-live --assumeyes --allow-inactive "${missing[@]}"
rc=$?
set -e
if [ $rc -ne 0 ]; then
# Common case: an earlier install --apply-live failed the live step but
# DID stage a deployment. Try `apply-live` on its own.
echo -e "${YELLOW}rpm-ostree install returned $rc; attempting apply-live on the staged deployment…${NC}"
set +e
$SUDO rpm-ostree apply-live --allow-replacement
rc=$?
set -e
fi
# ── Verify ───────────────────────────────────────────────────────────
echo ""
echo -e "${BLUE}Post-install verification${NC}"
fail_count=0
for pkg in "${REQUIRED_PACKAGES[@]}"; do
if rpm -q "$pkg" &>/dev/null; then
echo -e " ${GREEN}installed${NC} $pkg"
else
echo -e " ${RED}MISSING${NC} $pkg"
fail_count=$((fail_count + 1))
fi
done
if [ $fail_count -gt 0 ]; then
echo ""
echo -e "${RED}$fail_count package(s) still missing — re-run or debug rpm-ostree manually.${NC}"
exit 1
fi
# ── Remind user about persistence ────────────────────────────────────
echo ""
echo -e "${GREEN}All required packages installed (live in current boot).${NC}"
echo ""
echo -e "${YELLOW}Persistence note:${NC}"
echo -e " Transient --apply-live installs are wiped on reboot."
echo -e " To persist, add ${REQUIRED_PACKAGES[*]} to your bootc image"
echo -e " layer — typically at:"
echo -e " ${DIM}~/Code/bootc-bluefin/containerfiles/Containerfile.desktop-core${NC}"
echo -e " Rebuild + redeploy via ${DIM}~/Code/bootc-bluefin/rebuild-with-parser.sh${NC}"
echo -e " (or equivalent build.sh / deploy.sh)."