docs: record the two silent no-ops the end-to-end restore run found
Both were checks whose failure mode was to not run, and both produced output indistinguishable from a healthy report. Worth writing down as a shape rather than as two bugs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
647b19cf4a
commit
5b2d824aac
@ -88,6 +88,28 @@ Output is a verdict list, then one confirmation:
|
||||
Continue? [Y/n]:
|
||||
```
|
||||
|
||||
### 3.1 — Two silent no-ops, and what they have in common
|
||||
|
||||
Both were found by running the installer's restore path end to end against a
|
||||
real repository, not by reading the code — which is the point of doing that.
|
||||
|
||||
1. **The manifest is pretty-printed.** `"size_bytes": 123` carries a space, so
|
||||
a `"key":[0-9]*` pattern missed it. Size came back empty, and the fit check
|
||||
is guarded by `[[ -n "$size_bytes" ]]` — so it was skipped for every app.
|
||||
2. **The manifest was never read at all.** `storageSnapshotSourcePath` passed a
|
||||
snapshot id into an app-tag filter (see storage-locations §9), so it returned
|
||||
1 every time and the preflight fell back to a `?` size.
|
||||
|
||||
The shared shape: **a check whose failure mode is to not run.** Neither printed
|
||||
an error, and the report they produced — thirteen green ticks — is exactly what
|
||||
a healthy run looks like. The only visible tell was the `?` in a column nobody
|
||||
had a reason to distrust.
|
||||
|
||||
So the regression test (`scripts/dev/lp-preflight-test`) asserts the *negative*
|
||||
cases: an app too big for the disk must be refused, an app this version no
|
||||
longer ships must be refused, an app whose location is gone must be marked as
|
||||
moved. Reintroducing either historical bug fails it.
|
||||
|
||||
## 4. The password problem, stated plainly
|
||||
|
||||
**An encrypted repository cannot be opened with anything inside itself.** `CFG_BACKUP_LOC_<idx>_PASSWORD` lives in the system config — which is *inside the backup*. So on a fresh machine the user must supply the repository password by hand. There is no way around this and it is not a bug; it is what encryption means.
|
||||
|
||||
@ -349,6 +349,28 @@ The fix is needed for this feature and is worth doing on its own: restore into `
|
||||
|
||||
Also worth noting: an app's restic snapshot paths change when it moves. Snapshot *history* stays intact and restorable (each snapshot knows its own path), but path-based filters in the snapshot browser need to accept either.
|
||||
|
||||
**Built — and then found not to work, which is the part worth remembering.**
|
||||
`storageSnapshotSourcePath` / `storageRestoreAppTo` landed as described above,
|
||||
but the resolver asked for a snapshot with
|
||||
|
||||
```bash
|
||||
engineSnapshotsJson "$idx" "$snapshot_id"
|
||||
```
|
||||
|
||||
and that function's second parameter is an app **tag** filter. So it ran
|
||||
`restic snapshots --tag app=<snapshot-id>`, matched nothing, and returned 1 on
|
||||
every call. `storageRestoreAppTo` has a fallback for engines that cannot report
|
||||
paths (borg genuinely cannot), so it took that fallback *always* — restoring in
|
||||
place, which is exactly the blocker above, reinstated in the code written to
|
||||
remove it.
|
||||
|
||||
It survived because nothing failed: the fallback is a legitimate branch, and the
|
||||
restore preflight's only symptom was printing every app's size as `?`. Fixed by
|
||||
`engineSnapshotPaths`, an engine call that takes a snapshot id because that is
|
||||
what it is for. The lesson generalises — **a check with a fallback needs a test
|
||||
that the check itself fires**, not just that the command succeeds
|
||||
(`scripts/dev/lp-preflight-test`).
|
||||
|
||||
## 10. Risks, in the order they'll bite
|
||||
|
||||
**10.1 — An unplugged drive is the top data-integrity risk.** `crontab_boot_app_reconcile.sh` brings **every** installed app up at boot. If a location's drive isn't mounted yet — or at all — docker cheerfully creates the bind-mount directories on the bare mountpoint and the app boots **empty**. Plug the drive back in and there are now two divergent copies, with the good one hidden underneath the mount. Mitigation is mandatory, not optional:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user