hub v0.62.0 + scripts v1.19.0 — R-21 slice C: the universal secret-free ISO
A generic ISO carries NO customer secret. The box registers itself at the hub as an unclaimed appliance; the operator binds it to a customer; the hub delivers the customer-id + retrieval passphrase ONCE; day-0 completes via the slice-A path. Hub (v0.62.0): - store/appliance.go: appliance_registrations keyed by (uuid, mac_set) — MAC set is the tiebreaker (duplicate SMBIOS UUIDs); token stored as sha256 only. Idempotent register (sticky-discard), atomic one-shot delivery, bind/discard. - api/appliance.go: POST /appliance/register (the one unauth endpoint, per-IP rate-limited, 256-bit token); GET /appliance/poll (404 no-oracle / 204 unbound / 200 deliver-once / 410 delivered). Passphrase read live, never logged. - web/appliances.go: Hosts-page "Unclaimed appliances" section + BIND (customer picker, host count display-only) + DISCARD; SSH host-key fingerprints; events. - Red-proofs: one-shot delivery + register idempotency (both proven red); 404-no-oracle, sticky-discard, bind staging, render. Green + confirm gate. Scripts (v1.19.0): - felhom-bootstrap.sh: ONE unit, TWO modes. Direct (env has customer/passphrase) = slice-A path, byte-identical, only branched around. Pairing (generic) = register + poll (RestartSec=30 is the poll timer); on delivery write the env 0600 and fall through to direct. Secrets + token shredded on success. - build-felhom-iso.sh --pairing: generic secret-free ISO, -generic filename, manifest mode=pairing. profiles/generic.profile (new). - test/bootstrap-modes.sh: Scenario D (direct = zero appliance calls) + pairing register/poll + delivery handoff — all green in a debian container.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
# bootstrap-modes.sh — R-21 slice C regression harness for felhom-bootstrap.sh's two modes. Runs as
|
||||
# root inside a throwaway debian container (writes /etc/felhom etc.); fakes curl + host-install +
|
||||
# systemctl on PATH. Asserts:
|
||||
# D (regression): a DIRECT env (customer-id + passphrase) enters run_direct and makes ZERO calls to
|
||||
# /api/v1/appliance/* — the pairing code path is provably not entered.
|
||||
# pairing: an env WITHOUT customer-id/passphrase enters run_pairing, POSTs /appliance/register,
|
||||
# persists the token, and GETs /appliance/poll.
|
||||
# delivery: a poll that returns 200 writes the direct env (0600) and invokes host-install.
|
||||
set -uo pipefail
|
||||
BSTRAP=/work/felhom-bootstrap.sh
|
||||
FAKE=/work/fakebin; rm -rf "$FAKE"; mkdir -p "$FAKE"
|
||||
CALLS=/work/curl.log
|
||||
export PATH="$FAKE:$PATH"
|
||||
fail=0
|
||||
say() { echo "TEST: $*"; }
|
||||
check() { if eval "$2"; then echo " ok: $1"; else echo " FAIL: $1"; fail=1; fi; }
|
||||
|
||||
# --- fake curl: logs every invocation's URL; emulates -o (fetch), --data (register), -w code (poll) --
|
||||
cat > "$FAKE/curl" <<'CURL'
|
||||
#!/bin/bash
|
||||
url=""; ofile=""; wfmt=""
|
||||
prev=""
|
||||
for a in "$@"; do
|
||||
case "$a" in http*|https*) url="$a";; esac
|
||||
case "$prev" in -o) ofile="$a";; -w) wfmt="$a";; esac
|
||||
prev="$a"
|
||||
done
|
||||
echo "$url" >> /work/curl.log
|
||||
mode=$(cat /work/poll-mode 2>/dev/null || echo 204)
|
||||
case "$url" in
|
||||
*"/felhom-host-install.sh")
|
||||
# write a stub host-install to the -o target
|
||||
cat > "$ofile" <<'HI'
|
||||
#!/bin/bash
|
||||
echo "fake host-install ran: $*" >> /work/hostinstall.log
|
||||
exit 0
|
||||
HI
|
||||
exit 0 ;;
|
||||
*"/appliance/register")
|
||||
echo '{"appliance_token":"TESTTOKEN123456","poll_interval_sec":30}'
|
||||
exit 0 ;;
|
||||
*"/appliance/poll")
|
||||
if [ "$mode" = "200" ]; then
|
||||
# body then, if -w set, a newline + code (matches the bootstrap's -w '\n%{http_code}')
|
||||
printf '%s' '{"customer_id":"drill","retrieval_passphrase":"SEKRET-PASS","mode":"appliance","extra_args":"--cores 2"}'
|
||||
[ -n "$wfmt" ] && printf '\n200'
|
||||
else
|
||||
[ -n "$wfmt" ] && printf '\n204'
|
||||
fi
|
||||
exit 0 ;;
|
||||
esac
|
||||
exit 0
|
||||
CURL
|
||||
chmod +x "$FAKE/curl"
|
||||
|
||||
# fake systemctl (disable is a no-op)
|
||||
printf '#!/bin/bash\nexit 0\n' > "$FAKE/systemctl"; chmod +x "$FAKE/systemctl"
|
||||
|
||||
reset_state() {
|
||||
rm -rf /etc/felhom /run/felhom-bootstrap-pass /var/lib/felhom-install "$CALLS" /work/hostinstall.log /work/poll-mode
|
||||
mkdir -p /etc/felhom
|
||||
}
|
||||
|
||||
# ============================ Scenario D — direct mode, zero appliance calls =========================
|
||||
say "D: direct env -> run_direct, NO appliance calls"
|
||||
reset_state
|
||||
cat > /etc/felhom/bootstrap.env <<'ENV'
|
||||
FELHOM_CUSTOMER_ID=acme
|
||||
FELHOM_MODE=appliance
|
||||
FELHOM_RETRIEVAL_PASSPHRASE=direct-pass
|
||||
FELHOM_HUB_URL=https://hub.example
|
||||
ENV
|
||||
chmod 0600 /etc/felhom/bootstrap.env
|
||||
bash "$BSTRAP"; rc=$?
|
||||
check "run_direct exited 0 (host-install stub succeeded)" "[ $rc -eq 0 ]"
|
||||
check "host-install was invoked" "[ -f /work/hostinstall.log ]"
|
||||
check "ZERO /appliance/register calls" "! grep -q '/appliance/register' $CALLS"
|
||||
check "ZERO /appliance/poll calls" "! grep -q '/appliance/poll' $CALLS"
|
||||
check "done-flag written" "[ -f /etc/felhom/.bootstrap-done ]"
|
||||
check "env shredded on success" "[ ! -f /etc/felhom/bootstrap.env ]"
|
||||
|
||||
# ============================ pairing mode — registers, then polls ==================================
|
||||
say "pairing: no customer/passphrase -> register + poll (unbound=204)"
|
||||
reset_state
|
||||
cat > /etc/felhom/bootstrap.env <<'ENV'
|
||||
FELHOM_HUB_URL=https://hub.example
|
||||
ENV
|
||||
echo 204 > /work/poll-mode
|
||||
bash "$BSTRAP"; rc=$?
|
||||
check "unbound poll -> exit non-zero (systemd retries)" "[ $rc -ne 0 ]"
|
||||
check "POSTed /appliance/register" "grep -q '/appliance/register' $CALLS"
|
||||
check "appliance token persisted 0600" "[ -f /etc/felhom/appliance-token ] && [ \"\$(stat -c %a /etc/felhom/appliance-token)\" = 600 ]"
|
||||
check "GET /appliance/poll" "grep -q '/appliance/poll' $CALLS"
|
||||
check "no direct env written yet" "! grep -q FELHOM_CUSTOMER_ID /etc/felhom/bootstrap.env"
|
||||
check "host-install NOT run (unbound)" "[ ! -f /work/hostinstall.log ]"
|
||||
|
||||
# ============================ delivery — poll 200 writes env + runs host-install =====================
|
||||
say "delivery: bound poll (200) -> write direct env + run host-install"
|
||||
# keep the token from the previous step; flip the poll to 200
|
||||
echo 200 > /work/poll-mode
|
||||
bash "$BSTRAP"; rc=$?
|
||||
check "delivery run exited 0" "[ $rc -eq 0 ]"
|
||||
check "direct env written with customer-id" "grep -q 'FELHOM_CUSTOMER_ID=drill' /etc/felhom/bootstrap.env || [ -f /etc/felhom/.bootstrap-done ]"
|
||||
check "host-install invoked after delivery" "[ -f /work/hostinstall.log ]"
|
||||
check "done-flag written" "[ -f /etc/felhom/.bootstrap-done ]"
|
||||
|
||||
echo "=================================================="
|
||||
if [ $fail -eq 0 ]; then echo "ALL BOOTSTRAP-MODE TESTS PASSED"; else echo "SOME TESTS FAILED"; fi
|
||||
exit $fail
|
||||
Reference in New Issue
Block a user