feat(install): idempotent per-host package installer with host-gated enablement

This commit is contained in:
Frank
2026-09-10 19:42:57 -07:00
parent a30cd771f3
commit 779b65af8c
5 changed files with 167 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env bash
# install.sh — idempotent fleet package installer for the ~/.omp repo deployment.
#
# Model: packages/*.pkgs declare DESIRED state per host. This script computes
# (desired − installed) and installs only that delta via pacman/yay. It NEVER
# removes anything. Re-running after a fresh install, or casually months later,
# is safe by construction.
#
# Modes:
# install.sh check (default): print the plan for this host, write nothing
# install.sh --apply install the delta + run host-gated enablement actions
#
# Host selection: --host <name> overrides $(hostname); an unknown host gets the
# common manifest only — wrong-host runs are a no-op, not a hazard.
#
# Sudo: set FRANK_SUDO_PW in the environment for non-interactive runs;
# otherwise sudo prompts normally. The value is never stored in this repo.
set -euo pipefail
REPO="$(git -C "$(dirname "$(realpath "$0")")" rev-parse --show-toplevel 2>/dev/null || true)"
REPO="${INSTALL_REPO:-$REPO}"
[ -n "$REPO" ] && [ -d "$REPO/packages" ] || { echo "install.sh: no packages/ under ${REPO:-<repo>}" >&2; exit 1; }
MODE="check"
HOST="$(hostname)"
while [[ $# -gt 0 ]]; do
case "$1" in
--apply) MODE="apply"; shift ;;
--host) HOST="$2"; shift 2 ;;
*) echo "usage: install.sh [--apply] [--host <name>]" >&2; exit 2 ;;
esac
done
SUDO() {
if [[ -n "${FRANK_SUDO_PW:-}" ]]; then printf '%s' "$FRANK_SUDO_PW" | sudo -S -p '' "$@"
else sudo "$@"; fi
}
read_manifest() { # $1 = manifest path; emits package names, strips comments/blanks
sed 's/#.*//' "$1" | tr -d '\r' | awk 'NF'
}
# ---- desired-minus-installed delta ------------------------------------------
PKGS=()
for m in common.pkgs "$HOST.pkgs"; do
[[ -f "$REPO/packages/$m" ]] || continue
mapfile -t _pkgs < <(read_manifest "$REPO/packages/$m")
PKGS+=("${_pkgs[@]}")
done
# AUR phase only when the helper exists or can be bootstrapped from a repo pkg
AUR_PKGS=()
if [[ -f "$REPO/packages/aur.pkgs" ]]; then
mapfile -t AUR_PKGS < <(read_manifest "$REPO/packages/aur.pkgs")
fi
mapfile -t INSTALLED < <(pacman -Qq | sort)
DELTAC=()
for p in "${PKGS[@]}"; do
printf '%s\n' "${INSTALLED[@]}" | grep -qx -- "$p" || DELTAC+=("$p")
done
echo "install.sh [$MODE] host=$HOST"
if [[ ${#DELTAC[@]} -eq 0 ]]; then
echo "repo pkgs: delta empty — nothing to install"
else
echo "repo pkgs to install: ${DELTAC[*]}"
fi
for p in "${AUR_PKGS[@]}"; do
printf '%s\n' "${INSTALLED[@]}" | grep -qx -- "$p" || echo "aur pkg pending: $p"
done
[[ "$MODE" == "check" ]] && exit 0
# ---- apply ------------------------------------------------------------------
if [[ ${#DELTAC[@]} -gt 0 ]]; then
SUDO pacman -S --needed --noconfirm -- "${DELTAC[@]}"
fi
# Helper bootstrap: yay itself ships in the cachyos repo (no chicken-and-egg).
if [[ ${#AUR_PKGS[@]} -gt 0 ]] && ! pacman -Qq yay >/dev/null 2>&1; then
SUDO pacman -S --needed --noconfirm -- yay
fi
for p in "${AUR_PKGS[@]}"; do
printf '%s\n' "${INSTALLED[@]}" | grep -qx -- "$p" || {
YAYFLAGS="--answerclean None --answerdiff None" SUDO yay -S --needed --noconfirm -- "$p"
}
done
# ---- host-gated enablement ---------------------------------------------------
case "$HOST" in
dankware)
# nvidia sleep fix: package hooks already ship /usr/lib/modprobe.d/nvidia-sleep.conf
# (UseKernelSuspendNotifiers=1 + TemporaryFilePath); enable the units idempotently.
SUDO systemctl enable --now nvidia-suspend nvidia-resume 2>/dev/null || true
;;
blankpad)
# Cezanne iGPU: amdgpu is in-kernel, amd-ucode carried by kernel pkg; no module options.
:
;;
esac
# sshd + firewall — same posture on both hosts (decision 2026-09: ssh open in default zone)
if command -v sshd >/dev/null 2>&1 || pacman -Qq openssh >/dev/null 2>&1; then
SUDO systemctl enable --now sshd
fi
if command -v firewall-cmd >/dev/null 2>&1 && firewall-cmd --state >/dev/null 2>&1; then
if ! firewall-cmd --query-service ssh >/dev/null 2>&1; then
SUDO firewall-cmd --permanent --zone=public --add-service=ssh
SUDO firewall-cmd --reload
fi
fi
echo "install.sh [$MODE] host=$HOST done"