Files
44r0n7 0265afa054 chore: bootstrap lean sysadmin-chronicles repo
Import the runnable game code, content, docs, scripts, and repo guidance while leaving local agent state, dependency installs, build output, and backup copies out of the published tree.
2026-05-02 11:49:07 -04:00

170 lines
6.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Dependency detection and installation for Sysadmin Chronicles.
# Source this file; do not execute directly.
SC_DISTRO=""
detect_distro() {
if [ -f /etc/arch-release ]; then
SC_DISTRO=arch
elif grep -qi ubuntu /etc/os-release 2>/dev/null; then
SC_DISTRO=ubuntu
elif [ -f /etc/debian_version ]; then
SC_DISTRO=debian
elif [ -f /etc/fedora-release ]; then
SC_DISTRO=fedora
elif grep -qi opensuse /etc/os-release 2>/dev/null; then
SC_DISTRO=opensuse
else
SC_DISTRO=unknown
fi
}
# Per-distro package names for canonical dep names.
# Format: canonical:arch:debian:ubuntu:fedora:opensuse
# Empty field = not applicable / same as above / handled specially.
_SC_DEP_MAP=(
"libvirt:libvirt:libvirt-daemon-system:libvirt-daemon-system:libvirt:libvirt"
"qemu-system:qemu-system-x86:qemu-system-x86:qemu-kvm:qemu-kvm:qemu-kvm"
"qemu-img:qemu-img:qemu-utils:qemu-utils:qemu-img:qemu-tools"
"virt-install:virt-install:virtinst:virtinst:virt-install:virt-install"
"virt-viewer:virt-viewer:virt-viewer:virt-viewer:virt-viewer:virt-viewer"
"cloud-localds:cloud-image-utils:cloud-image-utils:cloud-image-utils:cloud-utils:cloud-utils"
"genisoimage:cdrtools:genisoimage:genisoimage:genisoimage:genisoimage"
"xorriso:libisoburn:xorriso:xorriso:xorriso:xorriso"
"nodejs:nodejs:nodejs:nodejs:nodejs:nodejs"
"openssh:openssh:openssh-client:openssh-client:openssh-clients:openssh-clients"
)
# Arch-only QEMU SPICE/display extras installed alongside qemu-system
_SC_ARCH_QEMU_EXTRAS=(
qemu-hw-display-qxl
qemu-hw-display-virtio-gpu
qemu-ui-spice-core
qemu-chardev-spice
qemu-audio-spice
)
map_package() {
local dep="$1"
local distro="${2:-$SC_DISTRO}"
local entry
for entry in "${_SC_DEP_MAP[@]}"; do
IFS=':' read -r name arch debian ubuntu fedora opensuse <<< "$entry"
if [ "$name" = "$dep" ]; then
case "$distro" in
arch) printf '%s' "$arch" ;;
debian) printf '%s' "$debian" ;;
ubuntu) printf '%s' "$ubuntu" ;;
fedora) printf '%s' "$fedora" ;;
opensuse) printf '%s' "$opensuse" ;;
esac
return
fi
done
}
# Outputs canonical dep names that are not yet installed (one per line)
check_deps() {
local missing=()
command -v virsh >/dev/null 2>&1 || missing+=(libvirt)
command -v qemu-system-x86_64 >/dev/null 2>&1 || missing+=(qemu-system)
command -v qemu-img >/dev/null 2>&1 || missing+=(qemu-img)
command -v virt-install >/dev/null 2>&1 || missing+=(virt-install)
command -v remote-viewer >/dev/null 2>&1 || missing+=(virt-viewer)
command -v node >/dev/null 2>&1 || missing+=(nodejs)
command -v ssh >/dev/null 2>&1 || missing+=(openssh)
# Need at least one cloud-init ISO tool
if ! command -v cloud-localds >/dev/null 2>&1 \
&& ! command -v genisoimage >/dev/null 2>&1 \
&& ! command -v mkisofs >/dev/null 2>&1 \
&& ! command -v xorriso >/dev/null 2>&1; then
missing+=(cloud-localds genisoimage xorriso)
fi
[ "${#missing[@]}" -gt 0 ] && printf '%s\n' "${missing[@]}" || true
}
# Install a list of canonical dep names. Logs to SC_INSTALL_LOG if set.
install_deps() {
local deps=("$@")
local pkgs=()
for dep in "${deps[@]}"; do
local pkg
pkg="$(map_package "$dep")"
[ -n "$pkg" ] && pkgs+=("$pkg")
done
if [ "$SC_DISTRO" = "arch" ]; then
pkgs+=("${_SC_ARCH_QEMU_EXTRAS[@]}")
fi
[ "${#pkgs[@]}" -eq 0 ] && return 0
local -a pm_cmd
case "$SC_DISTRO" in
arch) pm_cmd=(pacman -S --noconfirm --needed) ;;
debian|ubuntu) pm_cmd=(apt-get install -y) ;;
fedora) pm_cmd=(dnf install -y) ;;
opensuse) pm_cmd=(zypper install -y) ;;
*)
echo " Unsupported distro '$SC_DISTRO' — install these manually:"
printf ' %s\n' "${pkgs[@]}"
return 1
;;
esac
sudo "${pm_cmd[@]}" "${pkgs[@]}"
if [ -n "${SC_INSTALL_LOG:-}" ] && [ "$SC_INSTALL_LOG" != "/dev/null" ]; then
mkdir -p "$(dirname "$SC_INSTALL_LOG")"
local distro_label="$SC_DISTRO"
for pkg in "${pkgs[@]}"; do
local ver=""
case "$SC_DISTRO" in
arch) ver="$(pacman -Q "$pkg" 2>/dev/null | awk '{print $2}' || true)" ;;
debian|ubuntu) ver="$(dpkg -l "$pkg" 2>/dev/null | awk '/^ii/{print $3}' | head -1 || true)" ;;
fedora) ver="$(rpm -q --queryformat '%{VERSION}' "$pkg" 2>/dev/null || true)" ;;
esac
printf '[INSTALLED] %-36s %-14s via %s\n' "$pkg" "${ver:-}" "$distro_label" \
>> "$SC_INSTALL_LOG"
done
fi
}
# Outputs already-installed canonical deps (for log completeness)
log_present_deps() {
local log_file="${SC_INSTALL_LOG:-}"
[ -z "$log_file" ] || [ "$log_file" = "/dev/null" ] && return
local distro_label="$SC_DISTRO"
for dep in libvirt qemu-system qemu-img virt-install virt-viewer nodejs openssh; do
local bin
case "$dep" in
libvirt) bin=virsh ;;
qemu-system) bin=qemu-system-x86_64 ;;
qemu-img) bin=qemu-img ;;
virt-install) bin=virt-install ;;
virt-viewer) bin=remote-viewer ;;
nodejs) bin=node ;;
openssh) bin=ssh ;;
esac
if command -v "$bin" >/dev/null 2>&1; then
printf '[SKIPPED] %-36s already installed\n' "$dep" >> "$log_file"
fi
done
}
dep_label() {
case "$1" in
libvirt) echo "Virtual machine manager (libvirt)" ;;
qemu-system) echo "KVM virtualization support (QEMU)" ;;
qemu-img) echo "VM disk image tools (qemu-img)" ;;
virt-install) echo "VM installer (virt-install)" ;;
virt-viewer) echo "SPICE display viewer (virt-viewer)" ;;
cloud-localds|genisoimage|xorriso) echo "Cloud image tools" ;;
nodejs) echo "Node.js runtime" ;;
openssh) echo "SSH client" ;;
*) echo "$1" ;;
esac
}