#!/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