From 9647f1d158c8afab2b75ee89c93b1c04eb32eeb5 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sun, 25 Oct 2026 11:04:46 +0100 Subject: [PATCH] =?UTF-8?q?Restore-truth=20run=20(2026-10-25):=20D47=20+?= =?UTF-8?q?=20D48=20recorded=20(09=20=C2=A73=20decisions=20256,=20257;=20C?= =?UTF-8?q?ONTEXT);=2007=20=C2=A76.5=20(R-1271=20cause=20+=20the=20future-?= =?UTF-8?q?date=20rule),=20=C2=A76.6=20(D48=20order,=20the=20R-698=20sente?= =?UTF-8?q?nce),=20=C2=A78.2d=20(D47),=20=C2=A78.2e=20(R-1270);=20register?= =?UTF-8?q?=20217=20->=20219=20(R-1278,=20R-1279=20opened;=20R-1269/1270/1?= =?UTF-8?q?271=20VERIFY;=20notes=20R-1206,=20R-1243=20dated=20check=20done?= =?UTF-8?q?=20read-only,=20R-232=20moved=20one=20day);=20STATUS=20D49=20+?= =?UTF-8?q?=20Monday=20list;=20evidence=20(9202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTEXT.md | 10 ++ REPORT-restore-truth-2026-10-25.md | 59 ++++++++ STATUS.md | 9 +- .../architecture/07-backup-architecture.md | 91 ++++++++++++- .../architecture/09-update-architecture.md | 18 +++ .../audits/restore-truth-2026-10-25/README.md | 90 +++++++++++++ .../after/_keptprobe/romm/record.json | 43 ++++++ .../after/_keptprobe/romm/walk.log | 21 +++ .../after/_pullprobe/vikunja/record.json | 68 ++++++++++ .../after/_pullprobe/vikunja/walk.log | 27 ++++ .../_unitprobe2/adventurelog/record.json | 34 +++++ .../restore-page-kept-section.html | 20 +++ .../adventurelog/unit-1-after-backup.sha256 | 8 ++ .../adventurelog/unit-2-set-aside.sha256 | 8 ++ .../adventurelog/unit-3-primary-now.sha256 | 4 + .../after/_unitprobe2/adventurelog/walk.log | 26 ++++ .../after/_unitprobe2/tandoor/record.json | 34 +++++ .../tandoor/restore-page-kept-section.html | 20 +++ .../tandoor/unit-1-after-backup.sha256 | 9 ++ .../tandoor/unit-2-set-aside.sha256 | 9 ++ .../tandoor/unit-3-primary-now.sha256 | 4 + .../after/_unitprobe2/tandoor/walk.log | 17 +++ .../after/adventurelog-run.txt | 26 ++++ .../after/romm-run.txt | 21 +++ .../_unitprobe2/tandoor/record.json | 27 ++++ .../tandoor/restore-page-kept-section.html | 0 .../tandoor/unit-1-after-backup.sha256 | 9 ++ .../tandoor/unit-2-set-aside.sha256 | 9 ++ .../tandoor/unit-3-primary-now.sha256 | 4 + .../_unitprobe2/tandoor/walk.log | 13 ++ .../after/run1-list-hidden/tandoor-run.txt | 13 ++ .../_pullprobe/vikunja/record.json | 22 +++ .../_pullprobe/vikunja/walk.log | 7 + .../after/run1-probe-bug/vikunja-run.txt | 15 +++ .../after/tandoor-run.txt | 17 +++ .../after/vikunja-run.txt | 27 ++++ .../before/_unitprobe/tandoor/record.json | 33 +++++ .../tandoor/unit-1-after-backup.txt | 126 ++++++++++++++++++ .../tandoor/unit-2-after-keep-remove.txt | 126 ++++++++++++++++++ .../unit-3-after-reinstall-capture.txt | 126 ++++++++++++++++++ .../before/_unitprobe/tandoor/walk.log | 15 +++ .../before/tandoor-run.txt | 15 +++ .../redproof/d47-guard-off.txt | 26 ++++ .../redproof/d47-guard-on.txt | 10 ++ .../d47-kept-list-without-offsite.txt | 6 + .../redproof/d47-stacks-adopt-off.txt | 9 ++ .../redproof/d47-web-form-off.txt | 7 + .../redproof/d48-no-prepull.txt | 15 +++ .../redproof/r1270-warn-only.txt | 12 ++ .../redproof/r1270-web.txt | 6 + .../redproof/r1271-future-ignored.txt | 16 +++ .../redproof/remove-undo-copy-before.txt | 5 + .../tools/keptprobe.py | 102 ++++++++++++++ .../tools/pullprobe.py | 121 +++++++++++++++++ .../restore-truth-2026-10-25/tools/rows.py | 84 ++++++++++++ .../tools/unitprobe2.py | 126 ++++++++++++++++++ documentation/backlog/OPEN-ITEMS.md | 19 +-- documentation/backlog/STATUS-HISTORY.md | 4 + 58 files changed, 1834 insertions(+), 14 deletions(-) create mode 100644 REPORT-restore-truth-2026-10-25.md create mode 100644 documentation/audits/restore-truth-2026-10-25/README.md create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/record.json create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/walk.log create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/record.json create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/walk.log create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/record.json create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/restore-page-kept-section.html create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/unit-1-after-backup.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/unit-2-set-aside.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/unit-3-primary-now.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/walk.log create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/tandoor/record.json create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/tandoor/restore-page-kept-section.html create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/tandoor/unit-1-after-backup.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/tandoor/unit-2-set-aside.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/tandoor/unit-3-primary-now.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/tandoor/walk.log create mode 100644 documentation/audits/restore-truth-2026-10-25/after/adventurelog-run.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/after/romm-run.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-list-hidden/_unitprobe2/tandoor/record.json create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-list-hidden/_unitprobe2/tandoor/restore-page-kept-section.html create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-list-hidden/_unitprobe2/tandoor/unit-1-after-backup.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-list-hidden/_unitprobe2/tandoor/unit-2-set-aside.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-list-hidden/_unitprobe2/tandoor/unit-3-primary-now.sha256 create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-list-hidden/_unitprobe2/tandoor/walk.log create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-list-hidden/tandoor-run.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-probe-bug/_pullprobe/vikunja/record.json create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-probe-bug/_pullprobe/vikunja/walk.log create mode 100644 documentation/audits/restore-truth-2026-10-25/after/run1-probe-bug/vikunja-run.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/after/tandoor-run.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/after/vikunja-run.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/before/_unitprobe/tandoor/record.json create mode 100644 documentation/audits/restore-truth-2026-10-25/before/_unitprobe/tandoor/unit-1-after-backup.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/before/_unitprobe/tandoor/unit-2-after-keep-remove.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/before/_unitprobe/tandoor/unit-3-after-reinstall-capture.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/before/_unitprobe/tandoor/walk.log create mode 100644 documentation/audits/restore-truth-2026-10-25/before/tandoor-run.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/d47-guard-off.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/d47-guard-on.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/d47-kept-list-without-offsite.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/d47-stacks-adopt-off.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/d47-web-form-off.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/d48-no-prepull.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/r1270-warn-only.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/r1270-web.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/r1271-future-ignored.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/redproof/remove-undo-copy-before.txt create mode 100644 documentation/audits/restore-truth-2026-10-25/tools/keptprobe.py create mode 100644 documentation/audits/restore-truth-2026-10-25/tools/pullprobe.py create mode 100644 documentation/audits/restore-truth-2026-10-25/tools/rows.py create mode 100644 documentation/audits/restore-truth-2026-10-25/tools/unitprobe2.py diff --git a/CONTEXT.md b/CONTEXT.md index cf769758..5792111f 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -16,6 +16,16 @@ > and holds nothing of its own; this file does hold its own content, namely the standing rulings below. +> **2026-10-25 08:38 — operator rulings by starting the R-1269 brief: D47 and D48** (`09` §3 decisions 256, 257; +> `audits/restore-truth-2026-10-25/README.md`). **D47:** an existing recovery unit is never changed in part — its +> definition and data are written only together, by a backup of the same install; a unit an earlier install left is set +> aside whole and stays restorable (`07` §8.2d). **D48:** every restore path resolves and pulls every image its +> definition names before the first change to the app; a failed pull is a refusal with the app untouched (`07` §6.6). +> **Confirmed, no change:** `07` §6.6's version rule; R-698 and R-933. Built the same day, controller commits only (rides +> v0.343.0): `02daebe` (D47 / R-1269), `b680db8` (R-1270: a restore whose app does not start is never a success; the +> safest reading — no automatic pour-back, the undo copy kept, a late start turns it into a success), `2d71270` (D48), +> `bd9f4f7` (R-1271: a copy dated more than 10 minutes in the future is never „the newest"). + > **2026-10-24 (afternoon, attended) — two DooPlex backup alarms — DONE.** One cause: the 2026-10-23 window reboot > restarted `postgresql-2`; CNPG 1.29 sets the role `postgres` from the superuser secret, then from the > `bootstrap.initdb` owner secret (`owner: postgres`), so `postgres-superuser` is in force at every start; the dump diff --git a/REPORT-restore-truth-2026-10-25.md b/REPORT-restore-truth-2026-10-25.md new file mode 100644 index 00000000..693b3e59 --- /dev/null +++ b/REPORT-restore-truth-2026-10-25.md @@ -0,0 +1,59 @@ +# REPORT — a backup is never changed by a new install, a restore downloads first, a restore tells the truth (2026-10-25, unattended, commit only) + +**Plain words first.** +- **R-1269 is fixed and proven:** a reinstall no longer writes into the old backup. The old backup is set aside whole, + listed on the restore page, and restores with its own password (Tandoor and AdventureLog on 9202: the account back). +- **D48 download-first on every restore path that starts a definition (the unit restore and with it the second + drive's unit and whole restore, both kept-data loads and a set-aside unit; the off-site restore; the second drive's + file restore; the no-unit fallback).** An unpullable version is refused and the app is never stopped (proven). +- **R-1270:** a restore whose app does not start says so — never „it worked"; the old copy is kept (proven). +- **R-1271:** cause — the other box's off-site copy was dated in the future (its clock), and „newest wins" took it; + now a copy more than 10 minutes in the future never counts as the newest (proven on a forged copy). +- **One question for you:** D49 in STATUS — after a restore whose app does not start, keep the data and wait (CC's + pick, done) or pour the old data back by itself. + +**Safest readings taken** (also at the head of `documentation/audits/restore-truth-2026-10-25/README.md`): an install +identity field, not the data stamps; the set-aside unit is a D25 kept copy (remove-with-backups deletes it, as it does +other kept copies); a „partial write" means one half into another install's unit; R-1270 keeps the data and the undo +copy (no new retention rule); D48 tells a deleted version from a busy registry by Docker's answer; 10 minutes of clock +skew; the `.fab` import left to its own row. + +**Architecture read:** `07` §6.3, §6.5, §6.6, §8 (D20/D22, §8.2a D25); `03` (drive identity); `09` §3 decisions 14, +40, 53; rows R-1269–R-1271, R-1206, R-698, R-933, R-1267. + +**Each proof, before (`e1613ae`, 9202 on 0.342.0) → after (9202 on 0.343.0-rc.2):** +- R-1269: the kept unit's `app.yaml` rewritten (`cbfcb538…` → `e19d2610…`), restore broken → set aside byte for byte, + restored, the account back, 0 password errors (Tandoor, AdventureLog). +- R-1270: `ok: true` over a `starting` app → `ok: false`, `not_started`, the honest sentence, the undo copy kept. +- D48: the first pull after the stop (code order) → an unpullable pin refused, the container's start time unchanged. +- R-1271: the future copy chosen (sweep) → the own copy chosen; alone, the future copy marked and said. + +**Commits.** Controller: `02daebe` (D47) CI 2311 ✓, `b680db8` (R-1270) 2312 ✓, `2d71270` (D48) 2313 ✓, `bd9f4f7` +(R-1271) 2314 ✓, `1f9c863` (the kept list without off-site) 2315 ✓, `1f82959` (remove deletes the undo copy) 2316 ✓, +`e8d2151` (REPORT). felhom.eu: this commit (`07` §6.5/§6.6/§8.2d/§8.2e, `09` §3 decisions 256–257, CONTEXT, register, +STATUS, STATUS-HISTORY, the audit with its evidence and tools) — CI by hash in the final message. Test images +`0.343.0-rc.1` (`bd9f4f7`) and `0.343.0-rc.2` (`1f9c863`) in the registry; nothing released. + +**Teardown.** Machine: 9202 only; my throwaway apps removed through the product; two empty folders and one undo copy of +mine removed by hand after checking; my rc images removed from its Docker; back on 0.342.0; the apps found running still +run. Host: the session's 9202 password and session files shredded. Hub: provisioned nothing. ep0: nothing. + +**Register:** before 217, after 219; opened 2 (R-1278, R-1279), closed 0; R-1269, R-1270, R-1271 → VERIFY (fixed on +main, wait for the release); notes on R-1206 (cross-reference) and R-1243 (its dated check done, read-only); R-232's +dated check moved one day (this brief: no DooPlex work). + +**Observations:** +- FILED: R-1278 (a volume app's reinstall does not offer its kept backup). +- FILED: R-1279 (the `.fab` import removes the app's volumes before its pull — D48 does not cover it). +- FIXED without a row (found live, red-proved): the kept-copies list was hidden on a box without off-site (`1f9c863`); + a kept undo copy outlived remove-with-backups (`1f82959`). +- NOT-A-FINDING: Immich's 404 after the sweep's load — the copy brought its own address (`photos.`), as every unit + restore does; the app was healthy there. +- NOT-A-FINDING: „immich: definition REFUSED by the allow-list" on 9202 — present before this run's image; an earlier + session's Immich, not this change. +- NOT-A-FINDING: the D48 refusal reads „Visszaállítás sikertelen: …nem lehet letölteni… Az alkalmazáshoz nem + nyúltunk" — the page's failure frame around an honest sentence; true as written. + +**Secrets:** used only through `sec`; the evidence scanned for the box password and the session tokens (the CSRF token +in two saved page snippets was the positive control and is blanked); units compared by sha256 only. **System poster:** +no fact changed. **Instruction files:** none edited. diff --git a/STATUS.md b/STATUS.md index baa8ae84..3c46a2e4 100644 --- a/STATUS.md +++ b/STATUS.md @@ -2,7 +2,7 @@ **Ready for Tester 2? Yes — tell the friend go (hand-over list: `documentation/pilot/TESTER2-handover.md`).** -**Updated 2026-10-25 (night).** 65 catalog apps walked on a fresh box: 52 work, 10 with a problem, 0 broken; worst: a restore after a reinstall breaks an app (R-1269). +**Updated 2026-10-25 (Sunday).** A reinstall keeps old backups whole; a restore downloads first and tells the truth. ## What works - **The Plex attack (10-17 → 10-23) did not reach Felhom's secrets** (R-1241). @@ -18,13 +18,13 @@ - The hub mails alarms and recoveries and keeps a weekly whole-box copy on ep0; CC uses its own limited token (map F1, F11, G15). ## What is broken -- **P1 (fixed on main, NOT released):** a power cut while an app on a drive is restored can later pour old data over new data (R-1251); one wrong line in an app's backup settings deletes its second-drive copy (R-1252, P2). +- **P1 (fixed on main, NOT released):** a power cut while an app on a drive is restored can later pour old data over new data (R-1251); one wrong line in an app's backup settings deletes its second-drive copy (R-1252, P2); three restore holes (R-1269–R-1271). - **P1:** any hacked app on DooPlex can read the hub's nightly backups, and maybe the signing keys (R-1241, homelab session); about 12 homelab logins still use a password that was public, and the public Gitea repo is not decided (R-925, yours). - Tester 2 is off since 2026-10-04: old emergency password, no off-site check, no bootstrap (R-1139, R-1104, R-862). The scratch box cannot use agent features (R-1083). - DooPlex: something sets the shared checkout to „bare" (R-935). ## What we work on -- Dated checks, run by CC. 2026-10-25: tonight's database copy reaches the restic sweep (R-232). 2026-10-26: each hub daily job ran once on the clock-change day (R-1183). 2026-10-27: the weekly clean-up window (R-435; the logs of the last one were lost to restarts). 2026-10-30: D35, website and installer to Cloudflare, starts (R-1228, ruled yes). +- Dated checks, run by CC. 2026-10-26: tonight's database copy reaches the restic sweep (R-232); each hub daily job ran once on the clock-change day (R-1183). 2026-10-27: the weekly clean-up window (R-435; the logs of the last one were lost to restarts). 2026-10-30: D35, website and installer to Cloudflare, starts (R-1228, ruled yes). ## Waiting on you — decide @@ -32,6 +32,7 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te | # | Row | Question | Pick (why) | The other option costs | If you do nothing | Blocked | |---|---|---|---|---|---|---| +| D49 | R-1270 | A restore's data is back but the app does not start in 90 s. Keep the restored data and wait, or pour the old data back by itself? | **Keep and wait** (a slow first start is common; the old copy is kept, a late start turns it into a success; you get one alarm) | pour back by itself: a slow but correct restore is thrown away | the data stays restored, the old copy stays for support | — | | D46 | R-1272 | Put Homepage behind the family gate, like Glance? | **Yes** (a stranger now sees the box's CPU, memory and disk, and later the family's links; one line in the template, tried on the drill first) | leave it open: anyone who finds the address sees those | it stays open to strangers | — | | D45 | R-1266 | Seven places where a design document says one thing and the code does another. One line each, with a pick: `documentation/audits/review-round-2-2026-10-24/D44-D45-picks.md`. Answer „all picks" or name the ones you disagree with. | **Yes — the text follows the code** (each is how the system works today; you read every changed sentence) | the code follows the text: six code changes, one of them to the box's door for you | the documents keep saying what is not true | — | | D44 | R-1265 | 25 behaviours the code has but no document named. One line each, with a pick (21 confirm, 4 small changes): the same file. Answer „all picks" or name the ones you disagree with. | **All picks** (each was read in the code) | name the ones to change; each becomes a row | the notes stay marked „undocumented" | — | @@ -51,7 +52,7 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te 6. BIOS: on the N100, read „After Power Loss"; on the HP, set „Bypass F1 Prompt on Configuration Changes" to Enable. Since 2026-10-14. 7. Pin the first Facebook post (R-917), and look at the new cover in the Facebook phone app (R-919). Since 2026-10-12. -**Monday 2026-10-26, release list (attended).** 1. Controller v0.343.0: the restore and backup fixes (R-1251–R-1253), R-1250. If not: the P1 stays open. 2. Agent v0.165.0 + your vouch: BYO keeps its SSH (R-1257). 3. Hub v0.170.0: the recovery package in one step (R-1254). 4. Catalog: n8n usage data off; OpenGist 256 MB. +**Monday 2026-10-26, release list (attended).** 1. Controller v0.343.0: the restore and backup fixes (R-1251–R-1253, R-1269–R-1271), R-1250. If not: the P1 stays open. 2. Agent v0.165.0 + your vouch: BYO keeps its SSH (R-1257). 3. Hub v0.170.0: the recovery package in one step (R-1254). 4. Catalog: n8n usage data off; OpenGist 256 MB. **Day, 2026-10-23 — your do list.** 1. Print the break-glass sheet (`documentation/runbooks/break-glass-sheet.md`, the part from „The sheet”, one A4), fill it by hand, keep it outside the home (D32; R-923, R-924). If not: after a DooPlex loss no off-site copy opens. 2. On the hub's Hosts page: Discard appliance 49, and delete host Tester4-aa9466. If not: two dead entries alarm. diff --git a/documentation/architecture/07-backup-architecture.md b/documentation/architecture/07-backup-architecture.md index 5cd1da35..eba97409 100644 --- a/documentation/architecture/07-backup-architecture.md +++ b/documentation/architecture/07-backup-architecture.md @@ -937,6 +937,26 @@ holds no database, or **does not record its data version** (§6.6 — a unit wri a mixed or mismatched unit is refused by §6.6's own rule. Then a dated folder's files move back and the one unit restore runs. The downloaded copy is removed on every path. A failed download or a refusal leaves the kept files as they were. +**[FACT] 2026-10-25 — why the „another drive" check let another box's copy through (R-1271; catalog sweep 2026-10-24, +Tester4: Paperless-ngx, Nextcloud, Immich).** The check (`KeptCopyAt`, `internal/backup/kept_load.go`) compares the +unit's `app.yaml` `HDD_PATH` with the drive the kept files sit on. That is a mount PATH, and every box mounts its first +data drive under the same name (`/mnt/felhom-drives/hdd_1`) — so a copy taken of another box's disk matches. It is a +path check, not a physical identity, and it stays one: loading an old box's data on a new box is what off-site is for. +What chose the wrong copy was the DATE: the rehearsal box's clock had been set to 2026-10-28, its off-site snapshot +carried that time, this box had no data time of its own to cap it (`offsiteDataTime`), and „newer than every local +copy" took it over the family's own copy of the same evening. Immich's 20 minutes of 404 were the ROUTING, not a half +load: the unit brought the old box's `SUBDOMAIN` (`photos`), so the app answered at `photos.` and the probe +asked `immich.`; its containers were healthy. + +**[DESIGN] 2026-10-25 — a copy dated in the future is never „the newest" (R-1271; brief 2026-10-25 Part 4, the safest +reading; controller `bd9f4f7`, unreleased, rides v0.343.0).** A copy whose date lies more than **10 minutes** past this box's clock (`KeptClockSkew`: NTP keeps a box +within a second; ten minutes covers a box that synced late after a power cut) is future-dated. It never counts as the +newest: the newest copy with a true date wins (a tie goes local); the household's own local copy wins over any +off-site copy that is not newer by a true date. A future-dated copy is offered only when no other copy exists — then +the question says its date is in the future and does not recommend it (the „use" button is not the primary one). The +question always names the copy it will use. An off-site copy is never refused only because another box of the +household made it. + **It is NOT backed up.** No tier captures `/kept` or a leftover `appdata/` of a removed app; the page says so („Erről nem készül mentés." / "This is not backed up."). What brings it back into an app is the unit it carries (or the app's own unit on the drive), listed per row as „Visszatölthető innen" / "Can be loaded from". @@ -1027,13 +1047,28 @@ requires a database dump written after the conversion whose recorded engine is t image is re-pulled on restore. A version its maker has deleted cannot start. Measured 2026-09-26: the 42 ladder digests all resolve today (`audits/version-travel-2026-09-26/A7/`). **Accepted as a known limit — operator ruling 2026-10-12 (S8, `09` §3 decision 203; R-698 closed).** What a household meets: a restore whose version the maker has -deleted stops at the image pull, the app stays as it was, and the household uses another copy or a newer version. +deleted stops at the image pull, the app stays as it was (since D48 by ORDER — the pull comes before the stop; before it, +by the D22 put-back), and the household uses another copy or a newer version. The operator's follow-up — *„will need to mirror the apps we support later, just to be sure"* — is **R-933**: mirror the images of every catalog app we support into our own registry, before scale. Until it is built, this limit holds. **Since decision 53 (`09` §3, 2026-09-30 evening):** a box keeps only the image each app service runs and the one before it; older images of the app are deleted. A restore that needs an older version re-pulls it — as before; the limit above is unchanged, and kept data (decision 40) is not touched by the image clean-up. +**[DESIGN] 2026-10-25 — a restore downloads first (operator ruling D48, `09` §3 decision 257; controller `2d71270`, +unreleased — rides v0.343.0).** „The app stays as it was" in the paragraph above is now true BY ORDER, not by the D22 +put-back. After the existing refusals and before the first stop or change, every restore path resolves every image the +definition that will RUN names — present on the box, or pulled now — under the image-work lock held from the first +check until the restore's last start (R-863: the image clean-up cannot delete a pulled image before the start). A pull +that fails is a REFUSAL: the app is not stopped, its data is not moved, and the household reads which version, and +why: „Ennek a mentésnek a verzióját (%s) nem lehet letölteni: a készítője már nem kínálja…" when Docker says the version +does not exist (`manifest unknown`, `not found`, `pull access denied`), „…most nem lehet letölteni… Próbáld újra +később…" for everything else (a busy or unreachable registry). The operator gets one `backup_run_failures` line (leg +`restore-image-unavailable`). The paths: the local unit restore — and with it the second drive's unit restore, the +second drive's whole restore (its `CheckOnly` pass carries the pull, so its file half never runs first), a kept-data +load from a unit and from off-site, and a set-aside unit (D47) — the off-site restore, the second drive's file restore +and the no-unit fallback. Not covered: the `.fab` import — it removes the running app's volumes before its definition is pulled (R-1279). + ### 6.7 Why an off-site run failed — the failure classifier (R-571) **[FACT, read from source 2026-10-05, felhom-controller `114ff27`]** When an off-site (restic) run fails, the @@ -1651,6 +1686,60 @@ removed the old container at start; a restore probe during the copy was refused; 15-second test limit → the container removed, the partial copy stopped growing. Controller: `internal/backup/tier2_copy_lifecycle.go`. +### 8.2d An earlier install's unit is set aside, never rewritten [DESIGN, operator ruling D47, 2026-10-25 08:38; `09` §3 decision 256; R-1269 — controller `02daebe`, unreleased, rides v0.343.0] + +**[FACT] Measured before (controller 0.342.0, which is `e1613ae` for these files):** the catalog sweep 2026-10-24 +(three times) and 9202 2026-10-25 (`audits/restore-truth-2026-10-25/before/`): Tandoor, one account, „Mentés most", +remove keeping data and backups, install again. Within five minutes the periodic refresh rewrote ONLY the unit's +`compose/app.yaml` (checksum `cbfcb538…` → `e19d2610…`) — the new install's database password — beside the OLD install's +data. Its one „same definition" test was the image pins (`recovery_unit.go:194`, the R-696 `frozen` rule), and a +reinstall of the same version has the same pins. A restore then paired the new password with the old data directory: +`password authentication failed` ×44 (app) / ×23 (postgres), the app stayed `starting`, the account was gone from +view. The next night's dump legs would have overwritten the old data as well, and the stale-drive prune deleted a unit +on another drive whatever install it belonged to. + +**[DESIGN] The rule.** A recovery unit's definition and its data are written only together, by a backup of the same +install. Every install has an identity (`install_id` in its `app.yaml`): minted at a fresh install and at a `.fab` +import, carried by every load-then-save, taken FROM the unit by a restore (the app then holds that unit's data), and +minted once for an app installed before D47. The unit records it in its own `app.yaml`. Every writer of a unit asks +first — the capture and its refresh, the night database dump, the pre-backup and the update's pre-backup dumps, the +volume dump, the second drive's unit copy, the stale-drive prune. A unit of ANOTHER install (different identities; for +a unit written before D47, a carried secret that differs — a reinstall mints new ones) is **moved whole** (a rename on +its own drive; never a copy, never an edit) to `/backups/set-aside///` and recorded as a +kept copy (§8.2a's record: kind `unit`, reason `earlier_install`); the new install then gets its own unit from its +first backup. A move that cannot be done **refuses the write** and leaves the old unit byte for byte (an ERROR line +names the app and both identities). Nothing moves a unit while that app is being restored. + +**What the household sees.** The restore page lists the set-aside unit under „Megőrzött másolatok" („…· egy korábbi +telepítés mentése") with **„Visszaállítás"** — the one unit-restore body, with the unit's own database password — and +„Eltávolítás". Only those two, and the app's remove with „delete its backups too", ever remove it (the §8.2a / R-1252 H9 +rule). After a restore from it, the app is that unit's install; the app's own unit of the install it replaced is then +set aside at the next backup — never lost. + +**Known limit, stated.** A box that reinstalled and refreshed BEFORE this release already holds a rewritten unit; its +old password is gone and nothing can bring it back. A unit from before D47 of an app with no carried secret has no +signal: it is treated as this install's (the old behaviour) and gets the identity at its next write. +**Why a volume app's reinstall asks no kept-data question:** the question (§6.5, decision 36) is about the app's drive +FOLDER (`${HDD_PATH}` binds under `appdata/`); a volume app keeps nothing there — „remove, keep my data" removes its named +volumes and keeps only its backups — so the install starts empty, and the kept backup is now the set-aside unit on the +restore page. (The missing offer at install is its own row, R-1278.) + +### 8.2e A restore whose app does not start is never „success" [DESIGN, R-1270, 2026-10-25 — controller `b680db8`, unreleased, rides v0.343.0] + +**[FACT] Measured before:** the health check after a restore was a WARN on every path, so a Tandoor restore whose app +stayed `starting` was recorded `ok: true`, „…visszaállítva — az alkalmazás újraindult." (catalog sweep 2026-10-24; 9202 +2026-10-25, `audits/restore-truth-2026-10-25/before/`). **[DESIGN]** Every restore path — the unit restore (so the +second drive's unit and whole restore, a kept load, a set-aside unit), the off-site restore, the second drive's file +restore and the no-unit fallback — returns „not started" when the app does not reach running within the health wait +(90 s). The household reads „A(z) %s: az adatokat visszatöltöttük, de az alkalmazás még nem indult el. Várj pár percet, +majd nyisd meg újra. Ha így marad, szólj nekünk." (the record `ok: false`, `not_started: true`); the operator gets one +`backup_run_failures` line (leg `restore-not-started`). **The safest reading, the operator may change it:** a timeout +does NOT pour the old data back — a slow first start (a database migration) is common, and a put-back would throw away a +correct restore. The data stays restored and the restore's undo copy is KEPT — the same „kept for support" state a failed +put-back leaves (§8 D20/D22), so no new retention rule. A watcher looks 30 more minutes: when the app runs, the record +turns to success („…elindult: a visszaállítás kész.") and the copy is removed, as after any successful restore; if it +never runs, the copy stays for support. + ### 8.2c Decisions in code that no document recorded [DESIGN — undocumented, found 2026-10-24, review round 2 — the operator confirms them through one register row] Read at `file:line` on `main` (controller `321df1f`, hub `44d19042`) by the main session: diff --git a/documentation/architecture/09-update-architecture.md b/documentation/architecture/09-update-architecture.md index 07d6645f..0b491593 100644 --- a/documentation/architecture/09-update-architecture.md +++ b/documentation/architecture/09-update-architecture.md @@ -1089,6 +1089,24 @@ its length, and both fixes cost something the household would notice — operato `plex: security fix CVE-2026-96652,CVE-2026-96654,CVE-2026-96655,CVE-2026-96656 taken` and ended `done` in 30.1 s after the update's second-drive copy and undo copy. Released as controller 0.341.0, global floor 11:24 UTC. +### 2026-10-25 (08:38) — D47: nothing changes an existing backup; D48: a restore downloads first (operator rulings by starting the run; R-1269) + +256. **An existing recovery unit is never changed in part (D47).** A unit's definition (compose, pins, `app.yaml`) and + its data are written only together, by a backup of the same install. A new install never adopts, rewrites or + deletes a unit that an earlier install left; that unit is set aside whole and stays restorable. *Operator ruling + 2026-10-25 08:38, taken by starting the R-1269 brief.* Why: on 2026-10-24 the catalog sweep measured three times + that a reinstall's own five-minute refresh wrote the new install's database password into the unit „remove — keep + backups" had kept; a restore then could not open the old data (R-1269). Built: every install has an identity + (`install_id`), the unit records it, and every writer asks first — `07` §8.2a „An earlier install's unit is set + aside" (controller, unreleased; rides v0.343.0). +257. **Every restore path resolves and pulls every image its definition names before the first change to the app; a + failed pull is a refusal with the app untouched (D48).** *Operator ruling 2026-10-25 08:38, taken by starting the + brief.* Why: the restore stopped the app and moved its data first and pulled only inside the database-only start; + a version that could not be downloaded then ended in the D22 put-back, a full stop-and-pour-back for nothing. + Built: `07` §6.6 „The limit — the image is not in the backup" (controller, unreleased; rides v0.343.0). + **Confirmed, no change:** `07` §6.6 — a restore brings the app back at its data's version, then the guarded update + climbs the ladder; R-698 (a deleted version cannot come back) and R-933 (our own image mirror) are unchanged. + ### 2026-10-15 (07:48–08:20) — bake first; Plex through its own key; HSTS one day (recorded before the media build) 247. ~~**Bake first.** A controller version is RELEASED only when its golden is baked.~~ **REVERSED by decision 250, diff --git a/documentation/audits/restore-truth-2026-10-25/README.md b/documentation/audits/restore-truth-2026-10-25/README.md new file mode 100644 index 00000000..d6da6d41 --- /dev/null +++ b/documentation/audits/restore-truth-2026-10-25/README.md @@ -0,0 +1,90 @@ +# A backup is never changed by a new install, a restore downloads first, and a restore tells the truth (2026-10-25) + +Brief: Sunday 2026-10-25, up to 12 h, commit only. Operator rulings D47 and D48 (2026-10-25 08:38, `09` §3 decisions +256, 257). Box: scratch guest **9202** on demo-hp (`ssh hp`), controller 0.342.0 for the BEFORE proofs (its restore, +unit and kept-data code is byte-identical to `e1613ae`: no commit between `42cda07` and `e1613ae` touched +`recovery_unit.go`, `restore_unit.go`, `restore_dbcreds.go`), then **0.343.0-rc.1** built from `bd9f4f7` (an `-rc` tag +is never offered to a household) for the AFTER proofs; 0.342.0 put back at the end. + +## Safest readings taken (the brief allowed no question) + +1. **Install identity:** a new field `install_id` (16 random hex), not the data stamps — the stamps say which VERSION + wrote the data, not which install. A unit from before D47 has none: then a carried secret that differs on both sides + means another install (a reinstall mints new ones); with no differing secret it is this install's (the old behaviour). +2. **Where the set-aside unit lives and how it is removed:** `/backups/set-aside///` on its + own drive (a rename), recorded as a D25 kept copy — listed on the restore page with „Visszaállítás" and + „Eltávolítás". The app's remove with „delete its backups too" deletes it too: the D25 / R-1252 H9 rule for kept copies. +3. **A „partial write"** = one half (definition or data) written into a unit whose other half belongs to another + install. The writer refuses it when the set-aside cannot be done. A definition-only unit of a fresh install (no data + yet) is not partial — it is that install's whole unit. +4. **R-1270 (the brief's own safest reading):** a health timeout does not pour the old data back; the data stays, the + undo copy is kept (the „kept for support" state a failed put-back leaves — no new retention rule), a late start + within 30 minutes turns the record into a success and releases the copy. +5. **D48 sentences:** Docker's „manifest unknown / not found / pull access denied / repository does not exist" reads as + „the maker no longer offers it"; everything else (busy, rate limit, timeout, unreachable) as „try again later". +6. **R-1271:** the clock-skew allowance is **10 minutes**. A future-dated copy that is the only copy is still offered + (it may be the household's own), marked and not recommended. The „another drive" check stays a path check (the + brief: an old box's data on a new box is what off-site is for). +7. **The `.fab` import is not a „unit" path** and is not changed here; its gap is a row (R-1279). + +## Before (9202, controller 0.342.0 = `e1613ae` for these files) — `before/` + +`catalog-sweep-2026-10-24/tools/unitprobe.py tandoor` on 9202 (`before/_unitprobe/tandoor/`): install, one account, +„Mentés most" (unit 07:53:46), remove keeping data and backups, install again, wait for the controller's next capture, +„Visszaállítás". + +- **R-1269:** 08:00:36 „Recovery unit captured for tandoor" — the kept unit's `app.yaml` checksum `cbfcb538…` → + `e19d2610…`, `created_at` 07:53:46 → 08:00:36, the data files unchanged. Cause at `file:line`: + `felhom-controller/controller/internal/backup/recovery_unit.go:194` (`e1613ae`) — the refresh's only „same + definition" test is the pins (`frozen`), and a reinstall of the same version has the same pins; the writes at + `:254-258` then put the new install's `app.yaml` (its new database password) beside the old data. The restore takes + the unit's password (`restore_dbcreds.go` R-1106 rule) — the new one — over the old data directory. +- **R-1270:** the restore record `ok: true`, „A(z) tandoor: 3 adatkötet és az adatbázis visszaállítva — az alkalmazás + újraindult." while the app stayed `starting`; `password authentication failed` ×44 (app) / ×23 (postgres); the account + not there (`restore_unit.go:567-569` at `e1613ae`: the health failure is a WARN). +- **Why a volume app's reinstall asks no kept-data question:** the question is about the app's drive FOLDER + (`${HDD_PATH}` binds under `appdata/`, `stacks/kept.go` `OldAppDataPaths`; `07` §6.5, decision 36). Tandoor keeps + nothing there; „remove, keep my data" removed its three named volumes (the record's `volumes_removed`) and kept only + its backup. A gap for the household → **R-1278**. + +## After (9202, controller 0.343.0-rc.2 = `1f9c863`) — `after/` + +| proof | before (`e1613ae`) | after | +|---|---|---| +| **R-1269 / D47, Tandoor** (`tools/unitprobe2.py`, `after/_unitprobe2/tandoor/`) | the refresh rewrote the kept unit's `app.yaml`; the restore paired the new password with the old data, `starting`, account gone | 09:13:03 „the recovery unit of an earlier install (77ea…; the install ids differ) is SET ASIDE whole → `backups/set-aside/tandoor/20261025T091303Z`"; the set-aside unit is install A's unit byte for byte (9 files, sha256 each); „Megőrzött másolatok" offers „Visszaállítás"; restored in 42 s, `running`, the account reads back, 0 password errors (app and postgres); remove with data leaves nothing, the set-aside folder included | +| **R-1269 / D47, AdventureLog** (`after/_unitprobe2/adventurelog/`) | (sweep: the same fault on its re-run) | set aside 09:23:03, byte for byte (8 files), restored, `running`, the item back, 0 password errors, nothing left | +| **D48** (`tools/pullprobe.py vikunja`, `after/_pullprobe/vikunja/`) | the first pull came after the stop (code order, `restore_unit.go` at `e1613ae`) | the unit's pin edited to `vikunja:0.0.0-felhom-d48-missing` → „REFUSED … before anything was touched: … could not be downloaded (the version does not exist any more)"; the household read „…verzióját (vikunja:0.0.0-felhom-d48-missing) nem lehet letölteni: a készítője már nem kínálja. Az alkalmazáshoz nem nyúltunk…"; the container's `StartedAt` the same before and after (09:29:54.57); the item still there; the original unit back byte for byte → a normal restore worked, the item back | +| **R-1270** (same run) | `ok: true` „…az alkalmazás újraindult." over `starting` | the unit's pin edited to `busybox:1.36.1` (pulls, exits at once) → after the 90 s wait the record `ok: false`, `not_started: true`, „A(z) vikunja: az adatokat visszatöltöttük, de az alkalmazás még nem indult el. Várj pár percet…"; the undo copy kept (`restore-undo/vikunja/20261025T093149Z`); the original back → a normal restore worked, the item back | +| **R-1271** (`tools/keptprobe.py romm`, `after/_keptprobe/romm/`) | the future-dated off-site copy chosen over the family's own (sweep) | a forged second-drive copy dated 2026-10-28 06:39 beside the app's own unit: the question named „saját mentés, 2026-10-25 10:38", no future flag; the own unit moved away for a moment: the forged copy alone was offered with `use_future: true` and „Figyelem: ennek a mentésnek a dátuma (2026-10-28 07:39) a jövőben van…"; with the own unit back, „use my kept data" loaded tier 1 (`backups/primary/romm`, 09:38:55Z), the item back | + +**Two findings of the live runs, fixed without a row (each red-proved):** (1) run 1 of the Tandoor proof +(`after/run1-list-hidden/`) found the restore page listing NO kept copy on 9202: the „Megőrzött másolatok" section sat +inside the off-site card, and 9202 has no off-site — so a box without off-site never listed a D25 copy either. Fixed in +`1f9c863` (one named template, two call sites, parity fixtures unchanged); rc.2 then listed it. (2) The R-1270 run's +kept undo copy outlived the app's remove with its backups; fixed in `1f82959` (the remove deletes +`backups/restore-undo/`), proven by its test only — the copy on 9202 was removed by hand (2.6 MB, mine). +`after/run1-probe-bug/` is a probe of mine that crashed on its own bug before touching anything. + +**The `file:line` causes (at `e1613ae`):** R-1269 `backup/recovery_unit.go:194` (the `frozen` pins test) and `:254-258` +(the writes); R-1270 `backup/restore_unit.go:567-569`, the same WARN at `offbox_reconstitute.go` (the off-site path), +`tier2_restore.go` (the file restore) and `restore.go` (the fallback); D48 `restore_unit.go:497` (the stop) before +`:552` (the first `compose up`, the DB-only start); R-1271 `backup/kept_load.go:179-184` (`KeptNewer`: the newer date +wins, future or not) and `:97` (the „another drive" check compares `HDD_PATH`, a mount path). + +**Not covered and filed:** R-1278 (a volume app's reinstall does not offer its kept backup), R-1279 (the `.fab` import +removes the app's volumes before its pull). + +**Observation, NOT-A-FINDING:** 9202 logs „immich: definition REFUSED by the allow-list" at every start — it was there +before this run's image (an earlier session's Immich on `/mnt/sizing-bench`); not this run's. + + +## Teardown + +- **Machine:** 9202 only — my throwaway installs (Tandoor ×3, AdventureLog, Vikunja, RomM) each removed through the + product with their data; the two empty folders my runs left (RomM's `appdata/romm`, the empty `backups/set-aside/`) + and the one kept undo copy (above) removed by hand after checking they held nothing else; the `0.343.0-rc.1/.2` images + removed from its Docker; the controller back on 0.342.0 (`/etc/felhom-controller-image`); the apps found running + (Immich, Paperless-ngx, the file browser, traefik) running. No VM, no LXC created; Tester 1 and the thin pool untouched. +- **Host:** DooPlex — the session's 9202 password file in the session scratchpad shredded at the end. The rc images + stay in the registry as test tags (never offered to a household). +- **Hub:** provisioned nothing (9202 has no hub). **ep0:** nothing. diff --git a/documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/record.json b/documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/record.json new file mode 100644 index 00000000..d1d37601 --- /dev/null +++ b/documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/record.json @@ -0,0 +1,43 @@ +{ + "app": "romm", + "install": true, + "seed": true, + "backup": { + "code": "200", + "seconds": 75, + "status": "{\"db_dump\": {\"count\": 3, \"duration\": \"1m13.631435029s\", \"last_run\": \"2026-10-25T09:40:08.943436205Z\", \"success\": true}, \"enabled\": true, \"running\": false}" + }, + "own_unit": "/mnt/felhom-drives/scratch_hdd/backups/primary/romm", + "forged_at": "\"at\": \"2026-10-28T06:39:39Z\"\n\"at\": \"2026-10-28T06:39:39Z\"", + "q1_code": "409", + "q1": { + "code": "kept_data_choice", + "use_offered": true, + "use_desc": "Az adatbázist innen töltjük vissza: saját mentés, 2026-10-25 10:38. A régi fájlokkal indítjuk az alkalmazást. Ami ezután változott, hiányozhat.", + "use_future": null, + "use_warn": null, + "use_off": "" + }, + "q2_code": "409", + "q2": { + "code": "kept_data_choice", + "use_offered": true, + "use_desc": "Az adatbázist innen töltjük vissza: második meghajtó, 2026-10-28 07:39. A régi fájlokkal indítjuk az alkalmazást. Ami ezután változott, hiányozhat.", + "use_future": true, + "use_warn": "Figyelem: ennek a mentésnek a dátuma (2026-10-28 07:39) a jövőben van. A mentést készítő doboz órája rosszul járhatott. Csak akkor válaszd, ha biztosan ez a ti mentésetek.", + "use_off": "" + }, + "use_ok": true, + "load_status": "{\"running\": false, \"op\": \"restore\", \"stack\": \"romm\", \"started_at\": \"2026-10-25T09:41:21.356199563Z\", \"last\": {\"op\": \"restore\", \"stack\": \"romm\", \"ok\": true, \"message\": \"A(z) RomM a megőrzött adataival fut.\", \"finished_at\": \"2026-10-25T09:43:03.140979706Z\"}, \"last_recent\": true}", + "item_after_load": true, + "controller_lines": "2026/10/25 09:41:10 image_retention.go:238: [INFO] [stacks] image retention (remove of romm): pass over 42 image(s) of [mariadb redis rommapp/romm] — 2 candidate(s), 2 deleted, the rest kept\n2026/10/25 09:41:14 kept_install.go:88: [INFO] [api] Deploy romm: the drive already holds its old data [/mnt/felhom-drives/scratch_hdd/appdata/romm/resources] (0 bytes) — asking the household (use offered: true, future-dated: false)\n2026/10/25 09:41:17 kept_install.go:88: [INFO] [api] Deploy romm: the drive already holds its old data [/mnt/felhom-drives/scratch_hdd/appdata/romm/resources] (0 bytes) — asking the household (use offered: true, future-dated: true)\n2026/10/25 09:41:21 kept_install.go:105: [INFO] [api] Deploy romm: USE MY KEPT DATA — loading from /mnt/felhom-drives/scratch_hdd/backups/primary/romm (tier 1, 2026-10-25T09:38:55Z) under the kept files [/mnt/felhom-drives/scratch_hdd/appdata/romm/resources]\n2026/10/25 09:41:21 restore_dbcreds.go:114: [INFO] [backup] Restore romm: database password(s) [DB_PASSWORD MYSQL_ROOT_PASSWORD] come from the backup, [] stay as installed (older than the data) — values not logged (R-1106)\n2026/10/25 09:41:21 restore_unit.go:410: [INFO] [backup] Restoring romm from recovery unit /mnt/felhom-drives/scratch_hdd/backups/primary/romm: images=3, secrets recovered=3/3, data_keys=0\n2026/10/25 09:41:32 restore_pull.go:103: [INFO] [backup] Restore romm: downloaded rommapp/romm:5.3.1@sha256:0d66b4ea152a237c7f24b95e87459f46d3c596a7c0b35a82f26bc971487278b3 before anything was touched (11s, D48)\n2026/10/25 09:41:57 restore_pull.go:103: [INFO] [backup] Restore romm: downloaded mariadb:11.8@sha256:79d59758afc91b89b120b0a8904d637f5a3b3e1c4900f29b740d6d46c72fef68 before anything was touched (25s, D48)\n2026/10/25 09:41:57 restore.go:225: [INFO] [backup] Restoring Docker volume romm_romm_assets for romm\n2026/10/25 09:42:08 restore.go:263: [DEBUG] [backup] Volume romm_romm_assets restored successfully\n2026/10/25 09:42:08 restore.go:225: [INFO] [backup] Restoring Docker volume romm_romm_config for romm\n2026/10/25 09:42:08 restore.go:263: [DEBUG] [backup] Volume romm_romm_config restored successfully\n2026/10/25 09:42:08 restore.go:225: [INFO] [backup] Restoring Docker volume romm_romm_db_data for romm\n2026/10/25 09:42:13 restore.go:263: [DEBUG] [backup] Volume romm_romm_db_data restored successfully\n2026/10/25 09:42:13 restore.go:225: [INFO] [backup] Restoring Docker volume romm_romm_redis_data for romm\n2026/10/25 09:42:13 restore.go:263: [DEBUG] [backup] Volume romm_romm_redis_data restored successfully\n2026/10/25 09:42:13 restore.go:268: [INFO] [backup] Restored 4 Docker volume(s) for romm\n2026/10/25 09:42:14 restore_db.go:87: [INFO] [backup] Restore romm: replaying DB dump into romm-db (mariadb)\n2026/10/25 09:42:18 restore_db.go:97: [INFO] [backup] Restore romm: replayed 1 DB dump(s)\n2026/10/25 09:42:32 restore.go:308: [DEBUG] [backup] Post-restore health check: romm not yet running, waiting...\n2026/10/25 09:42:37 restore.go:308: [DEBUG] [backup] Post-restore health check: romm not yet running, waiting...\n2026/10/25 09:42:42 restore.go:308: [DEBUG] [backup] Post-restore health check: romm not yet running, waiting...\n2026/10/25 09:42:48 restore.go:308: [DEBUG] [backup] Post-restore health check: romm not yet running, waiting...\n2026/10/25 09:42:53 restore.go:308: [DEBUG] [backup] Post-restore health check: romm not yet running, waiting...\n2026/10/25 09:42:58 restore.go:308: [DEBUG] [backup] Post-restore health check: romm not yet running, waiting...\n2026/10/25 09:43:03 restore.go:303: [DEBUG] [backup] Post-restore health check: romm is running\n2026/10/25 09:43:03 restore_unit.go:591: [INFO] [backup] Restore-from-unit completed: romm — 4 volume(s) of 4 listed, 1 database(s) of 1 listed\n2026/10/25 09:43:03 kept_load.go:391: [INFO] [backup] kept load romm from /mnt/felhom-drives/scratch_hdd/backups/primary/romm done in 1m42s (volumes 4/4, dbs 1/1)\n", + "after_remove": { + "containers": "", + "volumes": "", + "appyaml": "", + "appdata": "/mnt/felhom-drives/scratch_hdd/appdata/romm", + "kept": "", + "subdomain": "404" + }, + "forged_left": "ls: cannot access '/mnt/sys_drive/felhom-data/backups/secondary/romm': No such file or directory" +} \ No newline at end of file diff --git a/documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/walk.log b/documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/walk.log new file mode 100644 index 00000000..75f161a4 --- /dev/null +++ b/documentation/audits/restore-truth-2026-10-25/after/_keptprobe/romm/walk.log @@ -0,0 +1,21 @@ +09:37:11Z [1] required fields filled beyond DOMAIN/SUBDOMAIN: ['HDD_PATH'] +09:37:12Z [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'} +09:38:47Z [1] deployed, controller state=running, pinned={'romm': 'rommapp/romm:5.3.1', 'romm-db': 'mariadb:11.8', 'romm-redis': 'redis:7-alpine'} +09:38:47Z gate: arcade is gated — passed as the household (cookie set) +09:38:55Z romm: POST /api/users http=201 +09:38:55Z [4] Mentés most -> 200 {'ok': True, 'message': 'Mentés elindítva'} +09:40:23Z forged a future-dated second-drive copy: "at": "2026-10-28T06:39:39Z" +"at": "2026-10-28T06:39:39Z" (own unit: /mnt/felhom-drives/scratch_hdd/backups/primary/romm) +09:41:09Z [5] stop 200, remove KEEPING data -> 200 {'ok': True, 'data': {'removed': 'romm', 'volumes_removed': ['romm_romm_assets', 'romm_romm_config', 'romm_romm_db_data', 'romm_romm_redis_data'], 'hdd_paths_removed': [], 'hdd_paths_preserved': ['/mn +09:41:14Z [1] required fields filled beyond DOMAIN/SUBDOMAIN: ['HDD_PATH'] +09:41:14Z [question, own copy + future copy] 409 {"code": "kept_data_choice", "use_offered": true, "use_desc": "Az adatbázist innen töltjük vissza: saját mentés, 2026-10-25 10:38. A régi fájlokkal indítjuk az alkalmazást. Ami ezután változott, hiányozhat.", "use_future": null, "use_warn": null, "use_off": ""} +09:41:17Z [1] required fields filled beyond DOMAIN/SUBDOMAIN: ['HDD_PATH'] +09:41:17Z [question, the future copy alone] 409 {"code": "kept_data_choice", "use_offered": true, "use_desc": "Az adatbázist innen töltjük vissza: második meghajtó, 2026-10-28 07:39. A régi fájlokkal indítjuk az alkalmazást. Ami ezután változott, hiányozhat.", "use_future": true, "use_warn": "Figyelem: ennek a mentésnek a dátuma (2026-10-28 07:39) a jövőben van. A mentést készítő doboz órája rosszul járhatott. Csak akkor válaszd, ha biztosan ez a ti mentésetek.", "use_off": ""} +09:41:21Z [1] required fields filled beyond DOMAIN/SUBDOMAIN: ['HDD_PATH'] +09:41:21Z [1] deploy -> 202 {'ok': True, 'message': 'A(z) RomM megőrzött adatainak betöltése elindult.'} +09:42:26Z [1] deployed, controller state=degraded, pinned={'romm': 'rommapp/romm:5.3.1', 'romm-db': 'mariadb:11.8', 'romm-redis': 'redis:7-alpine'} +09:42:26Z [1] NOTE: the controller's own state is 'degraded', not 'running' — recorded, not treated as a failure; the fixture's front-door wait is the real gate +09:43:06Z load: {"running": false, "op": "restore", "stack": "romm", "started_at": "2026-10-25T09:41:21.356199563Z", "last": {"op": "restore", "stack": "romm", "ok": true, "message": "A(z) RomM a megőrzött adataival fut.", "finished_at": "2026-10-25T09:43:03.140979706Z"}, "last_recent": true} +09:43:15Z romm: login as the seeded user http=200 ok=True +09:43:15Z item after use-my-kept-data: True +09:43:57Z [7] stop 200, remove with data -> 200 {'ok': True, 'data': {'removed': 'romm', 'volumes_removed': ['romm_romm_assets', 'romm_romm_config', 'romm_romm_db_data', 'romm_romm_redis_data'], 'hdd_paths_removed': ['/mnt/felhom-drives/scratch_hdd diff --git a/documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/record.json b/documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/record.json new file mode 100644 index 00000000..46cf0ecf --- /dev/null +++ b/documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/record.json @@ -0,0 +1,68 @@ +{ + "app": "vikunja", + "install": true, + "seed": true, + "backup": { + "code": "200", + "seconds": 55, + "status": "{\"db_dump\": {\"count\": 2, \"duration\": \"50.712761411s\", \"last_run\": \"2026-10-25T09:31:32.624265386Z\", \"success\": true}, \"enabled\": true, \"running\": false}" + }, + "unit_files": 7, + "d48_restore": { + "points": 1, + "location": [ + "location: /backups/restore?flash=flash.restore.started" + ], + "seconds": 10, + "status": "{\"running\": false, \"op\": \"restore\", \"stack\": \"vikunja\", \"started_at\": \"2026-10-25T09:30:11.335278772Z\", \"last\": {\"op\": \"restore\", \"stack\": \"vikunja\", \"ok\": false, \"message\": \"Visszaállítás sikertelen: Ennek a mentésnek a verzióját (vikunja:0.0.0-felhom-d48-missing) nem lehet letölteni: a készítője már nem kínálja. Az alkalmazáshoz nem nyúltunk. Válassz egy másik mentést.\", \"finished_at\": \"2026-10-25T09:30:13.943080647Z\"}, \"last_recent\": true}", + "state": "running" + }, + "d48_started_before": "/vikunja 2026-10-25T09:29:54.57273795Z running", + "d48_started_after": "/vikunja 2026-10-25T09:29:54.57273795Z running", + "d48_app_untouched": true, + "d48_item_still_there": true, + "original_back_1": true, + "normal_restore_1": { + "points": 1, + "location": [ + "location: /backups/restore?flash=flash.restore.started" + ], + "seconds": 10, + "status": "{\"running\": false, \"op\": \"restore\", \"stack\": \"vikunja\", \"started_at\": \"2026-10-25T09:30:31.410646319Z\", \"last\": {\"op\": \"restore\", \"stack\": \"vikunja\", \"ok\": true, \"message\": \"A(z) vikunja: 2 adatkötet visszaállítva — az alkalmazás újraindult.\", \"finished_at\": \"2026-10-25T09:30:38.26202133Z\"}, \"last_recent\": true}", + "state": "running" + }, + "item_after_normal_restore_1": true, + "r1270_restore": { + "points": 1, + "location": [ + "location: /backups/restore?flash=flash.restore.started" + ], + "seconds": 100, + "status": "{\"running\": false, \"op\": \"restore\", \"stack\": \"vikunja\", \"started_at\": \"2026-10-25T09:31:47.895007425Z\", \"last\": {\"op\": \"restore\", \"stack\": \"vikunja\", \"ok\": false, \"message\": \"A(z) vikunja: az adatokat visszatöltöttük, de az alkalmazás még nem indult el. Várj pár percet, majd nyisd meg újra. Ha így marad, szólj nekünk.\", \"finished_at\": \"2026-10-25T09:33:26.51097487Z\", \"not_started\": true}, \"last_recent\": true}", + "state": "restarting" + }, + "r1270_state": "restarting", + "r1270_undo_copies": "20261025T093149Z", + "original_back_2": true, + "normal_restore_2": { + "points": 1, + "location": [ + "location: /backups/restore?flash=flash.restore.started" + ], + "seconds": 10, + "status": "{\"running\": false, \"op\": \"restore\", \"stack\": \"vikunja\", \"started_at\": \"2026-10-25T09:33:38.075945508Z\", \"last\": {\"op\": \"restore\", \"stack\": \"vikunja\", \"ok\": true, \"message\": \"A(z) vikunja: 2 adatkötet visszaállítva — az alkalmazás újraindult.\", \"finished_at\": \"2026-10-25T09:33:44.816871537Z\"}, \"last_recent\": true}", + "state": "running" + }, + "item_after_normal_restore_2": true, + "controller_lines": "2026/10/25 09:30:11 handlers.go:1852: [DEBUG] [web] backupRestoreHandler: stack=vikunja snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:30:11 handlers.go:1894: [WARN] [web] Restore requested (async): stack=vikunja, snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:30:11 restore_unit.go:398: [INFO] [backup] Restore vikunja: the data belongs to [vikunja/vikunja:0.0.0-felhom-d48-missing] (written 2026-10-25T09:29:53Z); the app ran [vikunja/vikunja:2.6.0@sha256:417ada6f94e81f0267aa2f007d0a811fc82d38dd2aa58351e3ea520ca01c2ea5] — it comes back at its data's version, an\n2026/10/25 09:30:11 restore_unit.go:410: [INFO] [backup] Restoring vikunja from recovery unit /mnt/sys_drive/felhom-data/backups/primary/vikunja: images=1, secrets recovered=1/1, data_keys=0\n2026/10/25 09:30:13 restore_pull.go:96: [ERROR] [backup] Restore REFUSED for vikunja before anything was touched: the image vikunja/vikunja:0.0.0-felhom-d48-missing could not be downloaded (the version does not exist any more; after 1s): exit status 1 — Error response from daemon: manifest for vikunja/vikunja:0.0.0-f\n2026/10/25 09:30:13 handlers.go:1902: [ERROR] [web] Restore failed (async): stack=vikunja: Ennek a mentésnek a verzióját (vikunja:0.0.0-felhom-d48-missing) nem lehet letölteni: a készítője már nem kínálja. Az alkalmazáshoz nem nyúltunk. Válassz egy másik mentést.\n2026/10/25 09:30:31 handlers.go:1852: [DEBUG] [web] backupRestoreHandler: stack=vikunja snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:30:31 handlers.go:1894: [WARN] [web] Restore requested (async): stack=vikunja, snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:30:31 restore_unit.go:410: [INFO] [backup] Restoring vikunja from recovery unit /mnt/sys_drive/felhom-data/backups/primary/vikunja: images=1, secrets recovered=1/1, data_keys=0\n2026/10/25 09:30:33 offbox_restore_undo.go:163: [INFO] [offbox] vikunja: the live volumes are copied before the restore (2 copied, 0 new from the snapshot) in 883ms — /mnt/sys_drive/felhom-data/backups/restore-undo/vikunja/20261025T093032Z (R-893)\n2026/10/25 09:30:33 restore_crash_putback.go:89: [INFO] [backup] vikunja: the restore copy is recorded — a power cut from here on puts the app back on start (R-1195)\n2026/10/25 09:30:33 restore.go:225: [INFO] [backup] Restoring Docker volume vikunja_vikunja_data for vikunja\n2026/10/25 09:30:34 restore.go:263: [DEBUG] [backup] Volume vikunja_vikunja_data restored successfully\n2026/10/25 09:30:34 restore.go:225: [INFO] [backup] Restoring Docker volume vikunja_vikunja_db for vikunja\n2026/10/25 09:30:34 restore.go:263: [DEBUG] [backup] Volume vikunja_vikunja_db restored successfully\n2026/10/25 09:30:34 restore.go:268: [INFO] [backup] Restored 2 Docker volume(s) for vikunja\n2026/10/25 09:30:38 restore.go:303: [DEBUG] [backup] Post-restore health check: vikunja is running\n2026/10/25 09:30:38 restore_unit.go:591: [INFO] [backup] Restore-from-unit completed: vikunja — 2 volume(s) of 2 listed, 0 database(s) of 0 listed\n2026/10/25 09:30:38 handlers.go:1906: [INFO] [web] Restore completed (async): stack=vikunja in 6.850941322s (volumes 2/2, dbs 0/0)\n2026/10/25 09:31:47 handlers.go:1852: [DEBUG] [web] backupRestoreHandler: stack=vikunja snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:31:47 handlers.go:1894: [WARN] [web] Restore requested (async): stack=vikunja, snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:31:47 restore_unit.go:398: [INFO] [backup] Restore vikunja: the data belongs to [busybox:1.36.1] (written 2026-10-25T09:31:31Z); the app ran [vikunja/vikunja:2.6.0@sha256:417ada6f94e81f0267aa2f007d0a811fc82d38dd2aa58351e3ea520ca01c2ea5] — it comes back at its data's version, and the update climbs from t\n2026/10/25 09:31:47 restore_unit.go:410: [INFO] [backup] Restoring vikunja from recovery unit /mnt/sys_drive/felhom-data/backups/primary/vikunja: images=1, secrets recovered=1/1, data_keys=0\n2026/10/25 09:31:50 offbox_restore_undo.go:163: [INFO] [offbox] vikunja: the live volumes are copied before the restore (2 copied, 0 new from the snapshot) in 960ms — /mnt/sys_drive/felhom-data/backups/restore-undo/vikunja/20261025T093149Z (R-893)\n2026/10/25 09:31:50 restore_crash_putback.go:89: [INFO] [backup] vikunja: the restore copy is recorded — a power cut from here on puts the app back on start (R-1195)\n2026/10/25 09:31:50 restore.go:225: [INFO] [backup] Restoring Docker volume vikunja_vikunja_data for vikunja\n2026/10/25 09:31:51 restore.go:263: [DEBUG] [backup] Volume vikunja_vikunja_data restored successfully\n2026/10/25 09:31:51 restore.go:225: [INFO] [backup] Restoring Docker volume vikunja_vikunja_db for vikunja\n2026/10/25 09:31:51 restore.go:263: [DEBUG] [backup] Volume vikunja_vikunja_db restored successfully\n2026/10/25 09:31:51 restore.go:268: [INFO] [backup] Restored 2 Docker volume(s) for vikunja\n2026/10/25 09:31:55 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:00 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:05 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:11 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:16 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:21 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:26 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:31 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:36 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:41 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:46 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:51 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:32:56 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:33:01 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:33:03 recovery_unit.go:478: [DEBUG] [backup] recovery-unit refresh skipped for vikunja — a restore of it runs\n2026/10/25 09:33:06 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:33:11 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:33:16 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:33:21 restore.go:308: [DEBUG] [backup] Post-restore health check: vikunja not yet running, waiting...\n2026/10/25 09:33:26 restore_verdict.go:53: [ERROR] [backup] vikunja: the unit restore put the data back, but the app did not start: stack vikunja did not reach running state within 1m30s after restore — NOT reported as a success; the restore copy is kept (/mnt/sys_drive/felhom-data/backups/restore-undo/vikunja/202610\n2026/10/25 09:33:26 offbox_restore_undo.go:174: [WARN] [offbox] vikunja: the restore's volume copy is KEPT for support at /mnt/sys_drive/felhom-data/backups/restore-undo/vikunja/20261025T093149Z\n2026/10/25 09:33:26 handlers.go:1902: [ERROR] [web] Restore failed (async): stack=vikunja: A(z) vikunja: az adatokat visszatöltöttük, de az alkalmazás még nem indult el. Várj pár percet, majd nyisd meg újra. Ha így marad, szólj nekünk.\n2026/10/25 09:33:38 handlers.go:1852: [DEBUG] [web] backupRestoreHandler: stack=vikunja snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:33:38 handlers.go:1894: [WARN] [web] Restore requested (async): stack=vikunja, snapshot=helyi from 172.18.0.4:37324\n2026/10/25 09:33:38 restore_unit.go:398: [INFO] [backup] Restore vikunja: the data belongs to [vikunja/vikunja:2.6.0@sha256:417ada6f94e81f0267aa2f007d0a811fc82d38dd2aa58351e3ea520ca01c2ea5] (written 2026-10-25T09:31:31Z); the app ran [busybox:1.36.1] — it comes back at its data's version, and the update climbs from t\n2026/10/25 09:33:38 restore_unit.go:410: [INFO] [backup] Restoring vikunja from recovery unit /mnt/sys_drive/felhom-data/backups/primary/vikunja: images=1, secrets recovered=1/1, data_keys=0\n2026/10/25 09:33:40 offbox_restore_undo.go:163: [INFO] [offbox] vikunja: the live volumes are copied before the restore (2 copied, 0 new from the snapshot) in 888ms — /mnt/sys_drive/felhom-data/backups/restore-undo/vikunja/20261025T093339Z (R-893)\n2026/10/25 09:33:40 restore_crash_putback.go:89: [INFO] [backup] vikunja: the restore copy is recorded — a power cut from here on puts the app back on start (R-1195)\n2026/10/25 09:33:40 restore.go:225: [INFO] [backup] Restoring Docker volume vikunja_vikunja_data for vikunja\n2026/10/25 09:33:40 restore.go:263: [DEBUG] [backup] Volume vikunja_vikunja_data restored successfully\n2026/10/25 09:33:40 restore.go:225: [INFO] [backup] Restoring Docker volume vikunja_vikunja_db for vikunja\n2026/10/25 09:33:41 restore.go:263: [DEBUG] [backup] Volume vikunja_vikunja_db restored successfully\n2026/10/25 09:33:41 restore.go:268: [INFO] [backup] Restored 2 Docker volume(s) for vikunja\n2026/10/25 09:33:44 restore.go:303: [DEBUG] [backup] Post-restore health check: vikunja is running\n2026/10/25 09:33:44 restore_unit.go:591: [INFO] [backup] Restore-from-unit completed: vikunja — 2 volume(s) of 2 listed, 0 database(s) of 0 listed\n2026/10/25 09:33:44 handlers.go:1906: [INFO] [web] Restore completed (async): stack=vikunja in 6.74043384s (volumes 2/2, dbs 0/0)\n", + "after_remove": { + "containers": "", + "volumes": "", + "appyaml": "", + "appdata": "", + "kept": "", + "subdomain": "404" + }, + "test_copy_removed": "ls: cannot access '/mnt/sys_drive/felhom-data/backups/d48-test-original/vikunja': No such file or directory", + "restore_undo_left": "20261025T093149Z" +} \ No newline at end of file diff --git a/documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/walk.log b/documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/walk.log new file mode 100644 index 00000000..36f81f9f --- /dev/null +++ b/documentation/audits/restore-truth-2026-10-25/after/_pullprobe/vikunja/walk.log @@ -0,0 +1,27 @@ +09:28:46Z [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'} +09:28:56Z [1] deployed, controller state=running, pinned={'vikunja': 'vikunja/vikunja:2.6.0'} +09:28:56Z gate: tasks is gated — passed as the household (cookie set) +09:28:57Z vikunja: register http=200 +09:28:57Z vikunja: create project http=201 +09:28:57Z [4] Mentés most -> 200 {'ok': True, 'message': 'Mentés elindítva'} +09:30:08Z [D48] the unit's pin → vikunja/vikunja:0.0.0-felhom-d48-missing :: compose/docker-compose.yml:1 manifest.json:7 data-stamps.json:4 +09:30:11Z [6] POST /backup/restore -> HTTP/2 302 ['location: /backups/restore?flash=flash.restore.started'] +09:30:21Z d48_restore: {"running": false, "op": "restore", "stack": "vikunja", "started_at": "2026-10-25T09:30:11.335278772Z", "last": {"op": "restore", "stack": "vikunja", "ok": false, "message": "Visszaállítás sikertelen: Ennek a mentésnek a verzióját (vikunja:0.0.0-felhom-d48-missing) nem lehet letölteni: a készítője már nem kínálja. Az alkalmazáshoz nem nyúltunk. Válassz egy másik mentést.", "finished_at": "2026-10- +09:30:24Z [D48] containers never restarted: True (/vikunja 2026-10-25T09:29:54.57273795Z running) +09:30:25Z vikunja: readback of the seeded project http=200 ok=True +09:30:31Z the original unit is back byte for byte: True +09:30:31Z [6] POST /backup/restore -> HTTP/2 302 ['location: /backups/restore?flash=flash.restore.started'] +09:30:41Z normal_restore_1: {"running": false, "op": "restore", "stack": "vikunja", "started_at": "2026-10-25T09:30:31.410646319Z", "last": {"op": "restore", "stack": "vikunja", "ok": true, "message": "A(z) vikunja: 2 adatkötet visszaállítva — az alkalmazás újraindult.", "finished_at": "2026-10-25T09:30:38.26202133Z"}, "last_recent": true} +09:30:41Z vikunja: readback of the seeded project http=200 ok=True +09:30:41Z normal restore: item back True, state running +09:30:41Z [4] Mentés most -> 200 {'ok': True, 'message': 'Mentés elindítva'} +09:31:47Z [R-1270] the unit's pin → busybox:1.36.1 (pulls, exits at once) :: compose/docker-compose.yml:1 manifest.json:7 data-stamps.json:4 +09:31:47Z [6] POST /backup/restore -> HTTP/2 302 ['location: /backups/restore?flash=flash.restore.started'] +09:33:28Z r1270_restore: {"running": false, "op": "restore", "stack": "vikunja", "started_at": "2026-10-25T09:31:47.895007425Z", "last": {"op": "restore", "stack": "vikunja", "ok": false, "message": "A(z) vikunja: az adatokat visszatöltöttük, de az alkalmazás még nem indult el. Várj pár percet, majd nyisd meg újra. Ha így marad, szólj nekünk.", "finished_at": "2026-10-25T09:33:26.51097487Z", "not_started": true}, "last_re +09:33:31Z [R-1270] state restarting, kept undo copy: 20261025T093149Z +09:33:38Z the original unit is back byte for byte: True +09:33:38Z [6] POST /backup/restore -> HTTP/2 302 ['location: /backups/restore?flash=flash.restore.started'] +09:33:48Z normal_restore_2: {"running": false, "op": "restore", "stack": "vikunja", "started_at": "2026-10-25T09:33:38.075945508Z", "last": {"op": "restore", "stack": "vikunja", "ok": true, "message": "A(z) vikunja: 2 adatkötet visszaállítva — az alkalmazás újraindult.", "finished_at": "2026-10-25T09:33:44.816871537Z"}, "last_recent": true} +09:33:48Z vikunja: readback of the seeded project http=200 ok=True +09:33:48Z normal restore 2: item back True, state running +09:34:24Z [7] stop 200, remove with data -> 200 {'ok': True, 'data': {'removed': 'vikunja', 'volumes_removed': ['vikunja_vikunja_data', 'vikunja_vikunja_db'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'Az alkalmazás nem tárolt diff --git a/documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/record.json b/documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/record.json new file mode 100644 index 00000000..f186d921 --- /dev/null +++ b/documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/record.json @@ -0,0 +1,34 @@ +{ + "app": "adventurelog", + "install": true, + "seed": true, + "backup": { + "code": "200", + "seconds": 70, + "status": "{\"db_dump\": {\"count\": 3, \"duration\": \"1m6.314033847s\", \"last_run\": \"2026-10-25T09:20:04.942724577Z\", \"success\": true}, \"enabled\": true, \"running\": false}" + }, + "reinstall": true, + "set_aside_line": "2026/10/25 09:23:03 unit_owner.go:182: [INFO] [backup] adventurelog: the recovery unit of an earlier install (39b3ae7e65d7c197; the install ids differ) is SET ASIDE whole → /mnt/sys_drive/felhom-data/backups/set-aside/adventurelog/20261025T092303Z; this install (920d6a875fa0dadf) gets its own unit from its first backup (D47)", + "set_aside_dirs": [ + "20261025T092303Z" + ], + "set_aside_byte_identical": true, + "restore_page_offers": true, + "restore": { + "seconds": 45, + "status": "{\"running\": false, \"op\": \"restore\", \"stack\": \"adventurelog\", \"started_at\": \"2026-10-25T09:23:47.915496662Z\", \"last\": {\"op\": \"restore\", \"stack\": \"adventurelog\", \"ok\": true, \"message\": \"A(z) adventurelog: 2 adatkötet és az adatbázis visszaállítva — az alkalmazás újraindult.\", \"finished_at\": \"2026-10-25T09:24:32.727338795Z\"}, \"last_recent\": true}" + }, + "state_after_restore": "running", + "item_after_restore": true, + "db_auth_errors_after_restore": "adventurelog: 0\nadventurelog-frontend: 0\nadventurelog-postgres: 0", + "controller_lines": "2026/10/25 09:18:03 recovery_unit.go:297: [INFO] [backup] Recovery unit captured for adventurelog → /mnt/sys_drive/felhom-data/backups/primary/adventurelog (images=3, secrets-referenced=2, data_keys=1, portable-carried=2/2, withheld=0)\n2026/10/25 09:18:22 healthprobe.go:196: [WARN] Health probe adventurelog: API GET :8000/api/ → Get \"http://adventurelog:8000/api/\": dial tcp 172.18.0.8:8000: connect: connection refused\n2026/10/25 09:20:04 recovery_unit.go:297: [INFO] [backup] Recovery unit captured for adventurelog → /mnt/sys_drive/felhom-data/backups/primary/adventurelog (images=3, secrets-referenced=2, data_keys=1, portable-carried=2/2, withheld=0)\n2026/10/25 09:23:03 unit_owner.go:182: [INFO] [backup] adventurelog: the recovery unit of an earlier install (39b3ae7e65d7c197; the install ids differ) is SET ASIDE whole → /mnt/sys_drive/felhom-data/backups/set-aside/adventurelog/20261025T092303Z; this install (920d6a875fa0dadf) gets its own unit\n2026/10/25 09:23:03 recovery_unit.go:297: [INFO] [backup] Recovery unit captured for adventurelog → /mnt/sys_drive/felhom-data/backups/primary/adventurelog (images=3, secrets-referenced=2, data_keys=1, portable-carried=2/2, withheld=0)\n2026/10/25 09:23:47 kept_copies.go:108: [WARN] [web] Restore of adventurelog from a set-aside unit requested (async): /mnt/sys_drive/felhom-data/backups/set-aside/adventurelog/20261025T092303Z from 172.18.0.4:37324\n2026/10/25 09:23:47 unit_owner.go:316: [INFO] [backup] restore adventurelog from the set-aside unit /mnt/sys_drive/felhom-data/backups/set-aside/adventurelog/20261025T092303Z (an earlier install, D47)\n2026/10/25 09:23:47 restore_dbcreds.go:114: [INFO] [backup] Restore adventurelog: database password(s) [DB_PASSWORD] come from the backup, [] stay as installed (older than the data) — values not logged (R-1106)\n2026/10/25 09:23:47 restore_unit.go:410: [INFO] [backup] Restoring adventurelog from recovery unit /mnt/sys_drive/felhom-data/backups/set-aside/adventurelog/20261025T092303Z: images=3, secrets recovered=2/2, data_keys=1\n2026/10/25 09:23:56 offbox_restore_undo.go:163: [INFO] [offbox] adventurelog: the live volumes are copied before the restore (2 copied, 0 new from the snapshot) in 4.55s — /mnt/sys_drive/felhom-data/backups/restore-undo/adventurelog/20261025T092351Z (R-893)\n2026/10/25 09:23:56 restore_crash_putback.go:89: [INFO] [backup] adventurelog: the restore copy is recorded — a power cut from here on puts the app back on start (R-1195)\n2026/10/25 09:23:56 restore.go:225: [INFO] [backup] Restoring Docker volume adventurelog_adventurelog_media for adventurelog\n2026/10/25 09:23:57 restore.go:263: [DEBUG] [backup] Volume adventurelog_adventurelog_media restored successfully\n2026/10/25 09:23:57 restore.go:225: [INFO] [backup] Restoring Docker volume adventurelog_adventurelog_postgres_data for adventurelog\n2026/10/25 09:24:01 restore.go:263: [DEBUG] [backup] Volume adventurelog_adventurelog_postgres_data restored successfully\n2026/10/25 09:24:01 restore.go:268: [INFO] [backup] Restored 2 Docker volume(s) for adventurelog\n2026/10/25 09:24:01 deploy.go:866: [INFO] [stacks] adventurelog: the restored data belongs to install 39b3ae7e65d7c197 (was 920d6a875fa0dadf) — its backups follow it (D47)\n2026/10/25 09:24:02 restore_db.go:87: [INFO] [backup] Restore adventurelog: replaying DB dump into adventurelog-postgres (postgres)\n2026/10/25 09:24:08 restore_db.go:97: [INFO] [backup] Restore adventurelog: replayed 1 DB dump(s)\n2026/10/25 09:24:12 restore.go:308: [DEBUG] [backup] Post-restore health check: adventurelog not yet running, waiting...\n2026/10/25 09:24:17 restore.go:308: [DEBUG] [backup] Post-restore health check: adventurelog not yet running, waiting...\n2026/10/25 09:24:22 restore.go:308: [DEBUG] [backup] Post-restore health check: adventurelog not yet running, waiting...\n2026/10/25 09:24:27 restore.go:308: [DEBUG] [backup] Post-restore health check: adventurelog not yet running, waiting...\n2026/10/25 09:24:32 restore.go:303: [DEBUG] [backup] Post-restore health check: adventurelog is running\n2026/10/25 09:24:32 restore_unit.go:591: [INFO] [backup] Restore-from-unit completed: adventurelog — 2 volume(s) of 2 listed, 1 database(s) of 1 listed\n", + "after_remove": { + "containers": "", + "volumes": "", + "appyaml": "", + "appdata": "", + "kept": "", + "subdomain": "404" + }, + "set_aside_after_remove": "ls: cannot access '/mnt/sys_drive/felhom-data/backups/set-aside/adventurelog': No such file or directory" +} \ No newline at end of file diff --git a/documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/restore-page-kept-section.html b/documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/restore-page-kept-section.html new file mode 100644 index 00000000..40aea44b --- /dev/null +++ b/documentation/audits/restore-truth-2026-10-25/after/_unitprobe2/adventurelog/restore-page-kept-section.html @@ -0,0 +1,20 @@ +Megőrzött másolatok +

Ezek a második meghajtón lévő másolatok olyan mappákhoz tartoznak, amelyek most nem érhetők el: a meghajtó nincs csatlakoztatva, már nincs a gépen, vagy a mappa hiányzik. Megőrizzük őket, amíg te el nem távolítod őket.

+
+ + +
+ +
+ adventurelog + a(z) sys_drive meghajtóról megőrzött másolat · egy korábbi telepítés mentése (újratelepítés előtt készült) · 288,9 MB · 2026. 10. 25. 10:23 +
+
+ +
+ + + +