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:
@@ -34,16 +34,61 @@ hyprland_at="$(line_of '^HYPR_FILE=')"
|
||||
# ── Nothing fragile above the desktop ───────────────────────────────────────
|
||||
#
|
||||
# Named individually rather than by pattern: each is a command whose failure is
|
||||
# survivable, and each one above the Hyprland block is a machine that boots to
|
||||
# nothing.
|
||||
# survivable, and each one that EXECUTES above the Hyprland block is a machine
|
||||
# that boots to nothing.
|
||||
#
|
||||
# Executes, not appears: the fragile steps live in functions defined near the
|
||||
# top (the server role calls them without ever reaching a desktop section),
|
||||
# and a definition runs nothing. So function bodies are excluded from the
|
||||
# position scan, and the desktop path's calls to those functions are required
|
||||
# to sit below the desktop instead.
|
||||
|
||||
for fragile in 'dnf swap' 'groupupdate' 'group upgrade' 'gstreamer1-plugins' \
|
||||
'flatpak install' 'nvm install' 'curl -fsSL'; do
|
||||
while read -r at; do
|
||||
(( at < hyprland_at )) \
|
||||
&& note "'$fragile' runs at line $at, above the desktop at line $hyprland_at"
|
||||
done < <(grep -n -- "$fragile" "$installer" | grep -v '^\s*#' | cut -d: -f1)
|
||||
done
|
||||
while IFS= read -r finding; do
|
||||
[[ -n "$finding" ]] && note "$finding"
|
||||
done < <(python3 - "$installer" "$hyprland_at" <<'PY'
|
||||
import re, sys
|
||||
|
||||
path, hypr = sys.argv[1], int(sys.argv[2])
|
||||
lines = open(path, encoding="utf-8").read().splitlines()
|
||||
|
||||
in_body = False
|
||||
body = set()
|
||||
for i, line in enumerate(lines, 1):
|
||||
if not in_body and re.match(r'^[a-z_]+\(\)\s*\{', line):
|
||||
in_body = True
|
||||
body.add(i)
|
||||
continue
|
||||
if in_body:
|
||||
body.add(i)
|
||||
if line == '}':
|
||||
in_body = False
|
||||
|
||||
fragile = ['dnf swap', 'groupupdate', 'group upgrade', 'gstreamer1-plugins',
|
||||
'flatpak install', 'nvm install', 'curl -fsSL']
|
||||
for i, line in enumerate(lines, 1):
|
||||
if i >= hypr or i in body or line.strip().startswith('#'):
|
||||
continue
|
||||
for needle in fragile:
|
||||
if needle in line:
|
||||
print(f"'{needle}' runs at line {i}, above the desktop at line {hypr}")
|
||||
|
||||
# The desktop path still has to run the fragile helpers -- below the desktop.
|
||||
# (The server path calls them above, inside a branch that exits before the
|
||||
# desktop section; the exit is asserted back in bash.)
|
||||
for call in ('setup_node', 'install_bun', 'install_claude_code', 'install_codex'):
|
||||
calls = [i for i, line in enumerate(lines, 1)
|
||||
if re.match(r'^\s*' + call + r'\s*$', line) and i not in body]
|
||||
if not calls:
|
||||
print(f"{call} is never called, so the desktop path skips it")
|
||||
elif not any(i > hypr for i in calls):
|
||||
print(f"{call} is only called above the desktop")
|
||||
PY
|
||||
)
|
||||
|
||||
# The server branch is what excuses fragile calls above the desktop, and only
|
||||
# because it never falls through into the desktop section.
|
||||
sed -n '/^if \[\[ "\$ROLE" == server \]\]; then/,/^fi/p' "$installer" | grep -q '^\s*exit 0' \
|
||||
|| note 'the server branch does not exit before the desktop section'
|
||||
|
||||
# ── Everything fragile is actually tolerated ────────────────────────────────
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user