diff --git a/runtime/history/SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2.json b/runtime/history/SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2.json new file mode 100644 index 00000000..d0b6a401 --- /dev/null +++ b/runtime/history/SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2", + "status": "FAIL", + "rc": 3, + "host": "pve01", + "mode": "read-only", + "component": "pvepro-russian-ux-audit-readonly", + "started_at_utc": "2026-09-20T02:09:09Z", + "finished_at_utc": "2026-09-20T02:09:11Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "edea3a480f0293b06af4de348d408a007909a4abd7a3320814eac0a4942fbfa9", + "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": 3, + "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": "28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645", + "sanitized_output_sha256": "28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "W2UX738_BEGIN=True\nCOMMAND_ID=SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2\nVM_SAFETY={\"production_snapshots\":[],\"production_status\":\"running\",\"staging_all_link_down\":true,\"staging_name\":\"pvepro-staging-v1\",\"staging_nic_count\":1,\"staging_snapshots\":[],\"staging_status\":\"stopped\"}\nAUDIT_ERROR_CLASS=JSONDecodeError\nAUDIT_ERROR_SHA256=2bcabb5902c8525177f7096f6aec8b3c3ef4b5effeba69146827d0f656fe02eb\nTASK_RESULT=PVEPRO_RUSSIAN_UX_AUDIT_FAILED\nNO_MUTATION=True\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"FAIL\",\"version\":1}\n" +} diff --git a/runtime/history/SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2.txt b/runtime/history/SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2.txt new file mode 100644 index 00000000..4afc0913 --- /dev/null +++ b/runtime/history/SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2.txt @@ -0,0 +1,40 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2 +STATUS=FAIL +RC=3 +HOST=pve01 +MODE=read-only +COMPONENT=pvepro-russian-ux-audit-readonly +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 +COMMAND_SHA256=edea3a480f0293b06af4de348d408a007909a4abd7a3320814eac0a4942fbfa9 +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=3 +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=28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645 +SANITIZED_OUTPUT_SHA256=28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645 +OUTPUT_BEGIN +W2UX738_BEGIN=True +COMMAND_ID=SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2 +VM_SAFETY={"production_snapshots":[],"production_status":"running","staging_all_link_down":true,"staging_name":"pvepro-staging-v1","staging_nic_count":1,"staging_snapshots":[],"staging_status":"stopped"} +AUDIT_ERROR_CLASS=JSONDecodeError +AUDIT_ERROR_SHA256=2bcabb5902c8525177f7096f6aec8b3c3ef4b5effeba69146827d0f656fe02eb +TASK_RESULT=PVEPRO_RUSSIAN_UX_AUDIT_FAILED +NO_MUTATION=True +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2","rollback_restored":null,"rollback_started":false,"status":"FAIL","version":1} + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index e74c15b8..d0b6a401 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,19 +1,19 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "NEWFI-260920-NEWFDOM-MESSENGERS214-PRODUCER207", - "status": "OK", - "rc": 0, + "command_id": "SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2", + "status": "FAIL", + "rc": 3, "host": "pve01", "mode": "read-only", - "component": "newfi-newfdom-messengers214-backupv2-producer-contract-readonly-audit", - "started_at_utc": "2026-09-20T02:01:22Z", - "finished_at_utc": "2026-09-20T02:01:22Z", + "component": "pvepro-russian-ux-audit-readonly", + "started_at_utc": "2026-09-20T02:09:09Z", + "finished_at_utc": "2026-09-20T02:09:11Z", "reference_register_checked": true, "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", "error_register_checked": true, "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", - "command_sha256": "ead8fdf05c4cb0a9b8b49f67777a3e68a7a96170d3e4b5061fa03171a66917da", + "command_sha256": "edea3a480f0293b06af4de348d408a007909a4abd7a3320814eac0a4942fbfa9", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, @@ -21,7 +21,7 @@ "result_contract_valid": true, "result_contract_status": null, "result_contract_error": null, - "command_rc": 0, + "command_rc": 3, "changes_made": false, "rollback_started": false, "rollback_restored": null, @@ -30,9 +30,9 @@ "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "99d8dcf2767bb4aeb57e414153ec37f086162257482529c3dcce3939c780c5ec", - "sanitized_output_sha256": "99d8dcf2767bb4aeb57e414153ec37f086162257482529c3dcce3939c780c5ec", + "raw_evidence_sha256": "28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645", + "sanitized_output_sha256": "28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "NEWFI207_BEGIN=true\nMODE=read-only\nIMMUTABLE_PLAN_CHECK=PASS\nCHANGES_MADE=false\nMUTATION_OUTCOME=NO_MUTATION\nPIN_CHECK=PASS\nACCEPTED_RELEASE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b\nRELEASE_FILE_COUNT=6\nINTERESTING_FILE_COUNT=6\nFILE_1_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nFILE_1_BYTES=10566\nFILE_1_MODE=0o400\nFILE_1_SHA256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793\nFILE_1_KEYWORD_SCORE=13\nFILE_1_AST_DEF_COUNT=0\nFILE_1_AST_IMPORT_COUNT=0\nFILE_1_AST_STRING_COUNT=7\nFILE_1_STRING_1_LINE=4\nFILE_1_STRING_1_VALUE=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1\nFILE_1_STRING_2_LINE=62\nFILE_1_STRING_2_VALUE=backup_target\nFILE_1_STRING_3_LINE=62\nFILE_1_STRING_3_VALUE=ssh_remote\nFILE_1_STRING_4_LINE=135\nFILE_1_STRING_4_VALUE=payload_sha256\nFILE_1_STRING_5_LINE=135\nFILE_1_STRING_5_VALUE=manifest_sha256\nFILE_1_STRING_6_LINE=135\nFILE_1_STRING_6_VALUE=replicas\nFILE_1_STRING_7_LINE=132\nFILE_1_STRING_7_VALUE=homelab-scheduler-proof-\nFILE_2_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nFILE_2_BYTES=13825\nFILE_2_MODE=0o400\nFILE_2_SHA256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\nFILE_2_KEYWORD_SCORE=9\nFILE_2_AST_DEF_COUNT=2\nFILE_2_DEF_1_LINE=35\nFILE_2_DEF_1_NAME=_remote_sha\nFILE_2_DEF_2_LINE=117\nFILE_2_DEF_2_NAME=_execute_remote\nFILE_2_AST_IMPORT_COUNT=0\nFILE_2_AST_STRING_COUNT=17\nFILE_2_STRING_1_LINE=79\nFILE_2_STRING_1_VALUE=/var/tmp/homelab-vzdump-v2-plan-only\nFILE_2_STRING_2_LINE=118\nFILE_2_STRING_2_VALUE=REMOTE_NODE\nFILE_2_STRING_3_LINE=119\nFILE_2_STRING_3_VALUE=REMOTE_ARGV\nFILE_2_STRING_4_LINE=120\nFILE_2_STRING_4_VALUE=REMOTE_ARGV_NODE\nFILE_2_STRING_5_LINE=121\nFILE_2_STRING_5_VALUE=REMOTE_CAP_VALUE\nFILE_2_STRING_6_LINE=124\nFILE_2_STRING_6_VALUE=REMOTE_WORKDIR\nFILE_2_STRING_7_LINE=158\nFILE_2_STRING_7_VALUE=remote-bounded-ssh-cwd-root\nFILE_2_STRING_8_LINE=198\nFILE_2_STRING_8_VALUE=/var/tmp/homelab-vzdump-v2-\nFILE_2_STRING_9_LINE=149\nFILE_2_STRING_9_VALUE=REMOTE_TIMEOUT\nFILE_2_STRING_10_LINE=151\nFILE_2_STRING_10_VALUE=REMOTE_RC\nFILE_2_STRING_11_LINE=152\nFILE_2_STRING_11_VALUE=REMOTE_EMPTY\nFILE_2_STRING_12_LINE=155\nFILE_2_STRING_12_VALUE=REMOTE_FILE_IDENTITY\nFILE_2_STRING_13_LINE=162\nFILE_2_STRING_13_VALUE=remote-bounded-ssh-cwd-root\nFILE_2_STRING_14_LINE=204\nFILE_2_STRING_14_VALUE=payload.bin\nFILE_2_STRING_15_LINE=210\nFILE_2_STRING_15_VALUE=VZDUMP_PAYLOAD_BOUND\nFILE_2_STRING_16_LINE=138\nFILE_2_STRING_16_VALUE=REMOTE_TIMEOUT\nFILE_2_STRING_17_LINE=143\nFILE_2_STRING_17_VALUE=REMOTE_CAP\nFILE_3_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\nFILE_3_BYTES=4627\nFILE_3_MODE=0o400\nFILE_3_SHA256=1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b\nFILE_3_KEYWORD_SCORE=9\nFILE_3_AST_DEF_COUNT=1\nFILE_3_DEF_1_LINE=11\nFILE_3_DEF_1_NAME=_remote_sha\nFILE_3_AST_IMPORT_COUNT=0\nFILE_3_AST_STRING_COUNT=3\nFILE_3_STRING_1_LINE=48\nFILE_3_STRING_1_VALUE=/var/tmp/homelab-vzdump-v2-\nFILE_3_STRING_2_LINE=66\nFILE_3_STRING_2_VALUE=payload.bin\nFILE_3_STRING_3_LINE=70\nFILE_3_STRING_3_VALUE=QEMU_PAYLOAD_MISSING\nFILE_4_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\nFILE_4_BYTES=4097\nFILE_4_MODE=0o400\nFILE_4_SHA256=a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96\nFILE_4_KEYWORD_SCORE=9\nFILE_4_AST_DEF_COUNT=0\nFILE_4_AST_IMPORT_COUNT=0\nFILE_4_AST_STRING_COUNT=9\nFILE_4_STRING_1_LINE=44\nFILE_4_STRING_1_VALUE=last_success_payload_sha256\nFILE_4_STRING_2_LINE=45\nFILE_4_STRING_2_VALUE=last_success_manifest_sha256\nFILE_4_STRING_3_LINE=45\nFILE_4_STRING_3_VALUE=last_success_replicas\nFILE_4_STRING_4_LINE=37\nFILE_4_STRING_4_VALUE=payload_sha256\nFILE_4_STRING_5_LINE=37\nFILE_4_STRING_5_VALUE=last_success_payload_sha256\nFILE_4_STRING_6_LINE=38\nFILE_4_STRING_6_VALUE=manifest_sha256\nFILE_4_STRING_7_LINE=38\nFILE_4_STRING_7_VALUE=last_success_manifest_sha256\nFILE_4_STRING_8_LINE=38\nFILE_4_STRING_8_VALUE=replicas\nFILE_4_STRING_9_LINE=38\nFILE_4_STRING_9_VALUE=last_success_replicas\nFILE_5_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\nFILE_5_BYTES=3449\nFILE_5_MODE=0o400\nFILE_5_SHA256=b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3\nFILE_5_KEYWORD_SCORE=7\nFILE_5_AST_DEF_COUNT=0\nFILE_5_AST_IMPORT_COUNT=0\nFILE_5_AST_STRING_COUNT=2\nFILE_5_STRING_1_LINE=4\nFILE_5_STRING_1_VALUE=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411\nFILE_5_STRING_2_LINE=45\nFILE_5_STRING_2_VALUE=payload.bin\nFILE_6_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\nFILE_6_BYTES=2320\nFILE_6_MODE=0o400\nFILE_6_SHA256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\nFILE_6_KEYWORD_SCORE=3\nFILE_6_AST_DEF_COUNT=0\nFILE_6_AST_IMPORT_COUNT=0\nFILE_6_AST_STRING_COUNT=1\nFILE_6_STRING_1_LINE=4\nFILE_6_STRING_1_VALUE=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1\nCTX_1_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nCTX_1_START_LINE=15\nCTX_1_END_LINE=21\nCTX_1_L15=}\nCTX_1_L16=\nCTX_1_L17=def _sha(p):\nCTX_1_L18= h=hashlib.sha256()\nCTX_1_L19= with open(p,'rb',buffering=0) as f:\nCTX_1_L20= while True:\nCTX_1_L21= b=f.read(1<<20)\nCTX_2_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nCTX_2_START_LINE=34\nCTX_2_END_LINE=40\nCTX_2_L34=\nCTX_2_L35=class _GlobalsProxy:\nCTX_2_L36= __slots__=('_g',)\nCTX_2_L37= def __init__(self,g): object.__setattr__(self,'_g',g)\nCTX_2_L38= def __getattr__(self,n):\nCTX_2_L39= try: return self._g[n]\nCTX_2_L40= except KeyError as e: raise AttributeError(n) from e\nCTX_3_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nCTX_3_START_LINE=59\nCTX_3_END_LINE=72\nCTX_3_L59= if len(found)!=1:\nCTX_3_L60= raise RuntimeError('LEGACY_PROVENANCE_CARDINALITY')\nCTX_3_L61= g=next(iter(found.values()))\nCTX_3_L62= required=('capture_pve_guest','backup_target','load_targets','cluster_inventory','ssh_remote',\nCTX_3_L63= '_default_unprivileged_lxc','mapped_scratch_probe','_stream_argv_to_local','run',\nCTX_3_L64= 'choose_due_target','write_state','epoch')\nCTX_3_L65= if any(not callable(g.get(n)) for n in required):\nCTX_3_L66= raise RuntimeError('LEGACY_PROVENANCE_API')\nCTX_3_L67= original=g['capture_pve_guest']\nCTX_3_L68= proxy=_GlobalsProxy(g)\nCTX_3_L69= if not isinstance(g.get('SCP'),str) or not g['SCP'].startswith('/'):\nCTX_3_L70= raise RuntimeError('LEGACY_SCP_API')\nCTX_3_L71= qemu_patched=qemu_adapter.bind(proxy,original)\nCTX_3_L72= if not callable(qemu_patched):\nCTX_4_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nCTX_4_START_LINE=75\nCTX_4_END_LINE=82\nCTX_4_L75= if not callable(patched):\nCTX_4_L76= raise RuntimeError('LXC_ADAPTER_BIND_RESULT')\nCTX_4_L77= g['capture_pve_guest']=patched\nCTX_4_L78= scheduler_wired=scheduler_adapter.bind(proxy,g['choose_due_target'],g['write_state'])\nCTX_4_L79= if g.get('choose_due_target') is not scheduler_wired['choose_due_target'] or g.get('write_state') is not scheduler_wired['write_state']:\nCTX_4_L80= raise RuntimeError('SCHEDULER_ADAPTER_BIND_RESULT')\nCTX_4_L81= return {'legacy_globals':g,'legacy':proxy,'original_capture':original,'qemu_patched_capture':qemu_patched,'patched_capture':patched,'scheduler_wired':scheduler_wired}\nCTX_4_L82=\nCTX_5_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nCTX_5_START_LINE=96\nCTX_5_END_LINE=117\nCTX_5_L96= wired=_wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,BASE)\nCTX_5_L97= return wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired\nCTX_5_L98=\nCTX_5_L99=def _target(wrapper,lid):\nCTX_5_L100= rows=wrapper.load_targets(); hits=[x for x in rows if x.get('logical_id')==lid]\nCTX_5_L101= if len(hits)!=1: raise RuntimeError('TARGET_CARDINALITY')\nCTX_5_L102= return hits[0]\nCTX_5_L103=\nCTX_5_L104=def selftest():\nCTX_5_L105= wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired=_load()\nCTX_5_L106= if wired['legacy_globals'].get('capture_pve_guest') is not wired['patched_capture']:\nCTX_5_L107= raise RuntimeError('PATCH_BINDING')\nCTX_5_L108= if wired['legacy_globals'].get('choose_due_target') is not wired['scheduler_wired']['choose_due_target']:\nCTX_5_L109= raise RuntimeError('SCHEDULER_CHOOSE_BINDING')\nCTX_5_L110= if wired['legacy_globals'].get('write_state') is not wired['scheduler_wired']['write_state']:\nCTX_5_L111= raise RuntimeError('SCHEDULER_WRITE_BINDING')\nCTX_5_L112= if [scheduler_adapter.backoff_seconds(n) for n in range(1,7)]!=[1800,3600,7200,14400,21600,21600]:\nCTX_5_L113= raise RuntimeError('SCHEDULER_BACKOFF_CONTRACT')\nCTX_5_L114= if not callable(wrapper.backup_target) or not callable(wrapper.main) or not callable(wrapper.load_targets):\nCTX_5_L115= raise RuntimeError('WRAPPER_PUBLIC_API')\nCTX_5_L116= print('SELFTEST_OVERLAY504=PASS',flush=True)\nCTX_5_L117= return 0\nCTX_6_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\nCTX_6_START_LINE=125\nCTX_6_END_LINE=187\nCTX_6_L125= if argv==['scheduler-proof']:\nCTX_6_L126= import tempfile\nCTX_6_L127= legacy=wired['legacy']; g=wired['legacy_globals']\nCTX_6_L128= old_root=g.get('STATE_ROOT'); old_epoch=g.get('epoch')\nCTX_6_L129= if old_root is None or not callable(old_epoch): raise RuntimeError('SCHEDULER_PROOF_BASE')\nCTX_6_L130= now=[1000]\nCTX_6_L131= try:\nCTX_6_L132= with tempfile.TemporaryDirectory(prefix='homelab-scheduler-proof-',dir='/run') as td:\nCTX_6_L133= g['STATE_ROOT']=pathlib.Path(td); (g['STATE_ROOT']/'state').mkdir(mode=0o700)\nCTX_6_L134= g['epoch']=lambda: now[0]\nCTX_6_L135= common={'payload_sha256':'a'*64,'manifest_sha256':'b'*64,'replicas':['proof-r1','proof-r2']}\nCTX_6_L136= legacy.write_state('proof-a','SUCCESS',generation='proof-a-good',**common)\nCTX_6_L137= legacy.write_state('proof-b','SUCCESS',generation='proof-b-good',**common)\nCTX_6_L138= now[0]=100000\nCTX_6_L139= legacy.write_state('proof-a','FAIL',generation='proof-a-bad',reason='PROOF_FAILURE',sealed=False)\nCTX_6_L140= state=legacy.load_state_all(); a=state['proof-a']\nCTX_6_L141= targets=[{'logical_id':'proof-a','enabled':True,'due_seconds':100},{'logical_id':'proof-b','enabled':True,'due_seconds':100}]\nCTX_6_L142= first=legacy.choose_due_target(targets,state,now[0])\nCTX_6_L143= if not isinstance(first,dict) or first.get('logical_id')!='proof-b': raise RuntimeError('SCHEDULER_PROOF_PEER_NOT_SELECTED')\nCTX_6_L144= retry=int(a.get('retry_after_epoch',0)); preserved=int(a.get('last_success_epoch',0))\nCTX_6_L145= if preserved!=1000 or a.get('last_success_generation')!='proof-a-good' or int(a.get('consecutive_failures',0))!=1 or retry!=101800:\nCTX_6_L146= raise RuntimeError('SCHEDULER_PROOF_FAILURE_STATE')\nCTX_6_L147= now[0]=retry+1\nCTX_6_L148= second=legacy.choose_due_target(targets,legacy.load_state_all(),now[0])\nCTX_6_L149= if not isinstance(second,dict) or second.get('logical_id')!='proof-a': raise RuntimeError('SCHEDULER_PROOF_RETRY_NOT_REELIGIBLE')\nCTX_6_L150= legacy.write_state('proof-a','SUCCESS',generation='proof-a-recovered',**common)\nCTX_6_L151= recovered=legacy.load_state_all()['proof-a']\nCTX_6_L152= if int(recovered.get('consecutive_failures',-1))!=0 or int(recovered.get('retry_after_epoch',-1))!=0:\nCTX_6_L153= raise RuntimeError('SCHEDULER_PROOF_SUCCESS_RESET')\nCTX_6_L154= proof={'failed_target':'proof-a','peer_selected_during_backoff':first['logical_id'],'retry_after_epoch':retry,'last_success_preserved':preserved==1000,'retry_target_after_backoff':second['logical_id'],'success_resets_failures':True,'production_state_root_used':False}\nCTX_6_L155= print('SCHEDULER_FAILURE_ISOLATION_PROOF='+json.dumps(proof,separators=(',',':'),sort_keys=True),flush=True)\nCTX_6_L156= return 0\nCTX_6_L157= finally:\nCTX_6_L158= g['STATE_ROOT']=old_root; g['epoch']=old_epoch\nCTX_6_L159= if argv==['scheduler-select-live']:\nCTX_6_L160= state=legacy.load_state_all(); targets=wrapper.load_targets()\nCTX_6_L161= chosen=legacy.choose_due_target(targets,state)\nCTX_6_L162= if chosen is None:\nCTX_6_L163= print('SCHEDULER_LIVE_SELECTION=DEFER_NO_DUE_TARGET',flush=True)\nCTX_6_L164= else:\nCTX_6_L165= print('SCHEDULER_LIVE_SELECTION='+json.dumps({'logical_id':chosen.get('logical_id'),'due_seconds':chosen.get('due_seconds'),'enabled':chosen.get('enabled') is True},separators=(',',':'),sort_keys=True),flush=True)\nCTX_6_L166= return 0\nCTX_6_L167= if len(argv)==2 and argv[0]=='plan-lxc':\nCTX_6_L168= t=_target(wrapper,argv[1])\nCTX_6_L169= if t.get('guest_type')!='lxc' or t.get('logical_id')=='guest-pve01-lxc-112':\nCTX_6_L170= raise RuntimeError('PLAN_TARGET_NOT_LEGACY_LXC')\nCTX_6_L171= out=lxc_adapter.plan_only(legacy,t)\nCTX_6_L172= print('PLAN_LXC_RESULT='+json.dumps({'logical_id':t['logical_id'],'vmid':int(t['vmid']),'node':out['job']['node'],'job':out['job']},separators=(',',':'),sort_keys=True),flush=True)\nCTX_6_L173= return 0\nCTX_6_L174= if len(argv)==2 and argv[0]=='verify-target':\nCTX_6_L175= t=_target(wrapper,argv[1])\nCTX_6_L176= if t.get('logical_id')=='guest-pve01-lxc-112':\nCTX_6_L177= raise RuntimeError('VERIFY_SYNTHETIC_CT112_FORBIDDEN')\nCTX_6_L178= try:\nCTX_6_L179= out=wrapper.backup_target(t,True)\nCTX_6_L180= except legacy.BackupError as e:\nCTX_6_L181= print('VERIFY_TARGET_RESULT=FAIL',flush=True)\nCTX_6_L182= print('VERIFY_TARGET_REASON='+str(e.code),flush=True)\nCTX_6_L183= return 2\nCTX_6_L184= print('VERIFY_TARGET_RESULT='+json.dumps(out,separators=(',',':'),sort_keys=True),flush=True)\nCTX_6_L185= return 0\nCTX_6_L186= return wrapper.main([sys.argv[0],*argv])\nCTX_6_L187=\nCTX_7_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_7_START_LINE=20\nCTX_7_END_LINE=26\nCTX_7_L20= except Exception as e: raise AdapterError(code) from e\nCTX_7_L21=\nCTX_7_L22=def _sha_file(p):\nCTX_7_L23= h=hashlib.sha256()\nCTX_7_L24= with open(p,'rb',buffering=0) as f:\nCTX_7_L25= for b in iter(lambda:f.read(1<<20),b''): h.update(b)\nCTX_7_L26= return h.hexdigest()\nCTX_8_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_8_START_LINE=32\nCTX_8_END_LINE=62\nCTX_8_L32= if n<=0: raise AdapterError('WRITE_FAILED')\nCTX_8_L33= view=view[n:]\nCTX_8_L34=\nCTX_8_L35=def _remote_sha(legacy,node,path):\nCTX_8_L36= p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30)\nCTX_8_L37= parts=p.stdout.decode('ascii','strict').strip().split()\nCTX_8_L38= _need(len(parts)>=2 and parts[1]==path,'TOOL_SHA_OUTPUT')\nCTX_8_L39= return parts[0]\nCTX_8_L40=\nCTX_8_L41=def _live_inputs(legacy,node,vmid,scratch):\nCTX_8_L42= _need(_remote_sha(legacy,node,'/usr/bin/pvesh')==PVESH_SHA,'PVESH_IDENTITY')\nCTX_8_L43= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY')\nCTX_8_L44= rows=_j(legacy.ssh_remote(node,['pvesh','get','/cluster/resources','--type','vm','--output-format','json'],timeout=60),'RESOURCES_JSON')\nCTX_8_L45= stores=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/storage','--output-format','json'],timeout=60),'STORAGE_JSON')\nCTX_8_L46= _need(type(rows) is list and type(stores) is list,'PVE_LIST_SCHEMA')\nCTX_8_L47= configs=[]\nCTX_8_L48= for r in rows:\nCTX_8_L49= if not isinstance(r,dict) or r.get('node')!=node or r.get('type') not in ('lxc','qemu'): continue\nCTX_8_L50= try: rid=int(r.get('vmid'))\nCTX_8_L51= except Exception: raise AdapterError('RESOURCE_VMID')\nCTX_8_L52= cfg=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/{r[\"type\"]}/{rid}/config','--output-format','json'],timeout=60),'CONFIG_JSON')\nCTX_8_L53= _need(type(cfg) is dict,'CONFIG_SCHEMA')\nCTX_8_L54= configs.append([rid,cfg])\nCTX_8_L55= tasks=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/tasks','--limit','999','--output-format','json'],timeout=60),'TASKS_JSON')\nCTX_8_L56= _need(type(tasks) is list and len(tasks)<1000,'TASKS_SCHEMA')\nCTX_8_L57= q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False)\nCTX_8_L58= defaults=None\nCTX_8_L59= if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout\nCTX_8_L60= elif q.returncode!=1: raise AdapterError('DEFAULTS_PROBE')\nCTX_8_L61= st=os.statvfs('/mnt/staging'); free=int(st.f_bavail*st.f_frsize)\nCTX_8_L62= return {'node':node,'vmid':vmid,'scratch':scratch,'now':int(time.time()),'rows':rows,'storage_rows':stores,'configs':configs,\nCTX_9_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_9_START_LINE=85\nCTX_9_END_LINE=91\nCTX_9_L85= a=_helper(_live_inputs(legacy,node,vmid,scratch)); b=_helper(_live_inputs(legacy,node,vmid,scratch))\nCTX_9_L86= _need(_stable_job(a['job'])==_stable_job(b['job']),'FRESH_PLAN_UNSTABLE')\nCTX_9_L87= _need(a['argv']==b['argv'],'FRESH_ARGV_UNSTABLE')\nCTX_9_L88= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_POST')\nCTX_9_L89= return b\nCTX_9_L90=\nCTX_9_L91=def _execute_local(legacy,node,argv,dest,cap,timeout):\nCTX_10_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_10_START_LINE=94\nCTX_10_END_LINE=109\nCTX_10_L94= data=json.dumps(inp,separators=(',',':'),sort_keys=True).encode()\nCTX_10_L95= p=subprocess.run(['/usr/bin/python3','-I','-B',str(EXEC_HELPER)],input=data,capture_output=True,timeout=timeout+120,cwd='/',env=ENV)\nCTX_10_L96= if p.stderr or not p.stdout or len(p.stdout)>262144:\nCTX_10_L97= raise ExecFailure('LOCAL_HELPER_PROTOCOL',{'executor':'local-proven-pve270','producer_rc':None,'stderr_stream_sha256':hashlib.sha256(p.stderr).hexdigest(),'stderr_bytes_observed':len(p.stderr)})\nCTX_10_L98= try: out=json.loads(p.stdout)\nCTX_10_L99= except Exception:\nCTX_10_L100= raise ExecFailure('LOCAL_HELPER_JSON',{'executor':'local-proven-pve270','producer_rc':None,'stderr_stream_sha256':hashlib.sha256(p.stderr).hexdigest(),'stderr_bytes_observed':len(p.stderr)})\nCTX_10_L101= summary={'executor':'local-proven-pve270','helper_rc':p.returncode,'exception_class':out.get('exception_class'),'exception_message_sha256':out.get('exception_message_sha256')}\nCTX_10_L102= if isinstance(out.get('process'),dict): summary.update(out['process'])\nCTX_10_L103= if p.returncode!=0 or out.get('status')!='OK': raise ExecFailure('LOCAL_PRODUCER_FAILED',summary)\nCTX_10_L104= result=out.get('result'); _need(type(result) is dict,'LOCAL_RESULT_SCHEMA')\nCTX_10_L105= _need(pathlib.Path(dest).is_file() and pathlib.Path(dest).stat().st_size==int(result.get('size',-1)),'LOCAL_RESULT_FILE')\nCTX_10_L106= return summary|{'size':result['size'],'sha256':result['sha256'],'producer_rc':result.get('producer_rc')}\nCTX_10_L107=\nCTX_10_L108=def _kill(p):\nCTX_10_L109= try: os.killpg(p.pid,signal.SIGTERM)\nCTX_11_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_11_START_LINE=114\nCTX_11_END_LINE=166\nCTX_11_L114= except ProcessLookupError: pass\nCTX_11_L115= p.wait()\nCTX_11_L116=\nCTX_11_L117=def _execute_remote(legacy,node,argv,dest,cap,timeout):\nCTX_11_L118= _need(re.fullmatch(r'pve0[123]',str(node)) is not None and node!='pve01','REMOTE_NODE')\nCTX_11_L119= _need(type(argv) is list and argv and argv[0]=='/usr/bin/vzdump' and all(type(x) is str and '\\x00' not in x for x in argv),'REMOTE_ARGV')\nCTX_11_L120= _need('--node' in argv and argv[argv.index('--node')+1]==node,'REMOTE_ARGV_NODE')\nCTX_11_L121= _need(type(cap) is int and 0=deadline: raise ExecFailure('REMOTE_TIMEOUT',{})\nCTX_11_L139= for key,_ in sel.select(min(.2,max(0,deadline-now))):\nCTX_11_L140= b=os.read(key.fileobj.fileno(),65536)\nCTX_11_L141= if not b: sel.unregister(key.fileobj); continue\nCTX_11_L142= if key.fileobj is p.stdout:\nCTX_11_L143= if total+len(b)>cap: raise ExecFailure('REMOTE_CAP',{})\nCTX_11_L144= _write_all(fd,b); digest.update(b); total+=len(b)\nCTX_11_L145= else:\nCTX_11_L146= err_total+=len(b); eh.update(b); keep=b[:max(0,MAX_STDERR-err_kept)]\nCTX_11_L147= if keep: _write_all(efd,keep); err_kept+=len(keep)\nCTX_11_L148= left=deadline-time.monotonic()\nCTX_11_L149= if left<=0: raise ExecFailure('REMOTE_TIMEOUT',{})\nCTX_11_L150= rc=p.wait(timeout=left)\nCTX_11_L151= if rc!=0: raise ExecFailure('REMOTE_RC',{})\nCTX_11_L152= if total<=0: raise ExecFailure('REMOTE_EMPTY',{})\nCTX_11_L153= stf=os.fstat(fd); named=os.stat(dest,follow_symlinks=False)\nCTX_11_L154= if (stf.st_dev,stf.st_ino)!=(initial.st_dev,initial.st_ino) or (named.st_dev,named.st_ino)!=(initial.st_dev,initial.st_ino) or stf.st_nlink!=1 or stf.st_size!=total:\nCTX_11_L155= raise ExecFailure('REMOTE_FILE_IDENTITY',{})\nCTX_11_L156= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_POST')\nCTX_11_L157= os.fchmod(fd,0o400); os.fsync(fd); os.fsync(efd); good=True\nCTX_11_L158= return {'executor':'remote-bounded-ssh-cwd-root','producer_rc':rc,'size':total,'sha256':digest.hexdigest(),\nCTX_11_L159= 'stderr_bytes_observed':err_total,'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,'stderr_stream_sha256':eh.hexdigest()}\nCTX_11_L160= except ExecFailure as e:\nCTX_11_L161= if p is not None and p.poll() is None: _kill(p)\nCTX_11_L162= summary={'executor':'remote-bounded-ssh-cwd-root','producer_rc':None if p is None else p.returncode,'archive_bytes':total,\nCTX_11_L163= 'stderr_bytes_observed':err_total,'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,'stderr_stream_sha256':eh.hexdigest()}\nCTX_11_L164= summary.update(e.summary); raise ExecFailure(e.code,summary)\nCTX_11_L165= finally:\nCTX_11_L166= if p is not None:\nCTX_12_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_12_START_LINE=171\nCTX_12_END_LINE=178\nCTX_12_L171= try: os.fsync(fd); os.fsync(efd)\nCTX_12_L172= except OSError: pass\nCTX_12_L173= os.close(fd); os.close(efd)\nCTX_12_L174= summary={'process_started':p is not None,'producer_rc':None if p is None else p.returncode,'capture_success':good,'archive_bytes':total,\nCTX_12_L175= 'stderr_bytes_observed':err_total,'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,'stderr_stream_sha256':eh.hexdigest(),'raw_stderr_exported':False,'cwd':'/'}\nCTX_12_L176= try:\nCTX_12_L177= mb=(json.dumps(summary,separators=(',',':'),sort_keys=True)+'\\n').encode()\nCTX_12_L178= mfd=os.open(metap,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)\nCTX_13_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_13_START_LINE=182\nCTX_13_END_LINE=188\nCTX_13_L182=\nCTX_13_L183=def _emit_diag(node,summary):\nCTX_13_L184= safe={'node':node}\nCTX_13_L185= for k in ('executor','failure_code','helper_rc','producer_rc','archive_bytes','stderr_bytes_observed','stderr_bytes_retained','stderr_truncated','stderr_stream_sha256','exception_class','exception_message_sha256'):\nCTX_13_L186= if k in summary: safe[k]=summary[k]\nCTX_13_L187= print('LXC_EXECUTION_DIAG='+json.dumps(safe,separators=(',',':'),sort_keys=True),flush=True)\nCTX_13_L188=\nCTX_14_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nCTX_14_START_LINE=196\nCTX_14_END_LINE=218\nCTX_14_L196= _need(typ==t.get('guest_type')=='lxc','PVE_GUEST_TYPE_DRIFT')\nCTX_14_L197= legacy._default_unprivileged_lxc(node,vmid)\nCTX_14_L198= scratch=f'/var/tmp/homelab-vzdump-v2-{gen}'\nCTX_14_L199= legacy.ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30)\nCTX_14_L200= q=legacy.ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30)\nCTX_14_L201= _need(q.stdout.decode().strip()=='710:0:100000','PVE_MAPPED_SCRATCH_ACCESS_CONTRACT')\nCTX_14_L202= try:\nCTX_14_L203= legacy.mapped_scratch_probe(node,scratch)\nCTX_14_L204= p=plan_only(legacy,t,scratch); local=pathlib.Path(work)/'payload.bin'; cap=int(p['job']['archive_cap_bytes'])\nCTX_14_L205= try:\nCTX_14_L206= result=_execute_local(legacy,node,p['argv'],local,cap,7200) if node=='pve01' else _execute_remote(legacy,node,p['argv'],local,cap,7200)\nCTX_14_L207= except ExecFailure as e:\nCTX_14_L208= _emit_diag(node,e.summary|{'failure_code':e.code})\nCTX_14_L209= raise legacy.BackupError('LXC_PRODUCER_FAILED') from None\nCTX_14_L210= _need(local.is_file() and 0=2 and parts[1]==path,'QEMU_TOOL_SHA_OUTPUT')\nCTX_15_L15= return parts[0]\nCTX_15_L16=\nCTX_15_L17=def _select_qemu_outputs(vmid,files):\nCTX_15_L18= _need(type(vmid) is int and vmid>0,'QEMU_VMID')\nCTX_15_L19= _need(type(files) is list and files and all(type(x) is str and x.startswith('/') and '\\x00' not in x for x in files),'QEMU_OUTPUT_LIST')\nCTX_15_L20= _need(len(files)==len(set(files)),'QEMU_OUTPUT_DUPLICATE')\nCTX_15_L21= pat=re.compile(r'^vzdump-qemu-'+re.escape(str(vmid))+r'-(\\d{4}_\\d{2}_\\d{2}-\\d{2}_\\d{2}_\\d{2})\\.vma\\.zst$')\nCTX_15_L22= archives=[]\nCTX_15_L23= for f in files:\nCTX_15_L24= name=pathlib.PurePosixPath(f).name\nCTX_15_L25= m=pat.fullmatch(name)\nCTX_15_L26= if m: archives.append((f,m.group(1)))\nCTX_15_L27= _need(len(archives)==1,'QEMU_ARCHIVE_NOT_UNIQUE')\nCTX_15_L28= archive,stamp=archives[0]; parent=pathlib.PurePosixPath(archive).parent\nCTX_15_L29= expected_log=parent/f'vzdump-qemu-{vmid}-{stamp}.log'\nCTX_15_L30= allowed={archive}; log=None\nCTX_15_L31= if str(expected_log) in files:\nCTX_15_L32= log=str(expected_log); allowed.add(log)\nCTX_15_L33= _need(set(files)==allowed,'QEMU_OUTPUT_UNEXPECTED_FILE')\nCTX_15_L34= return archive,log\nCTX_15_L35=\nCTX_15_L36=def _emit_diag(**kw):\nCTX_15_L37= print('QEMU_EXECUTION_DIAG='+json.dumps(kw,separators=(',',':'),sort_keys=True),flush=True)\nCTX_16_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\nCTX_16_START_LINE=44\nCTX_16_END_LINE=78\nCTX_16_L44= _need(len(rows)==1,'PVE_GUEST_NOT_UNIQUE')\nCTX_16_L45= row=rows[0]; node=row.get('node'); typ=row.get('type')\nCTX_16_L46= _need(typ==t.get('guest_type')=='qemu','PVE_GUEST_TYPE_DRIFT')\nCTX_16_L47= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_PRE')\nCTX_16_L48= srcdir=f'/var/tmp/homelab-vzdump-v2-{gen}'\nCTX_16_L49= legacy.ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30)\nCTX_16_L50= try:\nCTX_16_L51= vp=legacy.ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200,check=False)\nCTX_16_L52= if vp.returncode!=0:\nCTX_16_L53= _emit_diag(vmid=vmid,node=node,producer_rc=vp.returncode,stderr_bytes=len(vp.stderr),stderr_sha256=hashlib.sha256(vp.stderr).hexdigest(),archive_selected=False)\nCTX_16_L54= raise legacy.BackupError('QEMU_VZDUMP_FAILED')\nCTX_16_L55= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_POST')\nCTX_16_L56= p=legacy.ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\\n'],timeout=30)\nCTX_16_L57= files=[x for x in p.stdout.decode('utf-8','strict').splitlines() if x]\nCTX_16_L58= try: src,log=_select_qemu_outputs(vmid,files)\nCTX_16_L59= except QemuAdapterError as e:\nCTX_16_L60= _emit_diag(vmid=vmid,node=node,producer_rc=0,regular_file_count=len(files),archive_selected=False,selector_error=str(e))\nCTX_16_L61= raise legacy.BackupError(str(e)) from None\nCTX_16_L62= q=legacy.ssh_remote(node,['stat','-c','%s','--',src],timeout=30)\nCTX_16_L63= raw=q.stdout.decode('ascii','strict').strip()\nCTX_16_L64= _need(raw.isdigit() and int(raw)>0,'QEMU_ARCHIVE_STAT')\nCTX_16_L65= size=int(raw)\nCTX_16_L66= local=pathlib.Path(work)/'payload.bin'\nCTX_16_L67= if node=='pve01': local=pathlib.Path(src)\nCTX_16_L68= else:\nCTX_16_L69= legacy.run([legacy.SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200)\nCTX_16_L70= _need(pathlib.Path(local).is_file() and pathlib.Path(local).stat().st_size==size,'QEMU_PAYLOAD_MISSING')\nCTX_16_L71= _emit_diag(vmid=vmid,node=node,producer_rc=0,regular_file_count=len(files),sidecar_count=1 if log else 0,archive_bytes=size,archive_selected=True)\nCTX_16_L72= except Exception:\nCTX_16_L73= legacy.ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False); raise\nCTX_16_L74= cleanup={'kind':'pve_source_dir','node':node,'path':srcdir}\nCTX_16_L75= meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'qemu','node':node,'status':row.get('status'),\nCTX_16_L76= 'producer_contract':'strict-qemu-vma-zst-plus-matching-log-overlay503'}\nCTX_16_L77= return pathlib.Path(local),meta,cleanup\nCTX_16_L78= capture_pve_guest.__name__='capture_pve_guest'\nCTX_17_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\nCTX_17_START_LINE=20\nCTX_17_END_LINE=28\nCTX_17_L20= n=max(1,_as_nonneg_int(consecutive_failures,1))\nCTX_17_L21= return min(MAX_BACKOFF,MIN_BACKOFF*(2**min(n-1,4)))\nCTX_17_L22=\nCTX_17_L23=def _read_prior(legacy,logical_id):\nCTX_17_L24= root=pathlib.Path(legacy.STATE_ROOT)/'state'\nCTX_17_L25= p=root/(str(logical_id)+'.json')\nCTX_17_L26= try:\nCTX_17_L27= if not p.is_file(): return {}\nCTX_17_L28= d=json.loads(p.read_text(encoding='utf-8'))\nCTX_18_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\nCTX_18_START_LINE=34\nCTX_18_END_LINE=48\nCTX_18_L34= if not isinstance(prior,dict): return {}\nCTX_18_L35= if prior.get('result')=='SUCCESS':\nCTX_18_L36= out={'last_success_epoch':_as_nonneg_int(prior.get('last_success_epoch'),0)}\nCTX_18_L37= mapping=(('generation','last_success_generation'),('payload_sha256','last_success_payload_sha256'),\nCTX_18_L38= ('manifest_sha256','last_success_manifest_sha256'),('replicas','last_success_replicas'),\nCTX_18_L39= ('green_verified','last_success_green_verified'))\nCTX_18_L40= for src,dst in mapping:\nCTX_18_L41= if src in prior: out[dst]=prior[src]\nCTX_18_L42= return out\nCTX_18_L43= out={}\nCTX_18_L44= for k in ('last_success_epoch','last_success_generation','last_success_payload_sha256',\nCTX_18_L45= 'last_success_manifest_sha256','last_success_replicas','last_success_green_verified'):\nCTX_18_L46= if k in prior: out[k]=prior[k]\nCTX_18_L47= return out\nCTX_18_L48=\nCTX_19_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\nCTX_19_START_LINE=50\nCTX_19_END_LINE=65\nCTX_19_L50= _need(callable(original_choose),'ORIGINAL_CHOOSE_REQUIRED')\nCTX_19_L51= _need(callable(original_write),'ORIGINAL_WRITE_REQUIRED')\nCTX_19_L52= _need(callable(getattr(legacy,'epoch',None)),'LEGACY_EPOCH_REQUIRED')\nCTX_19_L53= _need(hasattr(legacy,'STATE_ROOT'),'LEGACY_STATE_ROOT_REQUIRED')\nCTX_19_L54=\nCTX_19_L55= def choose_due_target(targets,state,now=None):\nCTX_19_L56= now=_as_nonneg_int(legacy.epoch() if now is None else now,0)\nCTX_19_L57= _need(isinstance(targets,list) and isinstance(state,dict),'SCHEDULER_INPUT_SCHEMA')\nCTX_19_L58= due=[]\nCTX_19_L59= for order,t in enumerate(targets):\nCTX_19_L60= if not isinstance(t,dict) or t.get('enabled') is not True: continue\nCTX_19_L61= lid=t.get('logical_id'); seconds=_as_nonneg_int(t.get('due_seconds'),0)\nCTX_19_L62= _need(isinstance(lid,str) and lid and seconds>0,'SCHEDULER_TARGET_SCHEMA')\nCTX_19_L63= s=state.get(lid,{})\nCTX_19_L64= if not isinstance(s,dict): s={}\nCTX_19_L65= retry_after=_as_nonneg_int(s.get('retry_after_epoch'),0)\nCTX_20_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\nCTX_20_START_LINE=72\nCTX_20_END_LINE=93\nCTX_20_L72= if not due: return None\nCTX_20_L73= return max(due,key=lambda x:(x[0],x[1]))[2]\nCTX_20_L74=\nCTX_20_L75= def write_state(logical_id,result,**kw):\nCTX_20_L76= now=_as_nonneg_int(legacy.epoch(),0)\nCTX_20_L77= prior=_read_prior(legacy,logical_id)\nCTX_20_L78= if result=='SUCCESS':\nCTX_20_L79= clean=dict(kw)\nCTX_20_L80= clean.update({'last_attempt_epoch':now,'consecutive_failures':0,'retry_after_epoch':0,'failure_backoff_seconds':0})\nCTX_20_L81= return original_write(logical_id,result,**clean)\nCTX_20_L82= failures=_as_nonneg_int(prior.get('consecutive_failures'),0)+1\nCTX_20_L83= backoff=backoff_seconds(failures)\nCTX_20_L84= clean=dict(kw)\nCTX_20_L85= clean.update(_success_snapshot(prior))\nCTX_20_L86= clean.update({'last_attempt_epoch':now,'consecutive_failures':failures,\nCTX_20_L87= 'retry_after_epoch':now+backoff,'failure_backoff_seconds':backoff})\nCTX_20_L88= return original_write(logical_id,result,**clean)\nCTX_20_L89=\nCTX_20_L90= legacy.choose_due_target=choose_due_target\nCTX_20_L91= legacy.write_state=write_state\nCTX_20_L92= return {'choose_due_target':choose_due_target,'write_state':write_state,\nCTX_20_L93= 'original_choose':original_choose,'original_write':original_write}\nCTX_21_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\nCTX_21_START_LINE=7\nCTX_21_END_LINE=13\nCTX_21_L7=MAX_INPUT=262144\nCTX_21_L8=\nCTX_21_L9=def sha_file(p:pathlib.Path)->str:\nCTX_21_L10= h=hashlib.sha256()\nCTX_21_L11= with open(p,'rb',buffering=0) as f:\nCTX_21_L12= for b in iter(lambda:f.read(1<<20),b''): h.update(b)\nCTX_21_L13= return h.hexdigest()\nCTX_22_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\nCTX_22_START_LINE=20\nCTX_22_END_LINE=33\nCTX_22_L20= if not p.is_file() or p.is_symlink(): return None\nCTX_22_L21= try: d=json.loads(p.read_bytes())\nCTX_22_L22= except Exception: return {'summary_read':'FAILED'}\nCTX_22_L23= keys=('process_started','producer_rc','capture_success','archive_bytes','stderr_bytes_observed','stderr_bytes_retained','stderr_truncated','stderr_stream_sha256','raw_stderr_exported','child_umask')\nCTX_22_L24= return {k:d.get(k) for k in keys if k in d}\nCTX_22_L25=\nCTX_22_L26=def selftest()->int:\nCTX_22_L27= if sha_file(VZDUMP)!=VZDUMP_SHA: fail('VZDUMP_IDENTITY')\nCTX_22_L28= sys.path.insert(0,str(BASE))\nCTX_22_L29= import adapter\nCTX_22_L30= adapter.verify_sources(); adapter.load_graph()\nCTX_22_L31= print('PRODUCER_EXEC_HELPER_SELFTEST=PASS',flush=True)\nCTX_22_L32= return 0\nCTX_22_L33=\nCTX_23_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\nCTX_23_START_LINE=42\nCTX_23_END_LINE=66\nCTX_23_L42= argv=x['argv']; dest=pathlib.Path(x['dest']); cap=x['cap']; seconds=x['seconds']\nCTX_23_L43= if not (type(argv) is list and argv and all(type(v) is str and '\\x00' not in v for v in argv)): fail('ARGV')\nCTX_23_L44= if argv[0]!='/usr/bin/vzdump': fail('VZDUMP_PATH')\nCTX_23_L45= if not (dest.is_absolute() and dest.name=='payload.bin' and '..' not in dest.parts): fail('DEST')\nCTX_23_L46= if not (type(cap) is int and 0str:\nCTX_25_L9= return hashlib.sha256(p.read_bytes()).hexdigest()\nCTX_25_L10=\nCTX_25_L11=def fail(code:str):\nCTX_25_L12= raise RuntimeError(code)\nCTX_26_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\nCTX_26_START_LINE=17\nCTX_26_END_LINE=23\nCTX_26_L17= if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')\nCTX_26_L18= sys.path.insert(0,str(C411))\nCTX_26_L19= import adapter\nCTX_26_L20= adapter.verify_sources()\nCTX_26_L21= guest266,pve265,_pve270,_pve282=adapter.load_graph()\nCTX_26_L22= data=sys.stdin.buffer.read(4_000_001)\nCTX_26_L23= if not data or len(data)>4_000_000: fail('INPUT_BOUND')\nCTX_27_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\nCTX_27_START_LINE=36\nCTX_27_END_LINE=42\nCTX_27_L36= if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY')\nCTX_27_L37= guest266.no_active_tasks(raw.get('tasks'),vmid)\nCTX_27_L38= argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now)\nCTX_27_L39= 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')\nCTX_27_L40= out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}}\nCTX_27_L41= sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\\n')\nCTX_27_L42= return 0\nUSA_STATE_FULL_SAFE_BEGIN=true\nUSA_STATE_FIELD=$.consecutive_failures=0\nUSA_STATE_FIELD=$.failure_backoff_seconds=0\nUSA_STATE_FIELD=$.generation=v2-md-relay-20260919T070058Z-0e409ea129e2\nUSA_STATE_FIELD=$.green_verified=False\nUSA_STATE_FIELD=$.last_attempt_epoch=1789801278\nUSA_STATE_FIELD=$.last_success_epoch=1789801278\nUSA_STATE_FIELD=$.logical_id=md-relay\nUSA_STATE_FIELD=$.manifest_sha256=6887c5423640738aeb2bc1d104d515df1d1a21e2cd2d3291481475aa81cb6838\nUSA_STATE_FIELD=$.payload_sha256=187401a5fbf6c29b4dfd77e5d272db77951aa45003d0d80e0be834235571f32f\nUSA_STATE_FIELD=$.replicas[0].crypt=pve03-mail-04-crypt\nUSA_STATE_FIELD=$.replicas[0].physical=pve03-mail-04\nUSA_STATE_FIELD=$.replicas[1].crypt=pve03-mail-01-crypt\nUSA_STATE_FIELD=$.replicas[1].physical=pve03-mail-01\nUSA_STATE_FIELD=$.result=SUCCESS\nUSA_STATE_FIELD=$.retry_after_epoch=0\nUSA_STATE_FIELD=$.schema=1\nUSA_STATE_FIELD=$.updated_at_utc=2026-09-19T07:01:18Z\nUSA_STATE_FULL_SAFE_END=true\nMOLDOVA_STATE_FULL_SAFE_BEGIN=true\nMOLDOVA_STATE_FIELD=$.consecutive_failures=6\nMOLDOVA_STATE_FIELD=$.failure_backoff_seconds=21600\nMOLDOVA_STATE_FIELD=$.generation=v2-us-netbird-20260920T000652Z-7ecdcfcafc12\nMOLDOVA_STATE_FIELD=$.last_attempt_epoch=1789862827\nMOLDOVA_STATE_FIELD=$.last_success_epoch=1789704670\nMOLDOVA_STATE_FIELD=$.last_success_generation=v2-us-netbird-20260918T041032Z-d7648be4c16b\nMOLDOVA_STATE_FIELD=$.last_success_green_verified=False\nMOLDOVA_STATE_FIELD=$.last_success_manifest_sha256=f82c761cafe8aa43d90d0b4b6124933799b5087d34daf880791d850d0d15cee5\nMOLDOVA_STATE_FIELD=$.last_success_payload_sha256=e41e3e012442ef41da1c667d7f5fbe4fd52786b0bb5ffca195660750c773efbf\nMOLDOVA_STATE_FIELD=$.last_success_replicas[0].crypt=pve01-mail-05-crypt\nMOLDOVA_STATE_FIELD=$.last_success_replicas[0].physical=pve01-mail-05\nMOLDOVA_STATE_FIELD=$.last_success_replicas[1].crypt=pve03-mail-04-crypt\nMOLDOVA_STATE_FIELD=$.last_success_replicas[1].physical=pve03-mail-04\nMOLDOVA_STATE_FIELD=$.logical_id=us-netbird\nMOLDOVA_STATE_FIELD=$.reason=PIPE_FAILED\nMOLDOVA_STATE_FIELD=$.result=FAIL\nMOLDOVA_STATE_FIELD=$.retry_after_epoch=1789884427\nMOLDOVA_STATE_FIELD=$.schema=1\nMOLDOVA_STATE_FIELD=$.sealed=False\nMOLDOVA_STATE_FIELD=$.updated_at_utc=2026-09-20T00:07:07Z\nMOLDOVA_STATE_FULL_SAFE_END=true\nHAS_RCLONE_SOURCE=false\nHAS_GENERATION_MANIFEST_PAYLOAD_SOURCE=true\nHAS_REMOTE_REPLICA_SOURCE=true\nDECISION=HOLD_BACKUP207_PRODUCER_CONTRACT_INCOMPLETE\nNEXT_GATE=READ_ONLY_TARGETED_MODULE_FOLLOWUP\nCLOUD_READS=0\nCLOUD_WRITES=0\nVPS_SSH_ATTEMPTS=0\nMESSENGERS214_CLOSED=false\nMAJOR_STAGES_REMAINING=8\nNEWFI207_END=true\n" + "output": "W2UX738_BEGIN=True\nCOMMAND_ID=SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2\nVM_SAFETY={\"production_snapshots\":[],\"production_status\":\"running\",\"staging_all_link_down\":true,\"staging_name\":\"pvepro-staging-v1\",\"staging_nic_count\":1,\"staging_snapshots\":[],\"staging_status\":\"stopped\"}\nAUDIT_ERROR_CLASS=JSONDecodeError\nAUDIT_ERROR_SHA256=2bcabb5902c8525177f7096f6aec8b3c3ef4b5effeba69146827d0f656fe02eb\nTASK_RESULT=PVEPRO_RUSSIAN_UX_AUDIT_FAILED\nNO_MUTATION=True\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"FAIL\",\"version\":1}\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index 692b5cb9..4afc0913 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,22 +1,22 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=NEWFI-260920-NEWFDOM-MESSENGERS214-PRODUCER207 -STATUS=OK -RC=0 +COMMAND_ID=SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2 +STATUS=FAIL +RC=3 HOST=pve01 MODE=read-only -COMPONENT=newfi-newfdom-messengers214-backupv2-producer-contract-readonly-audit +COMPONENT=pvepro-russian-ux-audit-readonly REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66 ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0 -COMMAND_SHA256=ead8fdf05c4cb0a9b8b49f67777a3e68a7a96170d3e4b5061fa03171a66917da +COMMAND_SHA256=edea3a480f0293b06af4de348d408a007909a4abd7a3320814eac0a4942fbfa9 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 +COMMAND_RC=3 CHANGES_MADE=false ROLLBACK_STARTED=false ROLLBACK_RESTORED=null @@ -24,756 +24,17 @@ MUTATION_OUTCOME=NO_MUTATION SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=99d8dcf2767bb4aeb57e414153ec37f086162257482529c3dcce3939c780c5ec -SANITIZED_OUTPUT_SHA256=99d8dcf2767bb4aeb57e414153ec37f086162257482529c3dcce3939c780c5ec +RAW_EVIDENCE_SHA256=28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645 +SANITIZED_OUTPUT_SHA256=28305f9335f5103cfdb74625e14fa9a12d56f58e2aaf3d7c970a9c54e190c645 OUTPUT_BEGIN -NEWFI207_BEGIN=true -MODE=read-only -IMMUTABLE_PLAN_CHECK=PASS -CHANGES_MADE=false -MUTATION_OUTCOME=NO_MUTATION -PIN_CHECK=PASS -ACCEPTED_RELEASE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b -RELEASE_FILE_COUNT=6 -INTERESTING_FILE_COUNT=6 -FILE_1_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py -FILE_1_BYTES=10566 -FILE_1_MODE=0o400 -FILE_1_SHA256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793 -FILE_1_KEYWORD_SCORE=13 -FILE_1_AST_DEF_COUNT=0 -FILE_1_AST_IMPORT_COUNT=0 -FILE_1_AST_STRING_COUNT=7 -FILE_1_STRING_1_LINE=4 -FILE_1_STRING_1_VALUE=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1 -FILE_1_STRING_2_LINE=62 -FILE_1_STRING_2_VALUE=backup_target -FILE_1_STRING_3_LINE=62 -FILE_1_STRING_3_VALUE=ssh_remote -FILE_1_STRING_4_LINE=135 -FILE_1_STRING_4_VALUE=payload_sha256 -FILE_1_STRING_5_LINE=135 -FILE_1_STRING_5_VALUE=manifest_sha256 -FILE_1_STRING_6_LINE=135 -FILE_1_STRING_6_VALUE=replicas -FILE_1_STRING_7_LINE=132 -FILE_1_STRING_7_VALUE=homelab-scheduler-proof- -FILE_2_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -FILE_2_BYTES=13825 -FILE_2_MODE=0o400 -FILE_2_SHA256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d -FILE_2_KEYWORD_SCORE=9 -FILE_2_AST_DEF_COUNT=2 -FILE_2_DEF_1_LINE=35 -FILE_2_DEF_1_NAME=_remote_sha -FILE_2_DEF_2_LINE=117 -FILE_2_DEF_2_NAME=_execute_remote -FILE_2_AST_IMPORT_COUNT=0 -FILE_2_AST_STRING_COUNT=17 -FILE_2_STRING_1_LINE=79 -FILE_2_STRING_1_VALUE=/var/tmp/homelab-vzdump-v2-plan-only -FILE_2_STRING_2_LINE=118 -FILE_2_STRING_2_VALUE=REMOTE_NODE -FILE_2_STRING_3_LINE=119 -FILE_2_STRING_3_VALUE=REMOTE_ARGV -FILE_2_STRING_4_LINE=120 -FILE_2_STRING_4_VALUE=REMOTE_ARGV_NODE -FILE_2_STRING_5_LINE=121 -FILE_2_STRING_5_VALUE=REMOTE_CAP_VALUE -FILE_2_STRING_6_LINE=124 -FILE_2_STRING_6_VALUE=REMOTE_WORKDIR -FILE_2_STRING_7_LINE=158 -FILE_2_STRING_7_VALUE=remote-bounded-ssh-cwd-root -FILE_2_STRING_8_LINE=198 -FILE_2_STRING_8_VALUE=/var/tmp/homelab-vzdump-v2- -FILE_2_STRING_9_LINE=149 -FILE_2_STRING_9_VALUE=REMOTE_TIMEOUT -FILE_2_STRING_10_LINE=151 -FILE_2_STRING_10_VALUE=REMOTE_RC -FILE_2_STRING_11_LINE=152 -FILE_2_STRING_11_VALUE=REMOTE_EMPTY -FILE_2_STRING_12_LINE=155 -FILE_2_STRING_12_VALUE=REMOTE_FILE_IDENTITY -FILE_2_STRING_13_LINE=162 -FILE_2_STRING_13_VALUE=remote-bounded-ssh-cwd-root -FILE_2_STRING_14_LINE=204 -FILE_2_STRING_14_VALUE=payload.bin -FILE_2_STRING_15_LINE=210 -FILE_2_STRING_15_VALUE=VZDUMP_PAYLOAD_BOUND -FILE_2_STRING_16_LINE=138 -FILE_2_STRING_16_VALUE=REMOTE_TIMEOUT -FILE_2_STRING_17_LINE=143 -FILE_2_STRING_17_VALUE=REMOTE_CAP -FILE_3_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py -FILE_3_BYTES=4627 -FILE_3_MODE=0o400 -FILE_3_SHA256=1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b -FILE_3_KEYWORD_SCORE=9 -FILE_3_AST_DEF_COUNT=1 -FILE_3_DEF_1_LINE=11 -FILE_3_DEF_1_NAME=_remote_sha -FILE_3_AST_IMPORT_COUNT=0 -FILE_3_AST_STRING_COUNT=3 -FILE_3_STRING_1_LINE=48 -FILE_3_STRING_1_VALUE=/var/tmp/homelab-vzdump-v2- -FILE_3_STRING_2_LINE=66 -FILE_3_STRING_2_VALUE=payload.bin -FILE_3_STRING_3_LINE=70 -FILE_3_STRING_3_VALUE=QEMU_PAYLOAD_MISSING -FILE_4_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py -FILE_4_BYTES=4097 -FILE_4_MODE=0o400 -FILE_4_SHA256=a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96 -FILE_4_KEYWORD_SCORE=9 -FILE_4_AST_DEF_COUNT=0 -FILE_4_AST_IMPORT_COUNT=0 -FILE_4_AST_STRING_COUNT=9 -FILE_4_STRING_1_LINE=44 -FILE_4_STRING_1_VALUE=last_success_payload_sha256 -FILE_4_STRING_2_LINE=45 -FILE_4_STRING_2_VALUE=last_success_manifest_sha256 -FILE_4_STRING_3_LINE=45 -FILE_4_STRING_3_VALUE=last_success_replicas -FILE_4_STRING_4_LINE=37 -FILE_4_STRING_4_VALUE=payload_sha256 -FILE_4_STRING_5_LINE=37 -FILE_4_STRING_5_VALUE=last_success_payload_sha256 -FILE_4_STRING_6_LINE=38 -FILE_4_STRING_6_VALUE=manifest_sha256 -FILE_4_STRING_7_LINE=38 -FILE_4_STRING_7_VALUE=last_success_manifest_sha256 -FILE_4_STRING_8_LINE=38 -FILE_4_STRING_8_VALUE=replicas -FILE_4_STRING_9_LINE=38 -FILE_4_STRING_9_VALUE=last_success_replicas -FILE_5_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py -FILE_5_BYTES=3449 -FILE_5_MODE=0o400 -FILE_5_SHA256=b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3 -FILE_5_KEYWORD_SCORE=7 -FILE_5_AST_DEF_COUNT=0 -FILE_5_AST_IMPORT_COUNT=0 -FILE_5_AST_STRING_COUNT=2 -FILE_5_STRING_1_LINE=4 -FILE_5_STRING_1_VALUE=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411 -FILE_5_STRING_2_LINE=45 -FILE_5_STRING_2_VALUE=payload.bin -FILE_6_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py -FILE_6_BYTES=2320 -FILE_6_MODE=0o400 -FILE_6_SHA256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011 -FILE_6_KEYWORD_SCORE=3 -FILE_6_AST_DEF_COUNT=0 -FILE_6_AST_IMPORT_COUNT=0 -FILE_6_AST_STRING_COUNT=1 -FILE_6_STRING_1_LINE=4 -FILE_6_STRING_1_VALUE=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1 -CTX_1_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py -CTX_1_START_LINE=15 -CTX_1_END_LINE=21 -CTX_1_L15=} -CTX_1_L16= -CTX_1_L17=def _sha(p): -CTX_1_L18= h=hashlib.sha256() -CTX_1_L19= with open(p,'rb',buffering=0) as f: -CTX_1_L20= while True: -CTX_1_L21= b=f.read(1<<20) -CTX_2_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py -CTX_2_START_LINE=34 -CTX_2_END_LINE=40 -CTX_2_L34= -CTX_2_L35=class _GlobalsProxy: -CTX_2_L36= __slots__=('_g',) -CTX_2_L37= def __init__(self,g): object.__setattr__(self,'_g',g) -CTX_2_L38= def __getattr__(self,n): -CTX_2_L39= try: return self._g[n] -CTX_2_L40= except KeyError as e: raise AttributeError(n) from e -CTX_3_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py -CTX_3_START_LINE=59 -CTX_3_END_LINE=72 -CTX_3_L59= if len(found)!=1: -CTX_3_L60= raise RuntimeError('LEGACY_PROVENANCE_CARDINALITY') -CTX_3_L61= g=next(iter(found.values())) -CTX_3_L62= required=('capture_pve_guest','backup_target','load_targets','cluster_inventory','ssh_remote', -CTX_3_L63= '_default_unprivileged_lxc','mapped_scratch_probe','_stream_argv_to_local','run', -CTX_3_L64= 'choose_due_target','write_state','epoch') -CTX_3_L65= if any(not callable(g.get(n)) for n in required): -CTX_3_L66= raise RuntimeError('LEGACY_PROVENANCE_API') -CTX_3_L67= original=g['capture_pve_guest'] -CTX_3_L68= proxy=_GlobalsProxy(g) -CTX_3_L69= if not isinstance(g.get('SCP'),str) or not g['SCP'].startswith('/'): -CTX_3_L70= raise RuntimeError('LEGACY_SCP_API') -CTX_3_L71= qemu_patched=qemu_adapter.bind(proxy,original) -CTX_3_L72= if not callable(qemu_patched): -CTX_4_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py -CTX_4_START_LINE=75 -CTX_4_END_LINE=82 -CTX_4_L75= if not callable(patched): -CTX_4_L76= raise RuntimeError('LXC_ADAPTER_BIND_RESULT') -CTX_4_L77= g['capture_pve_guest']=patched -CTX_4_L78= scheduler_wired=scheduler_adapter.bind(proxy,g['choose_due_target'],g['write_state']) -CTX_4_L79= if g.get('choose_due_target') is not scheduler_wired['choose_due_target'] or g.get('write_state') is not scheduler_wired['write_state']: -CTX_4_L80= raise RuntimeError('SCHEDULER_ADAPTER_BIND_RESULT') -CTX_4_L81= return {'legacy_globals':g,'legacy':proxy,'original_capture':original,'qemu_patched_capture':qemu_patched,'patched_capture':patched,'scheduler_wired':scheduler_wired} -CTX_4_L82= -CTX_5_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py -CTX_5_START_LINE=96 -CTX_5_END_LINE=117 -CTX_5_L96= wired=_wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,BASE) -CTX_5_L97= return wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired -CTX_5_L98= -CTX_5_L99=def _target(wrapper,lid): -CTX_5_L100= rows=wrapper.load_targets(); hits=[x for x in rows if x.get('logical_id')==lid] -CTX_5_L101= if len(hits)!=1: raise RuntimeError('TARGET_CARDINALITY') -CTX_5_L102= return hits[0] -CTX_5_L103= -CTX_5_L104=def selftest(): -CTX_5_L105= wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired=_load() -CTX_5_L106= if wired['legacy_globals'].get('capture_pve_guest') is not wired['patched_capture']: -CTX_5_L107= raise RuntimeError('PATCH_BINDING') -CTX_5_L108= if wired['legacy_globals'].get('choose_due_target') is not wired['scheduler_wired']['choose_due_target']: -CTX_5_L109= raise RuntimeError('SCHEDULER_CHOOSE_BINDING') -CTX_5_L110= if wired['legacy_globals'].get('write_state') is not wired['scheduler_wired']['write_state']: -CTX_5_L111= raise RuntimeError('SCHEDULER_WRITE_BINDING') -CTX_5_L112= if [scheduler_adapter.backoff_seconds(n) for n in range(1,7)]!=[1800,3600,7200,14400,21600,21600]: -CTX_5_L113= raise RuntimeError('SCHEDULER_BACKOFF_CONTRACT') -CTX_5_L114= if not callable(wrapper.backup_target) or not callable(wrapper.main) or not callable(wrapper.load_targets): -CTX_5_L115= raise RuntimeError('WRAPPER_PUBLIC_API') -CTX_5_L116= print('SELFTEST_OVERLAY504=PASS',flush=True) -CTX_5_L117= return 0 -CTX_6_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py -CTX_6_START_LINE=125 -CTX_6_END_LINE=187 -CTX_6_L125= if argv==['scheduler-proof']: -CTX_6_L126= import tempfile -CTX_6_L127= legacy=wired['legacy']; g=wired['legacy_globals'] -CTX_6_L128= old_root=g.get('STATE_ROOT'); old_epoch=g.get('epoch') -CTX_6_L129= if old_root is None or not callable(old_epoch): raise RuntimeError('SCHEDULER_PROOF_BASE') -CTX_6_L130= now=[1000] -CTX_6_L131= try: -CTX_6_L132= with tempfile.TemporaryDirectory(prefix='homelab-scheduler-proof-',dir='/run') as td: -CTX_6_L133= g['STATE_ROOT']=pathlib.Path(td); (g['STATE_ROOT']/'state').mkdir(mode=0o700) -CTX_6_L134= g['epoch']=lambda: now[0] -CTX_6_L135= common={'payload_sha256':'a'*64,'manifest_sha256':'b'*64,'replicas':['proof-r1','proof-r2']} -CTX_6_L136= legacy.write_state('proof-a','SUCCESS',generation='proof-a-good',**common) -CTX_6_L137= legacy.write_state('proof-b','SUCCESS',generation='proof-b-good',**common) -CTX_6_L138= now[0]=100000 -CTX_6_L139= legacy.write_state('proof-a','FAIL',generation='proof-a-bad',reason='PROOF_FAILURE',sealed=False) -CTX_6_L140= state=legacy.load_state_all(); a=state['proof-a'] -CTX_6_L141= targets=[{'logical_id':'proof-a','enabled':True,'due_seconds':100},{'logical_id':'proof-b','enabled':True,'due_seconds':100}] -CTX_6_L142= first=legacy.choose_due_target(targets,state,now[0]) -CTX_6_L143= if not isinstance(first,dict) or first.get('logical_id')!='proof-b': raise RuntimeError('SCHEDULER_PROOF_PEER_NOT_SELECTED') -CTX_6_L144= retry=int(a.get('retry_after_epoch',0)); preserved=int(a.get('last_success_epoch',0)) -CTX_6_L145= if preserved!=1000 or a.get('last_success_generation')!='proof-a-good' or int(a.get('consecutive_failures',0))!=1 or retry!=101800: -CTX_6_L146= raise RuntimeError('SCHEDULER_PROOF_FAILURE_STATE') -CTX_6_L147= now[0]=retry+1 -CTX_6_L148= second=legacy.choose_due_target(targets,legacy.load_state_all(),now[0]) -CTX_6_L149= if not isinstance(second,dict) or second.get('logical_id')!='proof-a': raise RuntimeError('SCHEDULER_PROOF_RETRY_NOT_REELIGIBLE') -CTX_6_L150= legacy.write_state('proof-a','SUCCESS',generation='proof-a-recovered',**common) -CTX_6_L151= recovered=legacy.load_state_all()['proof-a'] -CTX_6_L152= if int(recovered.get('consecutive_failures',-1))!=0 or int(recovered.get('retry_after_epoch',-1))!=0: -CTX_6_L153= raise RuntimeError('SCHEDULER_PROOF_SUCCESS_RESET') -CTX_6_L154= proof={'failed_target':'proof-a','peer_selected_during_backoff':first['logical_id'],'retry_after_epoch':retry,'last_success_preserved':preserved==1000,'retry_target_after_backoff':second['logical_id'],'success_resets_failures':True,'production_state_root_used':False} -CTX_6_L155= print('SCHEDULER_FAILURE_ISOLATION_PROOF='+json.dumps(proof,separators=(',',':'),sort_keys=True),flush=True) -CTX_6_L156= return 0 -CTX_6_L157= finally: -CTX_6_L158= g['STATE_ROOT']=old_root; g['epoch']=old_epoch -CTX_6_L159= if argv==['scheduler-select-live']: -CTX_6_L160= state=legacy.load_state_all(); targets=wrapper.load_targets() -CTX_6_L161= chosen=legacy.choose_due_target(targets,state) -CTX_6_L162= if chosen is None: -CTX_6_L163= print('SCHEDULER_LIVE_SELECTION=DEFER_NO_DUE_TARGET',flush=True) -CTX_6_L164= else: -CTX_6_L165= print('SCHEDULER_LIVE_SELECTION='+json.dumps({'logical_id':chosen.get('logical_id'),'due_seconds':chosen.get('due_seconds'),'enabled':chosen.get('enabled') is True},separators=(',',':'),sort_keys=True),flush=True) -CTX_6_L166= return 0 -CTX_6_L167= if len(argv)==2 and argv[0]=='plan-lxc': -CTX_6_L168= t=_target(wrapper,argv[1]) -CTX_6_L169= if t.get('guest_type')!='lxc' or t.get('logical_id')=='guest-pve01-lxc-112': -CTX_6_L170= raise RuntimeError('PLAN_TARGET_NOT_LEGACY_LXC') -CTX_6_L171= out=lxc_adapter.plan_only(legacy,t) -CTX_6_L172= print('PLAN_LXC_RESULT='+json.dumps({'logical_id':t['logical_id'],'vmid':int(t['vmid']),'node':out['job']['node'],'job':out['job']},separators=(',',':'),sort_keys=True),flush=True) -CTX_6_L173= return 0 -CTX_6_L174= if len(argv)==2 and argv[0]=='verify-target': -CTX_6_L175= t=_target(wrapper,argv[1]) -CTX_6_L176= if t.get('logical_id')=='guest-pve01-lxc-112': -CTX_6_L177= raise RuntimeError('VERIFY_SYNTHETIC_CT112_FORBIDDEN') -CTX_6_L178= try: -CTX_6_L179= out=wrapper.backup_target(t,True) -CTX_6_L180= except legacy.BackupError as e: -CTX_6_L181= print('VERIFY_TARGET_RESULT=FAIL',flush=True) -CTX_6_L182= print('VERIFY_TARGET_REASON='+str(e.code),flush=True) -CTX_6_L183= return 2 -CTX_6_L184= print('VERIFY_TARGET_RESULT='+json.dumps(out,separators=(',',':'),sort_keys=True),flush=True) -CTX_6_L185= return 0 -CTX_6_L186= return wrapper.main([sys.argv[0],*argv]) -CTX_6_L187= -CTX_7_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_7_START_LINE=20 -CTX_7_END_LINE=26 -CTX_7_L20= except Exception as e: raise AdapterError(code) from e -CTX_7_L21= -CTX_7_L22=def _sha_file(p): -CTX_7_L23= h=hashlib.sha256() -CTX_7_L24= with open(p,'rb',buffering=0) as f: -CTX_7_L25= for b in iter(lambda:f.read(1<<20),b''): h.update(b) -CTX_7_L26= return h.hexdigest() -CTX_8_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_8_START_LINE=32 -CTX_8_END_LINE=62 -CTX_8_L32= if n<=0: raise AdapterError('WRITE_FAILED') -CTX_8_L33= view=view[n:] -CTX_8_L34= -CTX_8_L35=def _remote_sha(legacy,node,path): -CTX_8_L36= p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30) -CTX_8_L37= parts=p.stdout.decode('ascii','strict').strip().split() -CTX_8_L38= _need(len(parts)>=2 and parts[1]==path,'TOOL_SHA_OUTPUT') -CTX_8_L39= return parts[0] -CTX_8_L40= -CTX_8_L41=def _live_inputs(legacy,node,vmid,scratch): -CTX_8_L42= _need(_remote_sha(legacy,node,'/usr/bin/pvesh')==PVESH_SHA,'PVESH_IDENTITY') -CTX_8_L43= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY') -CTX_8_L44= rows=_j(legacy.ssh_remote(node,['pvesh','get','/cluster/resources','--type','vm','--output-format','json'],timeout=60),'RESOURCES_JSON') -CTX_8_L45= stores=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/storage','--output-format','json'],timeout=60),'STORAGE_JSON') -CTX_8_L46= _need(type(rows) is list and type(stores) is list,'PVE_LIST_SCHEMA') -CTX_8_L47= configs=[] -CTX_8_L48= for r in rows: -CTX_8_L49= if not isinstance(r,dict) or r.get('node')!=node or r.get('type') not in ('lxc','qemu'): continue -CTX_8_L50= try: rid=int(r.get('vmid')) -CTX_8_L51= except Exception: raise AdapterError('RESOURCE_VMID') -CTX_8_L52= cfg=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/{r["type"]}/{rid}/config','--output-format','json'],timeout=60),'CONFIG_JSON') -CTX_8_L53= _need(type(cfg) is dict,'CONFIG_SCHEMA') -CTX_8_L54= configs.append([rid,cfg]) -CTX_8_L55= tasks=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/tasks','--limit','999','--output-format','json'],timeout=60),'TASKS_JSON') -CTX_8_L56= _need(type(tasks) is list and len(tasks)<1000,'TASKS_SCHEMA') -CTX_8_L57= q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False) -CTX_8_L58= defaults=None -CTX_8_L59= if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout -CTX_8_L60= elif q.returncode!=1: raise AdapterError('DEFAULTS_PROBE') -CTX_8_L61= st=os.statvfs('/mnt/staging'); free=int(st.f_bavail*st.f_frsize) -CTX_8_L62= return {'node':node,'vmid':vmid,'scratch':scratch,'now':int(time.time()),'rows':rows,'storage_rows':stores,'configs':configs, -CTX_9_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_9_START_LINE=85 -CTX_9_END_LINE=91 -CTX_9_L85= a=_helper(_live_inputs(legacy,node,vmid,scratch)); b=_helper(_live_inputs(legacy,node,vmid,scratch)) -CTX_9_L86= _need(_stable_job(a['job'])==_stable_job(b['job']),'FRESH_PLAN_UNSTABLE') -CTX_9_L87= _need(a['argv']==b['argv'],'FRESH_ARGV_UNSTABLE') -CTX_9_L88= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_POST') -CTX_9_L89= return b -CTX_9_L90= -CTX_9_L91=def _execute_local(legacy,node,argv,dest,cap,timeout): -CTX_10_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_10_START_LINE=94 -CTX_10_END_LINE=109 -CTX_10_L94= data=json.dumps(inp,separators=(',',':'),sort_keys=True).encode() -CTX_10_L95= p=subprocess.run(['/usr/bin/python3','-I','-B',str(EXEC_HELPER)],input=data,capture_output=True,timeout=timeout+120,cwd='/',env=ENV) -CTX_10_L96= if p.stderr or not p.stdout or len(p.stdout)>262144: -CTX_10_L97= raise ExecFailure('LOCAL_HELPER_PROTOCOL',{'executor':'local-proven-pve270','producer_rc':None,'stderr_stream_sha256':hashlib.sha256(p.stderr).hexdigest(),'stderr_bytes_observed':len(p.stderr)}) -CTX_10_L98= try: out=json.loads(p.stdout) -CTX_10_L99= except Exception: -CTX_10_L100= raise ExecFailure('LOCAL_HELPER_JSON',{'executor':'local-proven-pve270','producer_rc':None,'stderr_stream_sha256':hashlib.sha256(p.stderr).hexdigest(),'stderr_bytes_observed':len(p.stderr)}) -CTX_10_L101= summary={'executor':'local-proven-pve270','helper_rc':p.returncode,'exception_class':out.get('exception_class'),'exception_message_sha256':out.get('exception_message_sha256')} -CTX_10_L102= if isinstance(out.get('process'),dict): summary.update(out['process']) -CTX_10_L103= if p.returncode!=0 or out.get('status')!='OK': raise ExecFailure('LOCAL_PRODUCER_FAILED',summary) -CTX_10_L104= result=out.get('result'); _need(type(result) is dict,'LOCAL_RESULT_SCHEMA') -CTX_10_L105= _need(pathlib.Path(dest).is_file() and pathlib.Path(dest).stat().st_size==int(result.get('size',-1)),'LOCAL_RESULT_FILE') -CTX_10_L106= return summary|{'size':result['size'],'sha256':result['sha256'],'producer_rc':result.get('producer_rc')} -CTX_10_L107= -CTX_10_L108=def _kill(p): -CTX_10_L109= try: os.killpg(p.pid,signal.SIGTERM) -CTX_11_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_11_START_LINE=114 -CTX_11_END_LINE=166 -CTX_11_L114= except ProcessLookupError: pass -CTX_11_L115= p.wait() -CTX_11_L116= -CTX_11_L117=def _execute_remote(legacy,node,argv,dest,cap,timeout): -CTX_11_L118= _need(re.fullmatch(r'pve0[123]',str(node)) is not None and node!='pve01','REMOTE_NODE') -CTX_11_L119= _need(type(argv) is list and argv and argv[0]=='/usr/bin/vzdump' and all(type(x) is str and '\x00' not in x for x in argv),'REMOTE_ARGV') -CTX_11_L120= _need('--node' in argv and argv[argv.index('--node')+1]==node,'REMOTE_ARGV_NODE') -CTX_11_L121= _need(type(cap) is int and 0=deadline: raise ExecFailure('REMOTE_TIMEOUT',{}) -CTX_11_L139= for key,_ in sel.select(min(.2,max(0,deadline-now))): -CTX_11_L140= b=os.read(key.fileobj.fileno(),65536) -CTX_11_L141= if not b: sel.unregister(key.fileobj); continue -CTX_11_L142= if key.fileobj is p.stdout: -CTX_11_L143= if total+len(b)>cap: raise ExecFailure('REMOTE_CAP',{}) -CTX_11_L144= _write_all(fd,b); digest.update(b); total+=len(b) -CTX_11_L145= else: -CTX_11_L146= err_total+=len(b); eh.update(b); keep=b[:max(0,MAX_STDERR-err_kept)] -CTX_11_L147= if keep: _write_all(efd,keep); err_kept+=len(keep) -CTX_11_L148= left=deadline-time.monotonic() -CTX_11_L149= if left<=0: raise ExecFailure('REMOTE_TIMEOUT',{}) -CTX_11_L150= rc=p.wait(timeout=left) -CTX_11_L151= if rc!=0: raise ExecFailure('REMOTE_RC',{}) -CTX_11_L152= if total<=0: raise ExecFailure('REMOTE_EMPTY',{}) -CTX_11_L153= stf=os.fstat(fd); named=os.stat(dest,follow_symlinks=False) -CTX_11_L154= if (stf.st_dev,stf.st_ino)!=(initial.st_dev,initial.st_ino) or (named.st_dev,named.st_ino)!=(initial.st_dev,initial.st_ino) or stf.st_nlink!=1 or stf.st_size!=total: -CTX_11_L155= raise ExecFailure('REMOTE_FILE_IDENTITY',{}) -CTX_11_L156= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_POST') -CTX_11_L157= os.fchmod(fd,0o400); os.fsync(fd); os.fsync(efd); good=True -CTX_11_L158= return {'executor':'remote-bounded-ssh-cwd-root','producer_rc':rc,'size':total,'sha256':digest.hexdigest(), -CTX_11_L159= 'stderr_bytes_observed':err_total,'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,'stderr_stream_sha256':eh.hexdigest()} -CTX_11_L160= except ExecFailure as e: -CTX_11_L161= if p is not None and p.poll() is None: _kill(p) -CTX_11_L162= summary={'executor':'remote-bounded-ssh-cwd-root','producer_rc':None if p is None else p.returncode,'archive_bytes':total, -CTX_11_L163= 'stderr_bytes_observed':err_total,'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,'stderr_stream_sha256':eh.hexdigest()} -CTX_11_L164= summary.update(e.summary); raise ExecFailure(e.code,summary) -CTX_11_L165= finally: -CTX_11_L166= if p is not None: -CTX_12_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_12_START_LINE=171 -CTX_12_END_LINE=178 -CTX_12_L171= try: os.fsync(fd); os.fsync(efd) -CTX_12_L172= except OSError: pass -CTX_12_L173= os.close(fd); os.close(efd) -CTX_12_L174= summary={'process_started':p is not None,'producer_rc':None if p is None else p.returncode,'capture_success':good,'archive_bytes':total, -CTX_12_L175= 'stderr_bytes_observed':err_total,'stderr_bytes_retained':err_kept,'stderr_truncated':err_total>err_kept,'stderr_stream_sha256':eh.hexdigest(),'raw_stderr_exported':False,'cwd':'/'} -CTX_12_L176= try: -CTX_12_L177= mb=(json.dumps(summary,separators=(',',':'),sort_keys=True)+'\n').encode() -CTX_12_L178= mfd=os.open(metap,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600) -CTX_13_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_13_START_LINE=182 -CTX_13_END_LINE=188 -CTX_13_L182= -CTX_13_L183=def _emit_diag(node,summary): -CTX_13_L184= safe={'node':node} -CTX_13_L185= for k in ('executor','failure_code','helper_rc','producer_rc','archive_bytes','stderr_bytes_observed','stderr_bytes_retained','stderr_truncated','stderr_stream_sha256','exception_class','exception_message_sha256'): -CTX_13_L186= if k in summary: safe[k]=summary[k] -CTX_13_L187= print('LXC_EXECUTION_DIAG='+json.dumps(safe,separators=(',',':'),sort_keys=True),flush=True) -CTX_13_L188= -CTX_14_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py -CTX_14_START_LINE=196 -CTX_14_END_LINE=218 -CTX_14_L196= _need(typ==t.get('guest_type')=='lxc','PVE_GUEST_TYPE_DRIFT') -CTX_14_L197= legacy._default_unprivileged_lxc(node,vmid) -CTX_14_L198= scratch=f'/var/tmp/homelab-vzdump-v2-{gen}' -CTX_14_L199= legacy.ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30) -CTX_14_L200= q=legacy.ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30) -CTX_14_L201= _need(q.stdout.decode().strip()=='710:0:100000','PVE_MAPPED_SCRATCH_ACCESS_CONTRACT') -CTX_14_L202= try: -CTX_14_L203= legacy.mapped_scratch_probe(node,scratch) -CTX_14_L204= p=plan_only(legacy,t,scratch); local=pathlib.Path(work)/'payload.bin'; cap=int(p['job']['archive_cap_bytes']) -CTX_14_L205= try: -CTX_14_L206= result=_execute_local(legacy,node,p['argv'],local,cap,7200) if node=='pve01' else _execute_remote(legacy,node,p['argv'],local,cap,7200) -CTX_14_L207= except ExecFailure as e: -CTX_14_L208= _emit_diag(node,e.summary|{'failure_code':e.code}) -CTX_14_L209= raise legacy.BackupError('LXC_PRODUCER_FAILED') from None -CTX_14_L210= _need(local.is_file() and 0=2 and parts[1]==path,'QEMU_TOOL_SHA_OUTPUT') -CTX_15_L15= return parts[0] -CTX_15_L16= -CTX_15_L17=def _select_qemu_outputs(vmid,files): -CTX_15_L18= _need(type(vmid) is int and vmid>0,'QEMU_VMID') -CTX_15_L19= _need(type(files) is list and files and all(type(x) is str and x.startswith('/') and '\x00' not in x for x in files),'QEMU_OUTPUT_LIST') -CTX_15_L20= _need(len(files)==len(set(files)),'QEMU_OUTPUT_DUPLICATE') -CTX_15_L21= pat=re.compile(r'^vzdump-qemu-'+re.escape(str(vmid))+r'-(\d{4}_\d{2}_\d{2}-\d{2}_\d{2}_\d{2})\.vma\.zst$') -CTX_15_L22= archives=[] -CTX_15_L23= for f in files: -CTX_15_L24= name=pathlib.PurePosixPath(f).name -CTX_15_L25= m=pat.fullmatch(name) -CTX_15_L26= if m: archives.append((f,m.group(1))) -CTX_15_L27= _need(len(archives)==1,'QEMU_ARCHIVE_NOT_UNIQUE') -CTX_15_L28= archive,stamp=archives[0]; parent=pathlib.PurePosixPath(archive).parent -CTX_15_L29= expected_log=parent/f'vzdump-qemu-{vmid}-{stamp}.log' -CTX_15_L30= allowed={archive}; log=None -CTX_15_L31= if str(expected_log) in files: -CTX_15_L32= log=str(expected_log); allowed.add(log) -CTX_15_L33= _need(set(files)==allowed,'QEMU_OUTPUT_UNEXPECTED_FILE') -CTX_15_L34= return archive,log -CTX_15_L35= -CTX_15_L36=def _emit_diag(**kw): -CTX_15_L37= print('QEMU_EXECUTION_DIAG='+json.dumps(kw,separators=(',',':'),sort_keys=True),flush=True) -CTX_16_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py -CTX_16_START_LINE=44 -CTX_16_END_LINE=78 -CTX_16_L44= _need(len(rows)==1,'PVE_GUEST_NOT_UNIQUE') -CTX_16_L45= row=rows[0]; node=row.get('node'); typ=row.get('type') -CTX_16_L46= _need(typ==t.get('guest_type')=='qemu','PVE_GUEST_TYPE_DRIFT') -CTX_16_L47= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_PRE') -CTX_16_L48= srcdir=f'/var/tmp/homelab-vzdump-v2-{gen}' -CTX_16_L49= legacy.ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30) -CTX_16_L50= try: -CTX_16_L51= vp=legacy.ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200,check=False) -CTX_16_L52= if vp.returncode!=0: -CTX_16_L53= _emit_diag(vmid=vmid,node=node,producer_rc=vp.returncode,stderr_bytes=len(vp.stderr),stderr_sha256=hashlib.sha256(vp.stderr).hexdigest(),archive_selected=False) -CTX_16_L54= raise legacy.BackupError('QEMU_VZDUMP_FAILED') -CTX_16_L55= _need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_POST') -CTX_16_L56= p=legacy.ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\n'],timeout=30) -CTX_16_L57= files=[x for x in p.stdout.decode('utf-8','strict').splitlines() if x] -CTX_16_L58= try: src,log=_select_qemu_outputs(vmid,files) -CTX_16_L59= except QemuAdapterError as e: -CTX_16_L60= _emit_diag(vmid=vmid,node=node,producer_rc=0,regular_file_count=len(files),archive_selected=False,selector_error=str(e)) -CTX_16_L61= raise legacy.BackupError(str(e)) from None -CTX_16_L62= q=legacy.ssh_remote(node,['stat','-c','%s','--',src],timeout=30) -CTX_16_L63= raw=q.stdout.decode('ascii','strict').strip() -CTX_16_L64= _need(raw.isdigit() and int(raw)>0,'QEMU_ARCHIVE_STAT') -CTX_16_L65= size=int(raw) -CTX_16_L66= local=pathlib.Path(work)/'payload.bin' -CTX_16_L67= if node=='pve01': local=pathlib.Path(src) -CTX_16_L68= else: -CTX_16_L69= legacy.run([legacy.SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200) -CTX_16_L70= _need(pathlib.Path(local).is_file() and pathlib.Path(local).stat().st_size==size,'QEMU_PAYLOAD_MISSING') -CTX_16_L71= _emit_diag(vmid=vmid,node=node,producer_rc=0,regular_file_count=len(files),sidecar_count=1 if log else 0,archive_bytes=size,archive_selected=True) -CTX_16_L72= except Exception: -CTX_16_L73= legacy.ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False); raise -CTX_16_L74= cleanup={'kind':'pve_source_dir','node':node,'path':srcdir} -CTX_16_L75= meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'qemu','node':node,'status':row.get('status'), -CTX_16_L76= 'producer_contract':'strict-qemu-vma-zst-plus-matching-log-overlay503'} -CTX_16_L77= return pathlib.Path(local),meta,cleanup -CTX_16_L78= capture_pve_guest.__name__='capture_pve_guest' -CTX_17_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py -CTX_17_START_LINE=20 -CTX_17_END_LINE=28 -CTX_17_L20= n=max(1,_as_nonneg_int(consecutive_failures,1)) -CTX_17_L21= return min(MAX_BACKOFF,MIN_BACKOFF*(2**min(n-1,4))) -CTX_17_L22= -CTX_17_L23=def _read_prior(legacy,logical_id): -CTX_17_L24= root=pathlib.Path(legacy.STATE_ROOT)/'state' -CTX_17_L25= p=root/(str(logical_id)+'.json') -CTX_17_L26= try: -CTX_17_L27= if not p.is_file(): return {} -CTX_17_L28= d=json.loads(p.read_text(encoding='utf-8')) -CTX_18_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py -CTX_18_START_LINE=34 -CTX_18_END_LINE=48 -CTX_18_L34= if not isinstance(prior,dict): return {} -CTX_18_L35= if prior.get('result')=='SUCCESS': -CTX_18_L36= out={'last_success_epoch':_as_nonneg_int(prior.get('last_success_epoch'),0)} -CTX_18_L37= mapping=(('generation','last_success_generation'),('payload_sha256','last_success_payload_sha256'), -CTX_18_L38= ('manifest_sha256','last_success_manifest_sha256'),('replicas','last_success_replicas'), -CTX_18_L39= ('green_verified','last_success_green_verified')) -CTX_18_L40= for src,dst in mapping: -CTX_18_L41= if src in prior: out[dst]=prior[src] -CTX_18_L42= return out -CTX_18_L43= out={} -CTX_18_L44= for k in ('last_success_epoch','last_success_generation','last_success_payload_sha256', -CTX_18_L45= 'last_success_manifest_sha256','last_success_replicas','last_success_green_verified'): -CTX_18_L46= if k in prior: out[k]=prior[k] -CTX_18_L47= return out -CTX_18_L48= -CTX_19_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py -CTX_19_START_LINE=50 -CTX_19_END_LINE=65 -CTX_19_L50= _need(callable(original_choose),'ORIGINAL_CHOOSE_REQUIRED') -CTX_19_L51= _need(callable(original_write),'ORIGINAL_WRITE_REQUIRED') -CTX_19_L52= _need(callable(getattr(legacy,'epoch',None)),'LEGACY_EPOCH_REQUIRED') -CTX_19_L53= _need(hasattr(legacy,'STATE_ROOT'),'LEGACY_STATE_ROOT_REQUIRED') -CTX_19_L54= -CTX_19_L55= def choose_due_target(targets,state,now=None): -CTX_19_L56= now=_as_nonneg_int(legacy.epoch() if now is None else now,0) -CTX_19_L57= _need(isinstance(targets,list) and isinstance(state,dict),'SCHEDULER_INPUT_SCHEMA') -CTX_19_L58= due=[] -CTX_19_L59= for order,t in enumerate(targets): -CTX_19_L60= if not isinstance(t,dict) or t.get('enabled') is not True: continue -CTX_19_L61= lid=t.get('logical_id'); seconds=_as_nonneg_int(t.get('due_seconds'),0) -CTX_19_L62= _need(isinstance(lid,str) and lid and seconds>0,'SCHEDULER_TARGET_SCHEMA') -CTX_19_L63= s=state.get(lid,{}) -CTX_19_L64= if not isinstance(s,dict): s={} -CTX_19_L65= retry_after=_as_nonneg_int(s.get('retry_after_epoch'),0) -CTX_20_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py -CTX_20_START_LINE=72 -CTX_20_END_LINE=93 -CTX_20_L72= if not due: return None -CTX_20_L73= return max(due,key=lambda x:(x[0],x[1]))[2] -CTX_20_L74= -CTX_20_L75= def write_state(logical_id,result,**kw): -CTX_20_L76= now=_as_nonneg_int(legacy.epoch(),0) -CTX_20_L77= prior=_read_prior(legacy,logical_id) -CTX_20_L78= if result=='SUCCESS': -CTX_20_L79= clean=dict(kw) -CTX_20_L80= clean.update({'last_attempt_epoch':now,'consecutive_failures':0,'retry_after_epoch':0,'failure_backoff_seconds':0}) -CTX_20_L81= return original_write(logical_id,result,**clean) -CTX_20_L82= failures=_as_nonneg_int(prior.get('consecutive_failures'),0)+1 -CTX_20_L83= backoff=backoff_seconds(failures) -CTX_20_L84= clean=dict(kw) -CTX_20_L85= clean.update(_success_snapshot(prior)) -CTX_20_L86= clean.update({'last_attempt_epoch':now,'consecutive_failures':failures, -CTX_20_L87= 'retry_after_epoch':now+backoff,'failure_backoff_seconds':backoff}) -CTX_20_L88= return original_write(logical_id,result,**clean) -CTX_20_L89= -CTX_20_L90= legacy.choose_due_target=choose_due_target -CTX_20_L91= legacy.write_state=write_state -CTX_20_L92= return {'choose_due_target':choose_due_target,'write_state':write_state, -CTX_20_L93= 'original_choose':original_choose,'original_write':original_write} -CTX_21_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py -CTX_21_START_LINE=7 -CTX_21_END_LINE=13 -CTX_21_L7=MAX_INPUT=262144 -CTX_21_L8= -CTX_21_L9=def sha_file(p:pathlib.Path)->str: -CTX_21_L10= h=hashlib.sha256() -CTX_21_L11= with open(p,'rb',buffering=0) as f: -CTX_21_L12= for b in iter(lambda:f.read(1<<20),b''): h.update(b) -CTX_21_L13= return h.hexdigest() -CTX_22_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py -CTX_22_START_LINE=20 -CTX_22_END_LINE=33 -CTX_22_L20= if not p.is_file() or p.is_symlink(): return None -CTX_22_L21= try: d=json.loads(p.read_bytes()) -CTX_22_L22= except Exception: return {'summary_read':'FAILED'} -CTX_22_L23= keys=('process_started','producer_rc','capture_success','archive_bytes','stderr_bytes_observed','stderr_bytes_retained','stderr_truncated','stderr_stream_sha256','raw_stderr_exported','child_umask') -CTX_22_L24= return {k:d.get(k) for k in keys if k in d} -CTX_22_L25= -CTX_22_L26=def selftest()->int: -CTX_22_L27= if sha_file(VZDUMP)!=VZDUMP_SHA: fail('VZDUMP_IDENTITY') -CTX_22_L28= sys.path.insert(0,str(BASE)) -CTX_22_L29= import adapter -CTX_22_L30= adapter.verify_sources(); adapter.load_graph() -CTX_22_L31= print('PRODUCER_EXEC_HELPER_SELFTEST=PASS',flush=True) -CTX_22_L32= return 0 -CTX_22_L33= -CTX_23_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py -CTX_23_START_LINE=42 -CTX_23_END_LINE=66 -CTX_23_L42= argv=x['argv']; dest=pathlib.Path(x['dest']); cap=x['cap']; seconds=x['seconds'] -CTX_23_L43= if not (type(argv) is list and argv and all(type(v) is str and '\x00' not in v for v in argv)): fail('ARGV') -CTX_23_L44= if argv[0]!='/usr/bin/vzdump': fail('VZDUMP_PATH') -CTX_23_L45= if not (dest.is_absolute() and dest.name=='payload.bin' and '..' not in dest.parts): fail('DEST') -CTX_23_L46= if not (type(cap) is int and 0str: -CTX_25_L9= return hashlib.sha256(p.read_bytes()).hexdigest() -CTX_25_L10= -CTX_25_L11=def fail(code:str): -CTX_25_L12= raise RuntimeError(code) -CTX_26_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py -CTX_26_START_LINE=17 -CTX_26_END_LINE=23 -CTX_26_L17= if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY') -CTX_26_L18= sys.path.insert(0,str(C411)) -CTX_26_L19= import adapter -CTX_26_L20= adapter.verify_sources() -CTX_26_L21= guest266,pve265,_pve270,_pve282=adapter.load_graph() -CTX_26_L22= data=sys.stdin.buffer.read(4_000_001) -CTX_26_L23= if not data or len(data)>4_000_000: fail('INPUT_BOUND') -CTX_27_FILE=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py -CTX_27_START_LINE=36 -CTX_27_END_LINE=42 -CTX_27_L36= if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY') -CTX_27_L37= guest266.no_active_tasks(raw.get('tasks'),vmid) -CTX_27_L38= argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now) -CTX_27_L39= 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') -CTX_27_L40= out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}} -CTX_27_L41= sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\n') -CTX_27_L42= return 0 -USA_STATE_FULL_SAFE_BEGIN=true -USA_STATE_FIELD=$.consecutive_failures=0 -USA_STATE_FIELD=$.failure_backoff_seconds=0 -USA_STATE_FIELD=$.generation=v2-md-relay-20260919T070058Z-0e409ea129e2 -USA_STATE_FIELD=$.green_verified=False -USA_STATE_FIELD=$.last_attempt_epoch=1789801278 -USA_STATE_FIELD=$.last_success_epoch=1789801278 -USA_STATE_FIELD=$.logical_id=md-relay -USA_STATE_FIELD=$.manifest_sha256=6887c5423640738aeb2bc1d104d515df1d1a21e2cd2d3291481475aa81cb6838 -USA_STATE_FIELD=$.payload_sha256=187401a5fbf6c29b4dfd77e5d272db77951aa45003d0d80e0be834235571f32f -USA_STATE_FIELD=$.replicas[0].crypt=pve03-mail-04-crypt -USA_STATE_FIELD=$.replicas[0].physical=pve03-mail-04 -USA_STATE_FIELD=$.replicas[1].crypt=pve03-mail-01-crypt -USA_STATE_FIELD=$.replicas[1].physical=pve03-mail-01 -USA_STATE_FIELD=$.result=SUCCESS -USA_STATE_FIELD=$.retry_after_epoch=0 -USA_STATE_FIELD=$.schema=1 -USA_STATE_FIELD=$.updated_at_utc=2026-09-19T07:01:18Z -USA_STATE_FULL_SAFE_END=true -MOLDOVA_STATE_FULL_SAFE_BEGIN=true -MOLDOVA_STATE_FIELD=$.consecutive_failures=6 -MOLDOVA_STATE_FIELD=$.failure_backoff_seconds=21600 -MOLDOVA_STATE_FIELD=$.generation=v2-us-netbird-20260920T000652Z-7ecdcfcafc12 -MOLDOVA_STATE_FIELD=$.last_attempt_epoch=1789862827 -MOLDOVA_STATE_FIELD=$.last_success_epoch=1789704670 -MOLDOVA_STATE_FIELD=$.last_success_generation=v2-us-netbird-20260918T041032Z-d7648be4c16b -MOLDOVA_STATE_FIELD=$.last_success_green_verified=False -MOLDOVA_STATE_FIELD=$.last_success_manifest_sha256=f82c761cafe8aa43d90d0b4b6124933799b5087d34daf880791d850d0d15cee5 -MOLDOVA_STATE_FIELD=$.last_success_payload_sha256=e41e3e012442ef41da1c667d7f5fbe4fd52786b0bb5ffca195660750c773efbf -MOLDOVA_STATE_FIELD=$.last_success_replicas[0].crypt=pve01-mail-05-crypt -MOLDOVA_STATE_FIELD=$.last_success_replicas[0].physical=pve01-mail-05 -MOLDOVA_STATE_FIELD=$.last_success_replicas[1].crypt=pve03-mail-04-crypt -MOLDOVA_STATE_FIELD=$.last_success_replicas[1].physical=pve03-mail-04 -MOLDOVA_STATE_FIELD=$.logical_id=us-netbird -MOLDOVA_STATE_FIELD=$.reason=PIPE_FAILED -MOLDOVA_STATE_FIELD=$.result=FAIL -MOLDOVA_STATE_FIELD=$.retry_after_epoch=1789884427 -MOLDOVA_STATE_FIELD=$.schema=1 -MOLDOVA_STATE_FIELD=$.sealed=False -MOLDOVA_STATE_FIELD=$.updated_at_utc=2026-09-20T00:07:07Z -MOLDOVA_STATE_FULL_SAFE_END=true -HAS_RCLONE_SOURCE=false -HAS_GENERATION_MANIFEST_PAYLOAD_SOURCE=true -HAS_REMOTE_REPLICA_SOURCE=true -DECISION=HOLD_BACKUP207_PRODUCER_CONTRACT_INCOMPLETE -NEXT_GATE=READ_ONLY_TARGETED_MODULE_FOLLOWUP -CLOUD_READS=0 -CLOUD_WRITES=0 -VPS_SSH_ATTEMPTS=0 -MESSENGERS214_CLOSED=false -MAJOR_STAGES_REMAINING=8 -NEWFI207_END=true +W2UX738_BEGIN=True +COMMAND_ID=SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2 +VM_SAFETY={"production_snapshots":[],"production_status":"running","staging_all_link_down":true,"staging_name":"pvepro-staging-v1","staging_nic_count":1,"staging_snapshots":[],"staging_status":"stopped"} +AUDIT_ERROR_CLASS=JSONDecodeError +AUDIT_ERROR_SHA256=2bcabb5902c8525177f7096f6aec8b3c3ef4b5effeba69146827d0f656fe02eb +TASK_RESULT=PVEPRO_RUSSIAN_UX_AUDIT_FAILED +NO_MUTATION=True +HOMELAB_RESULT_CONTRACT={"changes_made":false,"command_id":"SUPPORT-260920-PVEPRO-RUSSIAN-UX-AUDIT-READONLY-738R2","rollback_restored":null,"rollback_started":false,"status":"FAIL","version":1} OUTPUT_END CHAT_OUTPUT_END