diff --git a/docs/roadmap/storage-locations.md b/docs/roadmap/storage-locations.md index a98b190..33d20c5 100644 --- a/docs/roadmap/storage-locations.md +++ b/docs/roadmap/storage-locations.md @@ -371,6 +371,27 @@ what it is for. The lesson generalises — **a check with a fallback needs a tes that the check itself fires**, not just that the command succeeds (`scripts/dev/lp-preflight-test`). +**What that actually cost, measured.** A restore onto a host whose containers +root differs from the backup's is the entire point of "rebuild my server", and +until this was fixed it restored *nothing* — silently, reporting success. The +in-place fallback builds restic's `--include` from the LOCAL root, so on a +relocated install the filter matched no path in the snapshot and zero bytes +landed. + +Verified end to end on a purpose-built install (`scripts/dev/lp-install-matrix` +case 4: system on one disk, apps and backups on another), restoring a real +13-app repository taken from a default-layout host: + +``` +This snapshot was taken at '/libreportal-containers/bookstack'; + restoring to '/mnt/lptest2/libreportal-containers/bookstack'. +✓ Restored bookstack to /mnt/lptest2/libreportal-containers/bookstack +``` + +Every app takes the stage-and-move branch there, and it crosses devices +(staging on disk 1, destination on disk 2), so `app-adopt` exercises its +copy-then-remove path rather than the same-device `mv`. + ## 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: