installer 1.30.0 (not yet tagged): the crash guard units + config, the root-owned slow-lane trust files (os-trust.json, operator-signers), their removal on uninstall
gates / gates (push) Successful in 28s
gates / gates (push) Successful in 28s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,3 +1,17 @@
|
||||
## felhom-host-install.sh 1.30.0 — the crash guard and the slow-lane trust files (2026-10-04)
|
||||
|
||||
Needs agent ≥ 0.142.0 at the pinned tag for the crash guard (an older agent: skipped with a warning, the box keeps
|
||||
`kernel.panic = 0`).
|
||||
|
||||
- **The crash guard** (`09` decision 88, R-851, `11` §5.9): fetches `configs/felhom-crash-guard`, its two services, the
|
||||
timer and `crash-guard.conf` from the pinned agent tag; syntax-checks; installs (0755 / 0644 root); enables
|
||||
`felhom-crash-guard.service` + `felhom-crash-guard-check.timer` now. An existing `/etc/felhom/crash-guard.conf` is kept.
|
||||
- **The root-owned slow-lane trust files** (`11` §5.8, the wrapper's R3): `/etc/felhom/os-trust.json` (this box's
|
||||
`host_id`; `ring0_slow_lane` false — an existing file keeps its mark) and `/etc/felhom/operator-signers` (the
|
||||
operational operator key in ssh `allowed_signers` form). The agent's own config is agent-writable and is not trusted
|
||||
for a Docker step.
|
||||
- Uninstall removes all of it (`kernel.panic` returns to the kernel default 0 at the next boot).
|
||||
|
||||
## felhom-host-install.sh 1.29.0 — installs the OS-update wrapper (2026-10-04, `11-os-updates.md` §8 step 2)
|
||||
|
||||
- Step 5 fetches `configs/felhom-os-apply` from the pinned agent tag and installs it as
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_VERSION="1.29.0" # the SINGLE version source (F-1): -h and the run banners follow it.
|
||||
SCRIPT_VERSION="1.30.0" # the SINGLE version source (F-1): -h and the run banners follow it.
|
||||
# The hub used to carry a copy for its Setup tab; R-94 DELETED it
|
||||
# (2026-08-02) because the hub cannot know which version a box runs —
|
||||
# the Setup command fetches this script at run time. scripts/
|
||||
@@ -1158,6 +1158,18 @@ run_uninstall() {
|
||||
if [[ -f /usr/local/sbin/felhom-pbs-apply ]]; then run rm -f /usr/local/sbin/felhom-pbs-apply; else log_skip " felhom-pbs-apply already absent"; fi
|
||||
if [[ -f /usr/local/sbin/felhom-backup-target-apply ]]; then run rm -f /usr/local/sbin/felhom-backup-target-apply; else log_skip " felhom-backup-target-apply already absent"; fi
|
||||
if [[ -f /usr/local/sbin/felhom-os-apply ]]; then run rm -f /usr/local/sbin/felhom-os-apply; else log_skip " felhom-os-apply already absent"; fi
|
||||
# 1.30.0: the crash guard (kernel.panic goes back to the kernel default 0 at the next boot) and the root-owned
|
||||
# slow-lane trust files.
|
||||
if systemctl list-unit-files felhom-crash-guard.service >/dev/null 2>&1; then
|
||||
run systemctl disable --now felhom-crash-guard-check.timer felhom-crash-guard.service 2>/dev/null || true
|
||||
fi
|
||||
local cgf
|
||||
for cgf in /usr/local/sbin/felhom-crash-guard /etc/systemd/system/felhom-crash-guard.service \
|
||||
/etc/systemd/system/felhom-crash-guard-check.service /etc/systemd/system/felhom-crash-guard-check.timer \
|
||||
/etc/felhom/crash-guard.conf /etc/felhom/os-trust.json /etc/felhom/operator-signers; do
|
||||
if [[ -e "$cgf" ]]; then run rm -f "$cgf"; fi
|
||||
done
|
||||
if [[ -d /var/lib/felhom-crash-guard ]]; then run rm -rf /var/lib/felhom-crash-guard; fi
|
||||
if [[ -f /var/lib/vz/snippets/felhom-guest-hook.sh ]]; then run rm -f /var/lib/vz/snippets/felhom-guest-hook.sh; fi
|
||||
local dconf _dnsmasq_touched=false
|
||||
for dconf in /etc/dnsmasq.d/felhom-*.conf; do
|
||||
@@ -2395,6 +2407,38 @@ step_agent_install() {
|
||||
rm -f "$ostmp"
|
||||
fi
|
||||
|
||||
# The crash guard (agent >= 0.142.0, `09` decision 88, `11` §5.9): a crashed host restarts by itself (kernel.panic =
|
||||
# 10 s), but the 3rd unclean stop within 60 minutes leaves it off. A root boot unit + an hourly re-arm timer + its
|
||||
# config. Like the wrapper above, an older pinned agent has none of it — skipped with a warning, never fatal.
|
||||
if $DRY_RUN; then
|
||||
log_dry "fetch configs/felhom-crash-guard + its .service/.timer + crash-guard.conf ; install ; enable --now felhom-crash-guard.service felhom-crash-guard-check.timer"
|
||||
else
|
||||
local cgtmp; cgtmp=$(mktemp -d -t felhom-cg.XXXXXX)
|
||||
local -a _cgauth; _git_auth_args _cgauth
|
||||
local cgok=true cgn
|
||||
for cgn in felhom-crash-guard felhom-crash-guard.service felhom-crash-guard-check.service felhom-crash-guard-check.timer crash-guard.conf; do
|
||||
curl -fsS "${_cgauth[@]}" -o "$cgtmp/$cgn" \
|
||||
"$GITEA_BASE/$GITEA_OWNER/$AGENT_REPO/raw/tag/v$ART_AGENT_VER/configs/$cgn" 2>/dev/null && [[ -s "$cgtmp/$cgn" ]] || { cgok=false; break; }
|
||||
done
|
||||
if $cgok; then
|
||||
python3 -c 'import ast,sys; ast.parse(open(sys.argv[1]).read())' "$cgtmp/felhom-crash-guard" \
|
||||
|| { rm -rf "$cgtmp"; die "fetched felhom-crash-guard failed the python3 syntax check — refusing to install"; }
|
||||
install -m 0755 -o root -g root "$cgtmp/felhom-crash-guard" /usr/local/sbin/felhom-crash-guard
|
||||
for cgn in felhom-crash-guard.service felhom-crash-guard-check.service felhom-crash-guard-check.timer; do
|
||||
install -m 0644 -o root -g root "$cgtmp/$cgn" "/etc/systemd/system/$cgn"
|
||||
done
|
||||
install -d -m 0755 -o root -g root /etc/felhom
|
||||
[[ -f /etc/felhom/crash-guard.conf ]] || install -m 0644 -o root -g root "$cgtmp/crash-guard.conf" /etc/felhom/crash-guard.conf
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now felhom-crash-guard.service felhom-crash-guard-check.timer \
|
||||
|| die "could not enable the crash guard units"
|
||||
log_success " installed the crash guard (kernel.panic=$(cat /proc/sys/kernel/panic) s; 3rd crash in 60 min stays off)"
|
||||
else
|
||||
log_warn " agent v$ART_AGENT_VER carries no crash guard (older than 0.142.0) — a crashed host stays off (kernel.panic=0)"
|
||||
fi
|
||||
rm -rf "$cgtmp"
|
||||
fi
|
||||
|
||||
# Sudoers — fetch the canonical file, validate with visudo -cf BEFORE installing (0440 root:root).
|
||||
if $DRY_RUN; then
|
||||
log_dry "fetch configs/felhom-agent.sudoers ; visudo -cf ; install 0440 -> $AGENT_SUDOERS"
|
||||
@@ -2845,9 +2889,50 @@ PY
|
||||
else
|
||||
log_warn " no felhom-agent systemd unit — daemon host-report loop not started (provision one-shot still works)"
|
||||
fi
|
||||
_write_slow_lane_trust
|
||||
_state_mark agent_config
|
||||
}
|
||||
|
||||
# _write_slow_lane_trust writes the ROOT-OWNED trust anchors the OS wrapper's slow lane checks itself (1.30.0, `11` §5.8,
|
||||
# R3): /etc/felhom/os-trust.json (this box's host_id; ring0_slow_lane FALSE — only the demo boxes are marked, by hand)
|
||||
# and /etc/felhom/operator-signers (the operational key, ssh allowed_signers form). The agent's own config is
|
||||
# agent-writable and therefore NOT trusted for this. An existing os-trust.json keeps its ring0 mark.
|
||||
_write_slow_lane_trust() {
|
||||
if $DRY_RUN; then
|
||||
log_dry "write /etc/felhom/os-trust.json {host_id=$HOST_ID, ring0_slow_lane=false} + /etc/felhom/operator-signers (${RESOLVED_OP_ID:-<none>}) 0644 root"
|
||||
return 0
|
||||
fi
|
||||
if [[ -z "$HOST_ID" ]]; then
|
||||
log_warn " no host_id — the slow-lane trust file is not written (Docker steps stay refused)"
|
||||
return 0
|
||||
fi
|
||||
install -d -m 0755 -o root -g root /etc/felhom
|
||||
HOST_ID="$HOST_ID" python3 - <<'PY'
|
||||
import json, os
|
||||
p = "/etc/felhom/os-trust.json"
|
||||
d = {}
|
||||
try:
|
||||
d = json.load(open(p))
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
d["host_id"] = os.environ["HOST_ID"]
|
||||
d.setdefault("ring0_slow_lane", False)
|
||||
tmp = p + ".tmp"
|
||||
with open(tmp, "w") as f:
|
||||
json.dump(d, f, indent=2, sort_keys=True)
|
||||
f.write("\n")
|
||||
os.chmod(tmp, 0o644)
|
||||
os.replace(tmp, p)
|
||||
PY
|
||||
if [[ -n "$RESOLVED_OP_LINE" ]]; then
|
||||
printf '%s namespaces="felhom-op-v1" %s\n' "$RESOLVED_OP_ID" "$RESOLVED_OP_LINE" > /etc/felhom/operator-signers.tmp
|
||||
chmod 0644 /etc/felhom/operator-signers.tmp && mv /etc/felhom/operator-signers.tmp /etc/felhom/operator-signers
|
||||
log_success " wrote /etc/felhom/os-trust.json + operator-signers ($RESOLVED_OP_ID) — the root-owned slow-lane anchors"
|
||||
else
|
||||
log_warn " no operational operator key resolved — signed Docker steps stay refused on this box"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# STEP 7 — golden: ensure a restorable golden archive (local else Gitea-fetched + verified)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user