127 lines
10 KiB
Markdown
127 lines
10 KiB
Markdown
# 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).
|