39 lines
14 KiB
JSON
39 lines
14 KiB
JSON
{
|
|
"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"
|
|
}
|