Files
felhom.eu/REPORT-debian13-restic-2026-10-16.md
T
admin 96e15c15ba
gates / gates (push) Successful in 6m38s
debian13-restic report: CI result
2026-10-16 21:44:31 +02:00

10 KiB

REPORT — the controller on Debian 13 with a pinned restic, re-proven; the Samba image rebuilt (2026-10-16)

Written in ASD-STE100 Simplified Technical English. Operator brief „the controller on Debian 13 with a pinned restic, re-proven; the Samba image rebuilt". Design read first: architecture/07-backup-architecture.md (Tier 3, §6.3, §6.7 the failure classifier, §3 the restore table; now §6.8), 06-offsite-connectivity.md, 03-host-agent.md (escrow), _recovery-inventory-2026-07-28.md. Evidence: documentation/audits/debian13-restic-2026-10-16/.

0. Decisions I took (inside the brief; reversible)

  1. I removed seven packages, not two. The brief named the two database clients. I read every program call in the controller: it never runs sqlite3, fdisk, e2fsprogs, parted (disk work is the agent's since v0.37.0) or sshpass (its key install was replaced by the hub's registrar in v0.289.0) either. On demo-hp every kept tool works, every removed one is gone, and the log has no „executable not found". To undo: put the names back in the apt list.
  2. I kept restic 0.18.1, as the brief says, although it adds scanner findings (§4). The choice of 0.19.x is yours (R-1107).

1. The assumption table (Part 1) and each row on restic 0.18.1

Measured on scratch stores with both official binaries side by side (part1/), then pinned as test fixtures of REAL outputs (felhom-controller internal/backup/testdata/restic/, TestR1105_*, red-proved by six mutations).

restic call · where What the code assumes 0.18.1
backup (+ missing path) · offbox.go, offbox_capture.go a missing source path: a warning, exit 0; an unreadable file: exit 3 same
backup --json · offbox_progress.go status lines: percent_done, totals, current_files same names (live bar moved on demo-hp)
snapshots --json, snapshots latest --tag · offbox.go, offbox_inventory.go, offbox_restore.go, offbox_window.go one JSON array, nothing else in the combined output (also with an empty cache) same (new fields only)
stats <id>, stats --mode raw-data · offbox_restore.go, offbox.go total_size same
forget … --dry-run --json · offbox_window.go the plan of the 7/4/6 policy, --group-by host,tags CHANGED, safe direction: 0.17+ also keeps each group's oldest snapshot while monthly slots are unused — fewer removals, never more (41-day set 60 vs 62; 230-day set identical, both time zones). The guard's verdict holds. Pinned. No code change needed.
restore … --include <unit> --no-lock · offbox_proof.go writes nothing to the store same (restores from a read-only store)
restore (plain) · offbox_restore.go, offbox.go, shares_restore.go the layout under the target same. The old comment „restore takes no lock" was wrong for both versions; corrected
cat config, init · offbox.go probe „wrong password…" = orphaned; „unable to open config file" = no repo; „already exists" = init race is success same
unlock, unlock --remove-all · resticStep lock text „repository is already locked"; stale-only unlock keeps a foreign lock same (both lock forms)
check · offbox_integrity.go a damaged pack reads as damage, a healthy run does not same verdict (other wording)
the §6.7 classifier refused port, refused key, unreachable host, dead rclone ssh → transport same
agent: escrow, recovery, DR recipe — the agent runs no restic; it only stores and returns the password

Exit codes changed (10, 11, 12); the controller reads none.

2. The version and the pin

  • restic 0.18.1 (newest 0.18 patch). The hosts run no restic (demo-hp, demo-felhom, Tester 1: not installed); every guest ran Debian's 0.14.0. So „one version for guest and host" means the guest only.
  • The pin: a restic build stage downloads the official release file; restic's SHA256SUMS signature is checked with the vendored release key (fingerprint CF8F 18F2 8445 7597 3F79 D4E1 91A6 868B D3F7 A907, cross-checked against restic's own install doc); the file must match the published sum AND the sum pinned in the Dockerfile. A wrong sum fails the build (proved). TestR1105_ResticIsPinnedOutsideTheOS, red-proved by four mutations.

