164 lines
6.2 KiB
Bash
Executable file
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)."
|