night 2026-09-24: A1/A2/A3/B live evidence; chaos schedule drawn (seed 20260924)
gates / gates (push) Successful in 29s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-24 13:05:29 +02:00
parent b33a33130e
commit 1cedf94d6b
45 changed files with 1889 additions and 2 deletions
@@ -0,0 +1,3 @@
gitea.dooplex.hu/admin/felhom-controller:0.269.0
gitea.dooplex.hu/admin/felhom-controller:0.269.0 Up 6 seconds (healthy)
@@ -0,0 +1,41 @@
{
"controller": "gitea.dooplex.hu/admin/felhom-controller:0.269.0",
"press_a": {
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "safety-dump",
"label": "Adatb\u00e1zis pillanatk\u00e9p\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 2.1,
"phase": "pulling",
"label": "\u00daj verzi\u00f3 let\u00f6lt\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 4.1,
"phase": "failed",
"label": "A friss\u00edt\u00e9s nem siker\u00fclt",
"updating": false,
"error": "Az \u00faj verzi\u00f3 let\u00f6lt\u00e9se nem siker\u00fclt, ez\u00e9rt a friss\u00edt\u00e9s elmaradt. Az alkalmaz\u00e1s a kor\u00e1bbi verzi\u00f3val fut tov\u00e1bb.",
"hold": null
}
],
"duration_s": 4.1,
"final_phase": "failed",
"update_error": "Az \u00faj verzi\u00f3 let\u00f6lt\u00e9se nem siker\u00fclt, ez\u00e9rt a friss\u00edt\u00e9s elmaradt. Az alkalmaz\u00e1s a kor\u00e1bbi verzi\u00f3val fut tov\u00e1bb.",
"hold_reason": null,
"state": "running"
},
"log_a": "2026/09/24 10:19:49 backup.go:467: [DEBUG] groupStacksByDrive: /mnt/felhom-drives/scratch_hdd/userdata/nextcloud \u2192 [nextcloud]\n2026/09/24 10:19:49 recovery_unit.go:224: [INFO] [backup] Recovery unit captured for nextcloud \u2192 /mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud (images=3, secrets-referenced=3, data_keys=0, portable-carried=2/2, withheld=1)\n2026/09/24 10:20:48 update.go:775: [INFO] [stacks] update nextcloud: precondition met \u2014 Tier 2 (second drive) copy from 2026-09-24T09:12:08Z (1h9m0s old, limit 24h0m0s)\n2026/09/24 10:20:48 dbdump.go:266: [DEBUG] DumpOne: starting dump for container=nextcloud-db, stack=nextcloud, dbType=mariadb, dest=/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql\n2026/09/24 10:20:49 dbdump.go:410: [INFO] [backup] DB dump: nextcloud-db \u2192 pre-restore-20260924T102048Z-nextcloud-mariadb.sql (854.3 KB, 478ms, 131 tables)\n2026/09/24 10:20:49 update_guard.go:478: [INFO] [backup] update safety dump for nextcloud: 1 file(s) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql]\n2026/09/24 10:20:49 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql]\n",
"mirror": "== /mnt/felhom-drives/scratch_hdd/userdata/romm/backups/secondary/nextcloud\nhdd\nrecovery-unit\nfelhom-seed-1-7cb158.txt\nfelhom-seed-0-e19728.txt\nfelhom-seed-2-8620d3.txt\n",
"record": "{\"enabled\": true, \"method\": \"rsync\", \"destination_path\": \"/mnt/felhom-drives/scratch_hdd/userdata/romm\", \"schedule\": \"daily\", \"last_run\": \"2026-09-24T09:12:08Z\", \"last_status\": \"ok\", \"last_success\": \"2026-09-24T09:12:08Z\", \"success_tracked\": true, \"unit_package_date\": \"2026-09-24T09:12:06Z\", \"last_duration\": \"1s\", \"last_size_human\": \"1.0 GB\"}\n"
}
@@ -0,0 +1,25 @@
12:20:43 drill: notag (backing-up + Tier 2, pull fails)
12:20:48 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
12:20:48 + 0.0s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
12:20:50 + 2.1s phase=pulling label=Új verzió letöltése… err=None hold=None
12:20:52 + 4.1s phase=failed label=A frissítés nem sikerült err=Az új verzió letöltése nem sikerült, ezért a frissítés elmaradt. Az alkalmazás a korábbi verzióval fut tovább. hold=None
12:20:56 log (a):
2026/09/24 10:19:49 backup.go:467: [DEBUG] groupStacksByDrive: /mnt/felhom-drives/scratch_hdd/userdata/nextcloud → [nextcloud]
2026/09/24 10:19:49 recovery_unit.go:224: [INFO] [backup] Recovery unit captured for nextcloud → /mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud (images=3, secrets-referenced=3, data_keys=0, portable-carried=2/2, withheld=1)
2026/09/24 10:20:48 update.go:775: [INFO] [stacks] update nextcloud: precondition met — Tier 2 (second drive) copy from 2026-09-24T09:12:08Z (1h9m0s old, limit 24h0m0s)
2026/09/24 10:20:48 dbdump.go:266: [DEBUG] DumpOne: starting dump for container=nextcloud-db, stack=nextcloud, dbType=mariadb, dest=/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql
2026/09/24 10:20:49 dbdump.go:410: [INFO] [backup] DB dump: nextcloud-db → pre-restore-20260924T102048Z-nextcloud-mariadb.sql (854.3 KB, 478ms, 131 tables)
2026/09/24 10:20:49 update_guard.go:478: [INFO] [backup] update safety dump for nextcloud: 1 file(s) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql]
2026/09/24 10:20:49 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql]
12:20:57 drill: back to 34.0.4
12:21:00 mirrors:
== /mnt/felhom-drives/scratch_hdd/userdata/romm/backups/secondary/nextcloud
hdd
recovery-unit
felhom-seed-1-7cb158.txt
felhom-seed-0-e19728.txt
felhom-seed-2-8620d3.txt
12:21:03 Tier-2 record: {"enabled": true, "method": "rsync", "destination_path": "/mnt/felhom-drives/scratch_hdd/userdata/romm", "schedule": "daily", "last_run": "2026-09-24T09:12:08Z", "last_status": "ok", "last_success": "2026-09-24T09:12:08Z", "success_tracked": true, "unit_package_date": "2026-09-24T09:12:06Z", "last_duration": "1s", "last_size_human": "1.0 GB"}
@@ -0,0 +1,25 @@
12:20:43 drill: notag (backing-up + Tier 2, pull fails)
12:20:48 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
12:20:48 + 0.0s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
12:20:50 + 2.1s phase=pulling label=Új verzió letöltése… err=None hold=None
12:20:52 + 4.1s phase=failed label=A frissítés nem sikerült err=Az új verzió letöltése nem sikerült, ezért a frissítés elmaradt. Az alkalmazás a korábbi verzióval fut tovább. hold=None
12:20:56 log (a):
2026/09/24 10:19:49 backup.go:467: [DEBUG] groupStacksByDrive: /mnt/felhom-drives/scratch_hdd/userdata/nextcloud → [nextcloud]
2026/09/24 10:19:49 recovery_unit.go:224: [INFO] [backup] Recovery unit captured for nextcloud → /mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud (images=3, secrets-referenced=3, data_keys=0, portable-carried=2/2, withheld=1)
2026/09/24 10:20:48 update.go:775: [INFO] [stacks] update nextcloud: precondition met — Tier 2 (second drive) copy from 2026-09-24T09:12:08Z (1h9m0s old, limit 24h0m0s)
2026/09/24 10:20:48 dbdump.go:266: [DEBUG] DumpOne: starting dump for container=nextcloud-db, stack=nextcloud, dbType=mariadb, dest=/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql
2026/09/24 10:20:49 dbdump.go:410: [INFO] [backup] DB dump: nextcloud-db → pre-restore-20260924T102048Z-nextcloud-mariadb.sql (854.3 KB, 478ms, 131 tables)
2026/09/24 10:20:49 update_guard.go:478: [INFO] [backup] update safety dump for nextcloud: 1 file(s) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql]
2026/09/24 10:20:49 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T102048Z-nextcloud-mariadb.sql]
12:20:57 drill: back to 34.0.4
12:21:00 mirrors:
== /mnt/felhom-drives/scratch_hdd/userdata/romm/backups/secondary/nextcloud
hdd
recovery-unit
felhom-seed-1-7cb158.txt
felhom-seed-0-e19728.txt
felhom-seed-2-8620d3.txt
12:21:03 Tier-2 record: {"enabled": true, "method": "rsync", "destination_path": "/mnt/felhom-drives/scratch_hdd/userdata/romm", "schedule": "daily", "last_run": "2026-09-24T09:12:08Z", "last_status": "ok", "last_success": "2026-09-24T09:12:08Z", "success_tracked": true, "unit_package_date": "2026-09-24T09:12:06Z", "last_duration": "1s", "last_size_human": "1.0 GB"}
@@ -0,0 +1,5 @@
update:$
health_timeout: 90s$
backup_max_age: 1m$
Up 15 seconds (healthy)
@@ -0,0 +1,41 @@
12:23:09 drill: notag
12:23:14 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
12:23:14 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None
12:23:29 + 15.4s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
12:23:35 + 20.5s phase=pulling label=Új verzió letöltése… err=None hold=None
12:23:37 + 22.6s phase=failed label=A frissítés nem sikerült err=Az új verzió letöltése nem sikerült, ezért a frissítés elmaradt. Az alkalmazás a korábbi verzióval fut tovább. hold=None
12:23:40 log (a):
2026/09/24 10:20:48 update.go:775: [INFO] [stacks] update nextcloud: precondition met — Tier 2 (second drive) copy from 2026-09-24T09:12:08Z (1h9m0s old, limit 24h0m0s)
2026/09/24 10:23:14 update.go:777: [INFO] [stacks] update nextcloud: no usable copy on any tier — younger than 1m0s and not older than this install's deploy (2026-09-24T09:09:53Z) (found: Tier 2 (second drive) at 2026-09-24T09:12:08Z (1h11m0s old); Tier 1 (own recovery unit) at 2026-09-24T10:21:21Z (2m0s old)) — backing up first
2026/09/24 10:23:14 update_guard.go:360: [INFO] [backup] update pre-backup for nextcloud: starting (DB dump → volume dump → unit capture → Tier 2)
2026/09/24 10:23:29 tier2.go:425: [INFO] [backup] Tier 2 copied nextcloud → /mnt/sys_drive/felhom-data/backups/secondary/nextcloud (1.0 GB, 1 leg(s), 1s) [SSD: state-only]
2026/09/24 10:23:29 update.go:792: [INFO] [stacks] update nextcloud: precondition met after the backup — Tier 2 (second drive) copy from 2026-09-24T10:23:29Z
12:23:41 drill: back to 34.0.4
12:23:44 Tier-2 record: {"enabled": true, "method": "rsync", "destination_path": "/mnt/sys_drive/felhom-data", "schedule": "daily", "last_run": "2026-09-24T10:23:29Z", "last_status": "ok", "last_success": "2026-09-24T10:23:29Z", "success_tracked": true, "unit_package_date": "2026-09-24T10:21:21Z", "last_duration": "1s", "last_size_human": "1.0 GB"}
12:23:48 mirror seeds + devices:
felhom-seed-2-8620d3.txt
felhom-seed-1-7cb158.txt
felhom-seed-0-e19728.txt
/mnt/sys_drive/felhom-data dev=1793
/mnt/felhom-drives/scratch_hdd/userdata/nextcloud dev=66304
12:23:51 (b) DELETE felhom-seed-0-e19728.txt -> 204
12:23:51 (b) PUT felhom-seed-1-7cb158.txt (newer than the copy) -> True
12:23:53 nextcloud files read back: 2/3 (negative control http=404)
12:23:54 drill: redis 7-alpine -> 7.2-alpine + probe 8999 (the failing edge)
12:23:59 (c) Update -> 202
12:23:59 + 0.0s phase=safety-dump
12:24:01 + 2.6s phase=pulling
12:24:04 + 5.3s phase=copying
12:24:13 + 14.2s phase=starting
12:24:14 + 15.8s phase=undoing
12:24:53 + 54.2s phase=undone
12:24:53 (c) held: {"update_phase": "undone", "hold_reason": null, "hold_no_whole_copy": null, "hold_kind": null, "state": "running"}
12:24:53 (c) [hu] None
12:24:53 (c) [en] None
12:24:54 drill: back to the head + the real probe
12:24:59 (d) POST /backup/tier2/unit-restore -> HTTP/2 302 ['location: /backups/apps?flash=flash.restore.full_started']
12:24:59 restore-status (True, None)
12:25:37 restore-status (False, None)
@@ -0,0 +1,32 @@
{
"restore_status": {
"ok": true,
"data": {
"running": false,
"op": "tier2-whole-restore",
"stack": "nextcloud",
"started_at": "2026-09-24T10:24:59.064176013Z",
"last": {
"op": "tier2-whole-restore",
"stack": "nextcloud",
"ok": true,
"message": "A(z) nextcloud: 3 adatkötet és az adatbázis visszaállítva — az alkalmazás újraindult. A meghajtó fájljai: 1 visszahozva, 0 kicserélve (a régebbi élő példány megmaradt mellette, .felhom-… végződéssel), 1 újabb példány érintetlenül hagyva, 137 változatlan. Fájl nem lett törölve.",
"finished_at": "2026-09-24T10:25:37.128885903Z"
},
"last_recent": true
}
},
"log": "2026/09/24 10:24:59 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:38812\n2026/09/24 10:24:59 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit\n2026/09/24 10:25:01 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=1 replaced=0 (live kept beside as *.felhom-20260924T102500Z) kept-newer=1 unchanged=137\n2026/09/24 10:25:01 restore.go:152: [INFO] [backup] Restoring Docker volume nextcloud_nextcloud_db_data for nextcloud\n2026/09/24 10:25:02 restore.go:152: [INFO] [backup] Restoring Docker volume nextcloud_nextcloud_html for nextcloud\n2026/09/24 10:25:12 restore.go:152: [INFO] [backup] Restoring Docker volume nextcloud_nextcloud_redis_data for nextcloud\n2026/09/24 10:25:37 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed\n2026/09/24 10:25:37 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 38.0640377s (files restored 1, replaced 0, kept-newer 1, unchanged 137; volumes 3/3, dbs 1/1)\n2026/09/24 10:29:18 settings.go:1814: [WARN] [settings] restore hold SET for gokapi — the app stays stopped until it is cleared\n",
"account": true,
"file0_back": true,
"file1_kept_edit": true,
"file2_unchanged": true,
"occ_scan": "| Folders | Files | New | Updated | Removed | Errors | Elapsed time |\n+---------+-------+-----+---------+---------+--------+--------------+\n| 11 | 69 | 0 | 8 | 0 | 0 | 00:00:00 |\n+---------+-------+-----+---------+---------+--------+--------------+\n",
"file0_back_after_scan": true,
"kept_beside": "",
"final": {
"state": "running",
"hold_reason": null,
"update_phase": "undone"
}
}
@@ -0,0 +1,21 @@
12:34:30 restore-status: {"ok": true, "data": {"running": false, "op": "tier2-whole-restore", "stack": "nextcloud", "started_at": "2026-09-24T10:24:59.064176013Z", "last": {"op": "tier2-whole-restore", "stack": "nextcloud", "ok": true, "message": "A(z) nextcloud: 3 adatkötet és az adatbázis visszaállítva — az alkalmazás újraindult. A meghajtó fájljai: 1 visszahozva, 0 kicserélve (a régebbi élő példány megmaradt mellette, .felhom-… végződéssel), 1 újabb példány érintetlenül hagyva, 137 változatlan. Fájl nem lett törölve.", "finished_at": "2026-09-24T10:25:37.128885903Z"}, "last_recent": true}}
12:34:34 log:
2026/09/24 10:24:59 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:38812
2026/09/24 10:24:59 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit
2026/09/24 10:25:01 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=1 replaced=0 (live kept beside as *.felhom-20260924T102500Z) kept-newer=1 unchanged=137
2026/09/24 10:25:01 restore.go:152: [INFO] [backup] Restoring Docker volume nextcloud_nextcloud_db_data for nextcloud
2026/09/24 10:25:02 restore.go:152: [INFO] [backup] Restoring Docker volume nextcloud_nextcloud_html for nextcloud
2026/09/24 10:25:12 restore.go:152: [INFO] [backup] Restoring Docker volume nextcloud_nextcloud_redis_data for nextcloud
2026/09/24 10:25:37 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
2026/09/24 10:25:37 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 38.0640377s (files restored 1, replaced 0, kept-newer 1, unchanged 137; volumes 3/3, dbs 1/1)
2026/09/24 10:29:18 settings.go:1814: [WARN] [settings] restore hold SET for gokapi — the app stays stopped until it is cleared
12:34:41 nextcloud: readback of the seeded user found=True
12:34:43 file0 (deleted after the copy) back=True (200); file1 (edited after the copy) kept the edit=True; file2 unchanged=True
12:34:46 occ files:scan (the app sees its files): | Folders | Files | New | Updated | Removed | Errors | Elapsed time |
+---------+-------+-----+---------+---------+--------+--------------+
| 11 | 69 | 0 | 8 | 0 | 0 | 00:00:00 |
+---------+-------+-----+---------+---------+--------+--------------+
12:34:47 file0 after occ scan: 200 True
12:34:50 final {"state": "running", "hold_reason": null, "update_phase": "undone"} | kept beside: ''
@@ -0,0 +1,35 @@
{
"controller": "gitea.dooplex.hu/admin/felhom-controller:0.269.0",
"held": {
"update_phase": "failed",
"hold_reason": "A frissítés nem sikerült, és az automatikus visszaállítás sem. Az adatok az új változat által hagyott állapotban vannak. A(z) nextcloud frissítése 2026-09-24 12:41-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: második meghajtó, 2026-09-24 12:39 — ez a másolat a beállításokat, az adatbázist és a fájlokat tartalmazza.",
"hold_no_whole_copy": null,
"hold_kind": "update_failed",
"state": "stopped"
},
"page_hu": "A frissítés nem sikerült, és az automatikus visszaállítás sem. Az adatok az új változat által hagyott állapotban vannak. A(z) nextcloud frissítése 2026-09-24 12:41-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: második meghajtó, 2026-09-24 12:39 — ez a másolat a beállításokat, az adatbázist és a fájlokat tartalmazza. <a href=\"/backups/apps\" class=\"btn btn-sm btn-outline\">Mentések</a>",
"page_en": "The update did not succeed, and the automatic undo did not either. The data is as the new version left it. The update of nextcloud at 2026-09-24 12:41 did not succeed, and the app did not start on the new version. The app stays stopped for safety, so that its data is not damaged. It can be restored on the Backups page from this backup: second drive, 2026-09-24 12:39 — this copy holds the settings, the database and the files. <a href=\"/backups/apps\" class=\"btn btn-sm btn-outline\">Backups</a>",
"hdd_data": {
"code": "200",
"keep_data_only": null
},
"restore_msg": [
false,
null
],
"restore_log": "2026/09/24 10:41:18 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:52346\n2026/09/24 10:41:18 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit\n2026/09/24 10:41:18 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=0 replaced=0 (live kept beside as *.felhom-20260924T104118Z) kept-newer=0 unchanged=142\n2026/09/24 10:41:52 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed\n2026/09/24 10:41:52 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud\n2026/09/24 10:41:52 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:41:12Z) is CLEARED\n2026/09/24 10:41:52 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 33.797173087s (files restored 0, replaced 0, kept-newer 0, unchanged 142; volumes 3/3, dbs 1/1)\n",
"account": true,
"files_after": [
{
"felhom-seed-0-e19728.txt": true,
"felhom-seed-2-8620d3.txt": true
},
"404"
],
"kept_beside": "",
"final": {
"state": "unhealthy",
"hold_reason": null,
"update_phase": null
}
}
@@ -0,0 +1,34 @@
12:38:51 drill: redis 7-alpine -> 7.4-alpine + probe 8999 (the failing edge)
12:38:56 (c) Update -> 202
12:38:56 + 0.0s phase=backing-up
12:39:19 + 23.2s phase=safety-dump
12:39:22 + 25.8s phase=pulling
12:39:23 + 26.9s phase=copying
12:39:33 + 36.9s phase=starting
12:39:39 + 43.2s phase=verifying
12:39:43 >>> marker removed:
copy: nextcloud_nextcloud_db_data.pre-update-20260924T103924Z
data
12:41:10 + 134.0s phase=undoing
12:41:12 + 136.1s phase=failed
12:41:12 (c) held: {"update_phase": "failed", "hold_reason": "A frissítés nem sikerült, és az automatikus visszaállítás sem. Az adatok az új változat által hagyott állapotban vannak. A(z) nextcloud frissítése 2026-09-24 12:41-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: második meghajtó, 2026-09-24 12:39 — ez a másolat a beállításokat, az adatbázist és a fájlokat tartalmazza.", "hold_no_whole_copy": null, "hold_kind": "update_failed", "state": "stopped"}
12:41:12 (c) [hu] 'A frissítés nem sikerült, és az automatikus visszaállítás sem. Az adatok az új változat által hagyott állapotban vannak. A(z) nextcloud frissítése 2026-09-24 12:41-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: második meghajtó, 2026-09-24 12:39 — ez a másolat a beállításokat, az adatbázist és a fájlokat tartalmazza. <a href="/backups/apps" class="btn btn-sm btn-outline">Mentések</a>'
12:41:12 (c) [en] 'The update did not succeed, and the automatic undo did not either. The data is as the new version left it. The update of nextcloud at 2026-09-24 12:41 did not succeed, and the app did not start on the new version. The app stays stopped for safety, so that its data is not damaged. It can be restored on the Backups page from this backup: second drive, 2026-09-24 12:39 — this copy holds the settings, the database and the files. <a href="/backups/apps" class="btn btn-sm btn-outline">Backups</a>'
12:41:12 (c2) hdd-data -> {"code": "200", "keep_data_only": null}
12:41:13 drill: back to the head + the real probe
12:41:18 (d) POST /backup/tier2/unit-restore -> HTTP/2 302 ['location: /backups/apps?flash=flash.restore.full_started']
12:41:18 restore-status (True, None)
12:41:52 restore-status (False, None)
12:41:56 (d) log:
2026/09/24 10:41:18 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:52346
2026/09/24 10:41:18 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit
2026/09/24 10:41:18 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=0 replaced=0 (live kept beside as *.felhom-20260924T104118Z) kept-newer=0 unchanged=142
2026/09/24 10:41:52 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
2026/09/24 10:41:52 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud
2026/09/24 10:41:52 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:41:12Z) is CLEARED
2026/09/24 10:41:52 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 33.797173087s (files restored 0, replaced 0, kept-newer 0, unchanged 142; volumes 3/3, dbs 1/1)
12:42:03 nextcloud: readback of the seeded user found=True
12:42:05 nextcloud files read back: 2/2 (negative control http=404)
12:42:08 (e) final {"state": "unhealthy", "hold_reason": null, "update_phase": null} kept-beside:
@@ -0,0 +1,34 @@
12:38:51 drill: redis 7-alpine -> 7.4-alpine + probe 8999 (the failing edge)
12:38:56 (c) Update -> 202
12:38:56 + 0.0s phase=backing-up
12:39:19 + 23.2s phase=safety-dump
12:39:22 + 25.8s phase=pulling
12:39:23 + 26.9s phase=copying
12:39:33 + 36.9s phase=starting
12:39:39 + 43.2s phase=verifying
12:39:43 >>> marker removed:
copy: nextcloud_nextcloud_db_data.pre-update-20260924T103924Z
data
12:41:10 + 134.0s phase=undoing
12:41:12 + 136.1s phase=failed
12:41:12 (c) held: {"update_phase": "failed", "hold_reason": "A frissítés nem sikerült, és az automatikus visszaállítás sem. Az adatok az új változat által hagyott állapotban vannak. A(z) nextcloud frissítése 2026-09-24 12:41-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: második meghajtó, 2026-09-24 12:39 — ez a másolat a beállításokat, az adatbázist és a fájlokat tartalmazza.", "hold_no_whole_copy": null, "hold_kind": "update_failed", "state": "stopped"}
12:41:12 (c) [hu] 'A frissítés nem sikerült, és az automatikus visszaállítás sem. Az adatok az új változat által hagyott állapotban vannak. A(z) nextcloud frissítése 2026-09-24 12:41-kor nem sikerült, és az alkalmazás nem indult el az új verzióval. Az alkalmazás biztonsági okból leállítva marad, hogy az adatai ne sérüljenek. Visszaállítható a Mentések oldalon ebből a biztonsági mentésből: második meghajtó, 2026-09-24 12:39 — ez a másolat a beállításokat, az adatbázist és a fájlokat tartalmazza. <a href="/backups/apps" class="btn btn-sm btn-outline">Mentések</a>'
12:41:12 (c) [en] 'The update did not succeed, and the automatic undo did not either. The data is as the new version left it. The update of nextcloud at 2026-09-24 12:41 did not succeed, and the app did not start on the new version. The app stays stopped for safety, so that its data is not damaged. It can be restored on the Backups page from this backup: second drive, 2026-09-24 12:39 — this copy holds the settings, the database and the files. <a href="/backups/apps" class="btn btn-sm btn-outline">Backups</a>'
12:41:12 (c2) hdd-data -> {"code": "200", "keep_data_only": null}
12:41:13 drill: back to the head + the real probe
12:41:18 (d) POST /backup/tier2/unit-restore -> HTTP/2 302 ['location: /backups/apps?flash=flash.restore.full_started']
12:41:18 restore-status (True, None)
12:41:52 restore-status (False, None)
12:41:56 (d) log:
2026/09/24 10:41:18 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:52346
2026/09/24 10:41:18 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit
2026/09/24 10:41:18 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=0 replaced=0 (live kept beside as *.felhom-20260924T104118Z) kept-newer=0 unchanged=142
2026/09/24 10:41:52 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
2026/09/24 10:41:52 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud
2026/09/24 10:41:52 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:41:12Z) is CLEARED
2026/09/24 10:41:52 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 33.797173087s (files restored 0, replaced 0, kept-newer 0, unchanged 142; volumes 3/3, dbs 1/1)
12:42:03 nextcloud: readback of the seeded user found=True
12:42:05 nextcloud files read back: 2/2 (negative control http=404)
12:42:08 (e) final {"state": "unhealthy", "hold_reason": null, "update_phase": null} kept-beside:
@@ -0,0 +1,49 @@
{
"controller": "gitea.dooplex.hu/admin/felhom-controller:0.269.0",
"held": {
"update_phase": "failed",
"hold_reason": "A(z) nextcloud frissítése nem sikerült, és az automatikus visszaállítás sem. Ezen a dobozon nincs olyan másolat, amely az alkalmazást a fájljaival együtt vissza tudná hozni. A Felhom ügyfélszolgálatát értesítettük — addig ne indítsd újra, és ne töröld az adatait.",
"hold_no_whole_copy": true,
"hold_kind": "update_failed",
"state": "stopped"
},
"page_hu": "A(z) nextcloud frissítése nem sikerült, és az automatikus visszaállítás sem. Ezen a dobozon nincs olyan másolat, amely az alkalmazást a fájljaival együtt vissza tudná hozni. A Felhom ügyfélszolgálatát értesítettük — addig ne indítsd újra, és ne töröld az adatait.",
"page_en": "The update of nextcloud did not work, and neither did the automatic undo. This box has no copy that can bring the app back together with its files. Felhom support has been told — until then, do not restart the app or delete its data.",
"hdd_data": {
"code": "200",
"keep_data_only": true
},
"remove_hu": {
"code": "409",
"error": "Amíg az ügyfélszolgálat foglalkozik az alkalmazással, az adatai nem törölhetők — az alkalmazást az adatai megtartásával eltávolíthatod."
},
"remove_en": {
"code": "409",
"error": "While support is working on this app, its data cannot be deleted — you can remove the app and keep its data."
},
"remove_backups_en": {
"code": "409",
"error": "While support is working on this app, its data cannot be deleted — you can remove the app and keep its data."
},
"still_deployed": true,
"mirror_back": "hdd\nrecovery-unit\n",
"restore_msg": [
false,
null
],
"restore_log": "2026/09/24 10:48:06 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:57508\n2026/09/24 10:48:06 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit\n2026/09/24 10:48:06 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=0 replaced=0 (live kept beside as *.felhom-20260924T104806Z) kept-newer=0 unchanged=142\n2026/09/24 10:48:40 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed\n2026/09/24 10:48:40 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud\n2026/09/24 10:48:40 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:47:57Z) is CLEARED\n2026/09/24 10:48:40 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 33.559200635s (files restored 0, replaced 0, kept-newer 0, unchanged 142; volumes 3/3, dbs 1/1)\n",
"account": true,
"files_after": [
{
"felhom-seed-0-e19728.txt": true,
"felhom-seed-2-8620d3.txt": true
},
"404"
],
"kept_beside": "",
"final": {
"state": "running",
"hold_reason": null,
"update_phase": null
}
}
@@ -0,0 +1,40 @@
12:43:54 drill: redis 7-alpine -> 7.4.0-alpine + probe 8999 (the failing edge)
12:43:59 (c) Update -> 202
12:43:59 + 0.0s phase=backing-up
12:44:16 + 16.8s phase=safety-dump
12:44:18 + 18.9s phase=pulling
12:44:21 + 22.1s phase=copying
12:44:31 + 32.1s phase=starting
12:44:38 + 38.9s phase=verifying
12:44:42 >>> marker removed:
copy: nextcloud_nextcloud_db_data.pre-update-20260924T103924Z
data
second-drive mirror moved aside (a one-drive box)
12:46:09 + 129.7s phase=undoing
12:47:57 + 237.4s phase=failed
12:47:57 (c) held: {"update_phase": "failed", "hold_reason": "A(z) nextcloud frissítése nem sikerült, és az automatikus visszaállítás sem. Ezen a dobozon nincs olyan másolat, amely az alkalmazást a fájljaival együtt vissza tudná hozni. A Felhom ügyfélszolgálatát értesítettük — addig ne indítsd újra, és ne töröld az adatait.", "hold_no_whole_copy": true, "hold_kind": "update_failed", "state": "stopped"}
12:47:57 (c) [hu] 'A(z) nextcloud frissítése nem sikerült, és az automatikus visszaállítás sem. Ezen a dobozon nincs olyan másolat, amely az alkalmazást a fájljaival együtt vissza tudná hozni. A Felhom ügyfélszolgálatát értesítettük — addig ne indítsd újra, és ne töröld az adatait.'
12:47:57 (c) [en] 'The update of nextcloud did not work, and neither did the automatic undo. This box has no copy that can bring the app back together with its files. Felhom support has been told — until then, do not restart the app or delete its data.'
12:47:57 (c2) hdd-data -> {"code": "200", "keep_data_only": true}
12:47:57 (c3) [hu] Remove with data -> 409 'Amíg az ügyfélszolgálat foglalkozik az alkalmazással, az adatai nem törölhetők — az alkalmazást az adatai megtartásával eltávolíthatod.'
12:47:57 (c3) [en] Remove with data -> 409 'While support is working on this app, its data cannot be deleted — you can remove the app and keep its data.'
12:47:57 (c3) [en] Remove with backups -> 409
12:47:57 (c3) still deployed: True
12:48:00 (c4) mirror moved back: hdd recovery-unit
12:48:01 drill: back to the head + the real probe
12:48:06 (d) POST /backup/tier2/unit-restore -> HTTP/2 302 ['location: /backups/apps?flash=flash.restore.full_started']
12:48:06 restore-status (True, None)
12:48:40 restore-status (False, None)
12:48:44 (d) log:
2026/09/24 10:48:06 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:57508
2026/09/24 10:48:06 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit
2026/09/24 10:48:06 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=0 replaced=0 (live kept beside as *.felhom-20260924T104806Z) kept-newer=0 unchanged=142
2026/09/24 10:48:40 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
2026/09/24 10:48:40 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud
2026/09/24 10:48:40 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:47:57Z) is CLEARED
2026/09/24 10:48:40 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 33.559200635s (files restored 0, replaced 0, kept-newer 0, unchanged 142; volumes 3/3, dbs 1/1)
12:48:51 nextcloud: readback of the seeded user found=True
12:48:53 nextcloud files read back: 2/2 (negative control http=404)
12:48:56 (e) final {"state": "running", "hold_reason": null, "update_phase": null} kept-beside:
@@ -0,0 +1,40 @@
12:43:54 drill: redis 7-alpine -> 7.4.0-alpine + probe 8999 (the failing edge)
12:43:59 (c) Update -> 202
12:43:59 + 0.0s phase=backing-up
12:44:16 + 16.8s phase=safety-dump
12:44:18 + 18.9s phase=pulling
12:44:21 + 22.1s phase=copying
12:44:31 + 32.1s phase=starting
12:44:38 + 38.9s phase=verifying
12:44:42 >>> marker removed:
copy: nextcloud_nextcloud_db_data.pre-update-20260924T103924Z
data
second-drive mirror moved aside (a one-drive box)
12:46:09 + 129.7s phase=undoing
12:47:57 + 237.4s phase=failed
12:47:57 (c) held: {"update_phase": "failed", "hold_reason": "A(z) nextcloud frissítése nem sikerült, és az automatikus visszaállítás sem. Ezen a dobozon nincs olyan másolat, amely az alkalmazást a fájljaival együtt vissza tudná hozni. A Felhom ügyfélszolgálatát értesítettük — addig ne indítsd újra, és ne töröld az adatait.", "hold_no_whole_copy": true, "hold_kind": "update_failed", "state": "stopped"}
12:47:57 (c) [hu] 'A(z) nextcloud frissítése nem sikerült, és az automatikus visszaállítás sem. Ezen a dobozon nincs olyan másolat, amely az alkalmazást a fájljaival együtt vissza tudná hozni. A Felhom ügyfélszolgálatát értesítettük — addig ne indítsd újra, és ne töröld az adatait.'
12:47:57 (c) [en] 'The update of nextcloud did not work, and neither did the automatic undo. This box has no copy that can bring the app back together with its files. Felhom support has been told — until then, do not restart the app or delete its data.'
12:47:57 (c2) hdd-data -> {"code": "200", "keep_data_only": true}
12:47:57 (c3) [hu] Remove with data -> 409 'Amíg az ügyfélszolgálat foglalkozik az alkalmazással, az adatai nem törölhetők — az alkalmazást az adatai megtartásával eltávolíthatod.'
12:47:57 (c3) [en] Remove with data -> 409 'While support is working on this app, its data cannot be deleted — you can remove the app and keep its data.'
12:47:57 (c3) [en] Remove with backups -> 409
12:47:57 (c3) still deployed: True
12:48:00 (c4) mirror moved back: hdd recovery-unit
12:48:01 drill: back to the head + the real probe
12:48:06 (d) POST /backup/tier2/unit-restore -> HTTP/2 302 ['location: /backups/apps?flash=flash.restore.full_started']
12:48:06 restore-status (True, None)
12:48:40 restore-status (False, None)
12:48:44 (d) log:
2026/09/24 10:48:06 handlers.go:2063: [WARN] [web] Tier-2 WHOLE restore requested (async, files + database): stack=nextcloud from 172.18.0.9:57508
2026/09/24 10:48:06 tier2_whole.go:304: [WARN] [backup] WHOLE restore for nextcloud from the second drive /mnt/sys_drive/felhom-data/backups/secondary/nextcloud: files by the four rules (never delete, never overwrite newer), then the unit
2026/09/24 10:48:06 tier2_whole.go:326: [INFO] [backup] whole restore nextcloud: files restored=0 replaced=0 (live kept beside as *.felhom-20260924T104806Z) kept-newer=0 unchanged=142
2026/09/24 10:48:40 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
2026/09/24 10:48:40 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud
2026/09/24 10:48:40 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:47:57Z) is CLEARED
2026/09/24 10:48:40 handlers.go:2074: [INFO] [web] Tier-2 whole restore completed (async): stack=nextcloud in 33.559200635s (files restored 0, replaced 0, kept-newer 0, unchanged 142; volumes 3/3, dbs 1/1)
12:48:51 nextcloud: readback of the seeded user found=True
12:48:53 nextcloud files read back: 2/2 (negative control http=404)
12:48:56 (e) final {"state": "running", "hold_reason": null, "update_phase": null} kept-beside:
@@ -0,0 +1,62 @@
## now: applied-meta and stack .felhom.yml probe port
2026-09-24 10:46:18.306558751 +0000 applied-meta/.felhom.yml
2026-09-24 10:48:16.019124190 +0000 .felhom.yml
applied-meta/.felhom.yml:106: port: 8999
.felhom.yml:106: port: 8999
## the controller log 10:38-10:49 (nextcloud: pin, applied, undo, hold, restore)
1 2026/09/24 10:38:51 sync.go:409: [INFO] [sync] Updated nextcloud/.felhom.yml
1 2026/09/24 10:39:21 undo.go:273: [INFO] [stacks] update nextcloud: the undo copy will hold 3 named volume(s), 928.8 MiB
1 2026/09/24 10:39:21 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7.4-alpine)
1 2026/09/24 10:39:25 undo.go:423: [INFO] [stacks] update nextcloud: copied nextcloud_nextcloud_db_data → nextcloud_nextcloud_db_data.pre-update-20260924T103924Z in 950ms
1 2026/09/24 10:39:28 healthprobe.go:190: [WARN] Health probe nextcloud: API GET :8999/status.php → Get "http://nextcloud:8999/status.php": dial tcp: lookup nextcloud on 127.0.0.11:53: no such host
1 2026/09/24 10:39:32 undo.go:423: [INFO] [stacks] update nextcloud: copied nextcloud_nextcloud_html → nextcloud_nextcloud_html.pre-update-20260924T103924Z in 6.779s
1 2026/09/24 10:39:33 undo.go:423: [INFO] [stacks] update nextcloud: copied nextcloud_nextcloud_redis_data → nextcloud_nextcloud_redis_data.pre-update-20260924T103924Z in 435ms
17 2026/09/24 10:39:49 healthprobe.go:190: [WARN] Health probe nextcloud: API GET :8999/status.php → Get "http://nextcloud:8999/status.php": dial tcp 172.18.0.5:8999: connect: connection refused
1 2026/09/24 10:41:10 update.go:961: [INFO] [stacks] update nextcloud: kept 6855 bytes of the app's own log at /opt/docker/stacks/nextcloud/hold-logs/20260924T104110Z/compose-logs.txt before stopping it (R-621)
1 2026/09/24 10:41:10 update.go:1260: [INFO] [stacks] update nextcloud: phase undoing
1 2026/09/24 10:41:10 undo.go:501: [WARN] [stacks] update nextcloud: UNDO — putting back the previous version and its 3 volume copy(ies) (reason: not healthy: not healthy within 1m30s (last: health check failing))
1 2026/09/24 10:41:12 undo.go:507: [ERROR] [stacks] update nextcloud: the undo copy nextcloud_nextcloud_db_data.pre-update-20260924T103924Z has no finished-marker — it is cut off or missing; NOTHING is put back
1 2026/09/24 10:41:12 update.go:981: [ERROR] [stacks] update nextcloud: the UNDO failed too (untouched) — HOLDING the app; the undo copies are kept: [{nextcloud_nextcloud_db_data nextcloud_nextcloud_db_data.pre-update-20260924T103924Z} {nextcloud_nextcloud_html nextcloud_nextcloud_html.pre-update-20260924T103924Z} {nextcloud_nextcloud_redis_data nextcloud_nextcloud_redis_data.pre-update-20260924T103924Z}]
1 2026/09/24 10:41:12 settings.go:1814: [WARN] [settings] restore hold SET for nextcloud — the app stays stopped until it is cleared
1 2026/09/24 10:41:12 update_guard.go:560: [WARN] [backup] nextcloud is HELD STOPPED after a failed update (restore point: tier 2 "második meghajtó", 2026-09-24T10:39:14Z; holds: "a beállításokat, az adatbázist és a fájlokat tartalmazza"; undo: "untouched")
1 2026/09/24 10:41:12 settings.go:1814: [WARN] [settings] restore hold SET for nextcloud — the app stays stopped until it is cleared
1 2026/09/24 10:41:12 undo.go:619: [INFO] [stacks] update nextcloud: event app_update_held (hold recorded: true)
1 2026/09/24 10:41:14 sync.go:409: [INFO] [sync] Updated nextcloud/.felhom.yml
1 2026/09/24 10:41:28 pin.go:93: [INFO] [stacks] pin nextcloud: nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine
1 2026/09/24 10:41:52 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
1 2026/09/24 10:41:52 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud
1 2026/09/24 10:41:52 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:41:12Z) is CLEARED
9 2026/09/24 10:41:58 healthprobe.go:190: [WARN] Health probe nextcloud: API GET :8999/status.php → Get "http://nextcloud:8999/status.php": dial tcp 172.18.0.5:8999: connect: connection refused
1 2026/09/24 10:44:13 offbox_reconstitute.go:319: [INFO] [backup] nextcloud: pruned old undo copy pre-restore-20260924T102048Z-nextcloud-mariadb.sql (keeping the newest 3)
1 2026/09/24 10:44:18 undo.go:273: [INFO] [stacks] update nextcloud: the undo copy will hold 3 named volume(s), 928.8 MiB
1 2026/09/24 10:44:18 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7.4.0-alpine)
1 2026/09/24 10:44:24 undo.go:423: [INFO] [stacks] update nextcloud: copied nextcloud_nextcloud_db_data → nextcloud_nextcloud_db_data.pre-update-20260924T104423Z in 929ms
1 2026/09/24 10:44:31 undo.go:423: [INFO] [stacks] update nextcloud: copied nextcloud_nextcloud_html → nextcloud_nextcloud_html.pre-update-20260924T104423Z in 7.147s
1 2026/09/24 10:44:31 undo.go:423: [INFO] [stacks] update nextcloud: copied nextcloud_nextcloud_redis_data → nextcloud_nextcloud_redis_data.pre-update-20260924T104423Z in 577ms
18 2026/09/24 10:44:48 healthprobe.go:190: [WARN] Health probe nextcloud: API GET :8999/status.php → Get "http://nextcloud:8999/status.php": dial tcp 172.18.0.5:8999: connect: connection refused
1 2026/09/24 10:46:08 update.go:961: [INFO] [stacks] update nextcloud: kept 6773 bytes of the app's own log at /opt/docker/stacks/nextcloud/hold-logs/20260924T104608Z/compose-logs.txt before stopping it (R-621)
1 2026/09/24 10:46:08 update.go:1260: [INFO] [stacks] update nextcloud: phase undoing
1 2026/09/24 10:46:08 undo.go:501: [WARN] [stacks] update nextcloud: UNDO — putting back the previous version and its 3 volume copy(ies) (reason: not healthy: not healthy within 1m30s (last: health check failing))
1 2026/09/24 10:46:18 pin.go:93: [INFO] [stacks] pin nextcloud: nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine
1 2026/09/24 10:46:24 [ERROR] [stacks] .felhom.yml backup block rejected in /opt/docker/stacks/nextcloud/pre-update-meta: docker-compose.yml unreadable: stat /opt/docker/stacks/nextcloud/pre-update-meta/docker-compose.yml: no such file or directory
17 2026/09/24 10:46:34 healthprobe.go:190: [WARN] Health probe nextcloud: API GET :8999/status.php → Get "http://nextcloud:8999/status.php": dial tcp 172.18.0.5:8999: connect: connection refused
1 2026/09/24 10:47:55 undo.go:535: [ERROR] [stacks] update nextcloud: the previous version did not come up after the undo: not healthy within 1m30s (last: health check failing)
1 2026/09/24 10:47:55 update.go:961: [INFO] [stacks] update nextcloud: kept 6798 bytes of the app's own log at /opt/docker/stacks/nextcloud/hold-logs/20260924T104755Z/compose-logs.txt before stopping it (R-621)
1 2026/09/24 10:47:57 update.go:981: [ERROR] [stacks] update nextcloud: the UNDO failed too (not_started) — HOLDING the app; the undo copies are kept: [{nextcloud_nextcloud_db_data nextcloud_nextcloud_db_data.pre-update-20260924T104423Z} {nextcloud_nextcloud_html nextcloud_nextcloud_html.pre-update-20260924T104423Z} {nextcloud_nextcloud_redis_data nextcloud_nextcloud_redis_data.pre-update-20260924T104423Z}]
1 2026/09/24 10:47:57 settings.go:1814: [WARN] [settings] restore hold SET for nextcloud — the app stays stopped until it is cleared
1 2026/09/24 10:47:57 update_guard.go:715: [ERROR] [backup] nextcloud is HELD STOPPED after a failed update and NO copy on this box brings it back whole (seen: [tier 1 at 2026-09-24T10:44:17Z]; drive files declared: true; undo: "not_started") — support must act (R-659)
1 2026/09/24 10:47:57 undo.go:619: [INFO] [stacks] update nextcloud: event app_update_held (hold recorded: true)
1 2026/09/24 10:48:02 sync.go:409: [INFO] [sync] Updated nextcloud/.felhom.yml
1 2026/09/24 10:48:16 pin.go:93: [INFO] [stacks] pin nextcloud: nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine
1 2026/09/24 10:48:40 restore_unit.go:464: [INFO] [backup] Restore-from-unit completed: nextcloud — 3 volume(s) of 3 listed, 1 database(s) of 1 listed
1 2026/09/24 10:48:40 settings.go:1848: [INFO] [settings] restore hold CLEARED for nextcloud
1 2026/09/24 10:48:40 update_guard.go:609: [INFO] [backup] nextcloud: restore completed — the update hold (set 2026-09-24T10:47:57Z) is CLEARED
## undo-copy volumes left
nextcloud_nextcloud_db_data.pre-update-20260924T103924Z
nextcloud_nextcloud_db_data.pre-update-20260924T104423Z
nextcloud_nextcloud_html.pre-update-20260924T103924Z
nextcloud_nextcloud_html.pre-update-20260924T104423Z
nextcloud_nextcloud_redis_data.pre-update-20260924T103924Z
nextcloud_nextcloud_redis_data.pre-update-20260924T104423Z
@@ -0,0 +1,2 @@
2026/09/24 11:39:35 [INFO] felhom-hub 0.123.0 starting
2026/09/24 11:39:35 [INFO] [store] app_stopped_unhealthy added to 3 household(s)' notification prefs (one-time, add-only): [demo-felhom _resend-rotation-test demo-hp]
@@ -0,0 +1,4 @@
2026/09/24 10:29:18 main.go:3671: [WARN] [deadapp] gokapi: crash_loop — 6 in 10m0s; STOPPING it (decision 28)
2026/09/24 10:29:18 update_guard.go:776: [WARN] [backup] gokapi is STOPPED by the box: crash_loop (trip 1 within 24h0m0s) — Start gives it one more try (decision 28)
@@ -0,0 +1,7 @@
API {"state": "stopped", "hold_reason": "Az alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod.", "hold_kind": "unhealthy_stop", "update_phase": null}
hu ('Az alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod.', 'Indítás')
hu app page: Az alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod. | restore-needed badge: False
en ('We stopped the app because it kept crashing (or ran out of memory). Press Start to try again.', 'Start')
en app page: We stopped the app because it kept crashing (or ran out of memory). Press Start to try again. | restore-needed badge: False
2026/09/24 10:29:18 notifier.go:1255: [WARN] notifier disabled (no hub configured): DROPPED event app_stopped_unhealthy (severity warning) — further app_stopped_unhealthy events are logged at DEBUG only
@@ -0,0 +1,18 @@
{
"controller": "gitea.dooplex.hu/admin/felhom-controller:0.269.0",
"before": {
"state": "stopped",
"hold_kind": "unhealthy_stop",
"hold_reason": "Az alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod."
},
"after_start": {
"state": "restarting",
"hold_kind": null,
"hold_reason": null
},
"tripped_after_s": 37,
"page_hu": "Az alkalmazást ismét leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). A Felhom ügyfélszolgálatát értesítettük. Az Indítás gombbal újra megpróbálhatod.",
"page_en": "We stopped the app again because it kept crashing (or ran out of memory). Felhom support has been told. Press Start to try again.",
"log": "2026/09/24 10:37:15 settings.go:2677: [INFO] [settings] unhealthy-stop hold LIFTED for gokapi (Start)\n2026/09/24 10:37:15 router.go:615: [INFO] [api] gokapi: the unhealthy stop is LIFTED by Start — one more try (decision 28)\n2026/09/24 10:37:18 scheduler.go:67: [DEBUG] [scheduler] job deadapp-check: execution starting\n2026/09/24 10:37:48 scheduler.go:67: [DEBUG] [scheduler] job deadapp-check: execution starting\n2026/09/24 10:37:48 main.go:3671: [WARN] [deadapp] gokapi: crash_loop — 9 in 10m0s; STOPPING it (decision 28)\n2026/09/24 10:37:48 settings.go:1814: [WARN] [settings] restore hold SET for gokapi — the app stays stopped until it is cleared\n2026/09/24 10:37:48 update_guard.go:776: [WARN] [backup] gokapi is STOPPED by the box: crash_loop (trip 2 within 24h0m0s) — Start gives it one more try (decision 28)\n2026/09/24 10:37:48 notifier.go:1259: [DEBUG] notifier disabled: dropped event app_stopped_unhealthy (severity warning)\n",
"start_failed_lines": "0"
}
@@ -0,0 +1,18 @@
12:37:15 before {"state": "stopped", "hold_kind": "unhealthy_stop", "hold_reason": "Az alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod."}
12:37:16 Start -> 200 {"ok": true, "data": {"state": "starting"}, "message": "Stack gokapi start requested — state now: starting"}
12:37:21 after start {"state": "restarting", "hold_kind": null, "hold_reason": null}
12:37:25 + 4s state=restarting hold=None restarts: /gokapi 6
12:37:58 + 37s state=stopped hold=unhealthy_stop restarts:
12:37:58 [hu] 'Az alkalmazást ismét leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). A Felhom ügyfélszolgálatát értesítettük. Az Indítás gombbal újra megpróbálhatod.'
12:37:58 [en] 'We stopped the app again because it kept crashing (or ran out of memory). Felhom support has been told. Press Start to try again.'
12:38:02 log:
2026/09/24 10:37:15 settings.go:2677: [INFO] [settings] unhealthy-stop hold LIFTED for gokapi (Start)
2026/09/24 10:37:15 router.go:615: [INFO] [api] gokapi: the unhealthy stop is LIFTED by Start — one more try (decision 28)
2026/09/24 10:37:18 scheduler.go:67: [DEBUG] [scheduler] job deadapp-check: execution starting
2026/09/24 10:37:48 scheduler.go:67: [DEBUG] [scheduler] job deadapp-check: execution starting
2026/09/24 10:37:48 main.go:3671: [WARN] [deadapp] gokapi: crash_loop — 9 in 10m0s; STOPPING it (decision 28)
2026/09/24 10:37:48 settings.go:1814: [WARN] [settings] restore hold SET for gokapi — the app stays stopped until it is cleared
2026/09/24 10:37:48 update_guard.go:776: [WARN] [backup] gokapi is STOPPED by the box: crash_loop (trip 2 within 24h0m0s) — Start gives it one more try (decision 28)
2026/09/24 10:37:48 notifier.go:1259: [DEBUG] notifier disabled: dropped event app_stopped_unhealthy (severity warning)
12:38:05 app_start_failed lines: 0
@@ -0,0 +1,18 @@
12:37:15 before {"state": "stopped", "hold_kind": "unhealthy_stop", "hold_reason": "Az alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod."}
12:37:16 Start -> 200 {"ok": true, "data": {"state": "starting"}, "message": "Stack gokapi start requested — state now: starting"}
12:37:21 after start {"state": "restarting", "hold_kind": null, "hold_reason": null}
12:37:25 + 4s state=restarting hold=None restarts: /gokapi 6
12:37:58 + 37s state=stopped hold=unhealthy_stop restarts:
12:37:58 [hu] 'Az alkalmazást ismét leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). A Felhom ügyfélszolgálatát értesítettük. Az Indítás gombbal újra megpróbálhatod.'
12:37:58 [en] 'We stopped the app again because it kept crashing (or ran out of memory). Felhom support has been told. Press Start to try again.'
12:38:02 log:
2026/09/24 10:37:15 settings.go:2677: [INFO] [settings] unhealthy-stop hold LIFTED for gokapi (Start)
2026/09/24 10:37:15 router.go:615: [INFO] [api] gokapi: the unhealthy stop is LIFTED by Start — one more try (decision 28)
2026/09/24 10:37:18 scheduler.go:67: [DEBUG] [scheduler] job deadapp-check: execution starting
2026/09/24 10:37:48 scheduler.go:67: [DEBUG] [scheduler] job deadapp-check: execution starting
2026/09/24 10:37:48 main.go:3671: [WARN] [deadapp] gokapi: crash_loop — 9 in 10m0s; STOPPING it (decision 28)
2026/09/24 10:37:48 settings.go:1814: [WARN] [settings] restore hold SET for gokapi — the app stays stopped until it is cleared
2026/09/24 10:37:48 update_guard.go:776: [WARN] [backup] gokapi is STOPPED by the box: crash_loop (trip 2 within 24h0m0s) — Start gives it one more try (decision 28)
2026/09/24 10:37:48 notifier.go:1259: [DEBUG] notifier disabled: dropped event app_stopped_unhealthy (severity warning)
12:38:05 app_start_failed lines: 0
@@ -0,0 +1,17 @@
# Does a crash-loop threshold separate a crash loop from a slow first start? (brief: "check against every
# app's first-start restarts in the drill evidence"). Read 2026-09-24 12:50 CEST over documentation/audits/.
$ grep -rhoE '"restarts": *[0-9]+|RestartCount[=: ]+[0-9]+' documentation/audits | sort | uniq -c
1831 "restarts": 0 <- harness state samples (172 files: bench to-/abort-states, memory samples)
11 RestartCount=0
1 RestartCount=9 SPIKE-app-update-2026-09-01.md:225 — a deliberately broken image (alpine:3.20), 37 s after start
1 RestartCount=6 evidence-chaos-night-2026-09-17/round-1-notes.txt:18 — nextcloud, corrupt image layer (ExitCode 127): BROKEN
1 RestartCount=12 evidence-chaos-night-2026-09-17/phase0-recovery.txt:213 — immich microservices, DB connection dropped at first-start import on a 6 GB guest; left broken that night
1 RestartCount 9 evidence-drill-0243-2026-09-16/phase2-m1-oom.txt:23 — paperless at a 128M cap: OOM loop
Also measured tonight: 40 containers on both demo boxes + 9202 — no healthy container above 1 restart (A3/02).
VERDICT: no sample shows a HEALTHY app restarting during a first start. Every count >= 6 is a broken app
(crash image, corrupt layer, OOM cap) — the thing decision 28 stops. The one borderline case is immich's
first-start import (12 restarts): it did not recover that night, so stopping it would have been correct,
but it is the shape a slow-but-recovering first start would take. Row filed (immich first-start watch).
Docker's back-off matters more than the count: a FRESH container restarts fast (9 in 32 s, A3/30), a
long-running loop slows to ~1/min (A3/04) — so 10 in 10 min misses a steady loop; 6 catches both.
@@ -0,0 +1,46 @@
# Part B — does Docker Compose accept tag@digest in EVERY template's image line? (2026-09-24T12:45:17+02:00)
# Method: a temporary (uncommitted, deleted) go test called the product's stacks.RenderWithLadderDigests over every
# live-catalog template @ cf7cf84; each rendered file and its original parsed with
# 'docker compose -f X config -q --no-interpolate' (parse only, no container; DooPlex Docker Compose version v5.3.1).
templates rendered: 53; carrying @sha256 after render: 25 apps
every tested digest of the head's ladder entry present in the render: 25 apps, 37 digests, 0 missing
compose config: 25 ok, 0 differ from the original's result
## the rendered image lines
actualbudget.yml: image: actualbudget/actual-server:26.9.0@sha256:552beab3dec8c93d46b8b9245612d63c3f123b8a45063a474f53e229b17621d3
bookstack.yml: image: lscr.io/linuxserver/bookstack:26.05.5@sha256:189c796273469115cf810e53f450e15b93184018e4728cd65fcaef8aa93584bc
bookstack.yml: image: mariadb:12.3@sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1
ghost.yml: image: ghost:6.65.0-alpine@sha256:65788e5e2c5478319f8fc65ac12816dbc941d1a9c834c87190cf1d2d1b79d4e2
navidrome.yml: image: deluan/navidrome:0.64.1@sha256:df22d661b8d0322c33754d999b567150df9e131a47ae53be71fed0154bf8cef5
grafana.yml: image: grafana/grafana:13.2.2@sha256:ac461fb352abc50da10a51c7d02462e9c05488f11f53f14b3ad79a8145f638a0
mealie.yml: image: ghcr.io/mealie-recipes/mealie:v3.27.0@sha256:ba24b88462380fb59a6c7d04c6d9e607e0b6b04e31306592181186bcdab1952b
nextcloud.yml: image: nextcloud:34.0.4-apache@sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c
nextcloud.yml: image: mariadb:12.3@sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1
nextcloud.yml: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
komga.yml: image: gotson/komga:1.27.1@sha256:9cf102f5fb78e2e020700c53eca757e4f4d4e347121b0a16380822760337cca9
wishlist.yml: image: ghcr.io/cmintey/wishlist:v0.67.1@sha256:4b89bfb5b57ffb087c33978d21b09048e5c37f4506326e9ccd2705a0a1d86548
radarr.yml: image: lscr.io/linuxserver/radarr:6.4.4@sha256:adb6c09d6b729ea5e642c99cea35af72702ef476bf4763f153299ac5db9f0b4f
romm.yml: image: rommapp/romm:5.3.1@sha256:0d66b4ea152a237c7f24b95e87459f46d3c596a7c0b35a82f26bc971487278b3
romm.yml: image: mariadb:11.8@sha256:79d59758afc91b89b120b0a8904d637f5a3b3e1c4900f29b740d6d46c72fef68
romm.yml: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
privatebin.yml: image: privatebin/pdo:2.0.6@sha256:4c141b2326f8b353598ce9ce7507a9cfecf2dad5c60a39fea903d430e296d8f5
audiobookshelf.yml: image: ghcr.io/advplyr/audiobookshelf:2.36.1@sha256:3528a93b6442ffe54bd46771bbbab7c97084e1101071586d9dc2254f30bb4358
vikunja.yml: image: vikunja/vikunja:2.6.0@sha256:417ada6f94e81f0267aa2f007d0a811fc82d38dd2aa58351e3ea520ca01c2ea5
docmost.yml: image: docmost/docmost:0.96.0@sha256:b56947fcfd08aab8fae12a377e1792784786adbf8b96e4281f14ef4fc072685a
docmost.yml: image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
docmost.yml: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
home-assistant.yml: image: ghcr.io/home-assistant/home-assistant:2026.9.3@sha256:d8922685169707fd91e8b9729902d975f06157d005e422874d201e0261dda196
immich.yml: image: ghcr.io/immich-app/immich-server:v3.2.2@sha256:79cc1623323d5894922686d8743b4780181428f98eecbfb58ce12c41ef02d1ea
immich.yml: image: ghcr.io/immich-app/immich-machine-learning:v3.2.2@sha256:60dfcf266a9ef3b7376f5678e8c980d4fb61db5fc48c078fe8a326ab1535d60d
immich.yml: image: ghcr.io/immich-app/postgres:16-vectorchord0.4.3-pgvectors0.2.0@sha256:1a078b237c1d9b420b0ee59147386b4aa60d3a07a8e6a402fc84a57e41b043a4
immich.yml: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499
opengist.yml: image: ghcr.io/thomiceli/opengist:1.15@sha256:7edc91273ee7d10a17406da8a08c803158baaff984c39b789c1313473d068f21
papra.yml: image: ghcr.io/papra-hq/papra:26.6.2-rootless@sha256:a281cb44176dbe5323e0f7ea2d6fd34d58914a3a8525c36437a086d1d7c4fef8
sonarr.yml: image: lscr.io/linuxserver/sonarr:4.0.20@sha256:a5c1a5fecbef946927ab90ad68df319ac5fe644057e5fc18cd993f01ac07b2b2
termix.yml: image: ghcr.io/lukegus/termix:2.8.0@sha256:25e8a0eb39f45c9ac5e8e7615fd84a0380018ea012317bc665b86458d900b4b9
emby.yml: image: emby/embyserver:4.11.0.3@sha256:2ff130d624a97782474e7de791875d2871d613b2afaddc73b3e11eb0c9caa770
kimai.yml: image: kimai/kimai2:apache-2.57.0@sha256:efa66c5eadf948b94d8031e9436feae491d90b2ceaa3d5e45e4d7c1a59dd8c38
kimai.yml: image: mariadb:11.8@sha256:79d59758afc91b89b120b0a8904d637f5a3b3e1c4900f29b740d6d46c72fef68
n8n.yml: image: n8nio/n8n:2.41.1@sha256:52f147bba97908fe58e616738f2f0485696ac7b5670a1baf169ccf1ff3173de7
tandoor.yml: image: ghcr.io/tandoorrecipes/recipes:2.6.15@sha256:2e759dd1478a2ed119ee474e28522079fb1cfa50b3fd25cba89f6b9a67abad72
tandoor.yml: image: postgres:16-alpine@sha256:721873c34ceb9f8d8fc265984940dc982404c105f19ad51be9fdc5970a6080ea
@@ -0,0 +1,224 @@
{
"controller": "gitea.dooplex.hu/admin/felhom-controller:0.269.0",
"1-control": {
"state": "running",
"installed": {
"nextcloud": {
"ref": "nextcloud:34.0.4-apache",
"digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-db": {
"ref": "mariadb:12.3",
"digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-redis": {
"ref": "redis:7-alpine",
"digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
"at": "2026-09-24T10:48:31Z"
}
},
"pinned": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_images": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_digests": {
"nextcloud": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"nextcloud-db": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"nextcloud-redis": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"
},
"catalog_tested_at": "2026-09-23T20:16:04Z",
"badges": {
"hu": [
{
"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.",
"text": "Naprakész"
}
],
"en": [
{
"title": "This app is running the newest version available.",
"text": "Up to date"
}
]
},
"compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
"running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"
},
"ladder_edit": {
"old": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
"new": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"tested_at": "2026-09-24T10:50:04Z"
},
"2-behind": {
"state": "running",
"installed": {
"nextcloud": {
"ref": "nextcloud:34.0.4-apache",
"digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-db": {
"ref": "mariadb:12.3",
"digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-redis": {
"ref": "redis:7-alpine",
"digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
"at": "2026-09-24T10:48:31Z"
}
},
"pinned": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_images": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_digests": {
"nextcloud": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"nextcloud-db": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"nextcloud-redis": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098"
},
"catalog_tested_at": "2026-09-24T10:50:04Z",
"badges": {
"hu": [
{
"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.",
"text": "Frissítés elérhető — 1 napja"
}
],
"en": [
{
"title": "A newer version of this app is available. Select the Update button to start it.",
"text": "Update available — 1 day ago"
}
]
},
"compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"
},
"update": {
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "backing-up",
"label": "Biztonsági mentés készül a frissítés előtt…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 16.4,
"phase": "safety-dump",
"label": "Adatbázis pillanatkép…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 18.5,
"phase": "copying",
"label": "Az adatok másolása a frissítés előtt…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 27.7,
"phase": "starting",
"label": "Indítás az új verzióval…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 33.9,
"phase": "verifying",
"label": "Működés ellenőrzése…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 45.1,
"phase": "done",
"label": "Frissítve",
"updating": false,
"error": null,
"hold": null
}
],
"duration_s": 45.2,
"final_phase": "done",
"update_error": null,
"hold_reason": null,
"state": "running"
},
"3-after": {
"state": "running",
"installed": {
"nextcloud": {
"ref": "nextcloud:34.0.4-apache",
"digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-db": {
"ref": "mariadb:12.3",
"digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-redis": {
"ref": "redis:7-alpine",
"digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"at": "2026-09-24T10:50:50Z"
}
},
"pinned": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_images": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_digests": {
"nextcloud": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"nextcloud-db": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"nextcloud-redis": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098"
},
"catalog_tested_at": "2026-09-24T10:50:04Z",
"badges": {
"hu": [
{
"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.",
"text": "Naprakész"
}
],
"en": [
{
"title": "This app is running the newest version available.",
"text": "Up to date"
}
]
},
"compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"
},
"pull_log": "2026/09/24 10:43:59 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition\n2026/09/24 10:44:17 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T104416Z-nextcloud-mariadb.sql]\n2026/09/24 10:44:18 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7.4.0-alpine)\n2026/09/24 10:44:18 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling\n2026/09/24 10:48:31 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:858f009f9709…))\n2026/09/24 10:50:37 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition\n2026/09/24 10:50:50 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:c35af3bbcef5…))\n2026/09/24 10:50:54 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T105053Z-nextcloud-mariadb.sql]\n2026/09/24 10:50:55 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine)\n2026/09/24 10:50:55 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling\n"
}
@@ -0,0 +1,28 @@
12:50:04 [1-control] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
12:50:04 [1-control] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T10:48:31Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:50:05 drill: ladder head entry digest sha256:858f009f9709 -> sha256:c35af3bbcef5
12:50:16 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
12:50:16 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T10:48:31Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:50:37 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.", "text": "Frissítés elérhető — 1 napja"}], "en": [{"title": "A newer version of this app is available. Select the Update button to start it.", "text": "Update available — 1 day ago"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
12:50:37 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T10:48:31Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:50:37 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
12:50:37 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None
12:50:54 + 16.4s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
12:50:56 + 18.5s phase=copying label=Az adatok másolása a frissítés előtt… err=None hold=None
12:51:05 + 27.7s phase=starting label=Indítás az új verzióval… err=None hold=None
12:51:11 + 33.9s phase=verifying label=Működés ellenőrzése… err=None hold=None
12:51:23 + 45.1s phase=done label=Frissítve err=None hold=None
12:51:34 [3-after] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
12:51:34 [3-after] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:51:37 log:
2026/09/24 10:43:59 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition
2026/09/24 10:44:17 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T104416Z-nextcloud-mariadb.sql]
2026/09/24 10:44:18 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7.4.0-alpine)
2026/09/24 10:44:18 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling
2026/09/24 10:48:31 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:858f009f9709…))
2026/09/24 10:50:37 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition
2026/09/24 10:50:50 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:c35af3bbcef5…))
2026/09/24 10:50:54 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T105053Z-nextcloud-mariadb.sql]
2026/09/24 10:50:55 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine)
2026/09/24 10:50:55 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling
@@ -0,0 +1,28 @@
12:50:04 [1-control] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
12:50:04 [1-control] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T10:48:31Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:50:05 drill: ladder head entry digest sha256:858f009f9709 -> sha256:c35af3bbcef5
12:50:16 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
12:50:16 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T10:48:31Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:50:37 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.", "text": "Frissítés elérhető — 1 napja"}], "en": [{"title": "A newer version of this app is available. Select the Update button to start it.", "text": "Update available — 1 day ago"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
12:50:37 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T10:48:31Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:50:37 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
12:50:37 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None
12:50:54 + 16.4s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
12:50:56 + 18.5s phase=copying label=Az adatok másolása a frissítés előtt… err=None hold=None
12:51:05 + 27.7s phase=starting label=Indítás az új verzióval… err=None hold=None
12:51:11 + 33.9s phase=verifying label=Működés ellenőrzése… err=None hold=None
12:51:23 + 45.1s phase=done label=Frissítve err=None hold=None
12:51:34 [3-after] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
12:51:34 [3-after] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
12:51:37 log:
2026/09/24 10:43:59 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition
2026/09/24 10:44:17 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T104416Z-nextcloud-mariadb.sql]
2026/09/24 10:44:18 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7.4.0-alpine)
2026/09/24 10:44:18 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling
2026/09/24 10:48:31 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:858f009f9709…))
2026/09/24 10:50:37 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition
2026/09/24 10:50:50 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:c35af3bbcef5…))
2026/09/24 10:50:54 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T105053Z-nextcloud-mariadb.sql]
2026/09/24 10:50:55 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine)
2026/09/24 10:50:55 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling
@@ -0,0 +1,3 @@
gitea.dooplex.hu/admin/felhom-controller:0.269.1
gitea.dooplex.hu/admin/felhom-controller:0.269.1
gitea.dooplex.hu/admin/felhom-controller:0.269.1 Up 20 seconds (healthy)
@@ -0,0 +1,233 @@
{
"controller": "gitea.dooplex.hu/admin/felhom-controller:0.269.1",
"1-control": {
"state": "running",
"installed": {
"nextcloud": {
"ref": "nextcloud:34.0.4-apache",
"digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-db": {
"ref": "mariadb:12.3",
"digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-redis": {
"ref": "redis:7-alpine",
"digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"at": "2026-09-24T10:50:50Z"
}
},
"pinned": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_images": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_digests": {
"nextcloud": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"nextcloud-db": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"nextcloud-redis": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098"
},
"catalog_tested_at": "2026-09-24T10:50:04Z",
"badges": {
"hu": [
{
"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.",
"text": "Naprakész"
}
],
"en": [
{
"title": "This app is running the newest version available.",
"text": "Up to date"
}
]
},
"compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"
},
"ladder_edit": {
"old": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"new": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
"tested_at": "2026-09-24T11:03:33Z"
},
"2-behind": {
"state": "running",
"installed": {
"nextcloud": {
"ref": "nextcloud:34.0.4-apache",
"digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-db": {
"ref": "mariadb:12.3",
"digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-redis": {
"ref": "redis:7-alpine",
"digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"at": "2026-09-24T10:50:50Z"
}
},
"pinned": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_images": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_digests": {
"nextcloud": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"nextcloud-db": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"nextcloud-redis": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"
},
"catalog_tested_at": "2026-09-24T11:03:33Z",
"badges": {
"hu": [
{
"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.",
"text": "Frissítés elérhető — 1 napja"
}
],
"en": [
{
"title": "A newer version of this app is available. Select the Update button to start it.",
"text": "Update available — 1 day ago"
}
]
},
"compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098",
"running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"
},
"sync_kept_running_digest": true,
"update": {
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "backing-up",
"label": "Biztonsági mentés készül a frissítés előtt…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 15.4,
"phase": "safety-dump",
"label": "Adatbázis pillanatkép…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 17.5,
"phase": "pulling",
"label": "Új verzió letöltése…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 18.5,
"phase": "copying",
"label": "Az adatok másolása a frissítés előtt…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 26.7,
"phase": "starting",
"label": "Indítás az új verzióval…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 32.8,
"phase": "verifying",
"label": "Működés ellenőrzése…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 44.1,
"phase": "done",
"label": "Frissítve",
"updating": false,
"error": null,
"hold": null
}
],
"duration_s": 44.1,
"final_phase": "done",
"update_error": null,
"hold_reason": null,
"state": "running"
},
"3-after": {
"state": "running",
"installed": {
"nextcloud": {
"ref": "nextcloud:34.0.4-apache",
"digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-db": {
"ref": "mariadb:12.3",
"digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"at": "2026-09-24T10:48:31Z"
},
"nextcloud-redis": {
"ref": "redis:7-alpine",
"digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
"at": "2026-09-24T11:04:49Z"
}
},
"pinned": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_images": {
"nextcloud": "nextcloud:34.0.4-apache",
"nextcloud-db": "mariadb:12.3",
"nextcloud-redis": "redis:7-alpine"
},
"catalog_digests": {
"nextcloud": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c",
"nextcloud-db": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1",
"nextcloud-redis": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499"
},
"catalog_tested_at": "2026-09-24T11:03:33Z",
"badges": {
"hu": [
{
"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.",
"text": "Naprakész"
}
],
"en": [
{
"title": "This app is running the newest version available.",
"text": "Up to date"
}
]
},
"compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499",
"running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"
},
"pull_log": "2026/09/24 11:04:07 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition\n2026/09/24 11:04:22 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T110422Z-nextcloud-mariadb.sql]\n2026/09/24 11:04:24 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine)\n2026/09/24 11:04:24 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling\n2026/09/24 11:04:49 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:858f009f9709…))\n"
}
@@ -0,0 +1,25 @@
13:03:33 [1-control] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
13:03:33 [1-control] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:03:35 drill: ladder head entry digest sha256:c35af3bbcef5 -> sha256:858f009f9709
13:03:45 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
13:03:45 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:04:06 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.", "text": "Frissítés elérhető — 1 napja"}], "en": [{"title": "A newer version of this app is available. Select the Update button to start it.", "text": "Update available — 1 day ago"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
13:04:06 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:04:06 CHECK the sync kept the running digest in the compose before Update: True
13:04:07 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
13:04:07 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None
13:04:22 + 15.4s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
13:04:24 + 17.5s phase=pulling label=Új verzió letöltése… err=None hold=None
13:04:25 + 18.5s phase=copying label=Az adatok másolása a frissítés előtt… err=None hold=None
13:04:33 + 26.7s phase=starting label=Indítás az új verzióval… err=None hold=None
13:04:39 + 32.8s phase=verifying label=Működés ellenőrzése… err=None hold=None
13:04:51 + 44.1s phase=done label=Frissítve err=None hold=None
13:05:02 [3-after] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
13:05:02 [3-after] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T11:04:49Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:05:05 log:
2026/09/24 11:04:07 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition
2026/09/24 11:04:22 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T110422Z-nextcloud-mariadb.sql]
2026/09/24 11:04:24 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine)
2026/09/24 11:04:24 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling
2026/09/24 11:04:49 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:858f009f9709…))
@@ -0,0 +1,25 @@
13:03:33 [1-control] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
13:03:33 [1-control] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:03:35 drill: ladder head entry digest sha256:c35af3bbcef5 -> sha256:858f009f9709
13:03:45 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
13:03:45 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:04:06 [2-behind] {"state": "running", "badges": {"hu": [{"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.", "text": "Frissítés elérhető — 1 napja"}], "en": [{"title": "A newer version of this app is available. Select the Update button to start it.", "text": "Update available — 1 day ago"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "running_redis": "redis:7-alpine@sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098 sha256:7d06252fad43690f61cbb858628b933fd85f048aaba4c05e577274b2c77cd7cb"}
13:04:06 [2-behind] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098", "at": "2026-09-24T10:50:50Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:04:06 CHECK the sync kept the running digest in the compose before Update: True
13:04:07 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
13:04:07 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None
13:04:22 + 15.4s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
13:04:24 + 17.5s phase=pulling label=Új verzió letöltése… err=None hold=None
13:04:25 + 18.5s phase=copying label=Az adatok másolása a frissítés előtt… err=None hold=None
13:04:33 + 26.7s phase=starting label=Indítás az új verzióval… err=None hold=None
13:04:39 + 32.8s phase=verifying label=Működés ellenőrzése… err=None hold=None
13:04:51 + 44.1s phase=done label=Frissítve err=None hold=None
13:05:02 [3-after] {"state": "running", "badges": {"hu": [{"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.", "text": "Naprakész"}], "en": [{"title": "This app is running the newest version available.", "text": "Up to date"}]}, "compose_redis": "103: image: redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "running_redis": "redis:7-alpine@sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499 sha256:f84b0c4678011602b9b98c227a4dcd5468bf8b088b02fdd4165cb7758bad8058"}
13:05:02 [3-after] installed={"nextcloud": {"ref": "nextcloud:34.0.4-apache", "digest": "sha256:a5ace30c695afe48c2c406e940ee7886a81e13fa382e57cd68b2416d1a66914c", "at": "2026-09-24T10:48:31Z"}, "nextcloud-db": {"ref": "mariadb:12.3", "digest": "sha256:805c8e104bd563d5bfa24fadd3f31cd419ea859cb5277f32b5dbf2db714f9ed1", "at": "2026-09-24T10:48:31Z"}, "nextcloud-redis": {"ref": "redis:7-alpine", "digest": "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499", "at": "2026-09-24T11:04:49Z"}} pinned={"nextcloud": "nextcloud:34.0.4-apache", "nextcloud-db": "mariadb:12.3", "nextcloud-redis": "redis:7-alpine"}
13:05:05 log:
2026/09/24 11:04:07 update.go:762: [INFO] [stacks] update nextcloud: ladder — the installed version nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine matches no update_ladder entry (2 entries) — an app older than the ladder has no record to climb; the catalog's current definition
2026/09/24 11:04:22 update.go:807: [INFO] [stacks] update nextcloud: safety dump done (1 file(s)) [/mnt/felhom-drives/scratch_hdd/userdata/nextcloud/backups/primary/nextcloud/db-dumps/pre-restore-20260924T110422Z-nextcloud-mariadb.sql]
2026/09/24 11:04:24 pin.go:373: [INFO] [stacks] update nextcloud: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/nextcloud/docker-compose.yml (nextcloud=nextcloud:34.0.4-apache, nextcloud-db=mariadb:12.3, nextcloud-redis=redis:7-alpine)
2026/09/24 11:04:24 update.go:1260: [INFO] [stacks] update nextcloud: phase pulling
2026/09/24 11:04:49 installed.go:420: [INFO] [stacks] installed-images nextcloud: recorded 3 service(s) (nextcloud=nextcloud:34.0.4-apache (sha256:a5ace30c695a…), nextcloud-db=mariadb:12.3 (sha256:805c8e104bd5…), nextcloud-redis=redis:7-alpine (sha256:858f009f9709…))
@@ -7,3 +7,21 @@ Step log. Newest at the bottom. Times CEST unless marked Z.
- 11:09 9202 repointed to the drill catalog (controller.yaml saved as .pre-night0924)
- 11:20 A1 (whole restore + R-668) and A2 (decision 27) built, tested, red-proofed
- 11:34 A3 built: detector (6 restarts/10 min — measured gokapi 1/min), stop+hold+event, Start lifts; red-proofs detector + skips
- 11:49 A4 (R-664 box+catalog, R-665, R-662 removed) and Part B (digests) built, red-proofed; hub 0.123.0 live
- 12:21 9202: drill setting update.backup_max_age 1m (forces the update's own backup + Tier 2); restored at teardown from .pre-night0924
- 12:25 A1 LIVE PASS (9202, v0.269.0): whole restore from the SSD Tier-2 copy — files restored=1 kept-newer=1 unchanged=137, unit 3/3 volumes 1/1 db, 38 s; account + all three files read back (A1/21-readback.json). R-668 live: the new copy went to the SSD, not the same disk.
- 12:29 A3 LIVE trip 1: gokapi stopped by the box „crash_loop — 6 in 10m0s", page hu/en + Start, no restore badge (A3/21).
- 12:37 A3 LIVE Start + trip 2: Start LIFTED the hold; Docker's back-off reset on the new start → 9 restarts in 32 s → stopped again, trip 2, page hu/en says support is told; 0 app_start_failed lines (A3/30-start-then-trip2.*).
- 12:41 A1 LIVE hold names the second drive: failing edge (redis 7.4-alpine + probe 8999), undo copy cut → HELD, page hu/en „második meghajtó … beállításokat, az adatbázist és a fájlokat" / "second drive … settings, the database and the files"; hdd-data keep_data_only absent (A2 positive control); the page's whole restore → hold CLEARED, 33.8 s, unit 3/3 1/1, account + files read back (A1/30-held-then-whole.*).
- 12:42 Part B seen live in passing: nextcloud's compose on 9202 runs redis:7-alpine@sha256:858f… (floating tag, digest from the ladder entry).
- 12:43 FINDING: after hold + whole restore the probe stays on the FAILED step's .felhom.yml (applied-meta 10:39:21 = port 8999; stack .felhom.yml restored from the unit, which the sync had already flowed). Steady probe heals on the next sync; applied-meta does not until a pin advance → a later failed update's undo would probe the old version with the wrong check. ROW to file.
- 12:43 FINDING: `[ERROR] .felhom.yml backup block rejected in …/pre-update-meta: docker-compose.yml unreadable` on an undo (10:24:41). ROW to file.
- 12:44 Part E schedule drawn (tools/chaos_schedule.py, seed 20260924, md5 of table b5ccf895…).
- 12:50 A3/40: first-start restarts in all drill evidence — no healthy app ≥ 6; immich 12 (broken, first-start import). ROW (watch).
ROWS TO FILE: R-668 (Tier-2 target on a missing path, fixed); applied-meta after restore; pre-update-meta ERROR noise; ladder log "older than the ladder" at head; missingFileLegsRefusal text names file restore not whole; immich first-start watch; R-644 gokapi disposition.
- 12:48 A2 LIVE PASS: a no-whole-copy hold (second-drive mirror moved aside = a one-drive box) → page hu/en „…ügyfélszolgálatát értesítettük — addig ne indítsd újra, és ne töröld az adatait." ; hdd-data keep_data_only=true; Remove with data → 409 hu/en, with backups → 409; app still deployed; mirror back → whole restore cleared it; account + files read back (A2/10-held-no-copy-keep-data.*).
- 12:48 FINDING CONSEQUENCE PROVEN: that hold was reached because the undo judged the (correct) old version with the FAILED step's probe (applied-meta 8999 left by the previous hold+restore) → a false hold (A2/11). Undo-copy volumes of the earlier hold (…103924Z, ~0.9 GiB) still present after its hold was cleared by a restore. ROWS.
- 12:55 Part B: compose config accepts tag@digest for every template (25 apps, 37 digests, 0 missing, 0 differ) — B/01.
- 12:51 Part B LIVE on 0.269.0: badge Behind for a newer tested digest of a floating tag, Update pulled it, record + badge current (B/10). FINDING: the SYNC wrote the new digest into the running app's compose BEFORE Update → a restart would pull it unguarded. FIXED v0.269.1 (CarryDigests), red-proofed (redproofs/B-sync-carry.txt), pushed 5b1b191, image built, 9202 on 0.269.1 (B/20).
- 13:05 Part B LIVE PASS on 0.269.1: sync KEPT the running digest before Update (True), badge Behind hu/en, Update done 44 s, running digest = the tested one, badge current (B/21-floating-tag-0.269.1.*).
- DECISION (CC, unattended): a second controller release tonight (0.269.1) instead of shipping the bypass with the floor — first in the morning note.
@@ -1,5 +1,5 @@
--- FAIL: TestR668_MissingStoragePathIsNotASecondDrive (0.01s)
r668_missing_path_test.go:45: chose the missing path /tmp/TestR668_MissingStoragePathIsNotASecondDrive1761835767/001/drive-gone as the second drive
r668_missing_path_test.go:38: chose the missing path /tmp/TestR668_MissingStoragePathIsNotASecondDrive2803100938/001/drive-gone as the second drive
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/backup 0.014s
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/backup 0.015s
FAIL
@@ -0,0 +1,2 @@
XX FACT: the step has its compose but no .felhom.yml rc=0 (expected 1)
XX DECOY: the step's .felhom.yml exists by NAME and holds no healthcheck rc=0 (expected 1)
@@ -0,0 +1,7 @@
--- FAIL: TestR665_TheVerifyUsesTheNewVersionsOwnFile (0.01s)
r665_verify_meta_test.go:39: verified with probe port 1111, want the catalog's 2222 (1111 = the restored file, R-665)
--- FAIL: TestR664_AStepIsVerifiedWithItsOwnFile (0.01s)
r665_verify_meta_test.go:54: step B verified with probe port 1111, want its own 3333
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/stacks 0.024s
FAIL
@@ -0,0 +1,6 @@
--- FAIL: TestDigest_FloatingTagBehindOnlyForANewerTestedDigest (0.00s)
digest_test.go:57: newer tested digest: 1, want 2
--- FAIL: TestDigest_TheUpdateRendersTheStepsTestedDigest (0.01s)
digest_test.go:74: the live compose does not pin the tested digest:
--- FAIL: TestDigest_SyncerRendersTheTestedDigest (0.00s)
digest_render_test.go:36: no digest in the rendered compose:
@@ -0,0 +1,10 @@
# Red-proof — the sync keeps a DEPLOYED app's running digest (v0.269.1; live finding night 2026-09-24 Part B)
# Mutation: the call site in internal/sync/sync.go rendered the ladder's newest digest for every app again
# (`if false && s.renderPlanFn != nil && s.renderPlanFn(appName).Deployed {`)
--- FAIL: TestDigest_SyncerKeepsTheRunningDigest (0.00s)
--- FAIL: TestDigest_SyncerKeepsTheRunningDigest/runs_an_older_digest (0.00s)
digest_render_test.go:65: the sync MOVED the running digest (want "@sha256:bbbb…", never "sha256:aaaa…")
--- FAIL: TestDigest_SyncerKeepsTheRunningDigest/runs_no_digest (0.00s)
digest_render_test.go:65: the sync MOVED the running digest (want "image: nextcloud:31.0.14-apache\n", never "sha256:aaaa…")
FAIL
# Fix restored → ok internal/sync; git diff of the mutation: none.
@@ -0,0 +1,65 @@
#!/usr/bin/env python3
"""Part E's schedule — night 2026-09-24. Deterministic: seed 20260924, 12 rounds of action x accident.
Committed BEFORE round 1 and printed into DRILL-night-2026-09-24.md, so the schedule cannot be chosen after
the fact. Constraints from the brief: every action at least once; controller killed at most 3 times, at
least 20 minutes apart (rounds are ~6 min, so kills sit >= 4 rounds apart); a whole-box backup only on 9202.
python3 chaos_schedule.py # prints the table
python3 chaos_schedule.py --json # for the runner
"""
import json
import random
import sys
SEED = 20260924
ROUNDS = 12
ROUND_MIN = 6 # planned length of one round, minutes
ACTIONS = [
"ladder_step", # a proven ladder step (Update)
"failing_step", # a step whose probe fails -> undo
"cutoff_undo_file_app", # a file app's undo copy cut off -> the second-drive whole restore
"crash_loop", # a drill image that exits -> the box stops it
"oom_app", # a tiny mem_limit -> out-of-memory kills
"install",
"remove_held", # Remove on a held app
"start_after_unhealthy",# Start after the box stopped an app
]
ACCIDENTS = ["none", "power_cut", "controller_killed", "docker_restart", "disk_to_floor_plus_1g",
"whole_box_backup"]
MAX_KILLS, KILL_GAP_MIN = 3, 20
def schedule(seed=SEED):
rng = random.Random(seed)
for _ in range(10000):
acts = ACTIONS + [rng.choice(ACTIONS) for _ in range(ROUNDS - len(ACTIONS))]
rng.shuffle(acts)
accs = [rng.choice(ACCIDENTS) for _ in range(ROUNDS)]
kills = [i for i, a in enumerate(accs) if a == "controller_killed"]
if len(kills) > MAX_KILLS:
continue
if any((b - a) * ROUND_MIN < KILL_GAP_MIN for a, b in zip(kills, kills[1:])):
continue
# Start-after-unhealthy needs an app the box stopped: never before the first crash_loop/oom_app.
first_stop = min(i for i, a in enumerate(acts) if a in ("crash_loop", "oom_app"))
if acts.index("start_after_unhealthy") < first_stop:
continue
# Remove-on-held needs a held app: after a failing_step or cutoff.
first_hold = min(i for i, a in enumerate(acts) if a in ("failing_step", "cutoff_undo_file_app"))
if acts.index("remove_held") < first_hold:
continue
return [{"round": i + 1, "action": acts[i], "accident": accs[i]} for i in range(ROUNDS)]
raise SystemExit("no schedule satisfies the constraints")
if __name__ == "__main__":
s = schedule()
if "--json" in sys.argv:
print(json.dumps(s, indent=1))
else:
print(f"seed {SEED}, {ROUNDS} rounds")
print("| round | action | accident |\n|---|---|---|")
for r in s:
print(f"| {r['round']} | {r['action']} | {r['accident']} |")
@@ -0,0 +1,44 @@
#!/usr/bin/env python3
"""A1 live on 9202 (v0.269.0) — decision 26: nextcloud (file app) with a fresh second copy, files changed through
the front door, a failing update whose undo copy is cut off (→ HOLD), then the second copy's „Teljes
visszaállítás" = the WHOLE restore. Read back: the account, every file, the counts."""
import html as H, json, re, sys, time
sys.path.insert(0, ".")
import walk as w, fixtures as fx, ncfiles as nf
F, SUB, APP = fx.Nextcloud(), "cloud-a1", "nextcloud"
CAT = f"{w.DRILL}/templates/{APP}"
S = json.load(open(f"{w.SC}/a1-secret-state.json"))
A, files = S["A"], S["files"]
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
w.login()
def drill(edit, msg):
import fcntl
with open(f"{w.SC}/drill.lock", "w") as lk:
fcntl.flock(lk, fcntl.LOCK_EX)
w.sh(["git", "-C", w.DRILL, "pull", "-q", "--rebase", "origin", "main"], timeout=120)
edit()
w.sh(["git", "-C", w.DRILL, "commit", "-qam", "NIGHT-A1 " + msg])
w.sh(["git", "-C", w.DRILL, "push", "-q", "origin", "main"], timeout=120)
w.say("drill: " + msg)
HEAD = open(f"{CAT}/docker-compose.yml").read()
FY = open(f"{CAT}/.felhom.yml").read()
names = list(files)
# (a) a fresh backup + second copy: an update whose tag does not exist
drill(lambda: open(f"{CAT}/docker-compose.yml", "w").write(HEAD.replace("nextcloud:34.0.4-apache", "nextcloud:34.0.98-notag")), "notag (backing-up + Tier 2, pull fails)")
w.sync_rescan(APP, "nextcloud:34.0.98-notag", tries=60)
# make the copy fresh-older than backup_max_age? the existing unit is < 24 h old -> force the backup by nothing: the
# precondition may lean on the existing copy. So record which copy it used.
out["press_a"] = w.press_update(APP)
out["log_a"] = w.guest("docker logs --since 5m felhom-controller 2>&1 | grep -E 'nextcloud' | grep -iE 'Tier 2|precondition|same-disk|backup' | tail -8")
w.say("log (a):\n" + out["log_a"])
drill(lambda: open(f"{CAT}/docker-compose.yml", "w").write(HEAD), "back to 34.0.4")
out["mirror"] = w.guest("""for b in $(find /mnt/sys_drive /mnt/felhom-drives -maxdepth 7 -type d -path '*backups/secondary/nextcloud' 2>/dev/null); do echo "== $b"; ls $b; find $b -name 'felhom-seed-*' | sed 's|.*/||'; done""")
w.say("mirrors:\n" + out["mirror"])
out["record"] = w.guest("python3 -c \"import json;d=json.load(open('/var/lib/docker/volumes/felhom-controller-data/_data/data/settings.json'));print(json.dumps(d['app_backup']['nextcloud']['cross_drive']))\"")
w.say("Tier-2 record: " + out["record"])
json.dump(out, open("../A1/11-copy.json", "w"), indent=2, default=str)
open("../A1/11-copy.log", "w").write("\n".join(w.LOG) + "\n")
@@ -0,0 +1,117 @@
#!/usr/bin/env python3
"""A1 live, whole: (a) a fresh second copy via the update's own backup; (b) through WebDAV: delete file 0, edit
file 1 (live newer than the copy); (c) a failing update (probe 8999) whose undo copy is cut off → HOLD, the
page naming the second drive; (d) the second copy's „Teljes visszaállítás" = the WHOLE restore; (e) read back."""
import html as H, json, re, sys, time
sys.path.insert(0, ".")
import walk as w, fixtures as fx, ncfiles as nf
F, SUB, APP = fx.Nextcloud(), "cloud-a1", "nextcloud"
CAT = f"{w.DRILL}/templates/{APP}"
S = json.load(open(f"{w.SC}/a1-secret-state.json"))
A, files = S["A"], S["files"]
names = sorted(files)
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
w.login()
def drill(edit, msg):
import fcntl
with open(f"{w.SC}/drill.lock", "w") as lk:
fcntl.flock(lk, fcntl.LOCK_EX)
w.sh(["git", "-C", w.DRILL, "pull", "-q", "--rebase", "origin", "main"], timeout=120)
edit()
w.sh(["git", "-C", w.DRILL, "commit", "-qam", "NIGHT-A1b " + msg])
w.sh(["git", "-C", w.DRILL, "push", "-q", "origin", "main"], timeout=120)
w.say("drill: " + msg)
HEAD = open(f"{CAT}/docker-compose.yml").read()
FY = open(f"{CAT}/.felhom.yml").read()
# (a)
drill(lambda: open(f"{CAT}/docker-compose.yml", "w").write(HEAD.replace("nextcloud:34.0.4-apache", "nextcloud:34.0.97-notag")), "notag")
w.sync_rescan(APP, "nextcloud:34.0.97-notag", tries=60)
out["press_a"] = w.press_update(APP)
out["log_a"] = w.guest("docker logs --since 3m felhom-controller 2>&1 | grep -iE 'nextcloud' | grep -iE 'Tier 2|precondition|same disk|same-disk' | tail -6")
w.say("log (a):\n" + out["log_a"])
drill(lambda: open(f"{CAT}/docker-compose.yml", "w").write(HEAD), "back to 34.0.4")
out["record"] = w.guest("python3 -c \"import json;d=json.load(open('/var/lib/docker/volumes/felhom-controller-data/_data/data/settings.json'));print(json.dumps(d['app_backup']['nextcloud']['cross_drive']))\"")
w.say("Tier-2 record: " + out["record"])
dest = json.loads(out["record"]).get("destination_path", "")
out["mirror_seeds"] = w.guest(f"find {dest}/backups/secondary/nextcloud -name 'felhom-seed-*' | sed 's|.*/||'; stat -c '%n dev=%d' {dest} /mnt/felhom-drives/scratch_hdd/userdata/nextcloud")
w.say("mirror seeds + devices:\n" + out["mirror_seeds"])
# (b)
time.sleep(2)
rc, code, _ = w.app_curl(SUB, f"/remote.php/dav/files/{A['uid']}/{names[0]}", "-u", f"{A['uid']}:{A['pw']}", method="DELETE")
w.say(f"(b) DELETE {names[0]} -> {code}")
files1 = "edited by the household " + str(time.time())
ok = nf.put(w, SUB, A, names[1], files1)
w.say(f"(b) PUT {names[1]} (newer than the copy) -> {ok}")
out["after_b"] = nf.verify_files(w, SUB, A, {names[0]: files[names[0]], names[1]: files1, names[2]: files[names[2]]}, w.say)
# (c)
def break_edge():
open(f"{CAT}/docker-compose.yml", "w").write(HEAD.replace("image: redis:7-alpine", "image: redis:7.2-alpine"))
f = re.sub(r"(healthcheck:\n\s+checks:\n\s+- type: api\n\s+port: )80\b", r"\g<1>8999", FY, count=1)
assert f != FY, "probe port not found"
open(f"{CAT}/.felhom.yml", "w").write(f)
drill(break_edge, "redis 7-alpine -> 7.2-alpine + probe 8999 (the failing edge)")
w.sync_rescan(APP, "redis:7.2-alpine", tries=60)
cut = {}
code, d = w.ctl("POST", f"/api/stacks/{APP}/update")
w.say(f"(c) Update -> {code}")
seen, tp = None, time.time()
while time.time() - tp < 1200:
st = w.stack(APP)
ph = st.get("update_phase")
if ph != seen and ph:
seen = ph
w.say(f" +{time.time()-tp:6.1f}s phase={ph}")
if ph == "verifying" and not cut:
cut["out"] = w.guest(f"""c=$(docker volume ls -q --filter label=felhom.undo-copy-of={APP} | head -1); echo "copy: $c"
docker run --rm -v $c:/c alpine sh -c 'rm -f /c/felhom-undo-complete; ls /c'""")
w.say(" >>> marker removed:\n" + cut["out"])
if not st.get("updating") and ph in ("done", "failed", "undone") and time.time() - tp > 3:
break
time.sleep(0.5)
st = w.stack(APP)
out["held"] = {k: st.get(k) for k in ("update_phase", "hold_reason", "hold_no_whole_copy", "hold_kind", "state")}
w.say("(c) held: " + json.dumps(out["held"], ensure_ascii=False))
for lang in ("hu", "en"):
page = H.unescape(w.page(f"/apps/{APP}?lang={lang}"))
m = re.search(r'data-held="true">(.*?)</div>', page, re.S)
out[f"page_{lang}"] = m.group(1).strip() if m else None
w.say(f"(c) [{lang}] {out[f'page_{lang}']!r}")
# (d) the WHOLE restore: the button the page offers on the Mentések page for the second copy
drill(lambda: (open(f"{CAT}/docker-compose.yml", "w").write(HEAD), open(f"{CAT}/.felhom.yml", "w").write(FY)), "back to the head + the real probe")
w.sync_rescan()
sess = open(f"{w.SC}/sess{__import__('os').getpid()}.txt").read().strip()
csrf = open(f"{w.SC}/csrf{__import__('os').getpid()}.txt").read().strip()
t0 = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
r = w.sh(["curl", "-sk", "-D", "-", "-o", "/dev/null", "-H", w.HOSTHDR, "-H", f"Cookie: {sess}", "-X", "POST",
"--data-urlencode", f"_csrf={csrf}", "--data-urlencode", f"stack_name={APP}", f"{w.BASE}/backup/tier2/unit-restore"], timeout=120)
w.say("(d) POST /backup/tier2/unit-restore -> " + (r.stdout or "").split("\n")[0] + " " + str([l for l in (r.stdout or "").split("\n") if l.lower().startswith("location")]))
last = None
for _ in range(600):
c2, dd = w.ctl("GET", "/api/backup/restore-status")
d2 = (dd.get("data") or {}) if isinstance(dd, dict) else {}
cur = (d2.get("running"), d2.get("message"))
if cur != last:
w.say(f" restore-status {cur}")
last = cur
if not d2.get("running") and d2.get("message"):
break
time.sleep(2)
out["restore_msg"] = last
out["restore_log"] = w.guest(f"docker logs --since {t0} felhom-controller 2>&1 | grep -iE 'whole restore|WHOLE restore|Tier-2 whole|Restore-from-unit|hold .*CLEARED' | tail -8")
w.say("(d) log:\n" + out["restore_log"])
# (e)
w.wait_app(SUB, "/status.php", want=("200",), tries=120, delay=5)
out["account"] = bool(F.verify(w, SUB, A, w.say))
out["files_after"] = nf.verify_files(w, SUB, A, {names[0]: files[names[0]], names[1]: files1, names[2]: files[names[2]]}, w.say)
out["kept_beside"] = w.guest(f"find /mnt/felhom-drives/scratch_hdd/userdata/nextcloud -name '*.felhom-*' | sed 's|.*/||'")
st = w.stack(APP)
out["final"] = {k: st.get(k) for k in ("state", "hold_reason", "update_phase")}
w.say("(e) final " + json.dumps(out["final"], ensure_ascii=False) + " kept-beside: " + out["kept_beside"])
json.dump(out, open("../A1/20-whole-restore.json", "w"), indent=2, ensure_ascii=False, default=str)
open("../A1/20-whole-restore.log", "w").write("\n".join(w.LOG) + "\n")
@@ -0,0 +1,33 @@
import json, sys, time
sys.path.insert(0, ".")
import walk as w, fixtures as fx, ncfiles as nf
F, SUB, APP = fx.Nextcloud(), "cloud-a1", "nextcloud"
S = json.load(open(f"{w.SC}/a1-secret-state.json"))
A, files = S["A"], S["files"]
names = sorted(files)
w.login()
out = {}
c, d = w.ctl("GET", "/api/backup/restore-status")
out["restore_status"] = d
w.say("restore-status: " + json.dumps(d, ensure_ascii=False)[:600])
out["log"] = w.guest("docker logs --since 2026-09-24T10:24:55Z felhom-controller 2>&1 | grep -iE 'whole restore|WHOLE restore|Tier-2 whole|Restore-from-unit completed|hold .*CLEARED|Restoring Docker volume' | cut -c1-330 | tail -10")
w.say("log:\n" + out["log"])
w.wait_app(SUB, "/status.php", want=("200",), tries=60, delay=5)
out["account"] = bool(F.verify(w, SUB, A, w.say))
# file 0 was DELETED after the copy (must come back); file 1 was EDITED after the copy (newer — must stay edited)
c0, b0 = nf.get(w, SUB, A, names[0]); c1, b1 = nf.get(w, SUB, A, names[1]); c2, b2 = nf.get(w, SUB, A, names[2])
out["file0_back"] = (c0 == "200" and b0 == files[names[0]])
out["file1_kept_edit"] = (c1 == "200" and b1.startswith("edited by the household"))
out["file2_unchanged"] = (c2 == "200" and b2 == files[names[2]])
w.say(f"file0 (deleted after the copy) back={out['file0_back']} ({c0}); file1 (edited after the copy) kept the edit={out['file1_kept_edit']}; file2 unchanged={out['file2_unchanged']}")
out["occ_scan"] = w.guest(f"docker exec -u www-data nextcloud php occ files:scan {A['uid']} 2>&1 | tail -4")
w.say("occ files:scan (the app sees its files): " + out["occ_scan"])
c0b, b0b = nf.get(w, SUB, A, names[0])
out["file0_back_after_scan"] = (c0b == "200" and b0b == files[names[0]])
w.say(f"file0 after occ scan: {c0b} {out['file0_back_after_scan']}")
out["kept_beside"] = w.guest("find /mnt/felhom-drives/scratch_hdd/userdata/nextcloud -name '*.felhom-*' | sed 's|.*/||'")
st = w.stack(APP)
out["final"] = {k: st.get(k) for k in ("state", "hold_reason", "update_phase")}
w.say("final " + json.dumps(out["final"], ensure_ascii=False) + " | kept beside: " + repr(out["kept_beside"]))
json.dump(out, open("../A1/21-readback.json", "w"), indent=2, ensure_ascii=False, default=str)
open("../A1/21-readback.log", "w").write("\n".join(w.LOG) + "\n")
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""A1 live, whole: (a) a fresh second copy via the update's own backup; (b) through WebDAV: delete file 0, edit
file 1 (live newer than the copy); (c) a failing update (probe 8999) whose undo copy is cut off → HOLD, the
page naming the second drive; (d) the second copy's „Teljes visszaállítás" = the WHOLE restore; (e) read back."""
import html as H, json, re, sys, time
sys.path.insert(0, ".")
import walk as w, fixtures as fx, ncfiles as nf
F, SUB, APP = fx.Nextcloud(), "cloud-a1", "nextcloud"
CAT = f"{w.DRILL}/templates/{APP}"
S = json.load(open(f"{w.SC}/a1-secret-state.json"))
A, files = S["A"], S["files"]
names = sorted(files)
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
w.login()
def drill(edit, msg):
import fcntl
with open(f"{w.SC}/drill.lock", "w") as lk:
fcntl.flock(lk, fcntl.LOCK_EX)
w.sh(["git", "-C", w.DRILL, "pull", "-q", "--rebase", "origin", "main"], timeout=120)
edit()
w.sh(["git", "-C", w.DRILL, "commit", "-qam", "NIGHT-A1b " + msg])
w.sh(["git", "-C", w.DRILL, "push", "-q", "origin", "main"], timeout=120)
w.say("drill: " + msg)
HEAD = open(f"{CAT}/docker-compose.yml").read()
FY = open(f"{CAT}/.felhom.yml").read()
names = sorted(files)
files1 = None
def break_edge():
open(f"{CAT}/docker-compose.yml", "w").write(HEAD.replace("image: redis:7-alpine", "image: redis:7.4-alpine"))
f = re.sub(r"(healthcheck:\n\s+checks:\n\s+- type: api\n\s+port: )80\b", r"\g<1>8999", FY, count=1)
assert f != FY, "probe port not found"
open(f"{CAT}/.felhom.yml", "w").write(f)
drill(break_edge, "redis 7-alpine -> 7.4-alpine + probe 8999 (the failing edge)")
w.sync_rescan(APP, "redis:7.4-alpine", tries=60)
cut = {}
code, d = w.ctl("POST", f"/api/stacks/{APP}/update")
w.say(f"(c) Update -> {code}")
seen, tp = None, time.time()
while time.time() - tp < 1200:
st = w.stack(APP)
ph = st.get("update_phase")
if ph != seen and ph:
seen = ph
w.say(f" +{time.time()-tp:6.1f}s phase={ph}")
if ph == "verifying" and not cut:
cut["out"] = w.guest(f"""c=$(docker volume ls -q --filter label=felhom.undo-copy-of={APP} | head -1); echo "copy: $c"
docker run --rm -v $c:/c alpine sh -c 'rm -f /c/felhom-undo-complete; ls /c'""")
w.say(" >>> marker removed:\n" + cut["out"])
if not st.get("updating") and ph in ("done", "failed", "undone") and time.time() - tp > 3:
break
time.sleep(0.5)
st = w.stack(APP)
out["held"] = {k: st.get(k) for k in ("update_phase", "hold_reason", "hold_no_whole_copy", "hold_kind", "state")}
w.say("(c) held: " + json.dumps(out["held"], ensure_ascii=False))
for lang in ("hu", "en"):
page = H.unescape(w.page(f"/apps/{APP}?lang={lang}"))
m = re.search(r'data-held="true">(.*?)</div>', page, re.S)
out[f"page_{lang}"] = m.group(1).strip() if m else None
w.say(f"(c) [{lang}] {out[f'page_{lang}']!r}")
# decision 27, positive control / refusal: what the Remove dialog reads, and the Remove itself
code, hd = w.ctl("GET", f"/api/stacks/{APP}/hdd-data")
out["hdd_data"] = {"code": code, "keep_data_only": ((hd or {}).get("data") or {}).get("keep_data_only")}
w.say("(c2) hdd-data -> " + json.dumps(out["hdd_data"]))
# (d) the WHOLE restore: the button the page offers on the Mentések page for the second copy
drill(lambda: (open(f"{CAT}/docker-compose.yml", "w").write(HEAD), open(f"{CAT}/.felhom.yml", "w").write(FY)), "back to the head + the real probe")
w.sync_rescan()
sess = open(f"{w.SC}/sess{__import__('os').getpid()}.txt").read().strip()
csrf = open(f"{w.SC}/csrf{__import__('os').getpid()}.txt").read().strip()
t0 = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
r = w.sh(["curl", "-sk", "-D", "-", "-o", "/dev/null", "-H", w.HOSTHDR, "-H", f"Cookie: {sess}", "-X", "POST",
"--data-urlencode", f"_csrf={csrf}", "--data-urlencode", f"stack_name={APP}", f"{w.BASE}/backup/tier2/unit-restore"], timeout=120)
w.say("(d) POST /backup/tier2/unit-restore -> " + (r.stdout or "").split("\n")[0] + " " + str([l for l in (r.stdout or "").split("\n") if l.lower().startswith("location")]))
last = None
for _ in range(600):
c2, dd = w.ctl("GET", "/api/backup/restore-status")
d2 = (dd.get("data") or {}) if isinstance(dd, dict) else {}
cur = (d2.get("running"), d2.get("message"))
if cur != last:
w.say(f" restore-status {cur}")
last = cur
if not d2.get("running") and d2.get("last"):
break
time.sleep(2)
out["restore_msg"] = last
out["restore_log"] = w.guest(f"docker logs --since {t0} felhom-controller 2>&1 | grep -iE 'whole restore|WHOLE restore|Tier-2 whole|Restore-from-unit|hold .*CLEARED' | tail -8")
w.say("(d) log:\n" + out["restore_log"])
# (e)
w.wait_app(SUB, "/status.php", want=("200",), tries=120, delay=5)
out["account"] = bool(F.verify(w, SUB, A, w.say))
out["files_after"] = nf.verify_files(w, SUB, A, {names[0]: files[names[0]], names[2]: files[names[2]]}, w.say)
out["kept_beside"] = w.guest(f"find /mnt/felhom-drives/scratch_hdd/userdata/nextcloud -name '*.felhom-*' | sed 's|.*/||'")
st = w.stack(APP)
out["final"] = {k: st.get(k) for k in ("state", "hold_reason", "update_phase")}
w.say("(e) final " + json.dumps(out["final"], ensure_ascii=False) + " kept-beside: " + out["kept_beside"])
json.dump(out, open("../A1/30-held-then-whole.json", "w"), indent=2, ensure_ascii=False, default=str)
open("../A1/30-held-then-whole.log", "w").write("\n".join(w.LOG) + "\n")
@@ -0,0 +1,116 @@
#!/usr/bin/env python3
"""A1 live, whole: (a) a fresh second copy via the update's own backup; (b) through WebDAV: delete file 0, edit
file 1 (live newer than the copy); (c) a failing update (probe 8999) whose undo copy is cut off → HOLD, the
page naming the second drive; (d) the second copy's „Teljes visszaállítás" = the WHOLE restore; (e) read back."""
import html as H, json, re, sys, time
sys.path.insert(0, ".")
import walk as w, fixtures as fx, ncfiles as nf
F, SUB, APP = fx.Nextcloud(), "cloud-a1", "nextcloud"
CAT = f"{w.DRILL}/templates/{APP}"
MIR = "/mnt/sys_drive/felhom-data/backups/secondary/nextcloud"
S = json.load(open(f"{w.SC}/a1-secret-state.json"))
A, files = S["A"], S["files"]
names = sorted(files)
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
w.login()
def drill(edit, msg):
import fcntl
with open(f"{w.SC}/drill.lock", "w") as lk:
fcntl.flock(lk, fcntl.LOCK_EX)
w.sh(["git", "-C", w.DRILL, "pull", "-q", "--rebase", "origin", "main"], timeout=120)
edit()
w.sh(["git", "-C", w.DRILL, "commit", "-qam", "NIGHT-A2 " + msg])
w.sh(["git", "-C", w.DRILL, "push", "-q", "origin", "main"], timeout=120)
w.say("drill: " + msg)
HEAD = open(f"{CAT}/docker-compose.yml").read()
FY = open(f"{CAT}/.felhom.yml").read()
names = sorted(files)
files1 = None
def break_edge():
open(f"{CAT}/docker-compose.yml", "w").write(HEAD.replace("image: redis:7-alpine", "image: redis:7.4.0-alpine"))
f = re.sub(r"(healthcheck:\n\s+checks:\n\s+- type: api\n\s+port: )80\b", r"\g<1>8999", FY, count=1)
assert f != FY, "probe port not found"
open(f"{CAT}/.felhom.yml", "w").write(f)
drill(break_edge, "redis 7-alpine -> 7.4.0-alpine + probe 8999 (the failing edge)")
w.sync_rescan(APP, "redis:7.4.0-alpine", tries=60)
cut = {}
code, d = w.ctl("POST", f"/api/stacks/{APP}/update")
w.say(f"(c) Update -> {code}")
seen, tp = None, time.time()
while time.time() - tp < 1200:
st = w.stack(APP)
ph = st.get("update_phase")
if ph != seen and ph:
seen = ph
w.say(f" +{time.time()-tp:6.1f}s phase={ph}")
if ph == "verifying" and not cut:
cut["out"] = w.guest(f"""c=$(docker volume ls -q --filter label=felhom.undo-copy-of={APP} | head -1); echo "copy: $c"
docker run --rm -v $c:/c alpine sh -c 'rm -f /c/felhom-undo-complete; ls /c'
mv {MIR} {MIR}.night-aside && echo "second-drive mirror moved aside (a one-drive box)" """)
w.say(" >>> marker removed:\n" + cut["out"])
if not st.get("updating") and ph in ("done", "failed", "undone") and time.time() - tp > 3:
break
time.sleep(0.5)
st = w.stack(APP)
out["held"] = {k: st.get(k) for k in ("update_phase", "hold_reason", "hold_no_whole_copy", "hold_kind", "state")}
w.say("(c) held: " + json.dumps(out["held"], ensure_ascii=False))
for lang in ("hu", "en"):
page = H.unescape(w.page(f"/apps/{APP}?lang={lang}"))
m = re.search(r'data-held="true">(.*?)</div>', page, re.S)
out[f"page_{lang}"] = m.group(1).strip() if m else None
w.say(f"(c) [{lang}] {out[f'page_{lang}']!r}")
# decision 27, positive control / refusal: what the Remove dialog reads, and the Remove itself
code, hd = w.ctl("GET", f"/api/stacks/{APP}/hdd-data")
out["hdd_data"] = {"code": code, "keep_data_only": ((hd or {}).get("data") or {}).get("keep_data_only")}
w.say("(c2) hdd-data -> " + json.dumps(out["hdd_data"]))
for lang in ("hu", "en"):
code, rr = w.ctl("POST", f"/api/stacks/{APP}/remove?lang={lang}", {"remove_hdd_data": True, "remove_backups": False})
out[f"remove_{lang}"] = {"code": code, "error": (rr or {}).get("error")}
w.say(f"(c3) [{lang}] Remove with data -> {code} {out[f'remove_{lang}']['error']!r}")
code, rr = w.ctl("POST", f"/api/stacks/{APP}/remove?lang=en", {"remove_hdd_data": False, "remove_backups": True})
out["remove_backups_en"] = {"code": code, "error": (rr or {}).get("error")}
w.say(f"(c3) [en] Remove with backups -> {code}")
st = w.stack(APP)
out["still_deployed"] = st.get("deployed")
w.say(f"(c3) still deployed: {st.get('deployed')}")
out["mirror_back"] = w.guest(f"mv {MIR}.night-aside {MIR} && ls {MIR}")
w.say("(c4) mirror moved back: " + out["mirror_back"].replace(chr(10), " "))
# (d) the WHOLE restore: the button the page offers on the Mentések page for the second copy
drill(lambda: (open(f"{CAT}/docker-compose.yml", "w").write(HEAD), open(f"{CAT}/.felhom.yml", "w").write(FY)), "back to the head + the real probe")
w.sync_rescan()
sess = open(f"{w.SC}/sess{__import__('os').getpid()}.txt").read().strip()
csrf = open(f"{w.SC}/csrf{__import__('os').getpid()}.txt").read().strip()
t0 = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
r = w.sh(["curl", "-sk", "-D", "-", "-o", "/dev/null", "-H", w.HOSTHDR, "-H", f"Cookie: {sess}", "-X", "POST",
"--data-urlencode", f"_csrf={csrf}", "--data-urlencode", f"stack_name={APP}", f"{w.BASE}/backup/tier2/unit-restore"], timeout=120)
w.say("(d) POST /backup/tier2/unit-restore -> " + (r.stdout or "").split("\n")[0] + " " + str([l for l in (r.stdout or "").split("\n") if l.lower().startswith("location")]))
last = None
for _ in range(600):
c2, dd = w.ctl("GET", "/api/backup/restore-status")
d2 = (dd.get("data") or {}) if isinstance(dd, dict) else {}
cur = (d2.get("running"), d2.get("message"))
if cur != last:
w.say(f" restore-status {cur}")
last = cur
if not d2.get("running") and d2.get("last"):
break
time.sleep(2)
out["restore_msg"] = last
out["restore_log"] = w.guest(f"docker logs --since {t0} felhom-controller 2>&1 | grep -iE 'whole restore|WHOLE restore|Tier-2 whole|Restore-from-unit|hold .*CLEARED' | tail -8")
w.say("(d) log:\n" + out["restore_log"])
# (e)
w.wait_app(SUB, "/status.php", want=("200",), tries=120, delay=5)
out["account"] = bool(F.verify(w, SUB, A, w.say))
out["files_after"] = nf.verify_files(w, SUB, A, {names[0]: files[names[0]], names[2]: files[names[2]]}, w.say)
out["kept_beside"] = w.guest(f"find /mnt/felhom-drives/scratch_hdd/userdata/nextcloud -name '*.felhom-*' | sed 's|.*/||'")
st = w.stack(APP)
out["final"] = {k: st.get(k) for k in ("state", "hold_reason", "update_phase")}
w.say("(e) final " + json.dumps(out["final"], ensure_ascii=False) + " kept-beside: " + out["kept_beside"])
json.dump(out, open("../A2/10-held-no-copy-keep-data.json", "w"), indent=2, ensure_ascii=False, default=str)
open("../A2/10-held-no-copy-keep-data.log", "w").write("\n".join(w.LOG) + "\n")
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""A3 live, part 2: Start on the box-stopped gokapi lifts the hold and gives ONE more try; the loop comes back,
the box stops it again (trip 2 within 24 h) and the page says support is informed. hu + en. No app_start_failed."""
import html as H, json, re, sys, time
sys.path.insert(0, ".")
import walk as w
APP = "gokapi"
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
w.login()
t0 = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
st = w.stack(APP)
out["before"] = {k: st.get(k) for k in ("state", "hold_kind", "hold_reason")}
w.say("before " + json.dumps(out["before"], ensure_ascii=False))
code, d = w.ctl("POST", f"/api/stacks/{APP}/start")
w.say(f"Start -> {code} {json.dumps(d, ensure_ascii=False)[:200]}")
time.sleep(5)
st = w.stack(APP)
out["after_start"] = {k: st.get(k) for k in ("state", "hold_kind", "hold_reason")}
w.say("after start " + json.dumps(out["after_start"], ensure_ascii=False))
tp, last = time.time(), None
while time.time() - tp < 1800:
st = w.stack(APP)
cur = (st.get("state"), st.get("hold_kind"))
if cur != last:
rc = w.guest("docker inspect -f '{{.Name}} {{.RestartCount}}' $(docker ps -aq --filter label=com.docker.compose.project=gokapi)").strip()
w.say(f" +{time.time()-tp:6.0f}s state={cur[0]} hold={cur[1]} restarts: {rc}")
last = cur
if cur[1] == "unhealthy_stop":
break
time.sleep(15)
out["tripped_after_s"] = round(time.time() - tp)
for lang in ("hu", "en"):
page = H.unescape(w.page(f"/apps/{APP}?lang={lang}"))
m = re.search(r'data-unhealthy-stop[^>]*>(.*?)</div>', page, re.S)
txt = re.sub(r"<[^>]+>", " ", m.group(1)).strip() if m else None
out[f"page_{lang}"] = re.sub(r"\s+", " ", txt) if txt else None
w.say(f"[{lang}] {out[f'page_{lang}']!r}")
out["log"] = w.guest(f"docker logs --since {t0} felhom-controller 2>&1 | grep -E 'deadapp|STOPPED by the box|hold (SET|CLEARED|lifted)|unhealthy|app_start_failed|app_stopped' | tail -15")
w.say("log:\n" + out["log"])
out["start_failed_lines"] = w.guest(f"docker logs --since {t0} felhom-controller 2>&1 | grep -c app_start_failed || true").strip()
w.say("app_start_failed lines: " + out["start_failed_lines"])
json.dump(out, open("../A3/30-start-then-trip2.json", "w"), indent=2, ensure_ascii=False, default=str)
open("../A3/30-start-then-trip2.log", "w").write("\n".join(w.LOG) + "\n")
@@ -0,0 +1,69 @@
#!/usr/bin/env python3
"""Part B live: a FLOATING tag (redis:7-alpine) whose tested digest moves in the catalog. (1) control: the box
runs the ladder's digest, badge current; (2) the drill ladder's head entry gets a different tested digest for the
same tag + a newer tested_at → badge must say behind (hu+en); (3) Update → the box pulls THAT digest, the compose
it runs names it, installed record's digest = it, badge current. Also: the pin and record stay digest-free."""
import json, re, sys, time, datetime
sys.path.insert(0, ".")
import walk as w
APP, SVC = "nextcloud", "nextcloud-redis"
NEW = "sha256:c35af3bbcef51a62c8bae5a9a563c6f1b60d7ebaea4cb5a3ccbcc157580ae098" # redis:7.4.0-alpine, stands in for a repush of 7-alpine
CAT = f"{w.DRILL}/templates/{APP}"
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
w.login()
def boxview(tag):
st = w.stack(APP)
ac = st.get("app_config") or {}
v = {"state": st.get("state"), "installed": ac.get("installed_images"), "pinned": ac.get("pinned_images"),
"catalog_images": st.get("catalog_images"), "catalog_digests": st.get("catalog_digests"),
"catalog_tested_at": st.get("catalog_tested_at"), "badges": w.badges(APP),
"compose_redis": w.guest(f"grep -n 'image:' /opt/docker/stacks/{APP}/docker-compose.yml | grep redis").strip(),
"running_redis": w.guest(f"docker inspect -f '{{{{.Config.Image}}}} {{{{.Image}}}}' {SVC}").strip()}
out[tag] = v
w.say(f"[{tag}] " + json.dumps({k: v[k] for k in ("state", "badges", "compose_redis", "running_redis")}, ensure_ascii=False))
w.say(f"[{tag}] installed={json.dumps(v['installed'])} pinned={json.dumps(v['pinned'])}")
return v
w.sync_rescan()
boxview("1-control")
fy = open(f"{CAT}/.felhom.yml").read()
lines = fy.split("\n")
idx = max(i for i, l in enumerate(lines) if l.startswith(" - {") and '"to"' in l)
e = json.loads(lines[idx][4:])
old = e["digest"][SVC]
e["digest"][SVC] = NEW
e["tested_at"] = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
e["note"] = "NIGHT-B drill: tested digest of redis:7-alpine moved (stand-in digest of redis:7.4.0-alpine)"
lines[idx] = " - " + json.dumps(e, ensure_ascii=False)
out["ladder_edit"] = {"old": old, "new": NEW, "tested_at": e["tested_at"]}
def edit():
open(f"{CAT}/.felhom.yml", "w").write("\n".join(lines))
import fcntl
with open(f"{w.SC}/drill.lock", "w") as lk:
fcntl.flock(lk, fcntl.LOCK_EX)
w.sh(["git", "-C", w.DRILL, "pull", "-q", "--rebase", "origin", "main"], timeout=120)
edit()
w.sh(["git", "-C", w.DRILL, "commit", "-qam", "NIGHT-B nextcloud: tested digest of redis:7-alpine moved"])
w.sh(["git", "-C", w.DRILL, "push", "-q", "origin", "main"], timeout=120)
w.say("drill: ladder head entry digest " + old[:19] + " -> " + NEW[:19])
w.sync_rescan()
for _ in range(20):
v = boxview("2-behind")
if (v.get("catalog_digests") or {}).get(SVC) == NEW:
break
time.sleep(10)
w.sync_rescan()
out["update"] = w.press_update(APP)
w.sync_rescan()
boxview("3-after")
out["pull_log"] = w.guest("docker logs --since 10m felhom-controller 2>&1 | grep nextcloud | grep -E 'pin advanced|digest|pull|UPDATED|done|installed' | grep -v DEBUG | tail -10")
w.say("log:\n" + out["pull_log"])
json.dump(out, open("../B/10-floating-tag.json", "w"), indent=2, ensure_ascii=False, default=str)
open("../B/10-floating-tag.log", "w").write("\n".join(w.LOG) + "\n")
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
"""Part B live: a FLOATING tag (redis:7-alpine) whose tested digest moves in the catalog. (1) control: the box
runs the ladder's digest, badge current; (2) the drill ladder's head entry gets a different tested digest for the
same tag + a newer tested_at → badge must say behind (hu+en); (3) Update → the box pulls THAT digest, the compose
it runs names it, installed record's digest = it, badge current. Also: the pin and record stay digest-free."""
import json, re, sys, time, datetime
sys.path.insert(0, ".")
import walk as w
APP, SVC = "nextcloud", "nextcloud-redis"
NEW = "sha256:858f009f9709ce576febc734aa78b8f6d624b82571f9ddb6bda4377c833b3499" # back to the registry's real 7-alpine digest
CAT = f"{w.DRILL}/templates/{APP}"
out = {"controller": w.guest("cat /etc/felhom-controller-image").strip()}
w.login()
def boxview(tag):
st = w.stack(APP)
ac = st.get("app_config") or {}
v = {"state": st.get("state"), "installed": ac.get("installed_images"), "pinned": ac.get("pinned_images"),
"catalog_images": st.get("catalog_images"), "catalog_digests": st.get("catalog_digests"),
"catalog_tested_at": st.get("catalog_tested_at"), "badges": w.badges(APP),
"compose_redis": w.guest(f"grep -n 'image:' /opt/docker/stacks/{APP}/docker-compose.yml | grep redis").strip(),
"running_redis": w.guest(f"docker inspect -f '{{{{.Config.Image}}}} {{{{.Image}}}}' {SVC}").strip()}
out[tag] = v
w.say(f"[{tag}] " + json.dumps({k: v[k] for k in ("state", "badges", "compose_redis", "running_redis")}, ensure_ascii=False))
w.say(f"[{tag}] installed={json.dumps(v['installed'])} pinned={json.dumps(v['pinned'])}")
return v
w.sync_rescan()
boxview("1-control")
fy = open(f"{CAT}/.felhom.yml").read()
lines = fy.split("\n")
idx = max(i for i, l in enumerate(lines) if l.startswith(" - {") and '"to"' in l)
e = json.loads(lines[idx][4:])
old = e["digest"][SVC]
e["digest"][SVC] = NEW
e["tested_at"] = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
e["note"] = "NIGHT-B2 drill: re-tested at the registry digest"
lines[idx] = " - " + json.dumps(e, ensure_ascii=False)
out["ladder_edit"] = {"old": old, "new": NEW, "tested_at": e["tested_at"]}
def edit():
open(f"{CAT}/.felhom.yml", "w").write("\n".join(lines))
import fcntl
with open(f"{w.SC}/drill.lock", "w") as lk:
fcntl.flock(lk, fcntl.LOCK_EX)
w.sh(["git", "-C", w.DRILL, "pull", "-q", "--rebase", "origin", "main"], timeout=120)
edit()
w.sh(["git", "-C", w.DRILL, "commit", "-qam", "NIGHT-B2 nextcloud: re-tested redis:7-alpine (v0.269.1 proof)"])
w.sh(["git", "-C", w.DRILL, "push", "-q", "origin", "main"], timeout=120)
w.say("drill: ladder head entry digest " + old[:19] + " -> " + NEW[:19])
w.sync_rescan()
for _ in range(20):
v = boxview("2-behind")
if (v.get("catalog_digests") or {}).get(SVC) == NEW:
break
time.sleep(10)
w.sync_rescan()
v2 = out["2-behind"]
out["sync_kept_running_digest"] = ("c35af3bb" in v2["compose_redis"]) and (NEW not in v2["compose_redis"])
w.say(f"CHECK the sync kept the running digest in the compose before Update: {out['sync_kept_running_digest']}")
out["update"] = w.press_update(APP)
w.sync_rescan()
boxview("3-after")
out["pull_log"] = w.guest("docker logs --since 10m felhom-controller 2>&1 | grep nextcloud | grep -E 'pin advanced|digest|pull|UPDATED|done|installed' | grep -v DEBUG | tail -10")
w.say("log:\n" + out["pull_log"])
json.dump(out, open("../B/21-floating-tag-0.269.1.json", "w"), indent=2, ensure_ascii=False, default=str)
open("../B/21-floating-tag-0.269.1.log", "w").write("\n".join(w.LOG) + "\n")