From c18421e7e4dad25f7c38b7c4a4ea46ee7aa7fd28 Mon Sep 17 00:00:00 2001 From: homelab-runtime-publisher Date: Sun, 27 Sep 2026 19:29:01 +0000 Subject: [PATCH] runtime: publish SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1 --- ...CKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.json | 38 ++ ...ACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.txt | 205 +++++++ runtime/latest.json | 16 +- runtime/latest.txt | 527 ++++++------------ 4 files changed, 425 insertions(+), 361 deletions(-) create mode 100644 runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.json create mode 100644 runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.txt diff --git a/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.json b/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.json new file mode 100644 index 00000000..7db674b9 --- /dev/null +++ b/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "read-only", + "component": "homelab-backup-overlay-hotfix-source-rca", + "started_at_utc": "2026-09-27T19:29:00Z", + "finished_at_utc": "2026-09-27T19:29:00Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "2dc27b7a91ac007c80176806c837e4a05af12349ce8d90549bb634a60b4976fb", + "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": "104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5", + "sanitized_output_sha256": "104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_BEGIN=true\nCOMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1\nMODE=read-only\nCOMPONENT=homelab-backup-overlay-hotfix-source-rca\nMUTATION_BOUNDARY=READ_ONLY_SOURCE_AUTHORITY_AND_DEPLOYMENT_TOPOLOGY;NO_GIT_FETCH_NO_GIT_WRITE_NO_CONFIG_WRITE_NO_RELEASE_WRITE_NO_WRAPPER_WRITE_NO_BACKUP_NO_AUDIT_RUN_NO_SYSTEMD_ACTION_NO_LOCK_BREAK_NO_MAIL_NO_NETBIRD_SKLADCHIK_CHANGE\nHOST=pve01\nCLUSTER_QUORATE=Yes\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nSOURCE_1228_STATUS=OK\nSOURCE_1228_DECISION=PASS_VZDUMP_GLOBAL_DEFAULT_RCA_COLLECTED\nSOURCE_1228_NEXT_GATE=READ_EXACT_1228_AND_FIX_ONLY_PROVEN_GLOBAL_DEFAULT_CAUSE\n=== LIVE_AUTHORITY ===\nLIVE_WRAPPER_PATH=/usr/local/sbin/homelab-backup-v2\nLIVE_WRAPPER_SHA256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2\nLIVE_WRAPPER_MATCH=true\nLIVE_HELPER_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\nLIVE_HELPER_SHA256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\nLIVE_HELPER_MATCH=true\nLIVE_LXC_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nLIVE_LXC_SHA256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\nLIVE_LXC_MATCH=true\nLIVE_ENTRY_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nLIVE_ENTRY_SHA256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793\nLIVE_ENTRY_MATCH=true\nLIVE_PVE265_PATH=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py\nLIVE_PVE265_SHA256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be\nLIVE_PVE265_MATCH=true\nLIVE_VZDUMP_CONF_SHA256=027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad\nLIVE_VZDUMP_CONF_MATCH=true\n=== GIT_SOURCE_AUTHORITY ===\nSOURCE_WORKTREE_EXISTS=true\nSOURCE_WORKTREE=/root/homelab-ops-cr-2026-1005\nSOURCE_TOPLEVEL=/root/homelab-ops-cr-2026-1005\nSOURCE_BRANCH=cr-2026-1005-backup-v2-health-alerting-remediation\nSOURCE_HEAD=e5f577d1abe9feeafcd48b1482990ce3aa242e45\nSOURCE_UPSTREAM=NONE\nSOURCE_STATUS_COUNT=0\nSOURCE_STATUS_BEGIN\n\nSOURCE_STATUS_END\nSOURCE_WORKTREE_CLEAN=true\nSOURCE_REMOTES_BEGIN\norigin\nSOURCE_REMOTES_END\nSOURCE_LOG_HEAD_BEGIN\ne5f577d1abe9feeafcd48b1482990ce3aa242e45|2026-09-25T11:53:41+03:00|backup alert: debounce transient health mail\n6401ea1e99988b9d2550de544c9e45bd7e829bdd|2026-09-22T12:19:14+03:00|CR-2026-1005: canonicalize Cloud B audit proof\n4e59d5afaa670899c56f87a84bc887175f299614|2026-09-21T07:52:31+03:00|CR-2026-1005: seal backup health alerting and DR closure\n47b9be72cf2487ba66295d7da998016bbeea57be|2026-09-21T06:31:05+03:00|CR-2026-1005: close V2 backup scheduling and retention gaps\n50bf24f8ee27f3d2e0d1cbc6c17b62c69ff06bae|2026-09-21T05:51:10+03:00|CR-2026-1005: hold retention timer during GFS apply\n46c6f9aaf8fa93ce9f0cee686f948704c1a61336|2026-09-21T05:14:29+03:00|CR-2026-1005: add controlled GFS lifecycle remediation task\n0d62d4a2077047b9b040a9378085ece09dd15883|2026-09-21T04:50:07+03:00|CR-2026-1005: make GFS critical policy lifecycle-safe\n326622a4864fa9b5f43b69981733236bb42c4d7b|2026-09-01T09:09:31Z|Merge pull request 'CR0108 record Gitea reconciler production closure' (#46) from cr-2026-0108-gitea-reconciler-production-closure into main\n6c970c4f1ee618149cf225b690e7a411c1b00df5|2026-09-01T11:30:57+03:00|CR0108 record Gitea reconciler production closure\n030d2bcf232a43e5673684b2116c7382da3ee412|2026-09-01T07:51:45Z|Merge pull request 'CR0107 invoke staged reconciler selftest through bash' (#45) from cr-2026-0107-gitea-reconciler-selftest-bash-invocation into main\n2ffbe030c6b5ebc9af1aa3aefb10520ad31153ed|2026-09-01T10:51:04+03:00|CR0107 invoke reconciler selftest through bash\nc6114944985f813794821629f889d7a8c6677743|2026-09-01T06:26:03Z|Merge pull request 'CR0106 harden Gitea reconciler token lifecycle' (#44) from cr-2026-0106-gitea-reconciler-token-lifecycle-hardening into main\n1d63b2607eea5dd5a8a390cd8b22e07a39aed7be|2026-09-01T09:16:48+03:00|CR0106 harden Gitea reconciler token lifecycle\n69acde73c234db97f6e2e080a0f725e8abd970d6|2026-09-01T08:27:21+03:00|CR0106 define Gitea reconciler token lifecycle contract (RED)\nb7adc4b1747e1ae2ab930392e2952d5d3b3a1a7e|2026-09-01T04:52:17Z|Merge pull request 'CR0105 add Gitea repository access reconciler' (#43) from cr-2026-0105-gitea-repo-access-reconciler into main\nf30216d8aa7a41de534499c48fa9174cc12242c9|2026-09-01T07:10:34+03:00|CR0105 make fake-token test CI-safe\nfd4273b3fc09c1b5f4497662cb3a79bf2180798a|2026-09-01T06:40:38+03:00|CR0105 implement VM170 Gitea access reconciler\n68a3fd045049038bd72c4f8f06b37e644aec0438|2026-09-01T00:54:22+03:00|CR0105 define Gitea access reconciler contract (RED)\n649b4b54e14281007264dda8eb4fd7d07623ad3c|2026-08-31T19:24:44Z|Merge pull request 'CR0104 record production closure' (#42) from cr-2026-0104-production-closure into main\n07f709b6fc06acad11b93e66ecd9367a3396f4f1|2026-08-31T22:23:17+03:00|CR0104 record production closure\nSOURCE_LOG_HEAD_END\n=== EXACT_SOURCE_FILE_CANDIDATES ===\nSOURCE_CANDIDATE|name=entry504.py|exact=true|sha256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/entry504.py\nSOURCE_CANDIDATE|name=fresh_lxc_helper.py|exact=true|sha256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py\nSOURCE_CANDIDATE|name=homelab-backup-v2|exact=true|sha256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2\nSOURCE_CANDIDATE|name=lxc_adapter.py|exact=true|sha256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py\nSOURCE_CANDIDATE_TOTAL|name=entry504.py|count=1|exact_count=1\nSOURCE_CANDIDATE_TOTAL|name=fresh_lxc_helper.py|count=1|exact_count=1\nSOURCE_CANDIDATE_TOTAL|name=homelab-backup-v2|count=1|exact_count=1\nSOURCE_CANDIDATE_TOTAL|name=lxc_adapter.py|count=1|exact_count=1\nSOURCE_CANDIDATE_TOTAL|name=pve265.py|count=0|exact_count=0\n=== RELEVANT_SOURCE_GREP ===\ntasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py:6:PVE265_SHA='cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be'\ntasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py:17: if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')\ntasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:6:HELPER=pathlib.Path(__file__).resolve().parent/'fresh_lxc_helper.py'\ntasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2:4:ACCEPTED=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b')\ntasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2:5:EXPECTED={'fresh_lxc_helper.py': 'dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011', 'producer_exec_helper.py': 'b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3', 'lxc_adapter.py': '3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d', 'qemu_adapter.py': '1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b', 'scheduler_adapter.py': 'a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96', 'entry504.py': 'ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793'}\n=== BASELINE_WRAPPER_AUTHORITY ===\nBASELINE_WRAPPER_PATH=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2\nBASELINE_WRAPPER_EXISTS=true\nBASELINE_WRAPPER_SHA256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2\nBASELINE_WRAPPER_MATCH_LIVE=true\n=== CHANGE1207_SOURCE_HINTS ===\ntasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:57: q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False)\ntasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:59: if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout\n=== CURRENT_WRAPPER_SOURCE ===\n#!/usr/bin/python3\nfrom __future__ import annotations\nimport hashlib, importlib, os, pathlib, stat, sys\nACCEPTED=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b')\nEXPECTED={'fresh_lxc_helper.py': 'dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011', 'producer_exec_helper.py': 'b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3', 'lxc_adapter.py': '3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d', 'qemu_adapter.py': '1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b', 'scheduler_adapter.py': 'a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96', 'entry504.py': 'ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793'}\ndef sha(p):\n h=hashlib.sha256()\n with open(p,'rb',buffering=0) as f:\n while True:\n b=f.read(1048576)\n if not b: break\n h.update(b)\n return h.hexdigest()\ndef main():\n st=os.lstat(ACCEPTED)\n if not stat.S_ISDIR(st.st_mode) or stat.S_ISLNK(st.st_mode) or st.st_uid!=0 or st.st_gid!=0 or stat.S_IMODE(st.st_mode)!=0o500: raise SystemExit('RELEASE_ROOT_IDENTITY')\n names=sorted(p.name for p in ACCEPTED.iterdir())\n if names!=sorted(EXPECTED): raise SystemExit('RELEASE_FILESET')\n for name,want in EXPECTED.items():\n p=ACCEPTED/name; s=os.lstat(p)\n if not stat.S_ISREG(s.st_mode) or stat.S_ISLNK(s.st_mode) or s.st_uid!=0 or s.st_gid!=0 or stat.S_IMODE(s.st_mode)!=0o400 or sha(p)!=want: raise SystemExit('RELEASE_FILE_IDENTITY_'+name)\n sys.dont_write_bytecode=True\n sys.path.insert(0,str(ACCEPTED))\n e=importlib.import_module('entry504')\n return int(e.main())\nif __name__=='__main__': raise SystemExit(main())\n=== CURRENT_HELPER_SOURCE ===\nfrom __future__ import annotations\nimport base64, hashlib, json, pathlib, sys\n\nBASE_RELEASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')\nC411=BASE_RELEASE/'candidate411'\nPVE265_SHA='cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be'\n\ndef sha(p:pathlib.Path)->str:\n return hashlib.sha256(p.read_bytes()).hexdigest()\n\ndef fail(code:str):\n raise RuntimeError(code)\n\ndef main()->int:\n if len(sys.argv)!=1: fail('HELPER_ARGC')\n p=C411/'pve265.py'\n if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')\n sys.path.insert(0,str(C411))\n import adapter\n adapter.verify_sources()\n guest266,pve265,_pve270,_pve282=adapter.load_graph()\n data=sys.stdin.buffer.read(4_000_001)\n if not data or len(data)>4_000_000: fail('INPUT_BOUND')\n raw=json.loads(data.decode('utf-8'))\n if type(raw) is not dict: fail('INPUT_SCHEMA')\n node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')\n if type(node) is not str or type(vmid) is not int or type(scratch) is not str or type(now) is not int: fail('INPUT_FIELDS')\n configs={int(k):v for k,v in raw.get('configs',[])}\n defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64'])\n plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)\n jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]\n if len(jobs)!=1: fail('JOB_CARDINALITY')\n job=jobs[0]\n pve265.validate_job(job,now)\n if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')\n if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY')\n guest266.no_active_tasks(raw.get('tasks'),vmid)\n argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now)\n keep=('vmid','type','node','status','template','config_sha256','disks','configured_disk_bytes','configured_archive_bound_bytes','archive_cap_bytes','global_defaults_sha256','blockers','coverage_eligible')\n out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}}\n sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\\n')\n return 0\n\nif __name__=='__main__':\n raise SystemExit(main())\n=== SOURCE_CLASSIFICATION ===\nSOURCE_HELPER_EXACT_COUNT=1\nSOURCE_LXC_EXACT_COUNT=1\nSOURCE_ENTRY_EXACT_COUNT=1\nSOURCE_PVE265_EXACT_COUNT=0\nSOURCE_AUTHORITY_READY=false\nTASK_RESULT=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED\nDECISION=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED\nNEXT_GATE=READ_EXACT_1229_AND_BUILD_IMMUTABLE_NOTIFICATION_POLICY_COMPAT_HOTFIX\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n" +} diff --git a/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.txt b/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.txt new file mode 100644 index 00000000..d21786aa --- /dev/null +++ b/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1.txt @@ -0,0 +1,205 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1 +STATUS=OK +RC=0 +HOST=pve01 +MODE=read-only +COMPONENT=homelab-backup-overlay-hotfix-source-rca +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 +COMMAND_SHA256=2dc27b7a91ac007c80176806c837e4a05af12349ce8d90549bb634a60b4976fb +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=104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5 +SANITIZED_OUTPUT_SHA256=104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5 +OUTPUT_BEGIN +BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_BEGIN=true +COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1 +MODE=read-only +COMPONENT=homelab-backup-overlay-hotfix-source-rca +MUTATION_BOUNDARY=READ_ONLY_SOURCE_AUTHORITY_AND_DEPLOYMENT_TOPOLOGY;NO_GIT_FETCH_NO_GIT_WRITE_NO_CONFIG_WRITE_NO_RELEASE_WRITE_NO_WRAPPER_WRITE_NO_BACKUP_NO_AUDIT_RUN_NO_SYSTEMD_ACTION_NO_LOCK_BREAK_NO_MAIL_NO_NETBIRD_SKLADCHIK_CHANGE +HOST=pve01 +CLUSTER_QUORATE=Yes +RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d +SOURCE_1228_STATUS=OK +SOURCE_1228_DECISION=PASS_VZDUMP_GLOBAL_DEFAULT_RCA_COLLECTED +SOURCE_1228_NEXT_GATE=READ_EXACT_1228_AND_FIX_ONLY_PROVEN_GLOBAL_DEFAULT_CAUSE +=== LIVE_AUTHORITY === +LIVE_WRAPPER_PATH=/usr/local/sbin/homelab-backup-v2 +LIVE_WRAPPER_SHA256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2 +LIVE_WRAPPER_MATCH=true +LIVE_HELPER_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py +LIVE_HELPER_SHA256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011 +LIVE_HELPER_MATCH=true +LIVE_LXC_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py +LIVE_LXC_SHA256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d +LIVE_LXC_MATCH=true +LIVE_ENTRY_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py +LIVE_ENTRY_SHA256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793 +LIVE_ENTRY_MATCH=true +LIVE_PVE265_PATH=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py +LIVE_PVE265_SHA256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be +LIVE_PVE265_MATCH=true +LIVE_VZDUMP_CONF_SHA256=027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad +LIVE_VZDUMP_CONF_MATCH=true +=== GIT_SOURCE_AUTHORITY === +SOURCE_WORKTREE_EXISTS=true +SOURCE_WORKTREE=/root/homelab-ops-cr-2026-1005 +SOURCE_TOPLEVEL=/root/homelab-ops-cr-2026-1005 +SOURCE_BRANCH=cr-2026-1005-backup-v2-health-alerting-remediation +SOURCE_HEAD=e5f577d1abe9feeafcd48b1482990ce3aa242e45 +SOURCE_UPSTREAM=NONE +SOURCE_STATUS_COUNT=0 +SOURCE_STATUS_BEGIN + +SOURCE_STATUS_END +SOURCE_WORKTREE_CLEAN=true +SOURCE_REMOTES_BEGIN +origin +SOURCE_REMOTES_END +SOURCE_LOG_HEAD_BEGIN +e5f577d1abe9feeafcd48b1482990ce3aa242e45|2026-09-25T11:53:41+03:00|backup alert: debounce transient health mail +6401ea1e99988b9d2550de544c9e45bd7e829bdd|2026-09-22T12:19:14+03:00|CR-2026-1005: canonicalize Cloud B audit proof +4e59d5afaa670899c56f87a84bc887175f299614|2026-09-21T07:52:31+03:00|CR-2026-1005: seal backup health alerting and DR closure +47b9be72cf2487ba66295d7da998016bbeea57be|2026-09-21T06:31:05+03:00|CR-2026-1005: close V2 backup scheduling and retention gaps +50bf24f8ee27f3d2e0d1cbc6c17b62c69ff06bae|2026-09-21T05:51:10+03:00|CR-2026-1005: hold retention timer during GFS apply +46c6f9aaf8fa93ce9f0cee686f948704c1a61336|2026-09-21T05:14:29+03:00|CR-2026-1005: add controlled GFS lifecycle remediation task +0d62d4a2077047b9b040a9378085ece09dd15883|2026-09-21T04:50:07+03:00|CR-2026-1005: make GFS critical policy lifecycle-safe +326622a4864fa9b5f43b69981733236bb42c4d7b|2026-09-01T09:09:31Z|Merge pull request 'CR0108 record Gitea reconciler production closure' (#46) from cr-2026-0108-gitea-reconciler-production-closure into main +6c970c4f1ee618149cf225b690e7a411c1b00df5|2026-09-01T11:30:57+03:00|CR0108 record Gitea reconciler production closure +030d2bcf232a43e5673684b2116c7382da3ee412|2026-09-01T07:51:45Z|Merge pull request 'CR0107 invoke staged reconciler selftest through bash' (#45) from cr-2026-0107-gitea-reconciler-selftest-bash-invocation into main +2ffbe030c6b5ebc9af1aa3aefb10520ad31153ed|2026-09-01T10:51:04+03:00|CR0107 invoke reconciler selftest through bash +c6114944985f813794821629f889d7a8c6677743|2026-09-01T06:26:03Z|Merge pull request 'CR0106 harden Gitea reconciler token lifecycle' (#44) from cr-2026-0106-gitea-reconciler-token-lifecycle-hardening into main +1d63b2607eea5dd5a8a390cd8b22e07a39aed7be|2026-09-01T09:16:48+03:00|CR0106 harden Gitea reconciler token lifecycle +69acde73c234db97f6e2e080a0f725e8abd970d6|2026-09-01T08:27:21+03:00|CR0106 define Gitea reconciler token lifecycle contract (RED) +b7adc4b1747e1ae2ab930392e2952d5d3b3a1a7e|2026-09-01T04:52:17Z|Merge pull request 'CR0105 add Gitea repository access reconciler' (#43) from cr-2026-0105-gitea-repo-access-reconciler into main +f30216d8aa7a41de534499c48fa9174cc12242c9|2026-09-01T07:10:34+03:00|CR0105 make fake-token test CI-safe +fd4273b3fc09c1b5f4497662cb3a79bf2180798a|2026-09-01T06:40:38+03:00|CR0105 implement VM170 Gitea access reconciler +68a3fd045049038bd72c4f8f06b37e644aec0438|2026-09-01T00:54:22+03:00|CR0105 define Gitea access reconciler contract (RED) +649b4b54e14281007264dda8eb4fd7d07623ad3c|2026-08-31T19:24:44Z|Merge pull request 'CR0104 record production closure' (#42) from cr-2026-0104-production-closure into main +07f709b6fc06acad11b93e66ecd9367a3396f4f1|2026-08-31T22:23:17+03:00|CR0104 record production closure +SOURCE_LOG_HEAD_END +=== EXACT_SOURCE_FILE_CANDIDATES === +SOURCE_CANDIDATE|name=entry504.py|exact=true|sha256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/entry504.py +SOURCE_CANDIDATE|name=fresh_lxc_helper.py|exact=true|sha256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py +SOURCE_CANDIDATE|name=homelab-backup-v2|exact=true|sha256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2 +SOURCE_CANDIDATE|name=lxc_adapter.py|exact=true|sha256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py +SOURCE_CANDIDATE_TOTAL|name=entry504.py|count=1|exact_count=1 +SOURCE_CANDIDATE_TOTAL|name=fresh_lxc_helper.py|count=1|exact_count=1 +SOURCE_CANDIDATE_TOTAL|name=homelab-backup-v2|count=1|exact_count=1 +SOURCE_CANDIDATE_TOTAL|name=lxc_adapter.py|count=1|exact_count=1 +SOURCE_CANDIDATE_TOTAL|name=pve265.py|count=0|exact_count=0 +=== RELEVANT_SOURCE_GREP === +tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py:6:PVE265_SHA='cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be' +tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py:17: if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY') +tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:6:HELPER=pathlib.Path(__file__).resolve().parent/'fresh_lxc_helper.py' +tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2:4:ACCEPTED=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b') +tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2:5:EXPECTED={'fresh_lxc_helper.py': 'dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011', 'producer_exec_helper.py': 'b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3', 'lxc_adapter.py': '3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d', 'qemu_adapter.py': '1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b', 'scheduler_adapter.py': 'a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96', 'entry504.py': 'ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793'} +=== BASELINE_WRAPPER_AUTHORITY === +BASELINE_WRAPPER_PATH=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2 +BASELINE_WRAPPER_EXISTS=true +BASELINE_WRAPPER_SHA256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2 +BASELINE_WRAPPER_MATCH_LIVE=true +=== CHANGE1207_SOURCE_HINTS === +tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:57: q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False) +tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:59: if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout +=== CURRENT_WRAPPER_SOURCE === +#!/usr/bin/python3 +from __future__ import annotations +import hashlib, importlib, os, pathlib, stat, sys +ACCEPTED=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b') +EXPECTED={'fresh_lxc_helper.py': 'dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011', 'producer_exec_helper.py': 'b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3', 'lxc_adapter.py': '3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d', 'qemu_adapter.py': '1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b', 'scheduler_adapter.py': 'a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96', 'entry504.py': 'ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793'} +def sha(p): + h=hashlib.sha256() + with open(p,'rb',buffering=0) as f: + while True: + b=f.read(1048576) + if not b: break + h.update(b) + return h.hexdigest() +def main(): + st=os.lstat(ACCEPTED) + if not stat.S_ISDIR(st.st_mode) or stat.S_ISLNK(st.st_mode) or st.st_uid!=0 or st.st_gid!=0 or stat.S_IMODE(st.st_mode)!=0o500: raise SystemExit('RELEASE_ROOT_IDENTITY') + names=sorted(p.name for p in ACCEPTED.iterdir()) + if names!=sorted(EXPECTED): raise SystemExit('RELEASE_FILESET') + for name,want in EXPECTED.items(): + p=ACCEPTED/name; s=os.lstat(p) + if not stat.S_ISREG(s.st_mode) or stat.S_ISLNK(s.st_mode) or s.st_uid!=0 or s.st_gid!=0 or stat.S_IMODE(s.st_mode)!=0o400 or sha(p)!=want: raise SystemExit('RELEASE_FILE_IDENTITY_'+name) + sys.dont_write_bytecode=True + sys.path.insert(0,str(ACCEPTED)) + e=importlib.import_module('entry504') + return int(e.main()) +if __name__=='__main__': raise SystemExit(main()) +=== CURRENT_HELPER_SOURCE === +from __future__ import annotations +import base64, hashlib, json, pathlib, sys + +BASE_RELEASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1') +C411=BASE_RELEASE/'candidate411' +PVE265_SHA='cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be' + +def sha(p:pathlib.Path)->str: + return hashlib.sha256(p.read_bytes()).hexdigest() + +def fail(code:str): + raise RuntimeError(code) + +def main()->int: + if len(sys.argv)!=1: fail('HELPER_ARGC') + p=C411/'pve265.py' + if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY') + sys.path.insert(0,str(C411)) + import adapter + adapter.verify_sources() + guest266,pve265,_pve270,_pve282=adapter.load_graph() + data=sys.stdin.buffer.read(4_000_001) + if not data or len(data)>4_000_000: fail('INPUT_BOUND') + raw=json.loads(data.decode('utf-8')) + if type(raw) is not dict: fail('INPUT_SCHEMA') + node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now') + if type(node) is not str or type(vmid) is not int or type(scratch) is not str or type(now) is not int: fail('INPUT_FIELDS') + configs={int(k):v for k,v in raw.get('configs',[])} + defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64']) + plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node) + jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid] + if len(jobs)!=1: fail('JOB_CARDINALITY') + job=jobs[0] + pve265.validate_job(job,now) + if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY') + if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY') + guest266.no_active_tasks(raw.get('tasks'),vmid) + argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now) + keep=('vmid','type','node','status','template','config_sha256','disks','configured_disk_bytes','configured_archive_bound_bytes','archive_cap_bytes','global_defaults_sha256','blockers','coverage_eligible') + out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}} + sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\n') + return 0 + +if __name__=='__main__': + raise SystemExit(main()) +=== SOURCE_CLASSIFICATION === +SOURCE_HELPER_EXACT_COUNT=1 +SOURCE_LXC_EXACT_COUNT=1 +SOURCE_ENTRY_EXACT_COUNT=1 +SOURCE_PVE265_EXACT_COUNT=0 +SOURCE_AUTHORITY_READY=false +TASK_RESULT=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED +DECISION=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED +NEXT_GATE=READ_EXACT_1229_AND_BUILD_IMMUTABLE_NOTIFICATION_POLICY_COMPAT_HOTFIX +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index 13ce465f..7db674b9 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "SUPPORT-260927-HOMELAB-BACKUP-VZDUMP-GLOBAL-DEFAULT-RCA-1228R1", + "command_id": "SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1", "status": "OK", "rc": 0, "host": "pve01", "mode": "read-only", - "component": "homelab-backup-vzdump-global-default-rca", - "started_at_utc": "2026-09-27T19:22:14Z", - "finished_at_utc": "2026-09-27T19:22:15Z", + "component": "homelab-backup-overlay-hotfix-source-rca", + "started_at_utc": "2026-09-27T19:29:00Z", + "finished_at_utc": "2026-09-27T19:29:00Z", "reference_register_checked": true, "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", "error_register_checked": true, "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", - "command_sha256": "15d336f94cd89972d76162968de50c467b1019237246ea38969b360382af78ef", + "command_sha256": "2dc27b7a91ac007c80176806c837e4a05af12349ce8d90549bb634a60b4976fb", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, @@ -30,9 +30,9 @@ "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "750d430f2795c687545bcfab0dc5f57f54c74baf36f47ec14a7de125a295c3d5", - "sanitized_output_sha256": "750d430f2795c687545bcfab0dc5f57f54c74baf36f47ec14a7de125a295c3d5", + "raw_evidence_sha256": "104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5", + "sanitized_output_sha256": "104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "BACKUP_VZDUMP_GLOBAL_DEFAULT_RCA_BEGIN=true\nCOMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-VZDUMP-GLOBAL-DEFAULT-RCA-1228R1\nMODE=read-only\nCOMPONENT=homelab-backup-vzdump-global-default-rca\nMUTATION_BOUNDARY=READ_ONLY_VZDUMP_CONF_AND_PVE265_DEFAULTS_PARSER_PLUS_JOURNAL_HISTORY;NO_CONFIG_WRITE;NO_HELPER_EXECUTION;NO_VZDUMP;NO_BACKUP;NO_AUDIT_RUN;NO_SYSTEMD_ACTION;NO_RETENTION;NO_LOCK_BREAK;NO_MAIL;NO_GIT_WRITE;NO_NETBIRD_SKLADCHIK_CHANGE\nHOST=pve01\nCLUSTER_QUORATE=Yes\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nSOURCE_1227_STATUS=OK\nSOURCE_1227_DECISION=PASS_CT110_PLAN_BLOCKER_RCA_COLLECTED\nSOURCE_1227_NEXT_GATE=READ_EXACT_1227_AND_FIX_ONLY_PROVEN_PLAN_BLOCKER\nPVE265_SHA256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be\nADAPTER_SHA256=18eb29cef165371b48bcb78e1a456e1939e6eff253787218133162cc89ab9fa3\n=== VZDUMP_CONF_METADATA ===\nVZDUMP_CONF_STAT=/etc/vzdump.conf|644|root:root|566|2026-05-21 14:20:02.000000000 +0300\nVZDUMP_CONF_SHA256_SHELL=027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad\n=== DEFAULTS_PARSER_AND_LINE_RCA ===\nDEFAULTS_SUMMARY_SOURCE_BEGIN\n0001:def defaults_summary(raw):\n0002: need(raw is None or type(raw) is bytes and len(raw)<=262144,'DEFAULTS_BOUND')\n0003: result={'present':raw is not None,'sha256':t.sha(raw) if raw is not None else None,'keys':[],'blockers':[]}\n0004: if raw is None:return result\n0005: try:text=raw.decode('utf-8-sig')\n0006: except UnicodeError:result['blockers']=['GLOBAL_DEFAULT_PARSE'];return result\n0007: seen=set();block=set()\n0008: for line in text.splitlines():\n0009: line=line.strip()\n0010: if not line or line.startswith('#'):continue\n0011: m=re.fullmatch(r'([a-z][a-z0-9_-]*)\\s*:\\s*(.*)',line)\n0012: if not m:block.add('GLOBAL_DEFAULT_PARSE');continue\n0013: key,value=m.groups()\n0014: if key in seen:block.add('GLOBAL_DEFAULT_DUPLICATE')\n0015: seen.add(key)\n0016: if key=='script':block.add('GLOBAL_DEFAULT_SCRIPT')\n0017: elif key=='exclude-path':block.add('GLOBAL_DEFAULT_EXCLUDE_PATH')\n0018: elif key not in OVERRIDDEN:block.add('GLOBAL_DEFAULT_UNREVIEWED')\n0019: result['keys']=sorted(seen);result['blockers']=sorted(block);return result\nDEFAULTS_SUMMARY_SOURCE_END\nDEFAULTS_SUMMARY_REFERENCED_NAMES=OVERRIDDEN,UnicodeError,block,bytes,key,len,line,m,need,raw,re,result,seen,set,sorted,t,text,type,value\nREFERENCED_CONST_OVERRIDDEN={'mode', 'compress', 'zstd', 'remove', 'prune-backups', 'stdexcludes', 'lockwait', 'bwlimit', 'ionice', 'tmpdir'}\nVZDUMP_CONF_EXISTS=true\nVZDUMP_CONF_SHA256=027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad\nVZDUMP_CONF_BYTES=566\nVZDUMP_CONF_MODE=0o644\nVZDUMP_CONF_UID=0\nVZDUMP_CONF_GID=0\nVZDUMP_CONF_MTIME_NS=1779362402000000000\nVZDUMP_CONF_MTIME_EPOCH=1779362402\nFULL_DEFAULTS_SUMMARY={\"blockers\":[\"GLOBAL_DEFAULT_UNREVIEWED\"],\"keys\":[\"mailnotification\",\"mailto\",\"notification-mode\"],\"present\":true,\"sha256\":\"027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad\"}\nACTIVE_DEFAULT_LINE_COUNT=3\nACTIVE_1_LINE=21\nACTIVE_1_KEY=notification-mode\nACTIVE_1_VALUE_SAFE=legacy-sendmail\nACTIVE_1_VALUE_SHA256=29f81a20d57a8428a4e7a910f2ad1de921e46d14f1eea1faffd8c49ea6fac577\nACTIVE_1_ALONE_SUMMARY={\"blockers\":[\"GLOBAL_DEFAULT_UNREVIEWED\"],\"keys\":[\"notification-mode\"],\"present\":true,\"sha256\":\"e7be8dafd93ab0e208e83799de41c7c877b898612c4485328f4ab2ecd33f21b3\"}\nACTIVE_2_LINE=22\nACTIVE_2_KEY=mailnotification\nACTIVE_2_VALUE_SAFE=failure\nACTIVE_2_VALUE_SHA256=16d34b5e7bcb341ee6cb3d16495d90e93fbe57c46d3827432613210a24ebca30\nACTIVE_2_ALONE_SUMMARY={\"blockers\":[\"GLOBAL_DEFAULT_UNREVIEWED\"],\"keys\":[\"mailnotification\"],\"present\":true,\"sha256\":\"82b11c636992daf77f24394f2a0635d4563265a3956d0cf386ea6914f5d14d3a\"}\nACTIVE_3_LINE=23\nACTIVE_3_KEY=mailto\nACTIVE_3_VALUE_SAFE=a***@yandex.ru\nACTIVE_3_VALUE_SHA256=0d4cf60ca8cd53a12ad50dc5419d3c9c32192f0852000eb10051fbdef52b04bf\nACTIVE_3_ALONE_SUMMARY={\"blockers\":[\"GLOBAL_DEFAULT_UNREVIEWED\"],\"keys\":[\"mailto\"],\"present\":true,\"sha256\":\"c837c49a10c7755feede42c3c4a5417675cb9c8225dff57599a6aee0e08df0e6\"}\nWITHOUT_ACTIVE_1_BLOCKERS=[\"GLOBAL_DEFAULT_UNREVIEWED\"]\nWITHOUT_ACTIVE_1_KEYS=[\"mailnotification\",\"mailto\"]\nWITHOUT_ACTIVE_1_SHA256=f424362c08197cd8f5e73333a19e6be4ad05021748b27bfff2dc749e72a720b3\nWITHOUT_ACTIVE_2_BLOCKERS=[\"GLOBAL_DEFAULT_UNREVIEWED\"]\nWITHOUT_ACTIVE_2_KEYS=[\"mailto\",\"notification-mode\"]\nWITHOUT_ACTIVE_2_SHA256=78755998062b3c9ccdf930772199a786a9f40ae78c04ec4789980c717a5f54e3\nWITHOUT_ACTIVE_3_BLOCKERS=[\"GLOBAL_DEFAULT_UNREVIEWED\"]\nWITHOUT_ACTIVE_3_KEYS=[\"mailnotification\",\"notification-mode\"]\nWITHOUT_ACTIVE_3_SHA256=8816dba85cded9488f8be0a2d414dda5ee00b1cee49959c5030cb4dba4d48d81\nVZDUMP_CONF_ACTIVE_SAFE_BEGIN\n21:notification-mode: legacy-sendmail\n22:mailnotification: failure\n23:mailto: a***@yandex.ru\nVZDUMP_CONF_ACTIVE_SAFE_END\nDEFAULTS_RCA_COMPLETE=true\nDEFAULTS_DIAG_RC=0\n=== VZDUMP_CONF_NEARBY_FILES ===\n/etc/vzdump.conf|566|2026-05-21T14:20:02.0000000000+0300\n=== BACKUP_SCHEDULER_TRANSITION_LAST7D ===\n2026-09-26T16:10:48.550873+03:00 pve01 systemd[1]: Starting homelab-backup-v2.service - Homelab Backup V2 manifest-driven scheduler...\n2026-09-26T16:10:55.546820+03:00 pve01 homelab-backup-v2[2892314]: SCHEDULE_TARGET=ct110\n2026-09-26T16:10:55.551525+03:00 pve01 homelab-backup-v2[2892314]: _need(p.returncode==0 and not p.stderr and 0str:\n return hashlib.sha256(p.read_bytes()).hexdigest()\n\ndef fail(code:str):\n raise RuntimeError(code)\n\ndef main()->int:\n if len(sys.argv)!=1: fail('HELPER_ARGC')\n p=C411/'pve265.py'\n if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')\n sys.path.insert(0,str(C411))\n import adapter\n adapter.verify_sources()\n guest266,pve265,_pve270,_pve282=adapter.load_graph()\n data=sys.stdin.buffer.read(4_000_001)\n if not data or len(data)>4_000_000: fail('INPUT_BOUND')\n raw=json.loads(data.decode('utf-8'))\n if type(raw) is not dict: fail('INPUT_SCHEMA')\n node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')\n if type(node) is not str or type(vmid) is not int or type(scratch) is not str or type(now) is not int: fail('INPUT_FIELDS')\n configs={int(k):v for k,v in raw.get('configs',[])}\n defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64'])\n plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)\n jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]\n if len(jobs)!=1: fail('JOB_CARDINALITY')\n job=jobs[0]\n pve265.validate_job(job,now)\n if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')\n if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY')\n guest266.no_active_tasks(raw.get('tasks'),vmid)\n argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now)\n keep=('vmid','type','node','status','template','config_sha256','disks','configured_disk_bytes','configured_archive_bound_bytes','archive_cap_bytes','global_defaults_sha256','blockers','coverage_eligible')\n out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}}\n sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\\n')\n return 0\n\nif __name__=='__main__':\n raise SystemExit(main())\n=== SOURCE_CLASSIFICATION ===\nSOURCE_HELPER_EXACT_COUNT=1\nSOURCE_LXC_EXACT_COUNT=1\nSOURCE_ENTRY_EXACT_COUNT=1\nSOURCE_PVE265_EXACT_COUNT=0\nSOURCE_AUTHORITY_READY=false\nTASK_RESULT=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED\nDECISION=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED\nNEXT_GATE=READ_EXACT_1229_AND_BUILD_IMMUTABLE_NOTIFICATION_POLICY_COMPAT_HOTFIX\nHOMELAB_RESULT_CONTRACT={\"version\":1,\"command_id\":\"SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1\",\"status\":\"OK\",\"changes_made\":false,\"rollback_started\":false,\"rollback_restored\":null}\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index fd1b07a1..d21786aa 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,15 +1,15 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-VZDUMP-GLOBAL-DEFAULT-RCA-1228R1 +COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1 STATUS=OK RC=0 HOST=pve01 MODE=read-only -COMPONENT=homelab-backup-vzdump-global-default-rca +COMPONENT=homelab-backup-overlay-hotfix-source-rca REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=15d336f94cd89972d76162968de50c467b1019237246ea38969b360382af78ef +COMMAND_SHA256=2dc27b7a91ac007c80176806c837e4a05af12349ce8d90549bb634a60b4976fb DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true CHANGE_DECLARED=false @@ -24,361 +24,182 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=750d430f2795c687545bcfab0dc5f57f54c74baf36f47ec14a7de125a295c3d5 -SANITIZED_OUTPUT_SHA256=750d430f2795c687545bcfab0dc5f57f54c74baf36f47ec14a7de125a295c3d5 +RAW_EVIDENCE_SHA256=104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5 +SANITIZED_OUTPUT_SHA256=104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5 OUTPUT_BEGIN -BACKUP_VZDUMP_GLOBAL_DEFAULT_RCA_BEGIN=true -COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-VZDUMP-GLOBAL-DEFAULT-RCA-1228R1 +BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_BEGIN=true +COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1 MODE=read-only -COMPONENT=homelab-backup-vzdump-global-default-rca -MUTATION_BOUNDARY=READ_ONLY_VZDUMP_CONF_AND_PVE265_DEFAULTS_PARSER_PLUS_JOURNAL_HISTORY;NO_CONFIG_WRITE;NO_HELPER_EXECUTION;NO_VZDUMP;NO_BACKUP;NO_AUDIT_RUN;NO_SYSTEMD_ACTION;NO_RETENTION;NO_LOCK_BREAK;NO_MAIL;NO_GIT_WRITE;NO_NETBIRD_SKLADCHIK_CHANGE +COMPONENT=homelab-backup-overlay-hotfix-source-rca +MUTATION_BOUNDARY=READ_ONLY_SOURCE_AUTHORITY_AND_DEPLOYMENT_TOPOLOGY;NO_GIT_FETCH_NO_GIT_WRITE_NO_CONFIG_WRITE_NO_RELEASE_WRITE_NO_WRAPPER_WRITE_NO_BACKUP_NO_AUDIT_RUN_NO_SYSTEMD_ACTION_NO_LOCK_BREAK_NO_MAIL_NO_NETBIRD_SKLADCHIK_CHANGE HOST=pve01 CLUSTER_QUORATE=Yes RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d -SOURCE_1227_STATUS=OK -SOURCE_1227_DECISION=PASS_CT110_PLAN_BLOCKER_RCA_COLLECTED -SOURCE_1227_NEXT_GATE=READ_EXACT_1227_AND_FIX_ONLY_PROVEN_PLAN_BLOCKER -PVE265_SHA256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be -ADAPTER_SHA256=18eb29cef165371b48bcb78e1a456e1939e6eff253787218133162cc89ab9fa3 -=== VZDUMP_CONF_METADATA === -VZDUMP_CONF_STAT=/etc/vzdump.conf|644|root:root|566|2026-05-21 14:20:02.000000000 +0300 -VZDUMP_CONF_SHA256_SHELL=027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad -=== DEFAULTS_PARSER_AND_LINE_RCA === -DEFAULTS_SUMMARY_SOURCE_BEGIN -0001:def defaults_summary(raw): -0002: need(raw is None or type(raw) is bytes and len(raw)<=262144,'DEFAULTS_BOUND') -0003: result={'present':raw is not None,'sha256':t.sha(raw) if raw is not None else None,'keys':[],'blockers':[]} -0004: if raw is None:return result -0005: try:text=raw.decode('utf-8-sig') -0006: except UnicodeError:result['blockers']=['GLOBAL_DEFAULT_PARSE'];return result -0007: seen=set();block=set() -0008: for line in text.splitlines(): -0009: line=line.strip() -0010: if not line or line.startswith('#'):continue -0011: m=re.fullmatch(r'([a-z][a-z0-9_-]*)\s*:\s*(.*)',line) -0012: if not m:block.add('GLOBAL_DEFAULT_PARSE');continue -0013: key,value=m.groups() -0014: if key in seen:block.add('GLOBAL_DEFAULT_DUPLICATE') -0015: seen.add(key) -0016: if key=='script':block.add('GLOBAL_DEFAULT_SCRIPT') -0017: elif key=='exclude-path':block.add('GLOBAL_DEFAULT_EXCLUDE_PATH') -0018: elif key not in OVERRIDDEN:block.add('GLOBAL_DEFAULT_UNREVIEWED') -0019: result['keys']=sorted(seen);result['blockers']=sorted(block);return result -DEFAULTS_SUMMARY_SOURCE_END -DEFAULTS_SUMMARY_REFERENCED_NAMES=OVERRIDDEN,UnicodeError,block,bytes,key,len,line,m,need,raw,re,result,seen,set,sorted,t,text,type,value -REFERENCED_CONST_OVERRIDDEN={'mode', 'compress', 'zstd', 'remove', 'prune-backups', 'stdexcludes', 'lockwait', 'bwlimit', 'ionice', 'tmpdir'} -VZDUMP_CONF_EXISTS=true -VZDUMP_CONF_SHA256=027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad -VZDUMP_CONF_BYTES=566 -VZDUMP_CONF_MODE=0o644 -VZDUMP_CONF_UID=0 -VZDUMP_CONF_GID=0 -VZDUMP_CONF_MTIME_NS=1779362402000000000 -VZDUMP_CONF_MTIME_EPOCH=1779362402 -FULL_DEFAULTS_SUMMARY={"blockers":["GLOBAL_DEFAULT_UNREVIEWED"],"keys":["mailnotification","mailto","notification-mode"],"present":true,"sha256":"027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad"} -ACTIVE_DEFAULT_LINE_COUNT=3 -ACTIVE_1_LINE=21 -ACTIVE_1_KEY=notification-mode -ACTIVE_1_VALUE_SAFE=legacy-sendmail -ACTIVE_1_VALUE_SHA256=29f81a20d57a8428a4e7a910f2ad1de921e46d14f1eea1faffd8c49ea6fac577 -ACTIVE_1_ALONE_SUMMARY={"blockers":["GLOBAL_DEFAULT_UNREVIEWED"],"keys":["notification-mode"],"present":true,"sha256":"e7be8dafd93ab0e208e83799de41c7c877b898612c4485328f4ab2ecd33f21b3"} -ACTIVE_2_LINE=22 -ACTIVE_2_KEY=mailnotification -ACTIVE_2_VALUE_SAFE=failure -ACTIVE_2_VALUE_SHA256=16d34b5e7bcb341ee6cb3d16495d90e93fbe57c46d3827432613210a24ebca30 -ACTIVE_2_ALONE_SUMMARY={"blockers":["GLOBAL_DEFAULT_UNREVIEWED"],"keys":["mailnotification"],"present":true,"sha256":"82b11c636992daf77f24394f2a0635d4563265a3956d0cf386ea6914f5d14d3a"} -ACTIVE_3_LINE=23 -ACTIVE_3_KEY=mailto -ACTIVE_3_VALUE_SAFE=a***@yandex.ru -ACTIVE_3_VALUE_SHA256=0d4cf60ca8cd53a12ad50dc5419d3c9c32192f0852000eb10051fbdef52b04bf -ACTIVE_3_ALONE_SUMMARY={"blockers":["GLOBAL_DEFAULT_UNREVIEWED"],"keys":["mailto"],"present":true,"sha256":"c837c49a10c7755feede42c3c4a5417675cb9c8225dff57599a6aee0e08df0e6"} -WITHOUT_ACTIVE_1_BLOCKERS=["GLOBAL_DEFAULT_UNREVIEWED"] -WITHOUT_ACTIVE_1_KEYS=["mailnotification","mailto"] -WITHOUT_ACTIVE_1_SHA256=f424362c08197cd8f5e73333a19e6be4ad05021748b27bfff2dc749e72a720b3 -WITHOUT_ACTIVE_2_BLOCKERS=["GLOBAL_DEFAULT_UNREVIEWED"] -WITHOUT_ACTIVE_2_KEYS=["mailto","notification-mode"] -WITHOUT_ACTIVE_2_SHA256=78755998062b3c9ccdf930772199a786a9f40ae78c04ec4789980c717a5f54e3 -WITHOUT_ACTIVE_3_BLOCKERS=["GLOBAL_DEFAULT_UNREVIEWED"] -WITHOUT_ACTIVE_3_KEYS=["mailnotification","notification-mode"] -WITHOUT_ACTIVE_3_SHA256=8816dba85cded9488f8be0a2d414dda5ee00b1cee49959c5030cb4dba4d48d81 -VZDUMP_CONF_ACTIVE_SAFE_BEGIN -21:notification-mode: legacy-sendmail -22:mailnotification: failure -23:mailto: a***@yandex.ru -VZDUMP_CONF_ACTIVE_SAFE_END -DEFAULTS_RCA_COMPLETE=true -DEFAULTS_DIAG_RC=0 -=== VZDUMP_CONF_NEARBY_FILES === -/etc/vzdump.conf|566|2026-05-21T14:20:02.0000000000+0300 -=== BACKUP_SCHEDULER_TRANSITION_LAST7D === -2026-09-26T16:10:48.550873+03:00 pve01 systemd[1]: Starting homelab-backup-v2.service - Homelab Backup V2 manifest-driven scheduler... -2026-09-26T16:10:55.546820+03:00 pve01 homelab-backup-v2[2892314]: SCHEDULE_TARGET=ct110 -2026-09-26T16:10:55.551525+03:00 pve01 homelab-backup-v2[2892314]: _need(p.returncode==0 and not p.stderr and 0str: + return hashlib.sha256(p.read_bytes()).hexdigest() + +def fail(code:str): + raise RuntimeError(code) + +def main()->int: + if len(sys.argv)!=1: fail('HELPER_ARGC') + p=C411/'pve265.py' + if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY') + sys.path.insert(0,str(C411)) + import adapter + adapter.verify_sources() + guest266,pve265,_pve270,_pve282=adapter.load_graph() + data=sys.stdin.buffer.read(4_000_001) + if not data or len(data)>4_000_000: fail('INPUT_BOUND') + raw=json.loads(data.decode('utf-8')) + if type(raw) is not dict: fail('INPUT_SCHEMA') + node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now') + if type(node) is not str or type(vmid) is not int or type(scratch) is not str or type(now) is not int: fail('INPUT_FIELDS') + configs={int(k):v for k,v in raw.get('configs',[])} + defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64']) + plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node) + jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid] + if len(jobs)!=1: fail('JOB_CARDINALITY') + job=jobs[0] + pve265.validate_job(job,now) + if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY') + if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY') + guest266.no_active_tasks(raw.get('tasks'),vmid) + argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now) + keep=('vmid','type','node','status','template','config_sha256','disks','configured_disk_bytes','configured_archive_bound_bytes','archive_cap_bytes','global_defaults_sha256','blockers','coverage_eligible') + out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}} + sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\n') + return 0 + +if __name__=='__main__': + raise SystemExit(main()) +=== SOURCE_CLASSIFICATION === +SOURCE_HELPER_EXACT_COUNT=1 +SOURCE_LXC_EXACT_COUNT=1 +SOURCE_ENTRY_EXACT_COUNT=1 +SOURCE_PVE265_EXACT_COUNT=0 +SOURCE_AUTHORITY_READY=false +TASK_RESULT=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED +DECISION=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED +NEXT_GATE=READ_EXACT_1229_AND_BUILD_IMMUTABLE_NOTIFICATION_POLICY_COMPAT_HOTFIX +HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null} OUTPUT_END CHAT_OUTPUT_END