3. Both directions and the drill (demo-hp 9201, rc.1, the dashboard's own posts)

  • 0.18.1 restores a 0.14.0 snapshot: the product's off-site restore of bookstack → a tree byte-identical to a 0.14.0 restore of the same snapshot. 0.14.0 restores a 0.18.1 snapshot: byte-identical too. Both on demo-hp's REAL store.
  • 0.14.0 after a 0.18.1 prune: proven on a scratch store (502 snapshots; check --read-data clean, both restores). On the real store it waits for demo-hp's next weekly clean-up window (due after 2026-10-18 14:16 UTC). In STATUS.
  • The drill: Rallly (database) and Grimmory (books folder): a marker row and a marker file; the off-site run (dumps + push, 3m33s, 186 → 202 snapshots); removed with data and backups; reinstalled (nothing there — the negative control); full restore from the off-site copy. The row and the file came back (file sha256 identical). But both apps were then unusable — not because of restic: the restore puts back the OLD database volume with the old password, and the reinstall made a new one. Rallly crash-looped on auth while the restore said done; Grimmory was held stopped. Filed R-1106 (R-127's class, on the reinstall path).

4. Debian 13 and the scanner

Kept: git, rsync, util-linux, openssh-client, curl, ca-certificates, gnupg, docker CLI + compose plugin. Removed: the seven in §0. trivy 0.74.0 (critical / high, fixable in brackets):

image critical high
controller 0.322.0 (Debian 12) 4 (0) 140 (4)
controller 0.323.0 (Debian 13) 3 (2) 122 (52)
— of which the OS 1 (0) 70 (0)
— of which restic 0.18.1 (Go 1.25.1, old modules) 2 (2) 48 (48)
felhom-samba 1.1.0 0 48 (48)
felhom-samba 1.2.0 0 0

The OS part fell by half. The official restic file is built with an old Go, so the fixable count rose. restic 0.19.1's official file: 0 / 19. R-1107.

5. Samba (R-972)

felhom-samba 1.2.0: Alpine 3.24.2 (digest-pinned), same packages, Samba 4.23.8. build-samba-image.sh now refuses a tag already in the registry, a registry it cannot ask, and a dirty or unpushed tree (6 cases; 4 fail on the old script). Checked on demo-hp first on 1.1.0, then after the switch to 1.2.0, with the SAME household password (the passdb volume survived): smbclient from DooPlex wrote, listed and read back a file; a wrong password was refused; nmbd answered the name; mDNS answered FELHOMHP.local; WS-Discovery answered; smbd, nmbd, wsdd, avahi, dbus under tini; testparm clean. Found on the way: a share added before the first password is not exported (R-1108, pre-existing, narrow).

6. Release

Built 0.323.0 from 8587198 (code identical to rc.1 fbcc3cf; only CHANGELOG and README differ), MinAgent 0.158.1. Per-box floors at 19:23:46 UTC (303 → floor_set, all three); Tester 1, demo-hp and demo-felhom on 0.323.0 at 19:25 UTC, each through the normal update path (Post-update startup: update successful). Box walk: no container unhealthy, restarting, exited or created (24 / 9 / 17); restic 0.18.1 and Debian 13 in each controller; the three dashboards 200; https-only 35 names OK with both controls (release/).

The global floor is NOT raised tonight (the brief). It waits until each test box has made one real night's off-site backup on 0.323.0 (they run at about 02:15 UTC). The exact check and the floor command are in STATUS.md („What we work on"). The real-store check „0.14.0 reads after a 0.18.1 prune" waits for demo-hp's clean-up window (after 2026-10-18 14:16 UTC).

CI: green by job for every commit of this task — controller fbcc3cf (1963), 8587198 (1965), 00a0d91 (1967); felhom.eu e713f6ae (1964), babf596c (1966).

7. Rows

Before 174, after 177. Opened 3 (R-1106, R-1107, R-1108). Closed 0. R-1105 and R-972 NARROWED (R-1105 waits on the night check; R-972's Samba part is done and rides the floor). unproven.py: NOT WALKED 35 of 55, unchanged.

8. Observations

  1. The forget plan of restic 0.17+ keeps each group's oldest snapshot while monthly slots are unused. NOT-A-FINDING: it only ever keeps more, the guard's verdict holds; pinned by TestR1105_TheForgetPlanOnlyEverKeepsMore and written into 07 §6.8.
  2. A reinstalled database app restored from the off-site copy is unusable (old volume, new password). FILED: R-1106
  3. The official restic 0.18.1 binary adds 50 fixable scanner findings. FILED: R-1107
  4. A share added before the first household password is not exported. FILED: R-1108
  5. A remove „with drive data" keeps userdata/media/grimmory. NOT-A-FINDING: by design (07 §6.5, decision 67 — the household's folders stay).
  6. A restore hold outlives the remove and a fresh install. NOT-A-FINDING: by design (R-379 — only the operator clears it; ClearUpdateHold's comment). The fresh install over it runs; the hold sentence stays on its page until cleared — part of R-1106's chain.
  7. The -clear-restore-hold tool's change is overwritten if the controller is not restarted at once. NOT-A-FINDING: the tool prints „NOW RESTART THE CONTROLLER"; done that way it worked.
  8. A plain restic restore writes a lock (both versions); an old code comment said it did not. NOT-A-FINDING: the comment is corrected; the nightly proof uses --no-lock and was never affected.
  9. build.sh --push also pushes :latest for an rc tag. NOT-A-FINDING: nothing pulls :latest (the update button reads X.Y.Z tags; boxes run a named tag).

9. Teardown (three layers)

  • Machine (demo-hp 9201): Rallly and Grimmory removed through the product (no container, volume, unit or folder left; the Grimmory restore hold cleared with the operator tool and a restart). The check copies are gone. Sharing turned off, both test shares deleted, their empty folders removed; the passdb volume and user_set stay, as the product leaves them. The helper scripts and scratch restores in the guest removed. 9201 runs 0.323.0.
  • Host: nothing.
  • Hub: per-box floors (see §6).