Panama learns what a server is: from a root login to running containers
A machine's role is now the interview's first question and the one answer Panama records. Servers get the same shell minus the screen: core packages, nvm, Bun, Claude Code and Codex (desktops get Codex too), linger, rootless ports from 80, firewalld, the nginx-bridge network, and a nightly image updater that replaced watchtower for cause. server/containers/ carries junior's 23 compose services -- secrets moved to per-machine .env files that never enter this public repo, every transformed compose proven to render byte-identical to what is live. 'panama server' enables, disables and relinks them; nothing here restarts a running service. 'boot --server' walks a fresh VPS from its root login to a normal install. Five new contracts pin the secrets rule, the catalog's shape, panama-server's behavior, the role plumbing, and the dotfile classification. Claude-Session: https://claude.ai/code/session_01NU5JGiN3JfzqrLQB6wmJ1E
This commit is contained in:
+53
-14
@@ -42,6 +42,24 @@ yes_no() { gum confirm --default=false "$1"; }
|
||||
# ── Machine ──────────────────────────────────────────────────────────────────
|
||||
|
||||
heading "This machine"
|
||||
|
||||
# The role decides most of what follows: a server is never asked about NVIDIA
|
||||
# drivers or Steam, and a desktop is never asked about compose services. It is
|
||||
# also the one answer that outlives the run -- install records it durably,
|
||||
# because `panama update` asks nothing and still has to know which machine it
|
||||
# is updating. See setup/lib/machine-role.
|
||||
#
|
||||
# PANAMA_ROLE_PRESET is how `./install --server` answers this without a prompt,
|
||||
# for the curl-onto-a-fresh-VPS path where the caller already said what the
|
||||
# machine is. An empty or escaped choice falls back to desktop, which is what
|
||||
# every Panama machine was before roles existed.
|
||||
role="${PANAMA_ROLE_PRESET:-}"
|
||||
if [[ -z "$role" ]]; then
|
||||
role="$(gum choose --header "What is this machine?" "desktop" "server")" || role=""
|
||||
fi
|
||||
[[ "$role" == server ]] || role=desktop
|
||||
record PANAMA_ROLE "$role"
|
||||
|
||||
current_hostname="$(hostname)"
|
||||
printf 'Current hostname: %s\n' "$current_hostname"
|
||||
new_hostname=""
|
||||
@@ -94,11 +112,23 @@ record PANAMA_SSH_KEY "$ssh_key"
|
||||
# machine rather than an answer to a hypothetical. A machine with no NVIDIA card
|
||||
# is never asked about drivers, and one with nothing to remove is never asked
|
||||
# about removing it.
|
||||
|
||||
heading "Hardware"
|
||||
#
|
||||
# A server is asked none of it. The stages these answers feed --
|
||||
# install-hardware, the debloat removal -- do not run on the server path at
|
||||
# all, and a question whose answer nothing consumes is a control that lies.
|
||||
# The defaults are still recorded so the answers file has the same shape
|
||||
# either way.
|
||||
|
||||
nvidia=no
|
||||
mok_hash=""
|
||||
installed=()
|
||||
firmware=no
|
||||
debloat=no
|
||||
|
||||
if [[ "$role" != server ]]; then
|
||||
|
||||
heading "Hardware"
|
||||
|
||||
nvidia_card="$(lspci 2>/dev/null | grep -iE 'vga compatible|3d controller' | grep -i nvidia | sed 's/.*: //' | head -1)"
|
||||
|
||||
if [[ -n "$nvidia_card" ]]; then
|
||||
@@ -139,13 +169,9 @@ if [[ -n "$nvidia_card" ]]; then
|
||||
else
|
||||
printf 'No NVIDIA card found.\n'
|
||||
fi
|
||||
record PANAMA_NVIDIA "$nvidia"
|
||||
record PANAMA_MOK_HASH "$mok_hash"
|
||||
|
||||
# The stage that removes them owns the list, so there is one copy of it.
|
||||
debloat=no
|
||||
mapfile -t removable < <("$(dirname "${BASH_SOURCE[0]}")/install-hardware" --debloat-list)
|
||||
installed=()
|
||||
for package in "${removable[@]}"; do
|
||||
rpm -q "$package" >/dev/null 2>&1 && installed+=("$package")
|
||||
done
|
||||
@@ -154,14 +180,18 @@ if (( ${#installed[@]} > 0 )); then
|
||||
debloat=yes
|
||||
fi
|
||||
fi
|
||||
record PANAMA_DEBLOAT "$debloat"
|
||||
|
||||
firmware=no
|
||||
if command -v fwupdmgr >/dev/null 2>&1; then
|
||||
if yes_no "Update firmware with fwupdmgr?"; then
|
||||
firmware=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
fi # role != server
|
||||
|
||||
record PANAMA_NVIDIA "$nvidia"
|
||||
record PANAMA_MOK_HASH "$mok_hash"
|
||||
record PANAMA_DEBLOAT "$debloat"
|
||||
record PANAMA_FIRMWARE "$firmware"
|
||||
|
||||
# ── Applications ─────────────────────────────────────────────────────────────
|
||||
@@ -175,10 +205,12 @@ record PANAMA_FIRMWARE "$firmware"
|
||||
# applications nobody chose, on a machine whose owner answered a question they
|
||||
# thought was about something else.
|
||||
|
||||
extras=""
|
||||
if [[ "$role" != server ]]; then
|
||||
|
||||
heading "Applications"
|
||||
|
||||
extras_dir="$(dirname "${BASH_SOURCE[0]}")/../packages/extras"
|
||||
extras=""
|
||||
if [[ -d "$extras_dir" ]]; then
|
||||
mapfile -t categories < <(for file in "$extras_dir"/*; do
|
||||
[[ -f "$file" ]] && basename "$file"
|
||||
@@ -189,6 +221,8 @@ if [[ -d "$extras_dir" ]]; then
|
||||
extras="${extras% }"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi # role != server
|
||||
record PANAMA_EXTRAS "$extras"
|
||||
|
||||
# ── Personal content ─────────────────────────────────────────────────────────
|
||||
@@ -227,17 +261,22 @@ shown() { [[ -n "$1" ]] && printf '%s' "$1" || printf 'unchanged'; }
|
||||
|
||||
heading "Ready"
|
||||
gum style --border rounded --padding "0 1" "$(
|
||||
printf 'Role %s\n' "$role"
|
||||
printf 'Hostname %s\n' "${new_hostname:-"$current_hostname (unchanged)"}"
|
||||
printf 'Git name %s\n' "$(shown "$git_name")"
|
||||
printf 'Git email %s\n' "$(shown "$git_email")"
|
||||
printf 'Git editor %s\n' "$(shown "$git_editor")"
|
||||
printf 'GitHub %s\n' "$([[ "$gh_login" == yes ]] && echo "sign in" || echo "no change")"
|
||||
printf 'SSH key %s\n' "$([[ "$ssh_key" == yes ]] && echo "generate" || echo "no change")"
|
||||
printf 'NVIDIA %s\n' "$([[ "$nvidia" == yes ]] && echo "install driver" || echo "no")"
|
||||
printf 'Secure Boot %s\n' "$([[ -n "$mok_hash" ]] && echo "enroll a key" || echo "no change")"
|
||||
printf 'Fedora apps %s\n' "$([[ "$debloat" == yes ]] && echo "remove ${installed[*]}" || echo "keep")"
|
||||
printf 'Firmware %s\n' "$([[ "$firmware" == yes ]] && echo "update" || echo "no")"
|
||||
printf 'Extras %s\n' "${extras:-none}"
|
||||
# Hardware and extras were never asked on a server, and a summary line for
|
||||
# a question that was not asked reads as a decision that was not made.
|
||||
if [[ "$role" != server ]]; then
|
||||
printf 'NVIDIA %s\n' "$([[ "$nvidia" == yes ]] && echo "install driver" || echo "no")"
|
||||
printf 'Secure Boot %s\n' "$([[ -n "$mok_hash" ]] && echo "enroll a key" || echo "no change")"
|
||||
printf 'Fedora apps %s\n' "$([[ "$debloat" == yes ]] && echo "remove ${installed[*]}" || echo "keep")"
|
||||
printf 'Firmware %s\n' "$([[ "$firmware" == yes ]] && echo "update" || echo "no")"
|
||||
printf 'Extras %s\n' "${extras:-none}"
|
||||
fi
|
||||
printf 'Personal %s' "$([[ "$user_content" == yes ]] && echo "link user/ into home" || echo "not linked")"
|
||||
)"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user