0265afa054
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.
180 lines
6.2 KiB
Bash
180 lines
6.2 KiB
Bash
#!/usr/bin/env bash
|
|
# check-host.sh — Sysadmin Chronicles host prerequisite checker
|
|
#
|
|
# Run this before first-run-setup.sh to see what's missing.
|
|
# Safe to run any number of times — read-only checks only.
|
|
#
|
|
# Exit code 0 = all required dependencies present.
|
|
# Exit code 1 = one or more required dependencies missing.
|
|
|
|
set -euo pipefail
|
|
|
|
OWNER_USER="${SUDO_USER:-$USER}"
|
|
OWNER_HOME="$(getent passwd "$OWNER_USER" | cut -d: -f6)"
|
|
OWNER_HOME="${OWNER_HOME:-$HOME}"
|
|
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
|
|
|
PASS="✓"
|
|
FAIL="✗"
|
|
WARN="⚠"
|
|
|
|
errors=0
|
|
warnings=0
|
|
|
|
run_virsh_quick() {
|
|
timeout 5 virsh "$@" >/dev/null 2>&1
|
|
}
|
|
|
|
check_cmd() {
|
|
local cmd="$1"
|
|
local label="${2:-$cmd}"
|
|
if command -v "$cmd" &>/dev/null; then
|
|
echo " $PASS $label"
|
|
else
|
|
echo " $FAIL $label — NOT FOUND"
|
|
((errors+=1))
|
|
fi
|
|
}
|
|
|
|
check_file() {
|
|
local path="$1"
|
|
local label="$2"
|
|
local required="${3:-true}"
|
|
if [ -e "$path" ]; then
|
|
echo " $PASS $label ($path)"
|
|
else
|
|
if [ "$required" = "true" ]; then
|
|
echo " $FAIL $label — NOT FOUND ($path)"
|
|
((errors+=1))
|
|
else
|
|
echo " $WARN $label — not found ($path) [optional]"
|
|
((warnings+=1))
|
|
fi
|
|
fi
|
|
}
|
|
|
|
check_group() {
|
|
local group="$1"
|
|
if id -nG "$OWNER_USER" | grep -qw "$group"; then
|
|
echo " $PASS User is in group: $group"
|
|
else
|
|
echo " $WARN Not in group '$group' — libvirt access may require sudo or group add"
|
|
((warnings+=1))
|
|
fi
|
|
}
|
|
|
|
check_kvm_access() {
|
|
if id -nG "$OWNER_USER" | grep -qw kvm; then
|
|
echo " $PASS User is in group: kvm"
|
|
elif [ -r /dev/kvm ] && [ -w /dev/kvm ]; then
|
|
echo " $PASS /dev/kvm is accessible to this session"
|
|
else
|
|
echo " $WARN Not in group 'kvm' — KVM acceleration may require sudo or group add"
|
|
((warnings+=1))
|
|
fi
|
|
}
|
|
|
|
libvirt_ready=false
|
|
socket_ready=false
|
|
|
|
if run_virsh_quick -q list --all; then
|
|
libvirt_ready=true
|
|
fi
|
|
|
|
if systemctl is-active --quiet libvirtd.socket 2>/dev/null || \
|
|
systemctl is-active --quiet virtqemud.socket 2>/dev/null; then
|
|
socket_ready=true
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
echo ""
|
|
echo "══════════════════════════════════════════════════"
|
|
echo " Sysadmin Chronicles — Host Prerequisite Check"
|
|
echo "══════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
echo "── Virtualization ─────────────────────────────────"
|
|
check_file "/dev/kvm" "KVM device node"
|
|
check_cmd "virsh" "virsh (libvirt CLI)"
|
|
check_cmd "qemu-system-x86_64" "QEMU (x86_64)"
|
|
|
|
# libvirt runtime
|
|
if [ "$libvirt_ready" = "true" ]; then
|
|
echo " $PASS libvirt responds to virsh"
|
|
elif [ "$socket_ready" = "true" ]; then
|
|
echo " $WARN libvirt socket activation is available, but this user cannot reach $LIBVIRT_DEFAULT_URI"
|
|
echo " Add yourself to the libvirt group or use sudo for setup."
|
|
((warnings+=1))
|
|
else
|
|
echo " $FAIL libvirt is not reachable — start socket activation or the daemon"
|
|
echo " Example: sudo systemctl enable --now libvirtd.socket"
|
|
((errors+=1))
|
|
fi
|
|
|
|
check_group "libvirt"
|
|
check_kvm_access
|
|
|
|
echo ""
|
|
echo "── Storage ────────────────────────────────────────"
|
|
check_cmd "qemu-img" "qemu-img (disk image tool)"
|
|
# Storage pool exists check
|
|
if run_virsh_quick pool-info sc-images; then
|
|
echo " $PASS sc-images storage pool exists"
|
|
else
|
|
echo " $WARN sc-images storage pool not yet created (run first-run-setup.sh)"
|
|
((warnings+=1))
|
|
fi
|
|
|
|
echo ""
|
|
echo "── Networking ─────────────────────────────────────"
|
|
if run_virsh_quick net-info sc-internal; then
|
|
echo " $PASS sc-internal network exists"
|
|
if timeout 5 virsh net-dumpxml sc-internal 2>/dev/null | grep -q "<forward mode=['\"]nat['\"]"; then
|
|
echo " $PASS sc-internal has NAT egress for VM provisioning"
|
|
else
|
|
echo " $WARN sc-internal is missing NAT egress — rebuilds may fail package installation"
|
|
echo " Run: sudo bash tools/setup/first-run-setup.sh"
|
|
((warnings+=1))
|
|
fi
|
|
else
|
|
echo " $WARN sc-internal network not yet created (run first-run-setup.sh)"
|
|
((warnings+=1))
|
|
fi
|
|
|
|
echo ""
|
|
echo "── SSH Keys ───────────────────────────────────────"
|
|
check_file "$OWNER_HOME/.ssh/sc_host_key" "Host→Guest SSH key" "false"
|
|
check_file "$OWNER_HOME/.ssh/sc_host_key.pub" "Host→Guest SSH public key" "false"
|
|
|
|
echo ""
|
|
echo "── Runtime Tools ──────────────────────────────────"
|
|
check_cmd "ssh" "ssh"
|
|
check_cmd "node" "node (Node.js, for content validation)"
|
|
check_cmd "godot" "godot (Godot 4 engine binary)" || true # warn only
|
|
|
|
echo ""
|
|
echo "── VM Images ──────────────────────────────────────"
|
|
for vm in sc-workstation sc-web-server sc-build-machine; do
|
|
if run_virsh_quick dominfo "$vm"; then
|
|
echo " $PASS Domain exists: $vm"
|
|
else
|
|
echo " $WARN Domain not yet created: $vm (run seed-vms.sh)"
|
|
((warnings+=1))
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "══════════════════════════════════════════════════"
|
|
if [ "$errors" -eq 0 ] && [ "$warnings" -eq 0 ]; then
|
|
echo " ✅ All checks passed. Ready to play."
|
|
elif [ "$errors" -eq 0 ]; then
|
|
echo " ⚠ $warnings warning(s). Run first-run-setup.sh if this is a fresh install."
|
|
else
|
|
echo " ❌ $errors error(s), $warnings warning(s). Run first-run-setup.sh to resolve."
|
|
fi
|
|
echo "══════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
exit $([ "$errors" -eq 0 ] && echo 0 || echo 1)
|