diff --git a/runtime/history/CONTEXT-AUTO-20260912T001701Z.json b/runtime/history/CONTEXT-AUTO-20260912T001701Z.json new file mode 100644 index 00000000..1662216a --- /dev/null +++ b/runtime/history/CONTEXT-AUTO-20260912T001701Z.json @@ -0,0 +1 @@ +{"schema_version":1,"channel":"homelab-runtime","command_id":"CONTEXT-AUTO-20260912T001701Z","status":"OK","rc":0,"host":"pve01","mode":"read-only","component":"cluster-context","started_at_utc":"2026-09-12T00:17:01Z","finished_at_utc":"2026-09-12T00:17:02Z","reference_register_checked":true,"reference_sha256":"5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66","error_register_checked":true,"error_register_sha256":"3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0","changes_made":false,"sanitized":true,"secrets_included":false,"private_addresses_included":false,"output":"AUTOMATIC_CLUSTER_CONTEXT_REFRESH=OK"} diff --git a/runtime/history/CONTEXT-AUTO-20260912T001701Z.txt b/runtime/history/CONTEXT-AUTO-20260912T001701Z.txt new file mode 100644 index 00000000..9da1ea2a --- /dev/null +++ b/runtime/history/CONTEXT-AUTO-20260912T001701Z.txt @@ -0,0 +1,162 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=CONTEXT-AUTO-[PRIVATE_IP]701Z +STATUS=OK +RC=0 +HOST=pve01 +COMPONENT=cluster-context +REFERENCE_SHA[PRIVATE_IP]e5154c41cb[PRIVATE_IP]aca68090be[PRIVATE_IP]bf[PRIVATE_IP]df[PRIVATE_IP] +ERROR_REGISTER_SHA[PRIVATE_IP]ec0f527ed3afeed[PRIVATE_IP]ee[PRIVATE_IP]bbfb[PRIVATE_IP]af4ba7ba0 +OUTPUT_BEGIN +GENERATED_AT_UTC=[PRIVATE_IP]T00:17:01Z +Cluster information +------------------- +Name: homelab +Config Version: 3 +Transport: knet +Secure auth: on + +Quorum information +------------------ +Date: Sat Sep [PRIVATE_IP] 2026 +Quorum provider: corosync_votequorum +Nodes: 3 +Node ID: [PRIVATE_IP] +Ring ID: 1.130 +Quorate: Yes + +Votequorum information +---------------------- +Expected votes: 3 +Highest expected: 3 +Total votes: 3 +Quorum: 2 +Flags: Quorate + +Membership information +---------------------- + Nodeid Votes Name +[PRIVATE_IP] [PRIVATE_IP].11 (local) +[PRIVATE_IP] [PRIVATE_IP].13 +[PRIVATE_IP] [PRIVATE_IP].12 + +Membership information +---------------------- + Nodeid Votes Name + 1 1 pve01 (local) + 2 1 pve03 + 3 1 pve02 +[{"cpu":[PRIVATE_IP]394231,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/110","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"dns1","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":110},{"cpu":[PRIVATE_IP]967041,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/111","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"dns2","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve02","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":111},{"cpu":0,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/112","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"unbound1","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":112},{"cpu":0,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/113","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"unbound2","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve02","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":113},{"cpu":[PRIVATE_IP]43079,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/130","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"edge-vm","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve03","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":130},{"cpu":[PRIVATE_IP]900349,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/150","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"snikket","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":150},{"cpu":[PRIVATE_IP]350356,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/160","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"forum-prod","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve02","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":160},{"cpu":[PRIVATE_IP]4505,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/170","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"core-apps","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":170},{"cpu":[PRIVATE_IP]51788,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/171","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"monitoring","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":171},{"cpu":[PRIVATE_IP]7115,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/190","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"homelab-ops-worker","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve03","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":190},{"cpu":[PRIVATE_IP]508068,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/210","maxcpu":2,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"newfi-prod","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":436761,"vmid":210},{"cpu":[PRIVATE_IP]302143,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/211","maxcpu":2,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"newfi-staging","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve03","status":"running","template":0,"type":"qemu","uptime":632686,"vmid":211},{"cpu":0,"disk":0,"diskread":0,"diskwrite":0,"id":"qemu/9130","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":0,"memhost":0,"name":"edge-cold-standby","netin":0,"netout":0,"node":"pve02","status":"stopped","template":0,"type":"qemu","uptime":0,"vmid":9130},{"cgroup-mode":2,"cpu":[PRIVATE_IP]917,"disk":[PRIVATE_IP],"id":"node/pve02","level":"","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"node":"pve02","status":"online","type":"node","uptime":[PRIVATE_IP]},{"cgroup-mode":2,"cpu":[PRIVATE_IP]13443,"disk":[PRIVATE_IP],"id":"node/pve03","level":"","maxcpu":8,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"node":"pve03","status":"online","type":"node","uptime":[PRIVATE_IP]},{"cgroup-mode":2,"cpu":[PRIVATE_IP]64094,"disk":[PRIVATE_IP],"id":"node/pve01","level":"","maxcpu":24,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"node":"pve01","status":"online","type":"node","uptime":[PRIVATE_IP]},{"content":"images,rootdir","disk":[PRIVATE_IP],"id":"storage/pve02/local-lvm","maxdisk":[PRIVATE_IP],"node":"pve02","plugintype":"lvmthin","shared":0,"status":"available","storage":"local-lvm","type":"storage"},{"content":"images,rootdir","disk":[PRIVATE_IP],"id":"storage/pve03/local-lvm","maxdisk":[PRIVATE_IP],"node":"pve03","plugintype":"lvmthin","shared":0,"status":"available","storage":"local-lvm","type":"storage"},{"content":"images,rootdir","disk":[PRIVATE_IP],"id":"storage/pve01/local-lvm","maxdisk":[PRIVATE_IP],"node":"pve01","plugintype":"lvmthin","shared":0,"status":"available","storage":"local-lvm","type":"storage"},{"content":"vztmpl,import,iso,backup","disk":[PRIVATE_IP],"id":"storage/pve02/local","maxdisk":[PRIVATE_IP],"node":"pve02","plugintype":"dir","shared":0,"status":"available","storage":"local","type":"storage"},{"content":"vztmpl,import,iso,backup","disk":[PRIVATE_IP],"id":"storage/pve03/local","maxdisk":[PRIVATE_IP],"node":"pve03","plugintype":"dir","shared":0,"status":"available","storage":"local","type":"storage"},{"content":"vztmpl,import,iso,backup","disk":[PRIVATE_IP],"id":"storage/pve01/local","maxdisk":[PRIVATE_IP],"node":"pve01","plugintype":"dir","shared":0,"status":"available","storage":"local","type":"storage"},{"id":"network/pve02/zone/localnetwork","network":"localnetwork","network-type":"zone","node":"pve02","status":"ok","type":"network"},{"id":"network/pve03/zone/localnetwork","network":"localnetwork","network-type":"zone","node":"pve03","status":"ok","type":"network"},{"id":"network/pve01/zone/localnetwork","network":"localnetwork","network-type":"zone","node":"pve01","status":"ok","type":"network"}] +Name Type Status Total (KiB) Used (KiB) Available (KiB) % +local dir active [PRIVATE_IP] [PRIVATE_IP] [PRIVATE_IP] 20.75% +local-lvm lvmthin active [PRIVATE_IP] [PRIVATE_IP] [PRIVATE_IP] 10.24% + UNIT LOAD ACTIVE SUB DESCRIPTION +● homelab-backup-retention-gc.service loaded failed failed Homelab owner-aware cloud retention GC + +Legend: LOAD → Reflects whether the unit definition was properly loaded. + ACTIVE → The high-level unit activation state, i.e. generalization of SUB. + SUB → The low-level unit activation state, values depend on unit type. + +1 loaded units listed. +NEXT LEFT LAST PASSED UNIT ACTIVATES +Sat [PRIVATE_IP] 03:17:16 MSK 14s Sat [PRIVATE_IP] 03:16:16 MSK 45s ago homelab-private-vpn-hosts-health.timer homelab-private-vpn-hosts-health.service +Sat [PRIVATE_IP] 03:17:35 MSK 32s Sat [PRIVATE_IP] 03:16:32 MSK 30s ago homelab-router-watchdog.timer homelab-router-watchdog.service +Sat [PRIVATE_IP] 03:18:08 MSK 1min 6s Sat [PRIVATE_IP] 03:03:08 MSK 13min ago homelab-disk-space-health.timer homelab-disk-space-health.service +Sat [PRIVATE_IP] 03:20:09 MSK 3min 6s Sat [PRIVATE_IP] 03:15:08 MSK 1min 53s ago homelab-health-metrics.timer homelab-health-metrics.service +Sat [PRIVATE_IP] 03:21:55 MSK 4min 53s Sat [PRIVATE_IP] 03:06:55 MSK 10min ago homelab-pve03-staging-capacity-health.timer homelab-pve03-staging-capacity-health.service +Sat [PRIVATE_IP] 03:25:38 MSK 8min Sat [PRIVATE_IP] 02:53:12 MSK 23min ago homelab-reference-refresh.timer homelab-reference-refresh.service +Sat [PRIVATE_IP] 03:25:55 MSK 8min Sat [PRIVATE_IP] 03:15:55 MSK 1min 6s ago skladchik-reports-monitor-supervisor.timer skladchik-reports-monitor-supervisor.service +Sat [PRIVATE_IP] 03:29:55 MSK 12min Sat [PRIVATE_IP] 03:14:55 MSK 2min 6s ago prometheus-node-exporter-apt.timer prometheus-node-exporter-apt.service +Sat [PRIVATE_IP] 03:30:00 MSK 12min Sat [PRIVATE_IP] 01:30:08 MSK 1h 46min ago homelab-app-cloud-quorum-queue.timer homelab-app-cloud-quorum-queue.service +Sat [PRIVATE_IP] 03:30:00 MSK 12min Sat [PRIVATE_IP] 03:15:08 MSK 1min 53s ago homelab-incident-journal.timer homelab-incident-journal.service +Sat [PRIVATE_IP] 03:30:41 MSK 13min Sat [PRIVATE_IP] 03:16:32 MSK 30s ago homelab-forum-snuffleupagus-health.timer homelab-forum-snuffleupagus-health.service +Sat [PRIVATE_IP] 03:31:00 MSK 13min Sat [PRIVATE_IP] 03:15:55 MSK 1min 6s ago homelab-external-probe-vps-health.timer homelab-external-probe-vps-health.service +Sat [PRIVATE_IP] 03:31:18 MSK 14min Sat [PRIVATE_IP] 03:15:13 MSK 1min 48s ago homelab-duty-admin-v2.timer homelab-duty-admin-v2.service +Sat [PRIVATE_IP] 03:31:38 MSK 14min Sat [PRIVATE_IP] 03:16:38 MSK 23s ago prometheus-node-exporter-nvme.timer prometheus-node-exporter-nvme.service +Sat [PRIVATE_IP] 03:32:47 MSK 15min Fri [PRIVATE_IP] 03:33:55 MSK 23h ago homelab-backup-retention-gc.timer homelab-backup-retention-gc.service +Sat [PRIVATE_IP] 03:33:20 MSK 16min Sat [PRIVATE_IP] 03:00:55 MSK 16min ago homelab-mkdocs-auto-refresh.timer homelab-mkdocs-auto-refresh.service +Sat [PRIVATE_IP] 03:36:20 MSK 19min Sat [PRIVATE_IP] 03:06:08 MSK 10min ago homelab-backup-audit.timer homelab-backup-audit.service +Sat [PRIVATE_IP] 04:00:26 MSK 43min Sat [PRIVATE_IP] 03:06:15 MSK 10min ago homelab-control-backup.timer homelab-control-backup.service +Sat [PRIVATE_IP] 04:30:37 MSK 1h 13min Sat [PRIVATE_IP] 00:34:38 MSK 2h 42min ago homelab-vm-cloud-quorum-queue.timer homelab-vm-cloud-quorum-queue.service +Sat [PRIVATE_IP] 04:35:55 MSK 1h 18min Fri [PRIVATE_IP] 22:35:55 MSK 4h 41min ago homelab-vps-identity-audit.timer homelab-vps-identity-audit.service +Sat [PRIVATE_IP] 06:04:23 MSK 2h 47min Sat [PRIVATE_IP] 00:00:32 MSK 3h 16min ago homelab-evidence-root.timer homelab-evidence-root.service +Sat [PRIVATE_IP] 06:24:02 MSK 3h 6min Fri [PRIVATE_IP] 21:07:38 MSK 6h ago apt-daily.timer apt-daily.service +Sat [PRIVATE_IP] 06:51:40 MSK 3h 34min Fri [PRIVATE_IP] 06:04:16 MSK 21h ago apt-daily-upgrade.timer apt-daily-upgrade.service +Sat [PRIVATE_IP] 07:17:30 MSK 4h 0min Fri [PRIVATE_IP] 07:15:52 MSK 20h ago homelab-drift-check.timer homelab-drift-check.service +Sat [PRIVATE_IP] 07:28:57 MSK 4h 11min Sat [PRIVATE_IP] 01:22:12 MSK 1h 54min ago homelab-mailru-trash-gc.timer homelab-mailru-trash-gc.service +Sat [PRIVATE_IP] 07:31:46 MSK 4h 14min Fri [PRIVATE_IP] 07:35:23 MSK 19h ago homelab-service-registry-check.timer homelab-service-registry-check.service +Sat [PRIVATE_IP] 07:43:45 MSK 4h 26min Fri [PRIVATE_IP] 07:50:12 MSK 19h ago homelab-alerting-health.timer homelab-alerting-health.service +Sat [PRIVATE_IP] 07:47:09 MSK 4h 30min Fri [PRIVATE_IP] 07:42:16 MSK 19h ago homelab-dependency-map-check.timer homelab-dependency-map-check.service +Sat [PRIVATE_IP] 07:49:02 MSK 4h 32min Fri [PRIVATE_IP] 07:46:55 MSK 19h ago homelab-runbook-generate.timer homelab-runbook-generate.service +Sat [PRIVATE_IP] 07:55:54 MSK 4h 38min Fri [PRIVATE_IP] 08:06:52 MSK 19h ago homelab-duty-admin-report.timer homelab-duty-admin-report.service +Sat [PRIVATE_IP] 08:01:33 MSK 4h 44min Fri [PRIVATE_IP] 08:02:27 MSK 19h ago homelab-desired-state-sync.timer homelab-desired-state-sync.service +Sat [PRIVATE_IP] 08:08:43 MSK 4h 51min Fri [PRIVATE_IP] 08:01:31 MSK 19h ago homelab-overall-health.timer homelab-overall-health.service +Sat [PRIVATE_IP] 08:24:50 MSK 5h 7min Fri [PRIVATE_IP] 08:30:55 MSK 18h ago homelab-capacity-risk.timer homelab-capacity-risk.service +Sat [PRIVATE_IP] 08:25:06 MSK 5h 8min Fri [PRIVATE_IP] 08:17:58 MSK 18h ago homelab-kuma-monitor-policy.timer homelab-kuma-monitor-policy.service +Sat [PRIVATE_IP] 08:27:21 MSK 5h 10min Fri [PRIVATE_IP] 08:18:07 MSK 18h ago homelab-final-readiness-gate.timer homelab-final-readiness-gate.service +Sat [PRIVATE_IP] 08:37:58 MSK 5h 20min Fri [PRIVATE_IP] 08:43:55 MSK 18h ago homelab-cluster-passport.timer homelab-cluster-passport.service +Sat [PRIVATE_IP] 08:40:38 MSK 5h 23min Fri [PRIVATE_IP] 08:45:52 MSK 18h ago homelab-secret-exposure-guard.timer homelab-secret-exposure-guard.service +Sat [PRIVATE_IP] 08:52:32 MSK 5h 35min Fri [PRIVATE_IP] 09:00:16 MSK 18h ago homelab-golden-state-index.timer homelab-golden-state-index.service +Sat [PRIVATE_IP] 10:15:00 MSK 6h Fri [PRIVATE_IP] 10:15:07 MSK 17h ago skladchik-reports-monitor-monthly-selftest-watch.timer skladchik-reports-monitor-monthly-selftest-watch.service +Sat [PRIVATE_IP] 10:17:46 MSK 7h Fri [PRIVATE_IP] 01:24:14 MSK 1 day 1h ago man-db.timer man-db.service +Sat [PRIVATE_IP] 16:47:55 MSK 13h Fri [PRIVATE_IP] 16:47:55 MSK 10h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service +Sun [PRIVATE_IP] 00:00:00 MSK 20h Sat [PRIVATE_IP] 00:00:08 MSK 3h 16min ago dpkg-db-backup.timer dpkg-db-backup.service +Sun [PRIVATE_IP] 00:10:42 MSK 20h Sat [PRIVATE_IP] 00:18:55 MSK 2h 58min ago homelab-evidence-catalog.timer homelab-evidence-catalog.service +Sun [PRIVATE_IP] 00:14:22 MSK 20h Sat [PRIVATE_IP] 00:03:42 MSK 3h 13min ago homelab-quality-gate.timer homelab-quality-gate.service +Sun [PRIVATE_IP] 00:18:36 MSK 21h Sat [PRIVATE_IP] 00:00:55 MSK 3h 16min ago homelab-docker-health.timer homelab-docker-health.service +Sun [PRIVATE_IP] 00:19:33 MSK 21h Sat [PRIVATE_IP] 00:00:55 MSK 3h 16min ago homelab-storage-capacity.timer homelab-storage-capacity.service +Sun [PRIVATE_IP] 00:41:51 MSK 21h Sat [PRIVATE_IP] 00:40:38 MSK 2h 36min ago logrotate.timer logrotate.service +Sun [PRIVATE_IP] 01:02:53 MSK 21h Sat [PRIVATE_IP] 02:59:55 MSK 17min ago pve-daily-update.timer pve-daily-update.service +Sun [PRIVATE_IP] 03:10:21 MSK 23h Sun [PRIVATE_IP] 03:11:16 MSK 6 days ago e2scrub_all.timer e2scrub_all.service +Sun [PRIVATE_IP] 03:10:35 MSK 23h Sun [PRIVATE_IP] 03:10:50 MSK 6 days ago xfs_scrub_all.timer xfs_scrub_all.service +Sun [PRIVATE_IP] 07:35:54 MSK 1 day 4h Sun [PRIVATE_IP] 07:57:53 MSK 5 days ago homelab-rotating-boot-drill.timer homelab-rotating-boot-drill.service +Mon [PRIVATE_IP] 00:10:37 MSK 1 day 20h Mon [PRIVATE_IP] 00:08:52 MSK 5 days ago homelab-secret-sanity.timer homelab-secret-sanity.service +Mon [PRIVATE_IP] 00:30:41 MSK 1 day 21h Mon [PRIVATE_IP] 00:39:53 MSK 5 days ago fstrim.timer fstrim.service +- - Sat [PRIVATE_IP] 03:17:02 MSK 17ms ago homelab-smartctl-textfile.timer homelab-smartctl-textfile.service +- - Sat [PRIVATE_IP] 03:17:02 MSK 18ms ago netbird-peers-health.timer netbird-peers-health.service +- - - - prometheus-node-exporter-ipmitool-sensor.timer prometheus-node-exporter-ipmitool-sensor.service +- - - - prometheus-node-exporter-mellanox-hca-temp.timer prometheus-node-exporter-mellanox-hca-temp.service +- - - - prometheus-node-exporter-smartmon.timer prometheus-node-exporter-smartmon.service + +58 timers listed. +RUNTIME_MANIFEST_ID=df[PRIVATE_IP]ac9b5abd[PRIVATE_IP]b[PRIVATE_IP]d89496fb2bde[PRIVATE_IP] +EXPERIMENT_ID=5462ee[PRIVATE_IP]ebe[PRIVATE_IP]feb2ad[PRIVATE_IP]1ad87bbac0b8108 +COLLECTION_START_AT=[PRIVATE_IP]T[PRIVATE_IP]:00 +FIRST_COMPLETE_D1_CLOSE=[PRIVATE_IP]T[PRIVATE_IP]:00 +PRODUCTION_LAUNCH_ALLOWED=False +EXECUTION_AUTHORITY=False +RISK_AUTHORITY=False +STAGE_A_HEALTH=AWAITING_PRIMARY_FINALITY +FORENSIC_PREVIOUS_EPOCH_PRESERVED=YES + +## NEWFI_TASK6_AUTH_CHECKPOINT_V[PRIVATE_IP] +- Scope: historical accepted AUTH test, not a current SMTP connection test. +- Newfi approved SMTP account/sender: aleisaev@yandex.ru. +- Endpoint used by accepted test: smtp.yandex.ru:465 with certificate verification; single PLAIN initial response accepted with code 235. +- Evidence: incident ledger ### NEWFI_TASK6_YANDEX_AUTH_V2_OBSERVATION and ### NEWFI_TASK6_AUTH_PROOF_CLOSE_V1. +- No password file written, no application configuration changed, no mail sent by the accepted AUTH test. +- Persistent transport installation and application delivery are not proven by this checkpoint. Task6 is not complete. +- AUTH challenge and missing-file incidents closed; launch/session incident remains OPEN with original cause unproven. +- This update does not change VM211, VM160, routing, board state or Git. +- Other incidents and infrastructure health were not assessed. + + +## NEWFI_PRIVATE_STRUCTURE92_WRONG_MARKER_SCOPE_[PRIVATE_IP] CLOSURE +- Status: CLOSED +- RCA: NEWFI92 inspected the pve01 NEWFI90 attempt marker, which had not been finalized because the outer shell exited immediately after the guest returned RC3 following its successful rollback. The guest marker contained the true final rollback state. +- Correction: NEWFI93 required both the guest FINISHED/ROLLED_BACK record and a fresh exact demo-state readback before reconciling the outer NEWFI90 marker. NEWFI92 itself never reserved an attempt or mutated state. + + +## NEWFI_PRIVATE_NEWFI95_NESTED_TRIPLE_QUOTE_PARSE_[PRIVATE_IP] +- Status: OPEN +- Command: NEWFI95 +- Symptom: after the content-structure precheck passed, the pve03 Python wrapper failed to parse at the PHP line beginning with $root. No Portal discovery or application mutation was reached. +- RCA: an outer raw triple-single-quoted guest Python payload contained an inner raw triple-single-quoted PHP payload. The inner delimiter terminated the outer Python string, causing PHP source to be parsed as Python. +- Safety: NEWFI95 was read-only, created no attempt marker, and did not reach the intended nested guest execution. Do not replay NEWFI95. + + +## NEWFI_PRIVATE_NEWFI95_NESTED_TRIPLE_QUOTE_PARSE_[PRIVATE_IP] CLOSURE +- Status: CLOSED +- RCA: an inner triple-single-quoted PHP literal terminated the outer triple-single-quoted Python guest payload in NEWFI95. The wrapper therefore failed parsing before the intended Portal discovery executed. +- Correction: NEWFI96 removed the nested Python payload layer entirely and passed one Python program directly to VM211 through qm guest exec stdin. The read-only Portal contract completed with QGA exit 0 and the implementation worktree remained unchanged. +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index dad1d4c0..1662216a 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,38 +1 @@ -{ - "schema_version": 1, - "channel": "homelab-runtime", - "command_id": "SUPPORT-260912-INFRA-DR-BACKUPV2-CONTROL-BACKUP-SOURCE-259R1", - "status": "OK", - "rc": 0, - "host": "pve01", - "mode": "read-only", - "component": "infra-dr-backupv2-control-backup-source", - "started_at_utc": "2026-09-12T00:02:19Z", - "finished_at_utc": "2026-09-12T00:02:19Z", - "reference_register_checked": true, - "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", - "error_register_checked": true, - "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", - "command_sha256": "09220124de7fa21ffc8fbc498052fa8ab92cee5d72b61fe34976f30307a58400", - "duplicate_failed_command_blocked": false, - "block_reason": null, - "execution_started": true, - "change_declared": false, - "result_contract_valid": true, - "result_contract_status": null, - "result_contract_error": null, - "command_rc": 0, - "changes_made": false, - "rollback_started": false, - "rollback_restored": null, - "mutation_outcome": "NO_MUTATION", - "sanitized": true, - "secrets_included": false, - "private_addresses_included": false, - "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "3762076dc1704d241330f8e0aa300dc7cbca2c80ec5ccc24137e59d67f7bd34b", - "sanitized_output_sha256": "497e4996869d853f0466d28fe81745576dffca2ccbe7ed64998990ed695d898b", - "output_truncated_in_json": false, - "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "SOURCE259_BEGIN\nCOMMAND_ID=SUPPORT-260912-INFRA-DR-BACKUPV2-CONTROL-BACKUP-SOURCE-259R1\nMODE=READ_ONLY_HASH_BOUND_SOURCE_EXPORT\nSOURCE_EXECUTION=FORBIDDEN\nERROR_REGISTER_CHECK=READ\nERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0\nREFERENCE_CHECK=READ\nREFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66\nAUTHORITY_FRESH_READ=OK\nENGINE_PATH=/usr/local/sbin/homelab-control-backup\nENGINE_SHA256=0b3a0f685d4e67cb86250df89a4918aff2e6c67799b7d35b0e54b1bbc016ee57\nENGINE_LINE_COUNT=150\nENGINE_REDACTED_LINE_COUNT=13\nENGINE_SOURCE_BEGIN\nENGINE_L0001_P001_OF001=#!/usr/bin/env bash\nENGINE_L0002_P001_OF001=set -Eeuo pipefail\nENGINE_L0003_P001_OF001=umask 077\nENGINE_L0004_P001_OF001=LOGICAL_ID=control-bootstrap-v2\nENGINE_L0005_P001_OF001=DUE_SECONDS=43200\nENGINE_L0006_P001_OF001=SLA_SECONDS=86400\nENGINE_L0007_P001_OF001=STATE_ROOT=\nENGINE_L0008_P001_OF001=STATE_DIR=$STATE_ROOT/$LOGICAL_ID\nENGINE_L0009_P001_OF001=EVIDENCE_ROOT=\nENGINE_L0010_P001_OF001=HEALTH=.json\nENGINE_L0011_P001_OF001=STAGE_ROOT=/mnt/staging/homelab-control-auto\nENGINE_L0012_P001_OF001=VERIFY_ROOT=/mnt/staging/homelab-control-verify\nENGINE_L0013_P001_OF001=LOCK=/run/lock/homelab-control-backup.lock\nENGINE_L0014_P001_OF001=HEAVY_LOCK=/run/homelab-backup-heavy.lock\nENGINE_L0015_P001_OF001=RCLONE_CONFIG_SOURCE=${RCLONE_CONFIG:-/root/.config/rclone/[SENSITIVE_FILE]}\nENGINE_L0016_P001_OF001=TRANSPORT=\nENGINE_L0017_P001_OF001=TRANSPORT_SHA=\nENGINE_L0018_P001_OF001=BUILDER=\nENGINE_L0019_P001_OF001=BUILDER_SHA=\nENGINE_L0020_P001_OF001=REMOTE_A=pve01-mail-01-crypt:homelab-backups\nENGINE_L0021_P001_OF001=REMOTE_B=pve01-mail-02-crypt:homelab-backups\nENGINE_L0022_P001_OF001=CLOUD_WRITE_MARKER=${HOMELAB_CONTROL_CLOUD_WRITE_MARKER:-}\nENGINE_L0023_P001_OF001=\nENGINE_L0024_P001_OF001=die(){ printf 'CONTROL_BACKUP_ERROR=%s\\n' \"$1\" >&2; exit \"${2:-65}\"; }\nENGINE_L0025_P001_OF002=for c in jq date find sort tail cut sha256sum stat flock rclone mktemp cmp awk mkdir rm install xargs grep cat mv chmod; do command -v \"$c\" >/dev/null || die \"T\nENGINE_L0025_P002_OF002=OOL_MISSING_$c\" 69; done\nENGINE_L0026_P001_OF001=[[ -x \"$TRANSPORT\" && ! -L \"$TRANSPORT\" ]] || die TRANSPORT_UNSAFE 69\nENGINE_L0027_P001_OF001=[[ \"$(sha256sum \"$TRANSPORT\"|awk '{print $1}')\" == \"$TRANSPORT_SHA\" ]] || die TRANSPORT_SHA_DRIFT 65\nENGINE_L0028_P001_OF001=[[ -x \"$BUILDER\" && ! -L \"$BUILDER\" ]] || die BUILDER_UNSAFE 69\nENGINE_L0029_P001_OF001=[[ \"$(sha256sum \"$BUILDER\"|awk '{print $1}')\" == \"$BUILDER_SHA\" ]] || die BUILDER_SHA_DRIFT 65\nENGINE_L0030_P001_OF001=\nENGINE_L0031_P001_OF001=latest_state(){\nENGINE_L0032_P001_OF001= [[ -d \"$STATE_DIR\" && ! -L \"$STATE_DIR\" ]] || return 0\nENGINE_L0033_P001_OF001= find \"$STATE_DIR\" -maxdepth 1 -type f -name 'control-bootstrap-v2-pve01-????????T??????Z.json' -print 2>/dev/null | LC_ALL=C sort | tail -1\nENGINE_L0034_P001_OF001=}\nENGINE_L0035_P001_OF001=state_decision(){\nENGINE_L0036_P001_OF001= local state=\"$1\" now=\"$2\" status gen upd epoch age ev sha\nENGINE_L0037_P001_OF001= if [[ -z \"$state\" ]]; then printf 'DECISION=BACKUP_UNVERIFIED REASON=NO_STATE AGE_SECONDS=-1\\n'; return 0; fi\nENGINE_L0038_P001_OF001= [[ -s \"$state\" && ! -L \"$state\" ]] || { printf 'DECISION=BACKUP_UNVERIFIED REASON=STATE_UNSAFE AGE_SECONDS=-1\\n'; return 0; }\nENGINE_L0039_P001_OF001= status=\"$(jq -r '.status // \"INVALID\"' \"$state\")\"; gen=\"$(jq -r '.generation // \"UNKNOWN\"' \"$state\")\"\nENGINE_L0040_P001_OF001= case \"$status\" in\nENGINE_L0041_P001_OF001= PREPARING|A_VERIFIED|PREPARED|DELETE_AUTHORIZED)\nENGINE_L0042_P001_OF001= printf 'DECISION=BACKUP_RESUME GENERATION=%s STATE_FILE=%s AGE_SECONDS=-1\\n' \"$gen\" \"$state\"; return 0;;\nENGINE_L0043_P001_OF001= SEALED) ;;\nENGINE_L0044_P001_OF001= *) printf 'DECISION=BACKUP_UNVERIFIED GENERATION=%s REASON=STATE_STATUS_INVALID AGE_SECONDS=-1\\n' \"$gen\"; return 0;;\nENGINE_L0045_P001_OF001= esac\nENGINE_L0046_P001_OF001= sha=\"$(jq -r '.archive_sha256 // \"\"' \"$state\")\"; upd=\"$(jq -r '.sealed_at_utc // .updated_at_utc // \"\"' \"$state\")\"\nENGINE_L0047_P001_OF001= epoch=\"$(date -u -d \"$upd\" +%s 2>/dev/null || true)\"\nENGINE_L0048_P001_OF002= [[ \"$epoch\" =~ ^[0-9]+$ && \"$epoch\" -le \"$now\" ]] || { printf 'DECISION=BACKUP_UNVERIFIED GENERATION=%s REASON=TIMESTAMP_INVALID AGE_SECONDS=-1\\n' \"$gen\"; ret\nENGINE_L0048_P002_OF002=urn 0; }\nENGINE_L0049_P001_OF001= ev=\"$EVIDENCE_ROOT/$gen.json\"\nENGINE_L0050_P001_OF001=\nENGINE_L0051_P001_OF001= printf 'DECISION=BACKUP_REVERIFY GENERATION=%s STATE_FILE=%s AGE_SECONDS=-1\\n' \"$gen\" \"$state\"; return 0\nENGINE_L0052_P001_OF001= fi\nENGINE_L0053_P001_OF001= age=$((now-epoch))\nENGINE_L0054_P001_OF001= if (( age < DUE_SECONDS )); then d=SKIP_FRESH; elif (( age < SLA_SECONDS )); then d=BACKUP_DUE; else d=BACKUP_STALE; fi\nENGINE_L0055_P001_OF001= printf 'DECISION=%s GENERATION=%s STATE_FILE=%s AGE_SECONDS=%s DUE_SECONDS=%s SLA_SECONDS=%s\\n' \"$d\" \"$gen\" \"$state\" \"$age\" \"$DUE_SECONDS\" \"$SLA_SECONDS\"\nENGINE_L0056_P001_OF001=}\nENGINE_L0057_P001_OF001=scan(){ local now state; now=\"$(date -u +%s)\"; state=\"$(latest_state)\"; state_decision \"$state\" \"$now\"; }\nENGINE_L0058_P001_OF001=mark_cloud_write(){\nENGINE_L0059_P001_OF001= [[ -z \"$CLOUD_WRITE_MARKER\" ]] && return 0\nENGINE_L0060_P001_OF001= [[ \"$CLOUD_WRITE_MARKER\" == /* ]] || die CLOUD_WRITE_MARKER_NOT_ABSOLUTE 65\nENGINE_L0061_P001_OF001= [[ ! -L \"$CLOUD_WRITE_MARKER\" ]] || die CLOUD_WRITE_MARKER_SYMLINK 65\nENGINE_L0062_P001_OF001= printf '%s\\n' \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" >\"$CLOUD_WRITE_MARKER\"\nENGINE_L0063_P001_OF001= chmod 0600 \"$CLOUD_WRITE_MARKER\"\nENGINE_L0064_P001_OF001=}\nENGINE_L0065_P001_OF001=\nENGINE_L0066_P001_OF001=prepare_rclone(){\nENGINE_L0067_P001_OF001= local dst=\"$1\"; [[ -f \"$RCLONE_CONFIG_SOURCE\" && ! -L \"$RCLONE_CONFIG_SOURCE\" ]] || die RCLONE_CONFIG_UNSAFE 66\nENGINE_L0068_P001_OF001= install -m 0600 \"$RCLONE_CONFIG_SOURCE\" \"$dst\"\nENGINE_L0069_P001_OF001=}\nENGINE_L0070_P001_OF001=reconstruct(){\nENGINE_L0071_P001_OF001= local base=\"$1\" out=\"$2\" cfg=\"$3\" state=\"$4\" label=\"$5\" manifest part idx name size hash got_size got_hash expected_manifest expected_archive\nENGINE_L0072_P001_OF001= expected_manifest=\"$(jq -er '.parts_manifest_sha256' \"$state\")\"; expected_archive=\"$(jq -er '.archive_sha256' \"$state\")\"\nENGINE_L0073_P001_OF001= manifest=\"${out}.PARTS.tsv\"; : >\"$out\"\nENGINE_L0074_P001_OF001= rclone --config \"$cfg\" cat \"${base%/}/PARTS.tsv\" >\"$manifest\" || die \"REMOTE_${label}_MANIFEST_READ_FAILED\" 74\nENGINE_L0075_P001_OF001= [[ \"$(sha256sum \"$manifest\"|awk '{print $1}')\" == \"$expected_manifest\" ]] || die \"REMOTE_${label}_MANIFEST_SHA_MISMATCH\" 68\nENGINE_L0076_P001_OF001= idx=0\nENGINE_L0077_P001_OF001= while IFS=$'\\t' read -r row name size hash; do\nENGINE_L0078_P001_OF002= [[ \"$row\" == \"$(printf '%08d' \"$idx\")\" && \"$name\" == part-????????.bin && \"$size\" =~ ^[1-9][0-9]*$ && \"$hash\" =~ ^[0-9a-f]{64}$ ]] || die \"REMOTE_${label}_M\nENGINE_L0078_P002_OF002=ANIFEST_ROW_INVALID\" 68\nENGINE_L0079_P001_OF001= part=\"${out}.part\"; rm -f \"$part\"; rclone --config \"$cfg\" cat \"${base%/}/payload.parts/$name\" >\"$part\" || die \"REMOTE_${label}_PART_READ_FAILED\" 74\nENGINE_L0080_P001_OF001= got_size=\"$(stat -c %s \"$part\")\"; got_hash=\"$(sha256sum \"$part\"|awk '{print $1}')\"\nENGINE_L0081_P001_OF001= [[ \"$got_size\" == \"$size\" && \"$got_hash\" == \"$hash\" ]] || die \"REMOTE_${label}_PART_VERIFY_FAILED\" 68\nENGINE_L0082_P001_OF001= cat \"$part\" >>\"$out\"; rm -f \"$part\"; idx=$((idx+1))\nENGINE_L0083_P001_OF001= done <\"$manifest\"\nENGINE_L0084_P001_OF001= [[ \"$(sha256sum \"$out\"|awk '{print $1}')\" == \"$expected_archive\" ]] || die \"REMOTE_${label}_ARCHIVE_SHA_MISMATCH\" 68\nENGINE_L0085_P001_OF001= rm -f \"$manifest\"\nENGINE_L0086_P001_OF001=}\nENGINE_L0087_P001_OF001=verify_generation(){\nENGINE_L0088_P001_OF001= local gen state work cfg base_a base_b a b verify_json archive_sha tmp now\nENGINE_L0089_P001_OF001= gen=\"$1\"\nENGINE_L0090_P001_OF001= state=\"$STATE_DIR/$gen.json\"\nENGINE_L0091_P001_OF001= [[ -s \"$state\" && ! -L \"$state\" ]] || die VERIFY_STATE_UNSAFE 68\nENGINE_L0092_P001_OF001= \"$TRANSPORT\" verify-sealed \"$LOGICAL_ID\" \"$gen\" \"$REMOTE_A\" \"$REMOTE_B\" \"$STATE_ROOT\" >/dev/null\nENGINE_L0093_P001_OF001= mkdir -p \"$VERIFY_ROOT\"; chmod 0700 \"$VERIFY_ROOT\"\nENGINE_L0094_P001_OF001= work=\"$(mktemp -d \"$VERIFY_ROOT/.verify.XXXXXX\")\"; cfg=\"$work/[SENSITIVE_FILE]\"; prepare_rclone \"$cfg\"\nENGINE_L0095_P001_OF001= cleanup_verify(){ rm -rf --one-file-system \"$work\"; }; trap cleanup_verify EXIT\nENGINE_L0096_P001_OF001= base_a=\"$(jq -er '.remote_a_base' \"$state\")\"; base_b=\"$(jq -er '.remote_b_base' \"$state\")\"; a=\"$work/A.tar.gz\"; b=\"$work/B.tar.gz\"\nENGINE_L0097_P001_OF001= reconstruct \"$base_a\" \"$a\" \"$cfg\" \"$state\" A; reconstruct \"$base_b\" \"$b\" \"$cfg\" \"$state\" B\nENGINE_L0098_P001_OF001= cmp -s \"$a\" \"$b\" || die CLOUD_A_B_PAYLOAD_MISMATCH 68\nENGINE_L0099_P001_OF001= verify_json=\"$(\"$BUILDER\" verify --archive \"$a\" --expected-generation \"$gen\")\" || die 68\nENGINE_L0100_P001_OF001=\nENGINE_L0101_P001_OF001= archive_sha=\"$(jq -er '.archive_sha256' \"$state\")\"; mkdir -p \"$EVIDENCE_ROOT\" /var/lib/homelab-health; chmod 0700 \"$EVIDENCE_ROOT\"\nENGINE_L0102_P001_OF001= tmp=\"$EVIDENCE_ROOT/.$gen.new.$$\"; now=\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"\nENGINE_L0103_P001_OF001=\nENGINE_L0104_P001_OF001= chmod 0600 \"$tmp\"; mv -f \"$tmp\" \"$EVIDENCE_ROOT/$gen.json\"\nENGINE_L0105_P001_OF003= tmp=\"${HEALTH}.new.$$\"; jq -n --arg gen \"$gen\" --arg state \"$state\" --arg evidence \"$EVIDENCE_ROOT/$gen.json\" --arg sha \"$archive_sha\" --arg now \"$now\" '{sche\nENGINE_L0105_P002_OF003=ma:\"homelab-control-backup-health-v1\",status:\"OK\",generation:$gen,state_file:$state,restore_evidence:$evidence,archive_sha256:$sha,cloud_quorum:2,control_freshn\nENGINE_L0105_P003_OF003=ess:\"FRESH\",full_site_dr_proven:false,updated_at_utc:$now}' >\"$tmp\"; chmod 0644 \"$tmp\"; mv -f \"$tmp\" \"$HEALTH\"\nENGINE_L0106_P001_OF001= trap - EXIT; cleanup_verify\nENGINE_L0107_P001_OF001= printf 'CONTROL_VERIFY=OK GENERATION=%s EVIDENCE=%s\\n' \"$gen\" \"$EVIDENCE_ROOT/$gen.json\"\nENGINE_L0108_P001_OF001=}\nENGINE_L0109_P001_OF001=run_backup(){\nENGINE_L0110_P001_OF001= local force=\"${1:-0}\" decision line state gen payload outdir now\nENGINE_L0111_P001_OF002= mkdir -p \"$STATE_DIR\" \"$EVIDENCE_ROOT\" \"$STAGE_ROOT\" \"$VERIFY_ROOT\" /run/lock; chmod 0700 \"$STATE_ROOT\" \"$STATE_DIR\" \"$EVIDENCE_ROOT\" \"$STAGE_ROOT\" \"$VERIFY_R\nENGINE_L0111_P002_OF002=OOT\"\nENGINE_L0112_P001_OF001= exec 9>\"$LOCK\"; flock -n 9 || { printf 'CONTROL_BACKUP_DEFERRED=LOCK_BUSY\\n'; return 0; }\nENGINE_L0113_P001_OF001= local incompletes\nENGINE_L0114_P001_OF002= incompletes=\"$(find \"$STATE_DIR\" -maxdepth 1 -type f -name 'control-bootstrap-v2-pve01-????????T??????Z.json' -print0 2>/dev/null | xargs -0 -r jq -r 'select(\nENGINE_L0114_P002_OF002=.status!=\"SEALED\")|.generation' 2>/dev/null || true)\"\nENGINE_L0115_P001_OF001= [[ \"$(grep -c . <<<\"$incompletes\" || true)\" -le 1 ]] || die MULTIPLE_INCOMPLETE_GENERATIONS 68\nENGINE_L0116_P001_OF001= line=\"$(scan)\"; printf '%s\\n' \"$line\"; decision=\"$(awk '{for(i=1;i<=NF;i++)if($i~/^DECISION=/){sub(/^DECISION=/,\"\",$i);print $i}}' <<<\"$line\")\"\nENGINE_L0117_P001_OF001= gen=\"$(awk '{for(i=1;i<=NF;i++)if($i~/^GENERATION=/){sub(/^GENERATION=/,\"\",$i);print $i}}' <<<\"$line\")\"\nENGINE_L0118_P001_OF001= if [[ \"$decision\" == SKIP_FRESH && \"$force\" != 1 ]]; then printf 'CONTROL_BACKUP_RESULT=SKIP_FRESH GENERATION=%s\\n' \"$gen\"; return 0; fi\nENGINE_L0119_P001_OF001= if [[ \"$decision\" == BACKUP_REVERIFY ]]; then\nENGINE_L0120_P001_OF001= if [[ \"$force\" != 1 ]]; then verify_generation \"$gen\"; return 0; fi\nENGINE_L0121_P001_OF001= # Forced refresh deliberately creates a new generation instead of requiring\nENGINE_L0122_P001_OF001= # a legacy generation to satisfy the current bundle schema.\nENGINE_L0123_P001_OF001= decision=BACKUP_DUE\nENGINE_L0124_P001_OF001= fi\nENGINE_L0125_P001_OF001= if [[ \"$decision\" == BACKUP_RESUME ]]; then\nENGINE_L0126_P001_OF001= state=\"$STATE_DIR/$gen.json\"; payload=\"$(jq -er '.payload_path' \"$state\")\"; [[ -s \"$payload\" && ! -L \"$payload\" ]] || die INCOMPLETE_PAYLOAD_MISSING 68\nENGINE_L0127_P001_OF001= \"$BUILDER\" verify --archive \"$payload\" --expected-generation \"$gen\" >/dev/null || die 68\nENGINE_L0128_P001_OF001= mark_cloud_write\nENGINE_L0129_P001_OF002= \"$TRANSPORT\" backup-delete \"$LOGICAL_ID\" \"$gen\" \"$payload\" \"$REMOTE_A\" \"$REMOTE_B\" \"$STATE_ROOT\"; verify_generation \"$gen\"; printf 'CONTROL_BACKUP_RESULT=SE\nENGINE_L0129_P002_OF002=ALED_RESUMED GENERATION=%s\\n' \"$gen\"; return 0\nENGINE_L0130_P001_OF001= fi\nENGINE_L0131_P001_OF001= case \"$decision\" in BACKUP_DUE|BACKUP_STALE|BACKUP_UNVERIFIED|SKIP_FRESH) ;; *) die \"DECISION_INVALID_$decision\" 65;; esac\nENGINE_L0132_P001_OF001= exec 8>\"$HEAVY_LOCK\"; flock -n 8 || { printf 'CONTROL_BACKUP_DEFERRED=HEAVY_LOCK_BUSY\\n'; return 0; }\nENGINE_L0133_P001_OF001= now=\"$(date -u +%Y%m%dT%H%M%SZ)\"; gen=\"control-bootstrap-v2-pve01-$now\"; outdir=\"$STAGE_ROOT/$gen\"\nENGINE_L0134_P001_OF001= \"$BUILDER\" build --generation \"$gen\" --output-dir \"$outdir\" >/dev/null\nENGINE_L0135_P001_OF001= payload=\"$outdir/$gen.tar.gz\"; [[ -s \"$payload\" && ! -L \"$payload\" ]] || die BUILT_PAYLOAD_MISSING 68\nENGINE_L0136_P001_OF001= \"$BUILDER\" verify --archive \"$payload\" --expected-generation \"$gen\" >/dev/null || die 68\nENGINE_L0137_P001_OF001= exec 8>&-\nENGINE_L0138_P001_OF001= mark_cloud_write\nENGINE_L0139_P001_OF001= \"$TRANSPORT\" backup-delete \"$LOGICAL_ID\" \"$gen\" \"$payload\" \"$REMOTE_A\" \"$REMOTE_B\" \"$STATE_ROOT\"\nENGINE_L0140_P001_OF001= rm -rf --one-file-system \"$outdir\" 2>/dev/null || true\nENGINE_L0141_P001_OF001= verify_generation \"$gen\"\nENGINE_L0142_P001_OF001= printf 'CONTROL_BACKUP_RESULT=SEALED_NEW GENERATION=%s\\n' \"$gen\"\nENGINE_L0143_P001_OF001=}\nENGINE_L0144_P001_OF001=case \"${1:-}\" in\nENGINE_L0145_P001_OF001= scan) [[ \"$#\" == 1 ]] || die USAGE 64; scan;;\nENGINE_L0146_P001_OF001= run) [[ \"$#\" == 1 ]] || die USAGE 64; run_backup 0;;\nENGINE_L0147_P001_OF001= force) [[ \"$#\" == 1 ]] || die USAGE 64; run_backup 1;;\nENGINE_L0148_P001_OF001= verify) [[ \"$#\" == 2 ]] || die USAGE 64; verify_generation \"$2\";;\nENGINE_L0149_P001_OF001= *) die USAGE_scan_run_force_verify 64;;\nENGINE_L0150_P001_OF001=esac\nENGINE_SOURCE_END\nUNIT_PATH=/etc/systemd/system/homelab-control-backup.service\nUNIT_SHA256=428d3e1f3042c3347b7c34b6f190e44fa35f7a97264eec3974239f581c9b9250\nUNIT_LINE_COUNT=16\nUNIT_REDACTED_LINE_COUNT=3\nUNIT_SOURCE_BEGIN\nUNIT_L0001_P001_OF001=[Unit]\nUNIT_L0002_P001_OF001=Description=Homelab recurring CONTROL cloud quorum backup\nUNIT_L0003_P001_OF001=After=network-online.target\nUNIT_L0004_P001_OF001=Wants=network-online.target\nUNIT_L0005_P001_OF001=ConditionPathExists=\nUNIT_L0006_P001_OF001=ConditionPathExists=\nUNIT_L0007_P001_OF001=\nUNIT_L0008_P001_OF001=[Service]\nUNIT_L0009_P001_OF001=Type=oneshot\nUNIT_L0010_P001_OF001=ExecStart= run\nUNIT_L0011_P001_OF001=User=root\nUNIT_L0012_P001_OF001=Group=root\nUNIT_L0013_P001_OF001=UMask=0077\nUNIT_L0014_P001_OF001=Nice=10\nUNIT_L0015_P001_OF001=IOSchedulingClass=best-effort\nUNIT_L0016_P001_OF001=IOSchedulingPriority=7\nUNIT_SOURCE_END\nSOURCE_TRUNCATED_LINES=0\nSOURCE_FUNCTION_PARSER_USED=NO\nBACKUP_ENGINE_EXECUTIONS=0\nRCLONE_COMMANDS_EXECUTED=0\nCLOUD_CALLS=0\nFILES_WRITTEN_BY_PAYLOAD=0\nSYSTEMD_MUTATIONS=0\nSOURCE259_READ_COMPLETE=YES\nSOURCE259_END\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SUPPORT-260912-INFRA-DR-BACKUPV2-CONTROL-BACKUP-SOURCE-259R1\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n" -} +{"schema_version":1,"channel":"homelab-runtime","command_id":"CONTEXT-AUTO-20260912T001701Z","status":"OK","rc":0,"host":"pve01","mode":"read-only","component":"cluster-context","started_at_utc":"2026-09-12T00:17:01Z","finished_at_utc":"2026-09-12T00:17:02Z","reference_register_checked":true,"reference_sha256":"5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66","error_register_checked":true,"error_register_sha256":"3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0","changes_made":false,"sanitized":true,"secrets_included":false,"private_addresses_included":false,"output":"AUTOMATIC_CLUSTER_CONTEXT_REFRESH=OK"} diff --git a/runtime/latest.txt b/runtime/latest.txt index ff8bbddc..9da1ea2a 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,237 +1,162 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=SUPPORT-260912-INFRA-DR-BACKUPV2-CONTROL-BACKUP-SOURCE-259R1 +COMMAND_ID=CONTEXT-AUTO-[PRIVATE_IP]701Z STATUS=OK RC=0 HOST=pve01 -MODE=read-only -COMPONENT=infra-dr-backupv2-control-backup-source -REFERENCE_REGISTER_CHECK=OK -REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 -ERROR_REGISTER_CHECK=OK -ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=09220124de7fa21ffc8fbc498052fa8ab92cee5d72b61fe34976f30307a58400 -DUPLICATE_FAILED_COMMAND_BLOCKED=false -EXECUTION_STARTED=true -CHANGE_DECLARED=false -RESULT_CONTRACT_VALID=true -RESULT_CONTRACT_STATUS=NOT_APPLICABLE -RESULT_CONTRACT_ERROR=NONE -COMMAND_RC=0 -CHANGES_MADE=false -ROLLBACK_STARTED=false -ROLLBACK_RESTORED=null -MUTATION_OUTCOME=NO_MUTATION -SANITIZED=yes -SECRETS_INCLUDED=no -PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=3762076dc1704d241330f8e0aa300dc7cbca2c80ec5ccc24137e59d67f7bd34b -SANITIZED_OUTPUT_SHA256=497e4996869d853f0466d28fe81745576dffca2ccbe7ed64998990ed695d898b +COMPONENT=cluster-context +REFERENCE_SHA[PRIVATE_IP]e5154c41cb[PRIVATE_IP]aca68090be[PRIVATE_IP]bf[PRIVATE_IP]df[PRIVATE_IP] +ERROR_REGISTER_SHA[PRIVATE_IP]ec0f527ed3afeed[PRIVATE_IP]ee[PRIVATE_IP]bbfb[PRIVATE_IP]af4ba7ba0 OUTPUT_BEGIN -SOURCE259_BEGIN -COMMAND_ID=SUPPORT-260912-INFRA-DR-BACKUPV2-CONTROL-BACKUP-SOURCE-259R1 -MODE=READ_ONLY_HASH_BOUND_SOURCE_EXPORT -SOURCE_EXECUTION=FORBIDDEN -ERROR_REGISTER_CHECK=READ -ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -REFERENCE_CHECK=READ -REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 -AUTHORITY_FRESH_READ=OK -ENGINE_PATH=/usr/local/sbin/homelab-control-backup -ENGINE_SHA256=0b3a0f685d4e67cb86250df89a4918aff2e6c67799b7d35b0e54b1bbc016ee57 -ENGINE_LINE_COUNT=150 -ENGINE_REDACTED_LINE_COUNT=13 -ENGINE_SOURCE_BEGIN -ENGINE_L0001_P001_OF001=#!/usr/bin/env bash -ENGINE_L0002_P001_OF001=set -Eeuo pipefail -ENGINE_L0003_P001_OF001=umask 077 -ENGINE_L0004_P001_OF001=LOGICAL_ID=control-bootstrap-v2 -ENGINE_L0005_P001_OF001=DUE_SECONDS=43200 -ENGINE_L0006_P001_OF001=SLA_SECONDS=86400 -ENGINE_L0007_P001_OF001=STATE_ROOT= -ENGINE_L0008_P001_OF001=STATE_DIR=$STATE_ROOT/$LOGICAL_ID -ENGINE_L0009_P001_OF001=EVIDENCE_ROOT= -ENGINE_L0010_P001_OF001=HEALTH=.json -ENGINE_L0011_P001_OF001=STAGE_ROOT=/mnt/staging/homelab-control-auto -ENGINE_L0012_P001_OF001=VERIFY_ROOT=/mnt/staging/homelab-control-verify -ENGINE_L0013_P001_OF001=LOCK=/run/lock/homelab-control-backup.lock -ENGINE_L0014_P001_OF001=HEAVY_LOCK=/run/homelab-backup-heavy.lock -ENGINE_L0015_P001_OF001=RCLONE_CONFIG_SOURCE=${RCLONE_CONFIG:-/root/.config/rclone/[SENSITIVE_FILE]} -ENGINE_L0016_P001_OF001=TRANSPORT= -ENGINE_L0017_P001_OF001=TRANSPORT_SHA= -ENGINE_L0018_P001_OF001=BUILDER= -ENGINE_L0019_P001_OF001=BUILDER_SHA= -ENGINE_L0020_P001_OF001=REMOTE_A=pve01-mail-01-crypt:homelab-backups -ENGINE_L0021_P001_OF001=REMOTE_B=pve01-mail-02-crypt:homelab-backups -ENGINE_L0022_P001_OF001=CLOUD_WRITE_MARKER=${HOMELAB_CONTROL_CLOUD_WRITE_MARKER:-} -ENGINE_L0023_P001_OF001= -ENGINE_L0024_P001_OF001=die(){ printf 'CONTROL_BACKUP_ERROR=%s\n' "$1" >&2; exit "${2:-65}"; } -ENGINE_L0025_P001_OF002=for c in jq date find sort tail cut sha256sum stat flock rclone mktemp cmp awk mkdir rm install xargs grep cat mv chmod; do command -v "$c" >/dev/null || die "T -ENGINE_L0025_P002_OF002=OOL_MISSING_$c" 69; done -ENGINE_L0026_P001_OF001=[[ -x "$TRANSPORT" && ! -L "$TRANSPORT" ]] || die TRANSPORT_UNSAFE 69 -ENGINE_L0027_P001_OF001=[[ "$(sha256sum "$TRANSPORT"|awk '{print $1}')" == "$TRANSPORT_SHA" ]] || die TRANSPORT_SHA_DRIFT 65 -ENGINE_L0028_P001_OF001=[[ -x "$BUILDER" && ! -L "$BUILDER" ]] || die BUILDER_UNSAFE 69 -ENGINE_L0029_P001_OF001=[[ "$(sha256sum "$BUILDER"|awk '{print $1}')" == "$BUILDER_SHA" ]] || die BUILDER_SHA_DRIFT 65 -ENGINE_L0030_P001_OF001= -ENGINE_L0031_P001_OF001=latest_state(){ -ENGINE_L0032_P001_OF001= [[ -d "$STATE_DIR" && ! -L "$STATE_DIR" ]] || return 0 -ENGINE_L0033_P001_OF001= find "$STATE_DIR" -maxdepth 1 -type f -name 'control-bootstrap-v2-pve01-????????T??????Z.json' -print 2>/dev/null | LC_ALL=C sort | tail -1 -ENGINE_L0034_P001_OF001=} -ENGINE_L0035_P001_OF001=state_decision(){ -ENGINE_L0036_P001_OF001= local state="$1" now="$2" status gen upd epoch age ev sha -ENGINE_L0037_P001_OF001= if [[ -z "$state" ]]; then printf 'DECISION=BACKUP_UNVERIFIED REASON=NO_STATE AGE_SECONDS=-1\n'; return 0; fi -ENGINE_L0038_P001_OF001= [[ -s "$state" && ! -L "$state" ]] || { printf 'DECISION=BACKUP_UNVERIFIED REASON=STATE_UNSAFE AGE_SECONDS=-1\n'; return 0; } -ENGINE_L0039_P001_OF001= status="$(jq -r '.status // "INVALID"' "$state")"; gen="$(jq -r '.generation // "UNKNOWN"' "$state")" -ENGINE_L0040_P001_OF001= case "$status" in -ENGINE_L0041_P001_OF001= PREPARING|A_VERIFIED|PREPARED|DELETE_AUTHORIZED) -ENGINE_L0042_P001_OF001= printf 'DECISION=BACKUP_RESUME GENERATION=%s STATE_FILE=%s AGE_SECONDS=-1\n' "$gen" "$state"; return 0;; -ENGINE_L0043_P001_OF001= SEALED) ;; -ENGINE_L0044_P001_OF001= *) printf 'DECISION=BACKUP_UNVERIFIED GENERATION=%s REASON=STATE_STATUS_INVALID AGE_SECONDS=-1\n' "$gen"; return 0;; -ENGINE_L0045_P001_OF001= esac -ENGINE_L0046_P001_OF001= sha="$(jq -r '.archive_sha256 // ""' "$state")"; upd="$(jq -r '.sealed_at_utc // .updated_at_utc // ""' "$state")" -ENGINE_L0047_P001_OF001= epoch="$(date -u -d "$upd" +%s 2>/dev/null || true)" -ENGINE_L0048_P001_OF002= [[ "$epoch" =~ ^[0-9]+$ && "$epoch" -le "$now" ]] || { printf 'DECISION=BACKUP_UNVERIFIED GENERATION=%s REASON=TIMESTAMP_INVALID AGE_SECONDS=-1\n' "$gen"; ret -ENGINE_L0048_P002_OF002=urn 0; } -ENGINE_L0049_P001_OF001= ev="$EVIDENCE_ROOT/$gen.json" -ENGINE_L0050_P001_OF001= -ENGINE_L0051_P001_OF001= printf 'DECISION=BACKUP_REVERIFY GENERATION=%s STATE_FILE=%s AGE_SECONDS=-1\n' "$gen" "$state"; return 0 -ENGINE_L0052_P001_OF001= fi -ENGINE_L0053_P001_OF001= age=$((now-epoch)) -ENGINE_L0054_P001_OF001= if (( age < DUE_SECONDS )); then d=SKIP_FRESH; elif (( age < SLA_SECONDS )); then d=BACKUP_DUE; else d=BACKUP_STALE; fi -ENGINE_L0055_P001_OF001= printf 'DECISION=%s GENERATION=%s STATE_FILE=%s AGE_SECONDS=%s DUE_SECONDS=%s SLA_SECONDS=%s\n' "$d" "$gen" "$state" "$age" "$DUE_SECONDS" "$SLA_SECONDS" -ENGINE_L0056_P001_OF001=} -ENGINE_L0057_P001_OF001=scan(){ local now state; now="$(date -u +%s)"; state="$(latest_state)"; state_decision "$state" "$now"; } -ENGINE_L0058_P001_OF001=mark_cloud_write(){ -ENGINE_L0059_P001_OF001= [[ -z "$CLOUD_WRITE_MARKER" ]] && return 0 -ENGINE_L0060_P001_OF001= [[ "$CLOUD_WRITE_MARKER" == /* ]] || die CLOUD_WRITE_MARKER_NOT_ABSOLUTE 65 -ENGINE_L0061_P001_OF001= [[ ! -L "$CLOUD_WRITE_MARKER" ]] || die CLOUD_WRITE_MARKER_SYMLINK 65 -ENGINE_L0062_P001_OF001= printf '%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" >"$CLOUD_WRITE_MARKER" -ENGINE_L0063_P001_OF001= chmod 0600 "$CLOUD_WRITE_MARKER" -ENGINE_L0064_P001_OF001=} -ENGINE_L0065_P001_OF001= -ENGINE_L0066_P001_OF001=prepare_rclone(){ -ENGINE_L0067_P001_OF001= local dst="$1"; [[ -f "$RCLONE_CONFIG_SOURCE" && ! -L "$RCLONE_CONFIG_SOURCE" ]] || die RCLONE_CONFIG_UNSAFE 66 -ENGINE_L0068_P001_OF001= install -m 0600 "$RCLONE_CONFIG_SOURCE" "$dst" -ENGINE_L0069_P001_OF001=} -ENGINE_L0070_P001_OF001=reconstruct(){ -ENGINE_L0071_P001_OF001= local base="$1" out="$2" cfg="$3" state="$4" label="$5" manifest part idx name size hash got_size got_hash expected_manifest expected_archive -ENGINE_L0072_P001_OF001= expected_manifest="$(jq -er '.parts_manifest_sha256' "$state")"; expected_archive="$(jq -er '.archive_sha256' "$state")" -ENGINE_L0073_P001_OF001= manifest="${out}.PARTS.tsv"; : >"$out" -ENGINE_L0074_P001_OF001= rclone --config "$cfg" cat "${base%/}/PARTS.tsv" >"$manifest" || die "REMOTE_${label}_MANIFEST_READ_FAILED" 74 -ENGINE_L0075_P001_OF001= [[ "$(sha256sum "$manifest"|awk '{print $1}')" == "$expected_manifest" ]] || die "REMOTE_${label}_MANIFEST_SHA_MISMATCH" 68 -ENGINE_L0076_P001_OF001= idx=0 -ENGINE_L0077_P001_OF001= while IFS=$'\t' read -r row name size hash; do -ENGINE_L0078_P001_OF002= [[ "$row" == "$(printf '%08d' "$idx")" && "$name" == part-????????.bin && "$size" =~ ^[1-9][0-9]*$ && "$hash" =~ ^[0-9a-f]{64}$ ]] || die "REMOTE_${label}_M -ENGINE_L0078_P002_OF002=ANIFEST_ROW_INVALID" 68 -ENGINE_L0079_P001_OF001= part="${out}.part"; rm -f "$part"; rclone --config "$cfg" cat "${base%/}/payload.parts/$name" >"$part" || die "REMOTE_${label}_PART_READ_FAILED" 74 -ENGINE_L0080_P001_OF001= got_size="$(stat -c %s "$part")"; got_hash="$(sha256sum "$part"|awk '{print $1}')" -ENGINE_L0081_P001_OF001= [[ "$got_size" == "$size" && "$got_hash" == "$hash" ]] || die "REMOTE_${label}_PART_VERIFY_FAILED" 68 -ENGINE_L0082_P001_OF001= cat "$part" >>"$out"; rm -f "$part"; idx=$((idx+1)) -ENGINE_L0083_P001_OF001= done <"$manifest" -ENGINE_L0084_P001_OF001= [[ "$(sha256sum "$out"|awk '{print $1}')" == "$expected_archive" ]] || die "REMOTE_${label}_ARCHIVE_SHA_MISMATCH" 68 -ENGINE_L0085_P001_OF001= rm -f "$manifest" -ENGINE_L0086_P001_OF001=} -ENGINE_L0087_P001_OF001=verify_generation(){ -ENGINE_L0088_P001_OF001= local gen state work cfg base_a base_b a b verify_json archive_sha tmp now -ENGINE_L0089_P001_OF001= gen="$1" -ENGINE_L0090_P001_OF001= state="$STATE_DIR/$gen.json" -ENGINE_L0091_P001_OF001= [[ -s "$state" && ! -L "$state" ]] || die VERIFY_STATE_UNSAFE 68 -ENGINE_L0092_P001_OF001= "$TRANSPORT" verify-sealed "$LOGICAL_ID" "$gen" "$REMOTE_A" "$REMOTE_B" "$STATE_ROOT" >/dev/null -ENGINE_L0093_P001_OF001= mkdir -p "$VERIFY_ROOT"; chmod 0700 "$VERIFY_ROOT" -ENGINE_L0094_P001_OF001= work="$(mktemp -d "$VERIFY_ROOT/.verify.XXXXXX")"; cfg="$work/[SENSITIVE_FILE]"; prepare_rclone "$cfg" -ENGINE_L0095_P001_OF001= cleanup_verify(){ rm -rf --one-file-system "$work"; }; trap cleanup_verify EXIT -ENGINE_L0096_P001_OF001= base_a="$(jq -er '.remote_a_base' "$state")"; base_b="$(jq -er '.remote_b_base' "$state")"; a="$work/A.tar.gz"; b="$work/B.tar.gz" -ENGINE_L0097_P001_OF001= reconstruct "$base_a" "$a" "$cfg" "$state" A; reconstruct "$base_b" "$b" "$cfg" "$state" B -ENGINE_L0098_P001_OF001= cmp -s "$a" "$b" || die CLOUD_A_B_PAYLOAD_MISMATCH 68 -ENGINE_L0099_P001_OF001= verify_json="$("$BUILDER" verify --archive "$a" --expected-generation "$gen")" || die 68 -ENGINE_L0100_P001_OF001= -ENGINE_L0101_P001_OF001= archive_sha="$(jq -er '.archive_sha256' "$state")"; mkdir -p "$EVIDENCE_ROOT" /var/lib/homelab-health; chmod 0700 "$EVIDENCE_ROOT" -ENGINE_L0102_P001_OF001= tmp="$EVIDENCE_ROOT/.$gen.new.$$"; now="$(date -u +%Y-%m-%dT%H:%M:%SZ)" -ENGINE_L0103_P001_OF001= -ENGINE_L0104_P001_OF001= chmod 0600 "$tmp"; mv -f "$tmp" "$EVIDENCE_ROOT/$gen.json" -ENGINE_L0105_P001_OF003= tmp="${HEALTH}.new.$$"; jq -n --arg gen "$gen" --arg state "$state" --arg evidence "$EVIDENCE_ROOT/$gen.json" --arg sha "$archive_sha" --arg now "$now" '{sche -ENGINE_L0105_P002_OF003=ma:"homelab-control-backup-health-v1",status:"OK",generation:$gen,state_file:$state,restore_evidence:$evidence,archive_sha256:$sha,cloud_quorum:2,control_freshn -ENGINE_L0105_P003_OF003=ess:"FRESH",full_site_dr_proven:false,updated_at_utc:$now}' >"$tmp"; chmod 0644 "$tmp"; mv -f "$tmp" "$HEALTH" -ENGINE_L0106_P001_OF001= trap - EXIT; cleanup_verify -ENGINE_L0107_P001_OF001= printf 'CONTROL_VERIFY=OK GENERATION=%s EVIDENCE=%s\n' "$gen" "$EVIDENCE_ROOT/$gen.json" -ENGINE_L0108_P001_OF001=} -ENGINE_L0109_P001_OF001=run_backup(){ -ENGINE_L0110_P001_OF001= local force="${1:-0}" decision line state gen payload outdir now -ENGINE_L0111_P001_OF002= mkdir -p "$STATE_DIR" "$EVIDENCE_ROOT" "$STAGE_ROOT" "$VERIFY_ROOT" /run/lock; chmod 0700 "$STATE_ROOT" "$STATE_DIR" "$EVIDENCE_ROOT" "$STAGE_ROOT" "$VERIFY_R -ENGINE_L0111_P002_OF002=OOT" -ENGINE_L0112_P001_OF001= exec 9>"$LOCK"; flock -n 9 || { printf 'CONTROL_BACKUP_DEFERRED=LOCK_BUSY\n'; return 0; } -ENGINE_L0113_P001_OF001= local incompletes -ENGINE_L0114_P001_OF002= incompletes="$(find "$STATE_DIR" -maxdepth 1 -type f -name 'control-bootstrap-v2-pve01-????????T??????Z.json' -print0 2>/dev/null | xargs -0 -r jq -r 'select( -ENGINE_L0114_P002_OF002=.status!="SEALED")|.generation' 2>/dev/null || true)" -ENGINE_L0115_P001_OF001= [[ "$(grep -c . <<<"$incompletes" || true)" -le 1 ]] || die MULTIPLE_INCOMPLETE_GENERATIONS 68 -ENGINE_L0116_P001_OF001= line="$(scan)"; printf '%s\n' "$line"; decision="$(awk '{for(i=1;i<=NF;i++)if($i~/^DECISION=/){sub(/^DECISION=/,"",$i);print $i}}' <<<"$line")" -ENGINE_L0117_P001_OF001= gen="$(awk '{for(i=1;i<=NF;i++)if($i~/^GENERATION=/){sub(/^GENERATION=/,"",$i);print $i}}' <<<"$line")" -ENGINE_L0118_P001_OF001= if [[ "$decision" == SKIP_FRESH && "$force" != 1 ]]; then printf 'CONTROL_BACKUP_RESULT=SKIP_FRESH GENERATION=%s\n' "$gen"; return 0; fi -ENGINE_L0119_P001_OF001= if [[ "$decision" == BACKUP_REVERIFY ]]; then -ENGINE_L0120_P001_OF001= if [[ "$force" != 1 ]]; then verify_generation "$gen"; return 0; fi -ENGINE_L0121_P001_OF001= # Forced refresh deliberately creates a new generation instead of requiring -ENGINE_L0122_P001_OF001= # a legacy generation to satisfy the current bundle schema. -ENGINE_L0123_P001_OF001= decision=BACKUP_DUE -ENGINE_L0124_P001_OF001= fi -ENGINE_L0125_P001_OF001= if [[ "$decision" == BACKUP_RESUME ]]; then -ENGINE_L0126_P001_OF001= state="$STATE_DIR/$gen.json"; payload="$(jq -er '.payload_path' "$state")"; [[ -s "$payload" && ! -L "$payload" ]] || die INCOMPLETE_PAYLOAD_MISSING 68 -ENGINE_L0127_P001_OF001= "$BUILDER" verify --archive "$payload" --expected-generation "$gen" >/dev/null || die 68 -ENGINE_L0128_P001_OF001= mark_cloud_write -ENGINE_L0129_P001_OF002= "$TRANSPORT" backup-delete "$LOGICAL_ID" "$gen" "$payload" "$REMOTE_A" "$REMOTE_B" "$STATE_ROOT"; verify_generation "$gen"; printf 'CONTROL_BACKUP_RESULT=SE -ENGINE_L0129_P002_OF002=ALED_RESUMED GENERATION=%s\n' "$gen"; return 0 -ENGINE_L0130_P001_OF001= fi -ENGINE_L0131_P001_OF001= case "$decision" in BACKUP_DUE|BACKUP_STALE|BACKUP_UNVERIFIED|SKIP_FRESH) ;; *) die "DECISION_INVALID_$decision" 65;; esac -ENGINE_L0132_P001_OF001= exec 8>"$HEAVY_LOCK"; flock -n 8 || { printf 'CONTROL_BACKUP_DEFERRED=HEAVY_LOCK_BUSY\n'; return 0; } -ENGINE_L0133_P001_OF001= now="$(date -u +%Y%m%dT%H%M%SZ)"; gen="control-bootstrap-v2-pve01-$now"; outdir="$STAGE_ROOT/$gen" -ENGINE_L0134_P001_OF001= "$BUILDER" build --generation "$gen" --output-dir "$outdir" >/dev/null -ENGINE_L0135_P001_OF001= payload="$outdir/$gen.tar.gz"; [[ -s "$payload" && ! -L "$payload" ]] || die BUILT_PAYLOAD_MISSING 68 -ENGINE_L0136_P001_OF001= "$BUILDER" verify --archive "$payload" --expected-generation "$gen" >/dev/null || die 68 -ENGINE_L0137_P001_OF001= exec 8>&- -ENGINE_L0138_P001_OF001= mark_cloud_write -ENGINE_L0139_P001_OF001= "$TRANSPORT" backup-delete "$LOGICAL_ID" "$gen" "$payload" "$REMOTE_A" "$REMOTE_B" "$STATE_ROOT" -ENGINE_L0140_P001_OF001= rm -rf --one-file-system "$outdir" 2>/dev/null || true -ENGINE_L0141_P001_OF001= verify_generation "$gen" -ENGINE_L0142_P001_OF001= printf 'CONTROL_BACKUP_RESULT=SEALED_NEW GENERATION=%s\n' "$gen" -ENGINE_L0143_P001_OF001=} -ENGINE_L0144_P001_OF001=case "${1:-}" in -ENGINE_L0145_P001_OF001= scan) [[ "$#" == 1 ]] || die USAGE 64; scan;; -ENGINE_L0146_P001_OF001= run) [[ "$#" == 1 ]] || die USAGE 64; run_backup 0;; -ENGINE_L0147_P001_OF001= force) [[ "$#" == 1 ]] || die USAGE 64; run_backup 1;; -ENGINE_L0148_P001_OF001= verify) [[ "$#" == 2 ]] || die USAGE 64; verify_generation "$2";; -ENGINE_L0149_P001_OF001= *) die USAGE_scan_run_force_verify 64;; -ENGINE_L0150_P001_OF001=esac -ENGINE_SOURCE_END -UNIT_PATH=/etc/systemd/system/homelab-control-backup.service -UNIT_SHA256=428d3e1f3042c3347b7c34b6f190e44fa35f7a97264eec3974239f581c9b9250 -UNIT_LINE_COUNT=16 -UNIT_REDACTED_LINE_COUNT=3 -UNIT_SOURCE_BEGIN -UNIT_L0001_P001_OF001=[Unit] -UNIT_L0002_P001_OF001=Description=Homelab recurring CONTROL cloud quorum backup -UNIT_L0003_P001_OF001=After=network-online.target -UNIT_L0004_P001_OF001=Wants=network-online.target -UNIT_L0005_P001_OF001=ConditionPathExists= -UNIT_L0006_P001_OF001=ConditionPathExists= -UNIT_L0007_P001_OF001= -UNIT_L0008_P001_OF001=[Service] -UNIT_L0009_P001_OF001=Type=oneshot -UNIT_L0010_P001_OF001=ExecStart= run -UNIT_L0011_P001_OF001=User=root -UNIT_L0012_P001_OF001=Group=root -UNIT_L0013_P001_OF001=UMask=0077 -UNIT_L0014_P001_OF001=Nice=10 -UNIT_L0015_P001_OF001=IOSchedulingClass=best-effort -UNIT_L0016_P001_OF001=IOSchedulingPriority=7 -UNIT_SOURCE_END -SOURCE_TRUNCATED_LINES=0 -SOURCE_FUNCTION_PARSER_USED=NO -BACKUP_ENGINE_EXECUTIONS=0 -RCLONE_COMMANDS_EXECUTED=0 -CLOUD_CALLS=0 -FILES_WRITTEN_BY_PAYLOAD=0 -SYSTEMD_MUTATIONS=0 -SOURCE259_READ_COMPLETE=YES -SOURCE259_END -HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260912-INFRA-DR-BACKUPV2-CONTROL-BACKUP-SOURCE-259R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} +GENERATED_AT_UTC=[PRIVATE_IP]T00:17:01Z +Cluster information +------------------- +Name: homelab +Config Version: 3 +Transport: knet +Secure auth: on +Quorum information +------------------ +Date: Sat Sep [PRIVATE_IP] 2026 +Quorum provider: corosync_votequorum +Nodes: 3 +Node ID: [PRIVATE_IP] +Ring ID: 1.130 +Quorate: Yes + +Votequorum information +---------------------- +Expected votes: 3 +Highest expected: 3 +Total votes: 3 +Quorum: 2 +Flags: Quorate + +Membership information +---------------------- + Nodeid Votes Name +[PRIVATE_IP] [PRIVATE_IP].11 (local) +[PRIVATE_IP] [PRIVATE_IP].13 +[PRIVATE_IP] [PRIVATE_IP].12 + +Membership information +---------------------- + Nodeid Votes Name + 1 1 pve01 (local) + 2 1 pve03 + 3 1 pve02 +[{"cpu":[PRIVATE_IP]394231,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/110","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"dns1","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":110},{"cpu":[PRIVATE_IP]967041,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/111","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"dns2","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve02","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":111},{"cpu":0,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/112","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"unbound1","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":112},{"cpu":0,"disk":[PRIVATE_IP],"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"lxc/113","maxcpu":1,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":0,"name":"unbound2","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve02","status":"running","template":0,"type":"lxc","uptime":[PRIVATE_IP],"vmid":113},{"cpu":[PRIVATE_IP]43079,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/130","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"edge-vm","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve03","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":130},{"cpu":[PRIVATE_IP]900349,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/150","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"snikket","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":150},{"cpu":[PRIVATE_IP]350356,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/160","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"forum-prod","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve02","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":160},{"cpu":[PRIVATE_IP]4505,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/170","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"core-apps","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":170},{"cpu":[PRIVATE_IP]51788,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/171","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"monitoring","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":171},{"cpu":[PRIVATE_IP]7115,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/190","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"homelab-ops-worker","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve03","status":"running","template":0,"type":"qemu","uptime":[PRIVATE_IP],"vmid":190},{"cpu":[PRIVATE_IP]508068,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/210","maxcpu":2,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"newfi-prod","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve01","status":"running","template":0,"type":"qemu","uptime":436761,"vmid":210},{"cpu":[PRIVATE_IP]302143,"disk":0,"diskread":[PRIVATE_IP],"diskwrite":[PRIVATE_IP],"id":"qemu/211","maxcpu":2,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"memhost":[PRIVATE_IP],"name":"newfi-staging","netin":[PRIVATE_IP],"netout":[PRIVATE_IP],"node":"pve03","status":"running","template":0,"type":"qemu","uptime":632686,"vmid":211},{"cpu":0,"disk":0,"diskread":0,"diskwrite":0,"id":"qemu/9130","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":0,"memhost":0,"name":"edge-cold-standby","netin":0,"netout":0,"node":"pve02","status":"stopped","template":0,"type":"qemu","uptime":0,"vmid":9130},{"cgroup-mode":2,"cpu":[PRIVATE_IP]917,"disk":[PRIVATE_IP],"id":"node/pve02","level":"","maxcpu":4,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"node":"pve02","status":"online","type":"node","uptime":[PRIVATE_IP]},{"cgroup-mode":2,"cpu":[PRIVATE_IP]13443,"disk":[PRIVATE_IP],"id":"node/pve03","level":"","maxcpu":8,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"node":"pve03","status":"online","type":"node","uptime":[PRIVATE_IP]},{"cgroup-mode":2,"cpu":[PRIVATE_IP]64094,"disk":[PRIVATE_IP],"id":"node/pve01","level":"","maxcpu":24,"maxdisk":[PRIVATE_IP],"maxmem":[PRIVATE_IP],"mem":[PRIVATE_IP],"node":"pve01","status":"online","type":"node","uptime":[PRIVATE_IP]},{"content":"images,rootdir","disk":[PRIVATE_IP],"id":"storage/pve02/local-lvm","maxdisk":[PRIVATE_IP],"node":"pve02","plugintype":"lvmthin","shared":0,"status":"available","storage":"local-lvm","type":"storage"},{"content":"images,rootdir","disk":[PRIVATE_IP],"id":"storage/pve03/local-lvm","maxdisk":[PRIVATE_IP],"node":"pve03","plugintype":"lvmthin","shared":0,"status":"available","storage":"local-lvm","type":"storage"},{"content":"images,rootdir","disk":[PRIVATE_IP],"id":"storage/pve01/local-lvm","maxdisk":[PRIVATE_IP],"node":"pve01","plugintype":"lvmthin","shared":0,"status":"available","storage":"local-lvm","type":"storage"},{"content":"vztmpl,import,iso,backup","disk":[PRIVATE_IP],"id":"storage/pve02/local","maxdisk":[PRIVATE_IP],"node":"pve02","plugintype":"dir","shared":0,"status":"available","storage":"local","type":"storage"},{"content":"vztmpl,import,iso,backup","disk":[PRIVATE_IP],"id":"storage/pve03/local","maxdisk":[PRIVATE_IP],"node":"pve03","plugintype":"dir","shared":0,"status":"available","storage":"local","type":"storage"},{"content":"vztmpl,import,iso,backup","disk":[PRIVATE_IP],"id":"storage/pve01/local","maxdisk":[PRIVATE_IP],"node":"pve01","plugintype":"dir","shared":0,"status":"available","storage":"local","type":"storage"},{"id":"network/pve02/zone/localnetwork","network":"localnetwork","network-type":"zone","node":"pve02","status":"ok","type":"network"},{"id":"network/pve03/zone/localnetwork","network":"localnetwork","network-type":"zone","node":"pve03","status":"ok","type":"network"},{"id":"network/pve01/zone/localnetwork","network":"localnetwork","network-type":"zone","node":"pve01","status":"ok","type":"network"}] +Name Type Status Total (KiB) Used (KiB) Available (KiB) % +local dir active [PRIVATE_IP] [PRIVATE_IP] [PRIVATE_IP] 20.75% +local-lvm lvmthin active [PRIVATE_IP] [PRIVATE_IP] [PRIVATE_IP] 10.24% + UNIT LOAD ACTIVE SUB DESCRIPTION +● homelab-backup-retention-gc.service loaded failed failed Homelab owner-aware cloud retention GC + +Legend: LOAD → Reflects whether the unit definition was properly loaded. + ACTIVE → The high-level unit activation state, i.e. generalization of SUB. + SUB → The low-level unit activation state, values depend on unit type. + +1 loaded units listed. +NEXT LEFT LAST PASSED UNIT ACTIVATES +Sat [PRIVATE_IP] 03:17:16 MSK 14s Sat [PRIVATE_IP] 03:16:16 MSK 45s ago homelab-private-vpn-hosts-health.timer homelab-private-vpn-hosts-health.service +Sat [PRIVATE_IP] 03:17:35 MSK 32s Sat [PRIVATE_IP] 03:16:32 MSK 30s ago homelab-router-watchdog.timer homelab-router-watchdog.service +Sat [PRIVATE_IP] 03:18:08 MSK 1min 6s Sat [PRIVATE_IP] 03:03:08 MSK 13min ago homelab-disk-space-health.timer homelab-disk-space-health.service +Sat [PRIVATE_IP] 03:20:09 MSK 3min 6s Sat [PRIVATE_IP] 03:15:08 MSK 1min 53s ago homelab-health-metrics.timer homelab-health-metrics.service +Sat [PRIVATE_IP] 03:21:55 MSK 4min 53s Sat [PRIVATE_IP] 03:06:55 MSK 10min ago homelab-pve03-staging-capacity-health.timer homelab-pve03-staging-capacity-health.service +Sat [PRIVATE_IP] 03:25:38 MSK 8min Sat [PRIVATE_IP] 02:53:12 MSK 23min ago homelab-reference-refresh.timer homelab-reference-refresh.service +Sat [PRIVATE_IP] 03:25:55 MSK 8min Sat [PRIVATE_IP] 03:15:55 MSK 1min 6s ago skladchik-reports-monitor-supervisor.timer skladchik-reports-monitor-supervisor.service +Sat [PRIVATE_IP] 03:29:55 MSK 12min Sat [PRIVATE_IP] 03:14:55 MSK 2min 6s ago prometheus-node-exporter-apt.timer prometheus-node-exporter-apt.service +Sat [PRIVATE_IP] 03:30:00 MSK 12min Sat [PRIVATE_IP] 01:30:08 MSK 1h 46min ago homelab-app-cloud-quorum-queue.timer homelab-app-cloud-quorum-queue.service +Sat [PRIVATE_IP] 03:30:00 MSK 12min Sat [PRIVATE_IP] 03:15:08 MSK 1min 53s ago homelab-incident-journal.timer homelab-incident-journal.service +Sat [PRIVATE_IP] 03:30:41 MSK 13min Sat [PRIVATE_IP] 03:16:32 MSK 30s ago homelab-forum-snuffleupagus-health.timer homelab-forum-snuffleupagus-health.service +Sat [PRIVATE_IP] 03:31:00 MSK 13min Sat [PRIVATE_IP] 03:15:55 MSK 1min 6s ago homelab-external-probe-vps-health.timer homelab-external-probe-vps-health.service +Sat [PRIVATE_IP] 03:31:18 MSK 14min Sat [PRIVATE_IP] 03:15:13 MSK 1min 48s ago homelab-duty-admin-v2.timer homelab-duty-admin-v2.service +Sat [PRIVATE_IP] 03:31:38 MSK 14min Sat [PRIVATE_IP] 03:16:38 MSK 23s ago prometheus-node-exporter-nvme.timer prometheus-node-exporter-nvme.service +Sat [PRIVATE_IP] 03:32:47 MSK 15min Fri [PRIVATE_IP] 03:33:55 MSK 23h ago homelab-backup-retention-gc.timer homelab-backup-retention-gc.service +Sat [PRIVATE_IP] 03:33:20 MSK 16min Sat [PRIVATE_IP] 03:00:55 MSK 16min ago homelab-mkdocs-auto-refresh.timer homelab-mkdocs-auto-refresh.service +Sat [PRIVATE_IP] 03:36:20 MSK 19min Sat [PRIVATE_IP] 03:06:08 MSK 10min ago homelab-backup-audit.timer homelab-backup-audit.service +Sat [PRIVATE_IP] 04:00:26 MSK 43min Sat [PRIVATE_IP] 03:06:15 MSK 10min ago homelab-control-backup.timer homelab-control-backup.service +Sat [PRIVATE_IP] 04:30:37 MSK 1h 13min Sat [PRIVATE_IP] 00:34:38 MSK 2h 42min ago homelab-vm-cloud-quorum-queue.timer homelab-vm-cloud-quorum-queue.service +Sat [PRIVATE_IP] 04:35:55 MSK 1h 18min Fri [PRIVATE_IP] 22:35:55 MSK 4h 41min ago homelab-vps-identity-audit.timer homelab-vps-identity-audit.service +Sat [PRIVATE_IP] 06:04:23 MSK 2h 47min Sat [PRIVATE_IP] 00:00:32 MSK 3h 16min ago homelab-evidence-root.timer homelab-evidence-root.service +Sat [PRIVATE_IP] 06:24:02 MSK 3h 6min Fri [PRIVATE_IP] 21:07:38 MSK 6h ago apt-daily.timer apt-daily.service +Sat [PRIVATE_IP] 06:51:40 MSK 3h 34min Fri [PRIVATE_IP] 06:04:16 MSK 21h ago apt-daily-upgrade.timer apt-daily-upgrade.service +Sat [PRIVATE_IP] 07:17:30 MSK 4h 0min Fri [PRIVATE_IP] 07:15:52 MSK 20h ago homelab-drift-check.timer homelab-drift-check.service +Sat [PRIVATE_IP] 07:28:57 MSK 4h 11min Sat [PRIVATE_IP] 01:22:12 MSK 1h 54min ago homelab-mailru-trash-gc.timer homelab-mailru-trash-gc.service +Sat [PRIVATE_IP] 07:31:46 MSK 4h 14min Fri [PRIVATE_IP] 07:35:23 MSK 19h ago homelab-service-registry-check.timer homelab-service-registry-check.service +Sat [PRIVATE_IP] 07:43:45 MSK 4h 26min Fri [PRIVATE_IP] 07:50:12 MSK 19h ago homelab-alerting-health.timer homelab-alerting-health.service +Sat [PRIVATE_IP] 07:47:09 MSK 4h 30min Fri [PRIVATE_IP] 07:42:16 MSK 19h ago homelab-dependency-map-check.timer homelab-dependency-map-check.service +Sat [PRIVATE_IP] 07:49:02 MSK 4h 32min Fri [PRIVATE_IP] 07:46:55 MSK 19h ago homelab-runbook-generate.timer homelab-runbook-generate.service +Sat [PRIVATE_IP] 07:55:54 MSK 4h 38min Fri [PRIVATE_IP] 08:06:52 MSK 19h ago homelab-duty-admin-report.timer homelab-duty-admin-report.service +Sat [PRIVATE_IP] 08:01:33 MSK 4h 44min Fri [PRIVATE_IP] 08:02:27 MSK 19h ago homelab-desired-state-sync.timer homelab-desired-state-sync.service +Sat [PRIVATE_IP] 08:08:43 MSK 4h 51min Fri [PRIVATE_IP] 08:01:31 MSK 19h ago homelab-overall-health.timer homelab-overall-health.service +Sat [PRIVATE_IP] 08:24:50 MSK 5h 7min Fri [PRIVATE_IP] 08:30:55 MSK 18h ago homelab-capacity-risk.timer homelab-capacity-risk.service +Sat [PRIVATE_IP] 08:25:06 MSK 5h 8min Fri [PRIVATE_IP] 08:17:58 MSK 18h ago homelab-kuma-monitor-policy.timer homelab-kuma-monitor-policy.service +Sat [PRIVATE_IP] 08:27:21 MSK 5h 10min Fri [PRIVATE_IP] 08:18:07 MSK 18h ago homelab-final-readiness-gate.timer homelab-final-readiness-gate.service +Sat [PRIVATE_IP] 08:37:58 MSK 5h 20min Fri [PRIVATE_IP] 08:43:55 MSK 18h ago homelab-cluster-passport.timer homelab-cluster-passport.service +Sat [PRIVATE_IP] 08:40:38 MSK 5h 23min Fri [PRIVATE_IP] 08:45:52 MSK 18h ago homelab-secret-exposure-guard.timer homelab-secret-exposure-guard.service +Sat [PRIVATE_IP] 08:52:32 MSK 5h 35min Fri [PRIVATE_IP] 09:00:16 MSK 18h ago homelab-golden-state-index.timer homelab-golden-state-index.service +Sat [PRIVATE_IP] 10:15:00 MSK 6h Fri [PRIVATE_IP] 10:15:07 MSK 17h ago skladchik-reports-monitor-monthly-selftest-watch.timer skladchik-reports-monitor-monthly-selftest-watch.service +Sat [PRIVATE_IP] 10:17:46 MSK 7h Fri [PRIVATE_IP] 01:24:14 MSK 1 day 1h ago man-db.timer man-db.service +Sat [PRIVATE_IP] 16:47:55 MSK 13h Fri [PRIVATE_IP] 16:47:55 MSK 10h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service +Sun [PRIVATE_IP] 00:00:00 MSK 20h Sat [PRIVATE_IP] 00:00:08 MSK 3h 16min ago dpkg-db-backup.timer dpkg-db-backup.service +Sun [PRIVATE_IP] 00:10:42 MSK 20h Sat [PRIVATE_IP] 00:18:55 MSK 2h 58min ago homelab-evidence-catalog.timer homelab-evidence-catalog.service +Sun [PRIVATE_IP] 00:14:22 MSK 20h Sat [PRIVATE_IP] 00:03:42 MSK 3h 13min ago homelab-quality-gate.timer homelab-quality-gate.service +Sun [PRIVATE_IP] 00:18:36 MSK 21h Sat [PRIVATE_IP] 00:00:55 MSK 3h 16min ago homelab-docker-health.timer homelab-docker-health.service +Sun [PRIVATE_IP] 00:19:33 MSK 21h Sat [PRIVATE_IP] 00:00:55 MSK 3h 16min ago homelab-storage-capacity.timer homelab-storage-capacity.service +Sun [PRIVATE_IP] 00:41:51 MSK 21h Sat [PRIVATE_IP] 00:40:38 MSK 2h 36min ago logrotate.timer logrotate.service +Sun [PRIVATE_IP] 01:02:53 MSK 21h Sat [PRIVATE_IP] 02:59:55 MSK 17min ago pve-daily-update.timer pve-daily-update.service +Sun [PRIVATE_IP] 03:10:21 MSK 23h Sun [PRIVATE_IP] 03:11:16 MSK 6 days ago e2scrub_all.timer e2scrub_all.service +Sun [PRIVATE_IP] 03:10:35 MSK 23h Sun [PRIVATE_IP] 03:10:50 MSK 6 days ago xfs_scrub_all.timer xfs_scrub_all.service +Sun [PRIVATE_IP] 07:35:54 MSK 1 day 4h Sun [PRIVATE_IP] 07:57:53 MSK 5 days ago homelab-rotating-boot-drill.timer homelab-rotating-boot-drill.service +Mon [PRIVATE_IP] 00:10:37 MSK 1 day 20h Mon [PRIVATE_IP] 00:08:52 MSK 5 days ago homelab-secret-sanity.timer homelab-secret-sanity.service +Mon [PRIVATE_IP] 00:30:41 MSK 1 day 21h Mon [PRIVATE_IP] 00:39:53 MSK 5 days ago fstrim.timer fstrim.service +- - Sat [PRIVATE_IP] 03:17:02 MSK 17ms ago homelab-smartctl-textfile.timer homelab-smartctl-textfile.service +- - Sat [PRIVATE_IP] 03:17:02 MSK 18ms ago netbird-peers-health.timer netbird-peers-health.service +- - - - prometheus-node-exporter-ipmitool-sensor.timer prometheus-node-exporter-ipmitool-sensor.service +- - - - prometheus-node-exporter-mellanox-hca-temp.timer prometheus-node-exporter-mellanox-hca-temp.service +- - - - prometheus-node-exporter-smartmon.timer prometheus-node-exporter-smartmon.service + +58 timers listed. +RUNTIME_MANIFEST_ID=df[PRIVATE_IP]ac9b5abd[PRIVATE_IP]b[PRIVATE_IP]d89496fb2bde[PRIVATE_IP] +EXPERIMENT_ID=5462ee[PRIVATE_IP]ebe[PRIVATE_IP]feb2ad[PRIVATE_IP]1ad87bbac0b8108 +COLLECTION_START_AT=[PRIVATE_IP]T[PRIVATE_IP]:00 +FIRST_COMPLETE_D1_CLOSE=[PRIVATE_IP]T[PRIVATE_IP]:00 +PRODUCTION_LAUNCH_ALLOWED=False +EXECUTION_AUTHORITY=False +RISK_AUTHORITY=False +STAGE_A_HEALTH=AWAITING_PRIMARY_FINALITY +FORENSIC_PREVIOUS_EPOCH_PRESERVED=YES + +## NEWFI_TASK6_AUTH_CHECKPOINT_V[PRIVATE_IP] +- Scope: historical accepted AUTH test, not a current SMTP connection test. +- Newfi approved SMTP account/sender: aleisaev@yandex.ru. +- Endpoint used by accepted test: smtp.yandex.ru:465 with certificate verification; single PLAIN initial response accepted with code 235. +- Evidence: incident ledger ### NEWFI_TASK6_YANDEX_AUTH_V2_OBSERVATION and ### NEWFI_TASK6_AUTH_PROOF_CLOSE_V1. +- No password file written, no application configuration changed, no mail sent by the accepted AUTH test. +- Persistent transport installation and application delivery are not proven by this checkpoint. Task6 is not complete. +- AUTH challenge and missing-file incidents closed; launch/session incident remains OPEN with original cause unproven. +- This update does not change VM211, VM160, routing, board state or Git. +- Other incidents and infrastructure health were not assessed. + + +## NEWFI_PRIVATE_STRUCTURE92_WRONG_MARKER_SCOPE_[PRIVATE_IP] CLOSURE +- Status: CLOSED +- RCA: NEWFI92 inspected the pve01 NEWFI90 attempt marker, which had not been finalized because the outer shell exited immediately after the guest returned RC3 following its successful rollback. The guest marker contained the true final rollback state. +- Correction: NEWFI93 required both the guest FINISHED/ROLLED_BACK record and a fresh exact demo-state readback before reconciling the outer NEWFI90 marker. NEWFI92 itself never reserved an attempt or mutated state. + + +## NEWFI_PRIVATE_NEWFI95_NESTED_TRIPLE_QUOTE_PARSE_[PRIVATE_IP] +- Status: OPEN +- Command: NEWFI95 +- Symptom: after the content-structure precheck passed, the pve03 Python wrapper failed to parse at the PHP line beginning with $root. No Portal discovery or application mutation was reached. +- RCA: an outer raw triple-single-quoted guest Python payload contained an inner raw triple-single-quoted PHP payload. The inner delimiter terminated the outer Python string, causing PHP source to be parsed as Python. +- Safety: NEWFI95 was read-only, created no attempt marker, and did not reach the intended nested guest execution. Do not replay NEWFI95. + + +## NEWFI_PRIVATE_NEWFI95_NESTED_TRIPLE_QUOTE_PARSE_[PRIVATE_IP] CLOSURE +- Status: CLOSED +- RCA: an inner triple-single-quoted PHP literal terminated the outer triple-single-quoted Python guest payload in NEWFI95. The wrapper therefore failed parsing before the intended Portal discovery executed. +- Correction: NEWFI96 removed the nested Python payload layer entirely and passed one Python program directly to VM211 through qm guest exec stdin. The read-only Portal contract completed with QGA exit 0 and the implementation worktree remained unchanged. OUTPUT_END CHAT_OUTPUT_END