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:
+70
-42
@@ -20,6 +20,13 @@ CONFIG="$HOME/.config"
|
||||
# every symlink below fail silently while the stage still reported success.
|
||||
mkdir -p "$PANAMA_OLD" "$CONFIG"
|
||||
|
||||
# Which machine this is. A server links the shell environment -- bash, vim,
|
||||
# the universal dirs below, the tmux and btop theming, the hook samples --
|
||||
# and then stops: everything after the early exit assumes a screen.
|
||||
# shellcheck source=../lib/machine-role
|
||||
source "$PANAMA_PATH/setup/lib/machine-role"
|
||||
ROLE="$(panama_role)"
|
||||
|
||||
# --- Bashrc ---
|
||||
echo -e "\n--- Replacing .bashrc ---"
|
||||
# Backup existing .bashrc if it's a regular file
|
||||
@@ -45,8 +52,21 @@ ln -s "$PANAMA_BASH/.bashrc" "$HOME/.bashrc"
|
||||
#
|
||||
# gnome-control-center is a separate matter and stays declared: Panama's own
|
||||
# Settings hands off to it for the panels it deliberately does not own.
|
||||
dirs=("espanso" "ghostty" "gtk-3.0" "gtk-4.0" "hypr" "kitty" "nvim" \
|
||||
"quickshell" "tmux" "uwsm" "vicinae" "wofi" "xdg-desktop-portal")
|
||||
#
|
||||
# Split by role, and every directory under config/dot must be claimed by
|
||||
# exactly one of these three lists -- universal, desktop, or handled (linked
|
||||
# or consumed some other way below: btop exposes only themes, ohmyposh is
|
||||
# read in place by config/bash/shell, panama's hook samples are copied, vim
|
||||
# links a single file). tests/setup/dotfile-classification-contract fails
|
||||
# when a new directory appears in none of them, because unclassified means
|
||||
# silently absent from every server.
|
||||
universal_dirs=("nvim" "tmux")
|
||||
desktop_dirs=("espanso" "ghostty" "gtk-3.0" "gtk-4.0" "hypr" "kitty" \
|
||||
"quickshell" "uwsm" "vicinae" "wofi" "xdg-desktop-portal")
|
||||
handled_dirs=("btop" "ohmyposh" "panama" "vim")
|
||||
|
||||
dirs=("${universal_dirs[@]}")
|
||||
[[ "$ROLE" == server ]] || dirs+=("${desktop_dirs[@]}")
|
||||
|
||||
# --- Vim vimrc ---
|
||||
echo -e "\n--- Setting up vim ---"
|
||||
@@ -107,6 +127,54 @@ elif [ -d "$PANAMA_DOT/tmux/themes" ]; then
|
||||
log "Seeded tmux $tmux_scheme theme ($tmux_name) → $TMUX_THEME"
|
||||
fi
|
||||
|
||||
# btop reads themes from its own config directory, but OWNS btop.conf -- it
|
||||
# rewrites that file on exit -- so only the theme files are exposed, per file,
|
||||
# and the config itself is left to btop. panama-theme-apps edits the single
|
||||
# color_theme line in place.
|
||||
BTOP_THEME_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/btop/themes"
|
||||
mkdir -p "$BTOP_THEME_DIR"
|
||||
for btop_theme_src in "$PANAMA_DOT"/btop/themes/*.theme; do
|
||||
[ -e "$btop_theme_src" ] || continue
|
||||
btop_theme_dst="$BTOP_THEME_DIR/$(basename "$btop_theme_src")"
|
||||
if [ -L "$btop_theme_dst" ]; then
|
||||
rm "$btop_theme_dst"
|
||||
fi
|
||||
if [ -e "$btop_theme_dst" ]; then
|
||||
log "Keeping existing btop theme at $btop_theme_dst"
|
||||
else
|
||||
ln -s "$btop_theme_src" "$btop_theme_dst"
|
||||
log "Linked btop theme → $btop_theme_dst"
|
||||
fi
|
||||
done
|
||||
|
||||
# Hook samples. Copied rather than symlinked, and only when absent: hooks are
|
||||
# the user's own scripts, and ~/.config/panama is theirs too -- settings.json
|
||||
# lives there. A symlinked directory would put their scripts in the repository
|
||||
# working tree, which is the mistake the gtk bookmarks made.
|
||||
PANAMA_HOOK_SAMPLES="$PANAMA_DOT/panama/hooks"
|
||||
USER_HOOK_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/panama/hooks"
|
||||
if [ -d "$PANAMA_HOOK_SAMPLES" ]; then
|
||||
mkdir -p "$USER_HOOK_DIR"
|
||||
for sample in "$PANAMA_HOOK_SAMPLES"/*.sample; do
|
||||
[ -e "$sample" ] || continue
|
||||
sample_dst="$USER_HOOK_DIR/$(basename "$sample")"
|
||||
if [ -e "$sample_dst" ]; then
|
||||
log "Keeping existing hook sample at $sample_dst"
|
||||
else
|
||||
cp "$sample" "$sample_dst"
|
||||
log "Copied hook sample → $sample_dst"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# A server's dotfiles end here. Everything below assumes a session: lock
|
||||
# screens, GTK, launcher themes, icons, wallpapers, Firefox chrome, desktop
|
||||
# entries, quadlets for the desktop's own containers, file associations.
|
||||
if [ "$ROLE" = server ]; then
|
||||
log "Server role: desktop dotfiles skipped"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# hyprlock.conf is generated from a template on every color scheme change and
|
||||
# is not committed. Seed it so the FIRST lock of a fresh install is themed --
|
||||
# without it hyprlock falls back to its own defaults, which is a bare gray
|
||||
@@ -139,26 +207,6 @@ elif [ -r "$HYPRLOCK_TEMPLATE" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# btop reads themes from its own config directory, but OWNS btop.conf -- it
|
||||
# rewrites that file on exit -- so only the theme files are exposed, per file,
|
||||
# and the config itself is left to btop. panama-theme-apps edits the single
|
||||
# color_theme line in place.
|
||||
BTOP_THEME_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/btop/themes"
|
||||
mkdir -p "$BTOP_THEME_DIR"
|
||||
for btop_theme_src in "$PANAMA_DOT"/btop/themes/*.theme; do
|
||||
[ -e "$btop_theme_src" ] || continue
|
||||
btop_theme_dst="$BTOP_THEME_DIR/$(basename "$btop_theme_src")"
|
||||
if [ -L "$btop_theme_dst" ]; then
|
||||
rm "$btop_theme_dst"
|
||||
fi
|
||||
if [ -e "$btop_theme_dst" ]; then
|
||||
log "Keeping existing btop theme at $btop_theme_dst"
|
||||
else
|
||||
ln -s "$btop_theme_src" "$btop_theme_dst"
|
||||
log "Linked btop theme → $btop_theme_dst"
|
||||
fi
|
||||
done
|
||||
|
||||
# GTK3 has no include mechanism, so its settings.ini is generated whole from a
|
||||
# template rather than layered. Without this, a fresh checkout has a template
|
||||
# and no settings.ini, and GTK3 applications fall back to their built-in theme.
|
||||
@@ -454,26 +502,6 @@ fi
|
||||
# than by symlinking the directory itself, the same way the quadlets and
|
||||
# desktop entries are: Nautilus writes nothing here today, but a directory
|
||||
# symlink into the repository is how machine state ends up in a tracked path.
|
||||
# Hook samples. Copied rather than symlinked, and only when absent: hooks are
|
||||
# the user's own scripts, and ~/.config/panama is theirs too -- settings.json
|
||||
# lives there. A symlinked directory would put their scripts in the repository
|
||||
# working tree, which is the mistake the gtk bookmarks made.
|
||||
PANAMA_HOOK_SAMPLES="$PANAMA_DOT/panama/hooks"
|
||||
USER_HOOK_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/panama/hooks"
|
||||
if [ -d "$PANAMA_HOOK_SAMPLES" ]; then
|
||||
mkdir -p "$USER_HOOK_DIR"
|
||||
for sample in "$PANAMA_HOOK_SAMPLES"/*.sample; do
|
||||
[ -e "$sample" ] || continue
|
||||
sample_dst="$USER_HOOK_DIR/$(basename "$sample")"
|
||||
if [ -e "$sample_dst" ]; then
|
||||
log "Keeping existing hook sample at $sample_dst"
|
||||
else
|
||||
cp "$sample" "$sample_dst"
|
||||
log "Copied hook sample → $sample_dst"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
PANAMA_NAUTILUS_DIR="$PANAMA_PATH/config/local/share/nautilus-python/extensions"
|
||||
USER_NAUTILUS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/nautilus-python/extensions"
|
||||
if [ -d "$PANAMA_NAUTILUS_DIR" ]; then
|
||||
|
||||
Reference in New Issue
Block a user