feat: Debian prep hardening, verify script, and quality pass

- 00-system-prep.sh: bootstrap sudo when run as root; on Debian enable
  contrib/non-free-firmware (SKIP_NONFREE to opt out) + install needrestart
- scripts/verify-debian.sh: non-destructive post-install sanity checker
  (exit 0/1) covering OS, tools, Debian renames, upstream tooling,
  .NET/Podman/Postgres, groups, flatpak, dotfile symlinks
- 01-package-install.sh: auto-detect current Kubernetes minor from upstream
  (fallback v1.36, override K8S_MINOR) instead of stale v1.32 pin
- fix shellcheck findings (SC2155, SC2207, SC2088); all scripts clean at
  warning severity
- docs: fold decisions/status into plan; README lists new tools
This commit is contained in:
Blake Ridgway
2026-09-02 16:32:40 -05:00
parent ae72614636
commit 0817d6a815
6 changed files with 319 additions and 75 deletions

176
scripts/verify-debian.sh Executable file
View File

@@ -0,0 +1,176 @@
#!/bin/bash
# verify-debian.sh
# Non-destructive sanity checks for a freshly set-up Debian 13 machine.
# Verifies the pieces that 00-03 + 04-config-symlinks.sh are expected to leave behind.
# Exit code: 0 = all critical checks passed; 1 = at least one critical check failed.
#
# Usage: bash scripts/verify-debian.sh (no root needed)
# --- output helpers -------------------------------------------------------
if [ -t 1 ]; then
C_GREEN=$'\e[32m'; C_RED=$'\e[31m'; C_YELLOW=$'\e[33m'; C_BOLD=$'\e[1m'; C_OFF=$'\e[0m'
else
C_GREEN=""; C_RED=""; C_YELLOW=""; C_BOLD=""; C_OFF=""
fi
PASS=0
WARN=0
FAIL=0
ok() { PASS=$((PASS+1)); echo "${C_GREEN}${C_OFF} $1"; }
warn() { WARN=$((WARN+1)); echo "${C_YELLOW}${C_OFF} $1"; }
bad() { FAIL=$((FAIL+1)); echo "${C_RED}${C_OFF} $1"; }
# --- helpers --------------------------------------------------------------
check_cmd() { # check_cmd "label" "command-name"
if command -v "$2" &>/dev/null; then ok "$1: found ($(command -v "$2"))"; else bad "$1: NOT FOUND"; fi
}
check_symlink_target() { # check_symlink_target "label" "link-path" "expected-target"
if [ -L "$2" ]; then
local target; target="$(readlink -f "$2")"
if [ "$target" = "$3" ] || [ "$(basename "$target")" = "$(basename "$3")" ]; then
ok "$1: $2 -> $target"
else
warn "$1: $2 points to $target (expected $3)"
fi
else
warn "$1: $2 is not a symlink"
fi
}
check_service() { # check_service "label" "unit"
if systemctl is-active --quiet "$2" 2>/dev/null; then ok "$1: active"; else warn "$1: not active"; fi
}
# --- 1. OS ------------------------------------------------------------------
echo "${C_BOLD}== OS ==${C_OFF}"
. /etc/os-release
echo " distro: $PRETTY_NAME (id=$ID, codename=${VERSION_CODENAME:-unknown})"
if [ "$ID" = "debian" ]; then
ok "Debian detected"
else
warn "Not Debian (id=$ID) - this script targets Debian 13"
fi
# --- 2. Package manager ------------------------------------------------------
echo ""
echo "${C_BOLD}== Package manager ==${C_OFF}"
if command -v apt-get &>/dev/null; then ok "apt present"; else bad "apt missing"; fi
if command -v dpkg-query &>/dev/null; then :; else bad "dpkg missing"; fi
# --- 3. Core packages ---------------------------------------------------------
echo ""
echo "${C_BOLD}== Core tools ==${C_OFF}"
for c in git curl wget jq ripgrep tmux zsh fzf zoxide eza unzip btop direnv tldr socat mtr nmap whois traceroute tcpdump iperf3 httpie ansible virt-manager flatpak python3; do
check_cmd "$c" "$c"
done
# --- 4. Debian binary renames -------------------------------------------------
echo ""
echo "${C_BOLD}== Debian binary renames ==${C_OFF}"
if command -v batcat &>/dev/null; then
check_symlink_target "bat -> batcat" "/usr/local/bin/bat" "/usr/bin/batcat"
elif command -v bat &>/dev/null; then
ok "bat present directly"
else
bad "bat/batcat not found"
fi
if command -v fdfind &>/dev/null; then
check_symlink_target "fd -> fdfind" "/usr/local/bin/fd" "/usr/bin/fdfind"
elif command -v fd &>/dev/null; then
ok "fd present directly"
else
bad "fd/fdfind not found"
fi
if command -v dig &>/dev/null; then ok "dig present"; else bad "dig missing (install bind9-dnsutils)"; fi
# --- 5. Upstream-only tools ----------------------------------------------------
echo ""
echo "${C_BOLD}== Upstream tooling ==${C_OFF}"
for c in gh terraform kubectl k9s minikube; do check_cmd "$c" "$c"; done
# --- 6. Development tools -------------------------------------------------------
echo ""
echo "${C_BOLD}== Development tools ==${C_OFF}"
for c in nvim go rustc cargo oh-my-posh helm kubectx kubens stern dive trivy aws; do check_cmd "$c" "$c"; done
# Go binary path sanity
if command -v go &>/dev/null; then ok "GOPATH=$(go env GOPATH 2>/dev/null)"; fi
# pynvim (PEP 668 note: system pip is externally managed on Debian 13)
if /usr/bin/python3 -m pip show pynvim &>/dev/null; then
ok "pynvim installed for python3"
else
warn "pynvim not found for /usr/bin/python3 (install with --break-system-packages if wanted)"
fi
# --- 7. .NET / backend -----------------------------------------------------------
echo ""
echo "${C_BOLD}== .NET / backend services ==${C_OFF}"
if command -v dotnet &>/dev/null; then
ok "dotnet: $(dotnet --version 2>/dev/null)"
else
bad "dotnet not on PATH (install via 03-dotnet-setup.sh or add ~/.dotnet to PATH)"
fi
check_cmd "podman" "podman"
if command -v docker &>/dev/null; then
ok "docker shim present ($(readlink -f "$(command -v docker)" 2>/dev/null || echo docker))"
else
warn "docker shim missing (install podman-docker)"
fi
if command -v podman-compose &>/dev/null; then ok "podman-compose present"; else warn "podman-compose missing"; fi
check_service "postgresql" "postgresql"
check_service "libvirtd" "libvirtd"
# --- 8. Groups -------------------------------------------------------------------
echo ""
echo "${C_BOLD}== Group membership ==${C_OFF}"
for g in libvirt kvm; do
if id -nG 2>/dev/null | tr ' ' '\n' | grep -qx "$g"; then
ok "in group '$g'"
else
warn "not in group '$g' (needed for virt-manager/KVM; log out/in after usermod)"
fi
done
# --- 9. Flatpak --------------------------------------------------------------------
echo ""
echo "${C_BOLD}== Flatpak ==${C_OFF}"
if command -v flatpak &>/dev/null && flatpak remotes 2>/dev/null | grep -q flathub; then
ok "flathub remote present"
else
warn "flathub remote not configured"
fi
# --- 10. Shell rc symlinks ----------------------------------------------------------
echo ""
echo "${C_BOLD}== Dotfile symlinks ==${C_OFF}"
for d in bashrc zshrc gitconfig aliases.bash aliases.zsh; do
if [ -e "$HOME/.$d" ] || [ -L "$HOME/.$d" ]; then
# shellcheck disable=SC2088
ok "~/.$d linked"
else
# shellcheck disable=SC2088
warn "~/.$d missing"
fi
done
check_symlink_target "oh-my-posh theme" "$HOME/.config/oh-my-posh/theme.omp.json" "theme.omp.json"
check_symlink_target "nvim config" "$HOME/.config/nvim" "nvim"
check_symlink_target "nushell config" "$HOME/.config/nushell" "nushell"
# --- Summary ------------------------------------------------------------------------
echo ""
echo "${C_BOLD}========================================${C_OFF}"
echo "${C_GREEN}${C_OFF} ${PASS} passed ${C_YELLOW}${C_OFF} ${WARN} warnings ${C_RED}${C_OFF} ${FAIL} failed"
echo "${C_BOLD}========================================${C_OFF}"
echo ""
if [ "$FAIL" -gt 0 ]; then
echo "Some critical checks failed. See ✘ items above."
exit 1
else
echo "All critical checks passed. Warnings above are optional/suggested."
exit 0
fi