From d3ac7fb118fd1abb329867b90f57581d0c333df5 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sun, 14 Jun 2026 00:37:49 +0200 Subject: [PATCH] Live drive: CTRL-T2-1 PASS (F14), restart-policy nuance (F15) --- LIVE-DRIVE-FINDINGS-2026-06-14.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/LIVE-DRIVE-FINDINGS-2026-06-14.md b/LIVE-DRIVE-FINDINGS-2026-06-14.md index 1ff2f74..c26ba7a 100644 --- a/LIVE-DRIVE-FINDINGS-2026-06-14.md +++ b/LIVE-DRIVE-FINDINGS-2026-06-14.md @@ -123,5 +123,19 @@ The demo dashboard has **no password set**, so the controller's `RequireAuth` an - **The 3-2-1 weakness (HIGH-ish, consequence of F9):** the "primary" tier (recovery units + DB dumps) is stored under `/mnt/sys_drive/felhom-data/backups`, which is the **same 32G OS rootfs (disk-0)** that holds the app data itself. So tier-1 gives **zero protection against disk-0 loss** — source and backup share a disk. With no second drive attached (F9), the only genuine off-host copy is PBS. Effective reality is **"2 copies on the same disk + 1 PBS"**, not 3-2-1. The UI/dashboard 3-2-1 framing would overstate resilience here. - **Minor:** `/api/backup/status` reports only `db_dump` + `running`/`enabled` — it does not surface recovery-unit or tier-2 status, so "is my backup complete?" requires multiple endpoints. The earlier guest-backup status briefly showed a **stale prior run** (20:27Z) before my new run appeared — momentary staleness, not a clock bug. +### F14 — CTRL-T2-1 crash-window: crash mid-image-pull leaves stack NOT-deployed and redeployable — PASS — INFO +- **Area:** CTRL-T2-1 regression. +- **Method:** deployed `code-server` (uncached ~1GB image) with a password, confirmed the `docker compose up -d` pull subprocess was running, then `docker kill felhom-controller` mid-pull. +- **On-disk state during the crash (read directly from the guest fs while controller down):** `app.yaml` had `deployed: false` (only `deployed_at` was stamped at start; the `deployed:true` flag is written **only on success**). +- **After restart:** `GET /api/stacks/code-server` → `state=not_deployed, deployed=False`; **no orphaned code-server container**. +- **Redeploy:** allowed (no "already deployed; use update" refusal) → returned deployed → polled to `running`/healthy, `code.demo-felhom.eu` → 302, `deployed: true` persisted on success. +- **Verdict:** the fix works — no ghost-stuck stack. **Severity: INFO (PASS).** +- **First-attempt note:** an initial attempt without the (required) PASSWORD was rejected at validation **before any pull** — so a missing required field is caught pre-pull (good), and I had to supply the password to actually exercise the pull window. + +### F15 — `docker kill`/`stop` does NOT auto-restart the controller; bootstrap service is oneshot/Restart=no — MEDIUM (operational expectation) +- **Area:** §3 crash recovery / operational. +- **Finding:** the runbook states the bootstrap service "restarts it within seconds." In reality: `felhom-controller-bootstrap.service` is `Type=oneshot, Restart=no` (it ran once and exited). The container has `--restart unless-stopped`, but Docker treats an explicit `docker kill`/`docker stop` as a **manual stop**, so `unless-stopped` does **not** restart it (observed: `RestartCount=0`, stayed `Exited (137)` indefinitely; I had to `docker start` it manually). +- **Impact:** `unless-stopped` *will* restart the controller after a genuine unexpected death (panic/OOM/host reboot) — so real crash-recovery is covered. But there is **no watchdog** that recovers from a manual stop or a clean exit, and the bootstrap service does not re-run. An operator who `docker stop`s the controller (or a tool that does) will find it stays down. The "auto-restarts within seconds" expectation is only partially true. **Severity: MEDIUM** (recovery assumption is narrower than documented). + ### F4 — `/api/stacks/rescan` returns "stack not found: rescan" — LOW - The runbook's documented rescan endpoint `GET /api/stacks/rescan` is routed as a stack name lookup → `{"ok":false,"error":"stack not found: rescan"}`. Either the route was removed/renamed or the runbook is stale. (Sync/rescan is reachable via `POST /api/sync`.) Cosmetic but documents a stale/missing endpoint.