39 lines
117 KiB
JSON
39 lines
117 KiB
JSON
{
|
|
"schema_version": 1,
|
|
"channel": "homelab-runtime",
|
|
"command_id": "SUPPORT-260921-HOMELAB-BACKUP-NODEWORKER-CONTRACT-RCA-READONLY-1104R1",
|
|
"status": "OK",
|
|
"rc": 0,
|
|
"host": "pve01",
|
|
"mode": "read-only",
|
|
"component": "homelab-backup-nodeworker-contract-rca",
|
|
"started_at_utc": "2026-09-21T21:06:14Z",
|
|
"finished_at_utc": "2026-09-21T21:06:14Z",
|
|
"reference_register_checked": true,
|
|
"reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66",
|
|
"error_register_checked": true,
|
|
"error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0",
|
|
"command_sha256": "476f69ce1ba9062cf703c5b1de5f81404fc50b1b31240c36e2e6ecdcd7aebecc",
|
|
"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": "6889fdc8e9ed9a2a2d17d6033311e611ad2a4fc46893776f10806c0b194ff052",
|
|
"sanitized_output_sha256": "6889fdc8e9ed9a2a2d17d6033311e611ad2a4fc46893776f10806c0b194ff052",
|
|
"output_truncated_in_json": false,
|
|
"full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt",
|
|
"output": "WORKERS2_NODEWORKER_CONTRACT_RCA_BEGIN=1\nCOMMAND_ID=SUPPORT-260921-HOMELAB-BACKUP-NODEWORKER-CONTRACT-RCA-READONLY-1104R1\nMODE=read-only\nCOMPONENT=homelab-backup-nodeworker-contract-rca\nMUTATION_BOUNDARY=READ_ONLY_NO_EXECUTION_OF_BACKUP_WORKERS_NO_SERVICE_START_NO_TIMER_CHANGE_NO_LOCK_BREAK_NO_GIT_WRITE\nWRAPPER_INFO={\"logic\":[{\"line\":4,\"text\":\"ACCEPTED=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b')\"},{\"line\":5,\"text\":\"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'}\"}],\"path\":\"/usr/local/sbin/homelab-backup-v2\",\"sha256\":\"5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2\",\"size\":1656}\nHASH_MATCHED_HELPERS={\"entry504.py\":[{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"sha256\":\"ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793\",\"size\":10566},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"sha256\":\"ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793\",\"size\":10566}],\"fresh_lxc_helper.py\":[{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-501r1-e55e5c8c446a/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-501r1-e55e5c8c446a/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\",\"sha256\":\"dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\",\"size\":2320}],\"lxc_adapter.py\":[{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"sha256\":\"3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\",\"size\":13825},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"sha256\":\"3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\",\"size\":13825},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"sha256\":\"3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\",\"size\":13825},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"sha256\":\"3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\",\"size\":13825},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"sha256\":\"3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\",\"size\":13825},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"sha256\":\"3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\",\"size\":13825}],\"producer_exec_helper.py\":[{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"sha256\":\"b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3\",\"size\":3449},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"sha256\":\"b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3\",\"size\":3449},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"sha256\":\"b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3\",\"size\":3449},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"sha256\":\"b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3\",\"size\":3449},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"sha256\":\"b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3\",\"size\":3449},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"sha256\":\"b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3\",\"size\":3449}],\"qemu_adapter.py\":[{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"sha256\":\"1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b\",\"size\":4627},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"sha256\":\"1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b\",\"size\":4627},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"sha256\":\"1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b\",\"size\":4627},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"sha256\":\"1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b\",\"size\":4627}],\"scheduler_adapter.py\":[{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"sha256\":\"a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96\",\"size\":4097},{\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"sha256\":\"a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96\",\"size\":4097}]}\nHELPER_LOGIC_HITS={\"entry504.py\":[{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"BASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"def _wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,base=BASE):\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"required=('capture_pve_guest','backup_target','load_targets','cluster_inventory','ssh_remote',\"},{\"line\":64,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"'choose_due_target','write_state','epoch')\"},{\"line\":78,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"scheduler_wired=scheduler_adapter.bind(proxy,g['choose_due_target'],g['write_state'])\"},{\"line\":79,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if g.get('choose_due_target') is not scheduler_wired['choose_due_target'] or g.get('write_state') is not scheduler_wired['write_state']:\"},{\"line\":80,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_ADAPTER_BIND_RESULT')\"},{\"line\":81,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return {'legacy_globals':g,'legacy':proxy,'original_capture':original,'qemu_patched_capture':qemu_patched,'patched_capture':patched,'scheduler_wired':scheduler_wired}\"},{\"line\":88,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"# Baseline accepted wrapper selftest stays the compatibility gate; no full old legacy selftest is reintroduced.\"},{\"line\":89,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wrapper.selftest()\"},{\"line\":93,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"scheduler_adapter=importlib.import_module('scheduler_adapter')\"},{\"line\":96,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wired=_wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,BASE)\"},{\"line\":97,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired\"},{\"line\":99,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"def _target(wrapper,lid):\"},{\"line\":100,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"rows=wrapper.load_targets(); hits=[x for x in rows if x.get('logical_id')==lid]\"},{\"line\":101,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if len(hits)!=1: raise RuntimeError('TARGET_CARDINALITY')\"},{\"line\":104,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"def selftest():\"},{\"line\":105,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired=_load()\"},{\"line\":108,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if wired['legacy_globals'].get('choose_due_target') is not wired['scheduler_wired']['choose_due_target']:\"},{\"line\":109,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_CHOOSE_BINDING')\"},{\"line\":110,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if wired['legacy_globals'].get('write_state') is not wired['scheduler_wired']['write_state']:\"},{\"line\":111,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_WRITE_BINDING')\"},{\"line\":112,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if [scheduler_adapter.backoff_seconds(n) for n in range(1,7)]!=[1800,3600,7200,14400,21600,21600]:\"},{\"line\":113,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_BACKOFF_CONTRACT')\"},{\"line\":114,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if not callable(wrapper.backup_target) or not callable(wrapper.main) or not callable(wrapper.load_targets):\"},{\"line\":116,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('SELFTEST_OVERLAY504=PASS',flush=True)\"},{\"line\":120,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"argv=list(sys.argv[1:] if argv is None else argv)\"},{\"line\":121,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if argv==['selftest']:\"},{\"line\":122,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return selftest()\"},{\"line\":123,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired=_load()\"},{\"line\":125,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if argv==['scheduler-proof']:\"},{\"line\":129,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if old_root is None or not callable(old_epoch): raise RuntimeError('SCHEDULER_PROOF_BASE')\"},{\"line\":132,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"with tempfile.TemporaryDirectory(prefix='homelab-scheduler-proof-',dir='/run') as td:\"},{\"line\":141,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"targets=[{'logical_id':'proof-a','enabled':True,'due_seconds':100},{'logical_id':'proof-b','enabled':True,'due_seconds':100}]\"},{\"line\":142,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"first=legacy.choose_due_target(targets,state,now[0])\"},{\"line\":143,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if not isinstance(first,dict) or first.get('logical_id')!='proof-b': raise RuntimeError('SCHEDULER_PROOF_PEER_NOT_SELECTED')\"},{\"line\":146,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_PROOF_FAILURE_STATE')\"},{\"line\":148,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"second=legacy.choose_due_target(targets,legacy.load_state_all(),now[0])\"},{\"line\":149,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if not isinstance(second,dict) or second.get('logical_id')!='proof-a': raise RuntimeError('SCHEDULER_PROOF_RETRY_NOT_REELIGIBLE')\"},{\"line\":153,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_PROOF_SUCCESS_RESET')\"},{\"line\":154,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"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}\"},{\"line\":155,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('SCHEDULER_FAILURE_ISOLATION_PROOF='+json.dumps(proof,separators=(',',':'),sort_keys=True),flush=True)\"},{\"line\":159,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if argv==['scheduler-select-live']:\"},{\"line\":160,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"state=legacy.load_state_all(); targets=wrapper.load_targets()\"},{\"line\":161,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"chosen=legacy.choose_due_target(targets,state)\"},{\"line\":163,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('SCHEDULER_LIVE_SELECTION=DEFER_NO_DUE_TARGET',flush=True)\"},{\"line\":165,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"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)\"},{\"line\":167,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if len(argv)==2 and argv[0]=='plan-lxc':\"},{\"line\":168,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"t=_target(wrapper,argv[1])\"},{\"line\":169,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if t.get('guest_type')!='lxc' or t.get('logical_id')=='guest-pve01-lxc-112':\"},{\"line\":170,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('PLAN_TARGET_NOT_LEGACY_LXC')\"},{\"line\":172,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"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)\"},{\"line\":174,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if len(argv)==2 and argv[0]=='verify-target':\"},{\"line\":175,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"t=_target(wrapper,argv[1])\"},{\"line\":176,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if t.get('logical_id')=='guest-pve01-lxc-112':\"},{\"line\":179,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"out=wrapper.backup_target(t,True)\"},{\"line\":180,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"except legacy.BackupError as e:\"},{\"line\":181,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('VERIFY_TARGET_RESULT=FAIL',flush=True)\"},{\"line\":182,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('VERIFY_TARGET_REASON='+str(e.code),flush=True)\"},{\"line\":184,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('VERIFY_TARGET_RESULT='+json.dumps(out,separators=(',',':'),sort_keys=True),flush=True)\"},{\"line\":186,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return wrapper.main([sys.argv[0],*argv])\"},{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"BASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"def _wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,base=BASE):\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"required=('capture_pve_guest','backup_target','load_targets','cluster_inventory','ssh_remote',\"},{\"line\":64,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"'choose_due_target','write_state','epoch')\"},{\"line\":78,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"scheduler_wired=scheduler_adapter.bind(proxy,g['choose_due_target'],g['write_state'])\"},{\"line\":79,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if g.get('choose_due_target') is not scheduler_wired['choose_due_target'] or g.get('write_state') is not scheduler_wired['write_state']:\"},{\"line\":80,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_ADAPTER_BIND_RESULT')\"},{\"line\":81,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return {'legacy_globals':g,'legacy':proxy,'original_capture':original,'qemu_patched_capture':qemu_patched,'patched_capture':patched,'scheduler_wired':scheduler_wired}\"},{\"line\":88,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"# Baseline accepted wrapper selftest stays the compatibility gate; no full old legacy selftest is reintroduced.\"},{\"line\":89,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wrapper.selftest()\"},{\"line\":93,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"scheduler_adapter=importlib.import_module('scheduler_adapter')\"},{\"line\":96,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wired=_wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,BASE)\"},{\"line\":97,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired\"},{\"line\":99,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"def _target(wrapper,lid):\"},{\"line\":100,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"rows=wrapper.load_targets(); hits=[x for x in rows if x.get('logical_id')==lid]\"},{\"line\":101,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if len(hits)!=1: raise RuntimeError('TARGET_CARDINALITY')\"},{\"line\":104,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"def selftest():\"},{\"line\":105,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired=_load()\"},{\"line\":108,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if wired['legacy_globals'].get('choose_due_target') is not wired['scheduler_wired']['choose_due_target']:\"},{\"line\":109,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_CHOOSE_BINDING')\"},{\"line\":110,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if wired['legacy_globals'].get('write_state') is not wired['scheduler_wired']['write_state']:\"},{\"line\":111,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_WRITE_BINDING')\"},{\"line\":112,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if [scheduler_adapter.backoff_seconds(n) for n in range(1,7)]!=[1800,3600,7200,14400,21600,21600]:\"},{\"line\":113,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_BACKOFF_CONTRACT')\"},{\"line\":114,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if not callable(wrapper.backup_target) or not callable(wrapper.main) or not callable(wrapper.load_targets):\"},{\"line\":116,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('SELFTEST_OVERLAY504=PASS',flush=True)\"},{\"line\":120,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"argv=list(sys.argv[1:] if argv is None else argv)\"},{\"line\":121,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if argv==['selftest']:\"},{\"line\":122,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return selftest()\"},{\"line\":123,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired=_load()\"},{\"line\":125,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if argv==['scheduler-proof']:\"},{\"line\":129,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if old_root is None or not callable(old_epoch): raise RuntimeError('SCHEDULER_PROOF_BASE')\"},{\"line\":132,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"with tempfile.TemporaryDirectory(prefix='homelab-scheduler-proof-',dir='/run') as td:\"},{\"line\":141,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"targets=[{'logical_id':'proof-a','enabled':True,'due_seconds':100},{'logical_id':'proof-b','enabled':True,'due_seconds':100}]\"},{\"line\":142,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"first=legacy.choose_due_target(targets,state,now[0])\"},{\"line\":143,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if not isinstance(first,dict) or first.get('logical_id')!='proof-b': raise RuntimeError('SCHEDULER_PROOF_PEER_NOT_SELECTED')\"},{\"line\":146,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_PROOF_FAILURE_STATE')\"},{\"line\":148,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"second=legacy.choose_due_target(targets,legacy.load_state_all(),now[0])\"},{\"line\":149,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if not isinstance(second,dict) or second.get('logical_id')!='proof-a': raise RuntimeError('SCHEDULER_PROOF_RETRY_NOT_REELIGIBLE')\"},{\"line\":153,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('SCHEDULER_PROOF_SUCCESS_RESET')\"},{\"line\":154,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"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}\"},{\"line\":155,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('SCHEDULER_FAILURE_ISOLATION_PROOF='+json.dumps(proof,separators=(',',':'),sort_keys=True),flush=True)\"},{\"line\":159,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if argv==['scheduler-select-live']:\"},{\"line\":160,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"state=legacy.load_state_all(); targets=wrapper.load_targets()\"},{\"line\":161,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"chosen=legacy.choose_due_target(targets,state)\"},{\"line\":163,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('SCHEDULER_LIVE_SELECTION=DEFER_NO_DUE_TARGET',flush=True)\"},{\"line\":165,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"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)\"},{\"line\":167,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if len(argv)==2 and argv[0]=='plan-lxc':\"},{\"line\":168,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"t=_target(wrapper,argv[1])\"},{\"line\":169,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if t.get('guest_type')!='lxc' or t.get('logical_id')=='guest-pve01-lxc-112':\"},{\"line\":170,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"raise RuntimeError('PLAN_TARGET_NOT_LEGACY_LXC')\"},{\"line\":172,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"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)\"},{\"line\":174,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if len(argv)==2 and argv[0]=='verify-target':\"},{\"line\":175,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"t=_target(wrapper,argv[1])\"},{\"line\":176,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"if t.get('logical_id')=='guest-pve01-lxc-112':\"},{\"line\":179,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"out=wrapper.backup_target(t,True)\"},{\"line\":180,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"except legacy.BackupError as e:\"},{\"line\":181,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('VERIFY_TARGET_RESULT=FAIL',flush=True)\"},{\"line\":182,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('VERIFY_TARGET_REASON='+str(e.code),flush=True)\"},{\"line\":184,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"print('VERIFY_TARGET_RESULT='+json.dumps(out,separators=(',',':'),sort_keys=True),flush=True)\"},{\"line\":186,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py\",\"text\":\"return wrapper.main([sys.argv[0],*argv])\"}],\"fresh_lxc_helper.py\":[{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"BASE_RELEASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')\"},{\"line\":15,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"if len(sys.argv)!=1: fail('HELPER_ARGC')\"},{\"line\":26,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')\"},{\"line\":27,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"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')\"},{\"line\":30,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)\"},{\"line\":31,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')\"},{\"line\":37,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"guest266.no_active_tasks(raw.get('tasks'),vmid)\"},{\"line\":39,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-500r1-a3964599e60c/fresh_lxc_helper.py\",\"text\":\"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')\"},{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"BASE_RELEASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')\"},{\"line\":15,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"if len(sys.argv)!=1: fail('HELPER_ARGC')\"},{\"line\":26,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')\"},{\"line\":27,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"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')\"},{\"line\":30,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)\"},{\"line\":31,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')\"},{\"line\":37,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"guest266.no_active_tasks(raw.get('tasks'),vmid)\"},{\"line\":39,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/fresh_lxc_helper.py\",\"text\":\"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')\"},{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"BASE_RELEASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')\"},{\"line\":15,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"if len(sys.argv)!=1: fail('HELPER_ARGC')\"},{\"line\":26,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')\"},{\"line\":27,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"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')\"},{\"line\":30,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)\"},{\"line\":31,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')\"},{\"line\":37,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"guest266.no_active_tasks(raw.get('tasks'),vmid)\"},{\"line\":39,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/fresh_lxc_helper.py\",\"text\":\"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')\"}],\"lxc_adapter.py\":[{\"line\":2,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"import base64, hashlib, json, os, pathlib, re, selectors, shlex, signal, stat, subprocess, sys, time\"},{\"line\":6,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"HELPER=pathlib.Path(__file__).resolve().parent/'fresh_lxc_helper.py'\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"def _remote_sha(legacy,node,path):\"},{\"line\":36,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30)\"},{\"line\":41,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"def _live_inputs(legacy,node,vmid,scratch):\"},{\"line\":42,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/pvesh')==PVESH_SHA,'PVESH_IDENTITY')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY')\"},{\"line\":44,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"rows=_j(legacy.ssh_remote(node,['pvesh','get','/cluster/resources','--type','vm','--output-format','json'],timeout=60),'RESOURCES_JSON')\"},{\"line\":45,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"stores=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/storage','--output-format','json'],timeout=60),'STORAGE_JSON')\"},{\"line\":49,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"if not isinstance(r,dict) or r.get('node')!=node or r.get('type') not in ('lxc','qemu'): continue\"},{\"line\":50,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"try: rid=int(r.get('vmid'))\"},{\"line\":51,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"except Exception: raise AdapterError('RESOURCE_VMID')\"},{\"line\":52,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"cfg=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/{r[\\\"type\\\"]}/{rid}/config','--output-format','json'],timeout=60),'CONFIG_JSON')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"tasks=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/tasks','--limit','999','--output-format','json'],timeout=60),'TASKS_JSON')\"},{\"line\":57,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False)\"},{\"line\":59,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"return {'node':node,'vmid':vmid,'scratch':scratch,'now':int(time.time()),'rows':rows,'storage_rows':stores,'configs':configs,\"},{\"line\":67,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(0<len(data)<=4_000_000,'FRESH_HELPER_INPUT_BOUND')\"},{\"line\":68,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"p=subprocess.run(['/usr/bin/python3','-I','-B',str(HELPER)],input=data,capture_output=True,timeout=120,cwd='/',env=ENV)\"},{\"line\":69,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(p.returncode==0 and not p.stderr and 0<len(p.stdout)<=262144,'FRESH_HELPER_FAILED')\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"except Exception as e: raise AdapterError('FRESH_HELPER_JSON') from e\"},{\"line\":72,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(type(out) is dict and out.get('schema')==1 and type(out.get('argv')) is list and type(out.get('job')) is dict,'FRESH_HELPER_SCHEMA')\"},{\"line\":80,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":82,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":84,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"legacy._default_unprivileged_lxc(node,vmid)\"},{\"line\":85,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"a=_helper(_live_inputs(legacy,node,vmid,scratch)); b=_helper(_live_inputs(legacy,node,vmid,scratch))\"},{\"line\":86,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(_stable_job(a['job'])==_stable_job(b['job']),'FRESH_PLAN_UNSTABLE')\"},{\"line\":87,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(a['argv']==b['argv'],'FRESH_ARGV_UNSTABLE')\"},{\"line\":88,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_POST')\"},{\"line\":91,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"def _execute_local(legacy,node,argv,dest,cap,timeout):\"},{\"line\":92,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(node=='pve01','LOCAL_NODE')\"},{\"line\":95,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"p=subprocess.run(['/usr/bin/python3','-I','-B',str(EXEC_HELPER)],input=data,capture_output=True,timeout=timeout+120,cwd='/',env=ENV)\"},{\"line\":112,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"except subprocess.TimeoutExpired:\"},{\"line\":117,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"def _execute_remote(legacy,node,argv,dest,cap,timeout):\"},{\"line\":118,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(re.fullmatch(r'pve0[123]',str(node)) is not None and node!='pve01','REMOTE_NODE')\"},{\"line\":120,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need('--node' in argv and argv[argv.index('--node')+1]==node,'REMOTE_ARGV_NODE')\"},{\"line\":122,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_PRE')\"},{\"line\":130,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"ssh=['/usr/bin/ssh','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','-o','ConnectTimeout=15',f'root@{node}',remote]\"},{\"line\":133,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"p=subprocess.Popen(ssh,stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,cwd='/',env=ENV,start_new_session=True,close_fds=True)\"},{\"line\":156,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_POST')\"},{\"line\":183,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"def _emit_diag(node,summary):\"},{\"line\":184,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"safe={'node':node}\"},{\"line\":193,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":195,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":197,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"legacy._default_unprivileged_lxc(node,vmid)\"},{\"line\":199,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"legacy.ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30)\"},{\"line\":200,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30)\"},{\"line\":203,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"legacy.mapped_scratch_probe(node,scratch)\"},{\"line\":206,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"result=_execute_local(legacy,node,p['argv'],local,cap,7200) if node=='pve01' else _execute_remote(legacy,node,p['argv'],local,cap,7200)\"},{\"line\":208,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_emit_diag(node,e.summary|{'failure_code':e.code})\"},{\"line\":209,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"raise legacy.BackupError('LXC_PRODUCER_FAILED') from None\"},{\"line\":211,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"_emit_diag(node,result)\"},{\"line\":213,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"legacy.ssh_remote(node,['rm','-rf','--',scratch],timeout=60,check=False); raise\"},{\"line\":214,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"cleanup={'kind':'pve_source_dir','node':node,'path':scratch}\"},{\"line\":215,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'lxc','node':node,'status':row.get('status'),\"},{\"line\":216,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/lxc_adapter.py\",\"text\":\"'producer_contract':'fresh-pve265-plan-bounded-producer-overlay502'}\"},{\"line\":2,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"import base64, hashlib, json, os, pathlib, re, selectors, shlex, signal, stat, subprocess, sys, time\"},{\"line\":6,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"HELPER=pathlib.Path(__file__).resolve().parent/'fresh_lxc_helper.py'\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"def _remote_sha(legacy,node,path):\"},{\"line\":36,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30)\"},{\"line\":41,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"def _live_inputs(legacy,node,vmid,scratch):\"},{\"line\":42,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/pvesh')==PVESH_SHA,'PVESH_IDENTITY')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY')\"},{\"line\":44,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"rows=_j(legacy.ssh_remote(node,['pvesh','get','/cluster/resources','--type','vm','--output-format','json'],timeout=60),'RESOURCES_JSON')\"},{\"line\":45,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"stores=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/storage','--output-format','json'],timeout=60),'STORAGE_JSON')\"},{\"line\":49,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"if not isinstance(r,dict) or r.get('node')!=node or r.get('type') not in ('lxc','qemu'): continue\"},{\"line\":50,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"try: rid=int(r.get('vmid'))\"},{\"line\":51,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"except Exception: raise AdapterError('RESOURCE_VMID')\"},{\"line\":52,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"cfg=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/{r[\\\"type\\\"]}/{rid}/config','--output-format','json'],timeout=60),'CONFIG_JSON')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"tasks=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/tasks','--limit','999','--output-format','json'],timeout=60),'TASKS_JSON')\"},{\"line\":57,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False)\"},{\"line\":59,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"return {'node':node,'vmid':vmid,'scratch':scratch,'now':int(time.time()),'rows':rows,'storage_rows':stores,'configs':configs,\"},{\"line\":67,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(0<len(data)<=4_000_000,'FRESH_HELPER_INPUT_BOUND')\"},{\"line\":68,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"p=subprocess.run(['/usr/bin/python3','-I','-B',str(HELPER)],input=data,capture_output=True,timeout=120,cwd='/',env=ENV)\"},{\"line\":69,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(p.returncode==0 and not p.stderr and 0<len(p.stdout)<=262144,'FRESH_HELPER_FAILED')\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"except Exception as e: raise AdapterError('FRESH_HELPER_JSON') from e\"},{\"line\":72,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(type(out) is dict and out.get('schema')==1 and type(out.get('argv')) is list and type(out.get('job')) is dict,'FRESH_HELPER_SCHEMA')\"},{\"line\":80,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":82,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":84,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"legacy._default_unprivileged_lxc(node,vmid)\"},{\"line\":85,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"a=_helper(_live_inputs(legacy,node,vmid,scratch)); b=_helper(_live_inputs(legacy,node,vmid,scratch))\"},{\"line\":86,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(_stable_job(a['job'])==_stable_job(b['job']),'FRESH_PLAN_UNSTABLE')\"},{\"line\":87,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(a['argv']==b['argv'],'FRESH_ARGV_UNSTABLE')\"},{\"line\":88,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_POST')\"},{\"line\":91,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"def _execute_local(legacy,node,argv,dest,cap,timeout):\"},{\"line\":92,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(node=='pve01','LOCAL_NODE')\"},{\"line\":95,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"p=subprocess.run(['/usr/bin/python3','-I','-B',str(EXEC_HELPER)],input=data,capture_output=True,timeout=timeout+120,cwd='/',env=ENV)\"},{\"line\":112,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"except subprocess.TimeoutExpired:\"},{\"line\":117,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"def _execute_remote(legacy,node,argv,dest,cap,timeout):\"},{\"line\":118,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(re.fullmatch(r'pve0[123]',str(node)) is not None and node!='pve01','REMOTE_NODE')\"},{\"line\":120,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need('--node' in argv and argv[argv.index('--node')+1]==node,'REMOTE_ARGV_NODE')\"},{\"line\":122,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_PRE')\"},{\"line\":130,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"ssh=['/usr/bin/ssh','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','-o','ConnectTimeout=15',f'root@{node}',remote]\"},{\"line\":133,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"p=subprocess.Popen(ssh,stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,cwd='/',env=ENV,start_new_session=True,close_fds=True)\"},{\"line\":156,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_POST')\"},{\"line\":183,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"def _emit_diag(node,summary):\"},{\"line\":184,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"safe={'node':node}\"},{\"line\":193,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":195,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":197,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"legacy._default_unprivileged_lxc(node,vmid)\"},{\"line\":199,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"legacy.ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30)\"},{\"line\":200,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30)\"},{\"line\":203,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"legacy.mapped_scratch_probe(node,scratch)\"},{\"line\":206,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"result=_execute_local(legacy,node,p['argv'],local,cap,7200) if node=='pve01' else _execute_remote(legacy,node,p['argv'],local,cap,7200)\"},{\"line\":208,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_emit_diag(node,e.summary|{'failure_code':e.code})\"},{\"line\":209,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"raise legacy.BackupError('LXC_PRODUCER_FAILED') from None\"},{\"line\":211,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"_emit_diag(node,result)\"},{\"line\":213,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"legacy.ssh_remote(node,['rm','-rf','--',scratch],timeout=60,check=False); raise\"},{\"line\":214,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"cleanup={'kind':'pve_source_dir','node':node,'path':scratch}\"},{\"line\":215,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'lxc','node':node,'status':row.get('status'),\"},{\"line\":216,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/lxc_adapter.py\",\"text\":\"'producer_contract':'fresh-pve265-plan-bounded-producer-overlay502'}\"},{\"line\":2,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"import base64, hashlib, json, os, pathlib, re, selectors, shlex, signal, stat, subprocess, sys, time\"},{\"line\":6,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"HELPER=pathlib.Path(__file__).resolve().parent/'fresh_lxc_helper.py'\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"def _remote_sha(legacy,node,path):\"},{\"line\":36,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30)\"},{\"line\":41,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"def _live_inputs(legacy,node,vmid,scratch):\"},{\"line\":42,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/pvesh')==PVESH_SHA,'PVESH_IDENTITY')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY')\"},{\"line\":44,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"rows=_j(legacy.ssh_remote(node,['pvesh','get','/cluster/resources','--type','vm','--output-format','json'],timeout=60),'RESOURCES_JSON')\"},{\"line\":45,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"stores=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/storage','--output-format','json'],timeout=60),'STORAGE_JSON')\"},{\"line\":49,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"if not isinstance(r,dict) or r.get('node')!=node or r.get('type') not in ('lxc','qemu'): continue\"},{\"line\":50,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"try: rid=int(r.get('vmid'))\"},{\"line\":51,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"except Exception: raise AdapterError('RESOURCE_VMID')\"},{\"line\":52,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"cfg=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/{r[\\\"type\\\"]}/{rid}/config','--output-format','json'],timeout=60),'CONFIG_JSON')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"tasks=_j(legacy.ssh_remote(node,['pvesh','get',f'/nodes/{node}/tasks','--limit','999','--output-format','json'],timeout=60),'TASKS_JSON')\"},{\"line\":57,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False)\"},{\"line\":59,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"return {'node':node,'vmid':vmid,'scratch':scratch,'now':int(time.time()),'rows':rows,'storage_rows':stores,'configs':configs,\"},{\"line\":67,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(0<len(data)<=4_000_000,'FRESH_HELPER_INPUT_BOUND')\"},{\"line\":68,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"p=subprocess.run(['/usr/bin/python3','-I','-B',str(HELPER)],input=data,capture_output=True,timeout=120,cwd='/',env=ENV)\"},{\"line\":69,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(p.returncode==0 and not p.stderr and 0<len(p.stdout)<=262144,'FRESH_HELPER_FAILED')\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"except Exception as e: raise AdapterError('FRESH_HELPER_JSON') from e\"},{\"line\":72,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(type(out) is dict and out.get('schema')==1 and type(out.get('argv')) is list and type(out.get('job')) is dict,'FRESH_HELPER_SCHEMA')\"},{\"line\":80,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":82,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":84,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"legacy._default_unprivileged_lxc(node,vmid)\"},{\"line\":85,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"a=_helper(_live_inputs(legacy,node,vmid,scratch)); b=_helper(_live_inputs(legacy,node,vmid,scratch))\"},{\"line\":86,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(_stable_job(a['job'])==_stable_job(b['job']),'FRESH_PLAN_UNSTABLE')\"},{\"line\":87,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(a['argv']==b['argv'],'FRESH_ARGV_UNSTABLE')\"},{\"line\":88,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_POST')\"},{\"line\":91,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"def _execute_local(legacy,node,argv,dest,cap,timeout):\"},{\"line\":92,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(node=='pve01','LOCAL_NODE')\"},{\"line\":95,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"p=subprocess.run(['/usr/bin/python3','-I','-B',str(EXEC_HELPER)],input=data,capture_output=True,timeout=timeout+120,cwd='/',env=ENV)\"},{\"line\":112,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"except subprocess.TimeoutExpired:\"},{\"line\":117,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"def _execute_remote(legacy,node,argv,dest,cap,timeout):\"},{\"line\":118,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(re.fullmatch(r'pve0[123]',str(node)) is not None and node!='pve01','REMOTE_NODE')\"},{\"line\":120,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need('--node' in argv and argv[argv.index('--node')+1]==node,'REMOTE_ARGV_NODE')\"},{\"line\":122,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_PRE')\"},{\"line\":130,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"ssh=['/usr/bin/ssh','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','-o','ConnectTimeout=15',f'root@{node}',remote]\"},{\"line\":133,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"p=subprocess.Popen(ssh,stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,cwd='/',env=ENV,start_new_session=True,close_fds=True)\"},{\"line\":156,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'VZDUMP_IDENTITY_EXEC_POST')\"},{\"line\":183,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"def _emit_diag(node,summary):\"},{\"line\":184,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"safe={'node':node}\"},{\"line\":193,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":195,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":197,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"legacy._default_unprivileged_lxc(node,vmid)\"},{\"line\":199,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"legacy.ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30)\"},{\"line\":200,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30)\"},{\"line\":203,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"legacy.mapped_scratch_probe(node,scratch)\"},{\"line\":206,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"result=_execute_local(legacy,node,p['argv'],local,cap,7200) if node=='pve01' else _execute_remote(legacy,node,p['argv'],local,cap,7200)\"},{\"line\":208,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_emit_diag(node,e.summary|{'failure_code':e.code})\"},{\"line\":209,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"raise legacy.BackupError('LXC_PRODUCER_FAILED') from None\"},{\"line\":211,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"_emit_diag(node,result)\"},{\"line\":213,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"legacy.ssh_remote(node,['rm','-rf','--',scratch],timeout=60,check=False); raise\"},{\"line\":214,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"cleanup={'kind':'pve_source_dir','node':node,'path':scratch}\"},{\"line\":215,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'lxc','node':node,'status':row.get('status'),\"},{\"line\":216,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\",\"text\":\"'producer_contract':'fresh-pve265-plan-bounded-producer-overlay502'}\"}],\"producer_exec_helper.py\":[{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"BASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411')\"},{\"line\":26,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"def selftest()->int:\"},{\"line\":31,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"print('PRODUCER_EXEC_HELPER_SELFTEST=PASS',flush=True)\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"if sys.argv[1:]==['selftest']: return selftest()\"},{\"line\":36,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"if sys.argv[1:]: fail('ARGC')\"},{\"line\":41,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"if type(x) is not dict or set(x)!={'argv','dest','cap','seconds'}: fail('INPUT_SCHEMA')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"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')\"},{\"line\":44,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-502r1-9d13ea486935/producer_exec_helper.py\",\"text\":\"if argv[0]!='/usr/bin/vzdump': fail('VZDUMP_PATH')\"},{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"BASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411')\"},{\"line\":26,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"def selftest()->int:\"},{\"line\":31,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"print('PRODUCER_EXEC_HELPER_SELFTEST=PASS',flush=True)\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"if sys.argv[1:]==['selftest']: return selftest()\"},{\"line\":36,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"if sys.argv[1:]: fail('ARGC')\"},{\"line\":41,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"if type(x) is not dict or set(x)!={'argv','dest','cap','seconds'}: fail('INPUT_SCHEMA')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"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')\"},{\"line\":44,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/producer_exec_helper.py\",\"text\":\"if argv[0]!='/usr/bin/vzdump': fail('VZDUMP_PATH')\"},{\"line\":4,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"BASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411')\"},{\"line\":26,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"def selftest()->int:\"},{\"line\":31,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"print('PRODUCER_EXEC_HELPER_SELFTEST=PASS',flush=True)\"},{\"line\":35,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"if sys.argv[1:]==['selftest']: return selftest()\"},{\"line\":36,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"if sys.argv[1:]: fail('ARGC')\"},{\"line\":41,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"if type(x) is not dict or set(x)!={'argv','dest','cap','seconds'}: fail('INPUT_SCHEMA')\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"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')\"},{\"line\":44,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/producer_exec_helper.py\",\"text\":\"if argv[0]!='/usr/bin/vzdump': fail('VZDUMP_PATH')\"}],\"qemu_adapter.py\":[{\"line\":11,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"def _remote_sha(legacy,node,path):\"},{\"line\":12,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30)\"},{\"line\":17,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"def _select_qemu_outputs(vmid,files):\"},{\"line\":18,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_need(type(vmid) is int and vmid>0,'QEMU_VMID')\"},{\"line\":21,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"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$')\"},{\"line\":29,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"expected_log=parent/f'vzdump-qemu-{vmid}-{stamp}.log'\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":45,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":47,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_PRE')\"},{\"line\":49,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"legacy.ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30)\"},{\"line\":51,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"vp=legacy.ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200,check=False)\"},{\"line\":53,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_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)\"},{\"line\":54,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"raise legacy.BackupError('QEMU_VZDUMP_FAILED')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_POST')\"},{\"line\":56,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\\\\n'],timeout=30)\"},{\"line\":58,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"try: src,log=_select_qemu_outputs(vmid,files)\"},{\"line\":60,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_emit_diag(vmid=vmid,node=node,producer_rc=0,regular_file_count=len(files),archive_selected=False,selector_error=str(e))\"},{\"line\":61,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"raise legacy.BackupError(str(e)) from None\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['stat','-c','%s','--',src],timeout=30)\"},{\"line\":67,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"if node=='pve01': local=pathlib.Path(src)\"},{\"line\":69,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"legacy.run([legacy.SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200)\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_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)\"},{\"line\":73,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"legacy.ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False); raise\"},{\"line\":74,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"cleanup={'kind':'pve_source_dir','node':node,'path':srcdir}\"},{\"line\":75,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'qemu','node':node,'status':row.get('status'),\"},{\"line\":11,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"def _remote_sha(legacy,node,path):\"},{\"line\":12,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30)\"},{\"line\":17,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"def _select_qemu_outputs(vmid,files):\"},{\"line\":18,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"_need(type(vmid) is int and vmid>0,'QEMU_VMID')\"},{\"line\":21,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"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$')\"},{\"line\":29,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"expected_log=parent/f'vzdump-qemu-{vmid}-{stamp}.log'\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":45,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":47,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_PRE')\"},{\"line\":49,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"legacy.ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30)\"},{\"line\":51,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"vp=legacy.ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200,check=False)\"},{\"line\":53,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"_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)\"},{\"line\":54,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"raise legacy.BackupError('QEMU_VZDUMP_FAILED')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_POST')\"},{\"line\":56,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\\\\n'],timeout=30)\"},{\"line\":58,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"try: src,log=_select_qemu_outputs(vmid,files)\"},{\"line\":60,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"_emit_diag(vmid=vmid,node=node,producer_rc=0,regular_file_count=len(files),archive_selected=False,selector_error=str(e))\"},{\"line\":61,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"raise legacy.BackupError(str(e)) from None\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['stat','-c','%s','--',src],timeout=30)\"},{\"line\":67,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"if node=='pve01': local=pathlib.Path(src)\"},{\"line\":69,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"legacy.run([legacy.SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200)\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"_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)\"},{\"line\":73,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"legacy.ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False); raise\"},{\"line\":74,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"cleanup={'kind':'pve_source_dir','node':node,'path':srcdir}\"},{\"line\":75,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/qemu_adapter.py\",\"text\":\"meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'qemu','node':node,'status':row.get('status'),\"},{\"line\":11,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"def _remote_sha(legacy,node,path):\"},{\"line\":12,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['sha256sum','--',path],timeout=30)\"},{\"line\":17,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"def _select_qemu_outputs(vmid,files):\"},{\"line\":18,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_need(type(vmid) is int and vmid>0,'QEMU_VMID')\"},{\"line\":21,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"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$')\"},{\"line\":29,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"expected_log=parent/f'vzdump-qemu-{vmid}-{stamp}.log'\"},{\"line\":43,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"vmid=int(t['vmid']); rows=[r for r in legacy.cluster_inventory() if int(r.get('vmid',-1))==vmid]\"},{\"line\":45,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"row=rows[0]; node=row.get('node'); typ=row.get('type')\"},{\"line\":47,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_PRE')\"},{\"line\":49,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"legacy.ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30)\"},{\"line\":51,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"vp=legacy.ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200,check=False)\"},{\"line\":53,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_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)\"},{\"line\":54,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"raise legacy.BackupError('QEMU_VZDUMP_FAILED')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_need(_remote_sha(legacy,node,'/usr/bin/vzdump')==VZDUMP_SHA,'QEMU_VZDUMP_IDENTITY_POST')\"},{\"line\":56,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"p=legacy.ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\\\\n'],timeout=30)\"},{\"line\":58,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"try: src,log=_select_qemu_outputs(vmid,files)\"},{\"line\":60,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_emit_diag(vmid=vmid,node=node,producer_rc=0,regular_file_count=len(files),archive_selected=False,selector_error=str(e))\"},{\"line\":61,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"raise legacy.BackupError(str(e)) from None\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"q=legacy.ssh_remote(node,['stat','-c','%s','--',src],timeout=30)\"},{\"line\":67,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"if node=='pve01': local=pathlib.Path(src)\"},{\"line\":69,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"legacy.run([legacy.SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200)\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"_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)\"},{\"line\":73,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"legacy.ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False); raise\"},{\"line\":74,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"cleanup={'kind':'pve_source_dir','node':node,'path':srcdir}\"},{\"line\":75,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-503r1-ac51fd96ec13/qemu_adapter.py\",\"text\":\"meta={'generation':gen,'source_class':'pve_guest','vmid':vmid,'guest_type':'qemu','node':node,'status':row.get('status'),\"}],\"scheduler_adapter.py\":[{\"line\":7,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"class SchedulerAdapterError(RuntimeError): pass\"},{\"line\":10,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"if not ok: raise SchedulerAdapterError(code)\"},{\"line\":23,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"def _read_prior(legacy,logical_id):\"},{\"line\":25,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"p=root/(str(logical_id)+'.json')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"def choose_due_target(targets,state,now=None):\"},{\"line\":57,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"_need(isinstance(targets,list) and isinstance(state,dict),'SCHEDULER_INPUT_SCHEMA')\"},{\"line\":58,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"due=[]\"},{\"line\":59,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"for order,t in enumerate(targets):\"},{\"line\":61,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"lid=t.get('logical_id'); seconds=_as_nonneg_int(t.get('due_seconds'),0)\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"_need(isinstance(lid,str) and lid and seconds>0,'SCHEDULER_TARGET_SCHEMA')\"},{\"line\":70,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"overdue=age-seconds\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"due.append((overdue,-order,t))\"},{\"line\":72,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"if not due: return None\"},{\"line\":73,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return max(due,key=lambda x:(x[0],x[1]))[2]\"},{\"line\":75,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"def write_state(logical_id,result,**kw):\"},{\"line\":77,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"prior=_read_prior(legacy,logical_id)\"},{\"line\":81,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return original_write(logical_id,result,**clean)\"},{\"line\":88,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return original_write(logical_id,result,**clean)\"},{\"line\":90,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"legacy.choose_due_target=choose_due_target\"},{\"line\":92,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return {'choose_due_target':choose_due_target,'write_state':write_state,\"},{\"line\":7,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"class SchedulerAdapterError(RuntimeError): pass\"},{\"line\":10,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"if not ok: raise SchedulerAdapterError(code)\"},{\"line\":23,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"def _read_prior(legacy,logical_id):\"},{\"line\":25,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"p=root/(str(logical_id)+'.json')\"},{\"line\":55,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"def choose_due_target(targets,state,now=None):\"},{\"line\":57,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"_need(isinstance(targets,list) and isinstance(state,dict),'SCHEDULER_INPUT_SCHEMA')\"},{\"line\":58,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"due=[]\"},{\"line\":59,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"for order,t in enumerate(targets):\"},{\"line\":61,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"lid=t.get('logical_id'); seconds=_as_nonneg_int(t.get('due_seconds'),0)\"},{\"line\":62,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"_need(isinstance(lid,str) and lid and seconds>0,'SCHEDULER_TARGET_SCHEMA')\"},{\"line\":70,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"overdue=age-seconds\"},{\"line\":71,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"due.append((overdue,-order,t))\"},{\"line\":72,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"if not due: return None\"},{\"line\":73,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return max(due,key=lambda x:(x[0],x[1]))[2]\"},{\"line\":75,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"def write_state(logical_id,result,**kw):\"},{\"line\":77,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"prior=_read_prior(legacy,logical_id)\"},{\"line\":81,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return original_write(logical_id,result,**clean)\"},{\"line\":88,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return original_write(logical_id,result,**clean)\"},{\"line\":90,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"legacy.choose_due_target=choose_due_target\"},{\"line\":92,\"path\":\"/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/scheduler_adapter.py\",\"text\":\"return {'choose_due_target':choose_due_target,'write_state':write_state,\"}]}\nNODEWORKER_INFO={\"path\":\"/usr/local/libexec/homelab-vm-cloud-quorum-node-worker\",\"sha256\":\"91bdd116be865560a38105dffbd1a66d687232035e2359e4a5be4d225e9c61d1\",\"size\":17702}\nNODEWORKER_LOGIC_HITS=[{\"line\":6,\"text\":\"STATE_ROOT=/var/lib/homelab-backup/cloud-quorum\"},{\"line\":8,\"text\":\"RESTORE_STATE_ROOT=/var/lib/homelab-backup/vm-restore-validation\"},{\"line\":9,\"text\":\"RESTORE_WORK_ROOT=/mnt/staging/homelab-vm-restore-validation\"},{\"line\":11,\"text\":\"REMOTE_A='pve01-mail-01-crypt:homelab-backups'\"},{\"line\":12,\"text\":\"REMOTE_B='pve01-mail-02-crypt:homelab-backups'\"},{\"line\":18,\"text\":\"ACTIVE_RESTORE_STAGE=\\\"\\\"\"},{\"line\":19,\"text\":\"cleanup_restore_stage(){ if [[ -n \\\"$ACTIVE_RESTORE_STAGE\\\" && \\\"$ACTIVE_RESTORE_STAGE\\\" == \\\"$RESTORE_WORK_ROOT\\\"/* && -d \\\"$ACTIVE_RESTORE_STAGE\\\" ]]; then rm -rf --one-file-system \\\"$ACTIVE_RESTORE_STAGE\\\"; fi; }\"},{\"line\":20,\"text\":\"trap cleanup_restore_stage EXIT\"},{\"line\":21,\"text\":\"active_backup_restore(){ local rc; if pgrep -af '(^|/)(vzdump|qmrestore|pctrestore|vma|zstd|rclone)([[:space:]]|$)'; then return 0; else rc=$?; [[ \\\"$rc\\\" == 1 ]] && return 0; die \\\"PGREP_FAILED_$rc\\\" 69; fi; }\"},{\"line\":24,\"text\":\"expected_owner(){\"},{\"line\":25,\"text\":\"case \\\"$1\\\" in\"},{\"line\":29,\"text\":\"*) die \\\"VMID_NOT_ALLOWED_$1\\\" 64 ;;\"},{\"line\":33,\"text\":\"case \\\"$1\\\" in\"},{\"line\":36,\"text\":\"*) die \\\"VMID_NOT_ALLOWED_$1\\\" 64 ;;\"},{\"line\":43,\"text\":\"local vmid=\\\"$1\\\" type=\\\"$2\\\"\"},{\"line\":44,\"text\":\"if [[ \\\"$type\\\" == \\\"qemu\\\" ]]; then qm status \\\"$vmid\\\" | awk '{print $2}'; else pct status \\\"$vmid\\\" | awk '{print $2}'; fi\"},{\"line\":47,\"text\":\"local vmid=\\\"$1\\\" owner type status expect_status\"},{\"line\":48,\"text\":\"owner=\\\"$(expected_owner \\\"$vmid\\\")\\\"\"},{\"line\":49,\"text\":\"type=\\\"$(expected_type \\\"$vmid\\\")\\\"\"},{\"line\":50,\"text\":\"[[ \\\"$HOST\\\" == \\\"$owner\\\" ]] || die \\\"OWNER_MISMATCH_${vmid}_${HOST}_EXPECTED_${owner}\\\" 65\"},{\"line\":52,\"text\":\"[[ -s \\\"/etc/pve/qemu-server/${vmid}.conf\\\" ]] || die \\\"QEMU_CONFIG_MISSING_$vmid\\\" 66\"},{\"line\":54,\"text\":\"[[ -s \\\"/etc/pve/lxc/${vmid}.conf\\\" ]] || die \\\"LXC_CONFIG_MISSING_$vmid\\\" 66\"},{\"line\":56,\"text\":\"status=\\\"$(current_status \\\"$vmid\\\" \\\"$type\\\")\\\"\"},{\"line\":57,\"text\":\"expect_status=\\\"$(expected_status \\\"$vmid\\\")\\\"\"},{\"line\":58,\"text\":\"[[ \\\"$status\\\" == \\\"$expect_status\\\" ]] || die \\\"STATUS_MISMATCH_${vmid}_${status}_EXPECTED_${expect_status}\\\" 66\"},{\"line\":59,\"text\":\"if [[ \\\"$vmid\\\" == \\\"160\\\" ]]; then [[ \\\"$(snapshot_count_160)\\\" == \\\"0\\\" ]] || die \\\"VM160_SNAPSHOT_COUNT_CHANGED\\\" 66; fi\"},{\"line\":60,\"text\":\"if [[ \\\"$vmid\\\" == \\\"9130\\\" ]]; then [[ \\\"$(vm_lock 9130)\\\" == \\\"none\\\" ]] || die \\\"VM9130_LOCK_PRESENT\\\" 66; fi\"},{\"line\":65,\"text\":\"local vmid=\\\"$1\\\" type=\\\"$2\\\" status expect_status\"},{\"line\":66,\"text\":\"status=\\\"$(current_status \\\"$vmid\\\" \\\"$type\\\")\\\"\"},{\"line\":67,\"text\":\"expect_status=\\\"$(expected_status \\\"$vmid\\\")\\\"\"},{\"line\":68,\"text\":\"[[ \\\"$status\\\" == \\\"$expect_status\\\" ]] || die \\\"POST_STATUS_MISMATCH_${vmid}_${status}_EXPECTED_${expect_status}\\\" 66\"},{\"line\":69,\"text\":\"if [[ \\\"$vmid\\\" == \\\"160\\\" ]]; then [[ \\\"$(snapshot_count_160)\\\" == \\\"0\\\" ]] || die \\\"VM160_SNAPSHOT_COUNT_CHANGED_POST\\\" 66; fi\"},{\"line\":70,\"text\":\"if [[ \\\"$vmid\\\" == \\\"9130\\\" ]]; then [[ \\\"$(vm_lock 9130)\\\" == \\\"none\\\" ]] || die \\\"VM9130_LOCK_PRESENT_POST\\\" 66; fi\"},{\"line\":73,\"text\":\"local vmid=\\\"$1\\\" dir=\\\"$STATE_ROOT/vm${vmid}\\\" f\"},{\"line\":79,\"text\":\"restore_dir(){ printf '%s\\\\n' \\\"$RESTORE_STATE_ROOT/vm$1\\\"; }\"},{\"line\":80,\"text\":\"restore_ok(){\"},{\"line\":81,\"text\":\"local vmid=\\\"$1\\\" gen=\\\"$2\\\" f state sha\"},{\"line\":82,\"text\":\"f=\\\"$(restore_dir \\\"$vmid\\\")/$gen.json\\\"; state=\\\"$STATE_ROOT/vm${vmid}/$gen.json\\\"\"},{\"line\":85,\"text\":\"jq -e --arg l \\\"vm${vmid}\\\" --arg g \\\"$gen\\\" --arg s \\\"$state\\\" --arg sha \\\"$sha\\\" '.schema==\\\"homelab-vm-restore-validation-v1\\\" and .logical_id==$l and .generation==$g and .transport_state==\\\"SEALED\\\" and .transport_state_file==$s and .restore_source==\\\"Cloud A\\\" and .parts_manifest_verified==true and .payload_sha256==$sha and .payload_sha256_verified==true and .payload_decompression_verified==true and .proxmox_config_extract_verified==true and .archive_recovery_readback_verified==true and .bounded_staging==true and .full_local_payload_written==false and .full_restore_proven==false and .result==\\\"OK\\\"' \\\"$f\\\" >/dev/null\"},{\"line\":88,\"text\":\"local vmid=\\\"$1\\\" gen=\\\"$2\\\" state=\\\"$3\\\" work=\\\"$4\\\" base manifest expected_msha got_msha expected_count expected_size idx name size psha count total\"},{\"line\":90,\"text\":\"[[ \\\"$base\\\" == \\\"${REMOTE_A%/}/vm${vmid}/$gen\\\" ]] || die \\\"RESTORE_A_BASE_MISMATCH_$vmid\\\" 70\"},{\"line\":92,\"text\":\"got_msha=\\\"$(sha256sum \\\"$manifest\\\"|awk '{print $1}')\\\"; [[ \\\"$got_msha\\\" == \\\"$expected_msha\\\" ]] || die \\\"RESTORE_A_MANIFEST_SHA_MISMATCH_$vmid\\\" 70\"},{\"line\":95,\"text\":\"[[ \\\"$idx\\\" =~ ^[0-9]{8}$ && \\\"$name\\\" == part-????????.bin && \\\"$size\\\" =~ ^[1-9][0-9]*$ && \\\"$psha\\\" =~ ^[0-9a-f]{64}$ ]] || die \\\"RESTORE_A_MANIFEST_ROW_INVALID_$vmid\\\" 70\"},{\"line\":96,\"text\":\"(( size <= 536870912 )) || die \\\"RESTORE_A_PART_EXCEEDS_BOUND_$vmid\\\" 70\"},{\"line\":97,\"text\":\"[[ \\\"$idx\\\" == \\\"$(printf '%08d' \\\"$count\\\")\\\" ]] || die \\\"RESTORE_A_MANIFEST_INDEX_INVALID_$vmid\\\" 70\"},{\"line\":100,\"text\":\"[[ \\\"$count\\\" == \\\"$expected_count\\\" ]] || die \\\"RESTORE_A_PART_COUNT_MISMATCH_$vmid\\\" 70\"},{\"line\":101,\"text\":\"[[ \\\"$total\\\" == \\\"$expected_size\\\" ]] || die \\\"RESTORE_A_MANIFEST_TOTAL_SIZE_MISMATCH_$vmid\\\" 70\"},{\"line\":105,\"text\":\"local vmid=\\\"$1\\\" base=\\\"$2\\\" manifest=\\\"$3\\\" work=\\\"$4\\\" idx name size psha part actual count\"},{\"line\":109,\"text\":\"[[ -s \\\"$part\\\" && ! -L \\\"$part\\\" && \\\"$(stat -c %s \\\"$part\\\")\\\" == \\\"$size\\\" ]] || die \\\"RESTORE_A_PART_SIZE_MISMATCH_$vmid\\\" 70\"},{\"line\":110,\"text\":\"actual=\\\"$(sha256sum \\\"$part\\\"|awk '{print $1}')\\\"; [[ \\\"$actual\\\" == \\\"$psha\\\" ]] || die \\\"RESTORE_A_PART_SHA_MISMATCH_$vmid\\\" 70\"},{\"line\":114,\"text\":\"restore_validate(){\"},{\"line\":115,\"text\":\"local vmid=\\\"$1\\\" gen=\\\"$2\\\" logical state work payload_name expected_sha expected_size base manifest fifo sha_out sha_pid pipe_rc sha_rc actual_sha config config_sha members member_count cfg_member level out tmp\"},{\"line\":116,\"text\":\"assert_local_identity \\\"$vmid\\\"; logical=\\\"vm${vmid}\\\"; state=\\\"$STATE_ROOT/$logical/$gen.json\\\"\"},{\"line\":117,\"text\":\"[[ -s \\\"$state\\\" && ! -L \\\"$state\\\" ]] || die \\\"RESTORE_STATE_MISSING_$vmid\\\" 65\"},{\"line\":118,\"text\":\"jq -e '.schema==\\\"homelab-cloud-quorum-payload-v1\\\" and .status==\\\"SEALED\\\" and .cloud_quorum==2 and .cloud_a_verified==true and .cloud_b_verified==true and .part_hashes_verified==true and .seal_written==true and .cloud_a_seal_verified==true and .cloud_b_seal_verified==true and .local_payload_present==false and .local_cleanup==\\\"OK\\\"' \\\"$state\\\" >/dev/null || die \\\"RESTORE_REQUIRES_STRICT_SEALED_$vmid\\\" 65\"},{\"line\":119,\"text\":\"if restore_ok \\\"$vmid\\\" \\\"$gen\\\"; then printf 'RESTORE_VALIDATION_STATUS=OK\\\\nVMID=%s\\\\nGENERATION=%s\\\\nRESULT=ALREADY_VALIDATED\\\\nRESTORE_EVIDENCE=%s\\\\n' \\\"$vmid\\\" \\\"$gen\\\" \\\"$(restore_dir \\\"$vmid\\\")/$gen.json\\\"; return 0; fi\"},{\"line\":120,\"text\":\"[[ -z \\\"$(active_backup_restore)\\\" ]] || die ACTIVE_BACKUP_RESTORE_PRESENT 75\"},{\"line\":122,\"text\":\"[[ \\\"$payload_name\\\" == \\\"vzdump-lxc-${vmid}-\\\"*.tar.zst || \\\"$payload_name\\\" == \\\"vzdump-qemu-${vmid}-\\\"*.vma.zst ]] || die \\\"RESTORE_PAYLOAD_NAME_INVALID_$vmid\\\" 70\"},{\"line\":123,\"text\":\"work=\\\"$RESTORE_WORK_ROOT/$logical/$gen\\\"; if [[ -e \\\"$work\\\" ]]; then [[ -d \\\"$work\\\" && ! -L \\\"$work\\\" ]] || die \\\"RESTORE_WORK_UNSAFE_$vmid\\\" 70; rm -rf --one-file-system \\\"$work\\\"; fi; mkdir -p \\\"$work\\\"; chmod 0700 \\\"$RESTORE_WORK_ROOT\\\" \\\"$RESTORE_WORK_ROOT/$logical\\\" \\\"$work\\\"; ACTIVE_RESTORE_STAGE=\\\"$work\\\"\"},{\"line\":124,\"text\":\"base=\\\"$(prepare_cloud_a_manifest \\\"$vmid\\\" \\\"$gen\\\" \\\"$state\\\" \\\"$work\\\")\\\"; manifest=\\\"$work/PARTS.tsv\\\"; fifo=\\\"$work/archive.sha.fifo\\\"; sha_out=\\\"$work/archive.sha256\\\"; mkfifo -m 0600 \\\"$fifo\\\"\"},{\"line\":127,\"text\":\"members=\\\"$work/members.txt\\\"; if stream_cloud_a \\\"$vmid\\\" \\\"$base\\\" \\\"$manifest\\\" \\\"$work\\\" | tee \\\"$fifo\\\" | zstd -dc | tar -tf - >\\\"$members\\\"; then pipe_rc=0; else pipe_rc=$?; fi\"},{\"line\":129,\"text\":\"if stream_cloud_a \\\"$vmid\\\" \\\"$base\\\" \\\"$manifest\\\" \\\"$work\\\" | tee \\\"$fifo\\\" | zstd -t - >/dev/null; then pipe_rc=0; else pipe_rc=$?; fi\"},{\"line\":132,\"text\":\"(( pipe_rc == 0 && sha_rc == 0 )) || die \\\"RESTORE_A_STREAM_VALIDATION_FAILED_${vmid}_${pipe_rc}_${sha_rc}\\\" 70\"},{\"line\":133,\"text\":\"actual_sha=\\\"$(awk 'NR==1{print $1}' \\\"$sha_out\\\")\\\"; [[ \\\"$actual_sha\\\" == \\\"$expected_sha\\\" ]] || die \\\"RESTORE_A_PAYLOAD_SHA_MISMATCH_$vmid\\\" 70\"},{\"line\":136,\"text\":\"[[ -s \\\"$members\\\" ]] || die \\\"RESTORE_LXC_ARCHIVE_EMPTY_$vmid\\\" 70\"},{\"line\":137,\"text\":\"awk '$0 ~ /^\\\\// || $0 ~ /(^|\\\\/)\\\\.\\\\.(\\\\/|$)/ {bad=1} END{exit bad}' \\\"$members\\\" || die \\\"RESTORE_LXC_MEMBER_UNSAFE_$vmid\\\" 70\"},{\"line\":138,\"text\":\"member_count=\\\"$(wc -l <\\\"$members\\\")\\\"; [[ \\\"$member_count\\\" =~ ^[1-9][0-9]*$ ]] || die \\\"RESTORE_LXC_MEMBER_COUNT_INVALID_$vmid\\\" 70\"},{\"line\":139,\"text\":\"cfg_member=\\\"$(awk '$0==\\\"./etc/vzdump/pct.conf\\\" || $0==\\\"etc/vzdump/pct.conf\\\" {print; exit}' \\\"$members\\\")\\\"; [[ -n \\\"$cfg_member\\\" ]] || die \\\"RESTORE_LXC_CONFIG_MEMBER_MISSING_$vmid\\\" 70\"},{\"line\":140,\"text\":\"if ( set +o pipefail; stream_cloud_a \\\"$vmid\\\" \\\"$base\\\" \\\"$manifest\\\" \\\"$work\\\" | zstd -dc | tar -xOf - \\\"$cfg_member\\\" >\\\"$config\\\" ); then :; else die \\\"RESTORE_LXC_CONFIG_EXTRACT_FAILED_$vmid\\\" 70; fi\"},{\"line\":143,\"text\":\"if ( set +o pipefail; stream_cloud_a \\\"$vmid\\\" \\\"$base\\\" \\\"$manifest\\\" \\\"$work\\\" | zstd -dc | vma config - >\\\"$config\\\" ); then :; else die \\\"RESTORE_QEMU_CONFIG_EXTRACT_FAILED_$vmid\\\" 70; fi\"},{\"line\":146,\"text\":\"[[ -s \\\"$config\\\" && ! -L \\\"$config\\\" ]] || die \\\"RESTORE_CONFIG_EMPTY_$vmid\\\" 70; config_sha=\\\"$(sha256sum \\\"$config\\\"|awk '{print $1}')\\\"\"},{\"line\":147,\"text\":\"out=\\\"$(restore_dir \\\"$vmid\\\")/$gen.json\\\"; mkdir -p \\\"$(dirname \\\"$out\\\")\\\"; chmod 0700 \\\"$RESTORE_STATE_ROOT\\\" \\\"$(dirname \\\"$out\\\")\\\"; tmp=\\\"${out}.new.$$\\\"\"},{\"line\":148,\"text\":\"jq -n --arg logical \\\"$logical\\\" --arg generation \\\"$gen\\\" --argjson vmid \\\"$vmid\\\" --arg vm_type \\\"$VM_TYPE\\\" --arg state \\\"$state\\\" --arg sha \\\"$expected_sha\\\" --arg config_sha \\\"$config_sha\\\" --arg level \\\"$level\\\" --argjson member_count \\\"$member_count\\\" --arg at \\\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\\\" '{schema:\\\"homelab-vm-restore-validation-v1\\\",logical_id:$logical,generation:$generation,vmid:$vmid,vm_type:$vm_type,transport_state:\\\"SEALED\\\",transport_state_file:$state,restore_source:\\\"Cloud A\\\",parts_manifest_verified:true,payload_sha256:$sha,payload_sha256_verified:true,payload_decompression_verified:true,proxmox_config_extract_verified:true,proxmox_config_sha256:$config_sha,lxc_member_count:$member_count,archive_recovery_readback_verified:true,bounded_staging:true,max_staged_part_bytes:536870912,full_local_payload_written:false,full_restore_proven:false,validation_level:$level,result:\\\"OK\\\",validated_at_utc:$at}' >\\\"$tmp\\\"\"},{\"line\":149,\"text\":\"chmod 0600 \\\"$tmp\\\"; mv -f -- \\\"$tmp\\\" \\\"$out\\\"; rm -rf --one-file-system \\\"$work\\\"; ACTIVE_RESTORE_STAGE=\\\"\\\"\"},{\"line\":150,\"text\":\"restore_ok \\\"$vmid\\\" \\\"$gen\\\" || die \\\"RESTORE_EVIDENCE_POSTWRITE_INVALID_$vmid\\\" 70\"},{\"line\":151,\"text\":\"printf 'RESTORE_VALIDATION_STATUS=OK\\\\nVMID=%s\\\\nGENERATION=%s\\\\nRESTORE_EVIDENCE=%s\\\\n' \\\"$vmid\\\" \\\"$gen\\\" \\\"$out\\\"\"},{\"line\":154,\"text\":\"local vmid=\\\"$1\\\" owner type status\"},{\"line\":155,\"text\":\"assert_local_identity \\\"$vmid\\\"\"},{\"line\":156,\"text\":\"owner=\\\"$(expected_owner \\\"$vmid\\\")\\\"\"},{\"line\":157,\"text\":\"type=\\\"$(expected_type \\\"$vmid\\\")\\\"\"},{\"line\":158,\"text\":\"status=\\\"$(expected_status \\\"$vmid\\\")\\\"\"},{\"line\":159,\"text\":\"printf 'PLAN_STATUS=OK\\\\nVMID=%s\\\\nOWNER=%s\\\\nTYPE=%s\\\\nEXPECTED_STATUS=%s\\\\n' \\\"$vmid\\\" \\\"$owner\\\" \\\"$type\\\" \\\"$status\\\"\"},{\"line\":162,\"text\":\"local vmid=\\\"$1\\\" generation=\\\"$2\\\"\"},{\"line\":163,\"text\":\"assert_local_identity \\\"$vmid\\\"\"},{\"line\":164,\"text\":\"restore_validate \\\"$vmid\\\" \\\"$generation\\\"\"},{\"line\":165,\"text\":\"assert_post_identity \\\"$vmid\\\" \\\"$VM_TYPE\\\"\"},{\"line\":166,\"text\":\"printf 'VERIFY_STATUS=OK\\\\nVMID=%s\\\\nGENERATION=%s\\\\nRESTORE_EVIDENCE=%s\\\\n' \\\"$vmid\\\" \\\"$generation\\\" \\\"$(restore_dir \\\"$vmid\\\")/$generation.json\\\"\"},{\"line\":168,\"text\":\"backup_one(){\"},{\"line\":169,\"text\":\"local vmid=\\\"$1\\\" pending_count pending state generation payload gen_dir archive_count archive log_file before_status\"},{\"line\":171,\"text\":\"assert_local_identity \\\"$vmid\\\"\"},{\"line\":176,\"text\":\"[[ -z \\\"$(active_backup_restore)\\\" ]] || die \\\"ACTIVE_BACKUP_RESTORE_PRESENT\\\" 75\"},{\"line\":179,\"text\":\"mapfile -t pending < <(latest_incomplete_state \\\"$vmid\\\")\"},{\"line\":181,\"text\":\"(( pending_count <= 1 )) || die \\\"MULTIPLE_INCOMPLETE_GENERATIONS_$vmid\\\" 65\"},{\"line\":186,\"text\":\"printf 'RESUME=YES\\\\nVMID=%s\\\\nGENERATION=%s\\\\nSTATE=%s\\\\n' \\\"$vmid\\\" \\\"$generation\\\" \\\"$state\\\"\"},{\"line\":187,\"text\":\"\\\"$TRANSPORT\\\" backup-delete \\\"vm${vmid}\\\" \\\"$generation\\\" \\\"$payload\\\" \\\"$REMOTE_A\\\" \\\"$REMOTE_B\\\" \\\"$STATE_ROOT\\\"\"},{\"line\":189,\"text\":\"generation=\\\"vm${vmid}-${HOST}-$(date -u +%Y%m%dT%H%M%SZ)\\\"\"},{\"line\":190,\"text\":\"gen_dir=\\\"$STAGE_ROOT/vm${vmid}/$generation\\\"\"},{\"line\":195,\"text\":\"printf 'RESUME=NO\\\\nVMID=%s\\\\nGENERATION=%s\\\\n' \\\"$vmid\\\" \\\"$generation\\\"\"},{\"line\":202,\"text\":\"if ! ( umask 0022; exec vzdump \\\"$vmid\\\" \\\"${vzdump_args[@]}\\\" ) >\\\"$log_file\\\" 2>&1; then\"},{\"line\":204,\"text\":\"die \\\"VZDUMP_FAILED_$vmid\\\" 70\"},{\"line\":206,\"text\":\"mapfile -t archives < <(find \\\"$gen_dir\\\" -maxdepth 1 -type f -name \\\"vzdump-*-${vmid}-*.zst\\\" -print)\"},{\"line\":208,\"text\":\"[[ \\\"$archive_count\\\" == \\\"1\\\" ]] || { rm -rf -- \\\"$gen_dir\\\"; die \\\"VZDUMP_ARCHIVE_COUNT_${vmid}_${archive_count}\\\" 70; }\"},{\"line\":210,\"text\":\"[[ -s \\\"$archive\\\" && ! -L \\\"$archive\\\" ]] || die \\\"VZDUMP_ARCHIVE_UNSAFE_$vmid\\\" 70\"},{\"line\":212,\"text\":\"\\\"$TRANSPORT\\\" backup-delete \\\"vm${vmid}\\\" \\\"$generation\\\" \\\"$archive\\\" \\\"$REMOTE_A\\\" \\\"$REMOTE_B\\\" \\\"$STATE_ROOT\\\"\"},{\"line\":215,\"text\":\"rmdir -- \\\"$STAGE_ROOT/vm${vmid}\\\" 2>/dev/null || true\"},{\"line\":217,\"text\":\"assert_post_identity \\\"$vmid\\\" \\\"$VM_TYPE\\\"\"},{\"line\":218,\"text\":\"state=\\\"$STATE_ROOT/vm${vmid}/$generation.json\\\"\"},{\"line\":220,\"text\":\"restore_validate \\\"$vmid\\\" \\\"$generation\\\"\"},{\"line\":221,\"text\":\"printf 'BACKUP_STATUS=SEALED\\\\nVMID=%s\\\\nGENERATION=%s\\\\nOWNER=%s\\\\nTYPE=%s\\\\nPOST_STATUS=%s\\\\nRESTORE_EVIDENCE=%s\\\\n' \\\"$vmid\\\" \\\"$generation\\\" \\\"$HOST\\\" \\\"$VM_TYPE\\\" \\\"$(expected_status \\\"$vmid\\\")\\\" \\\"$(restore_dir \\\"$vmid\\\")/$generation.json\\\"\"},{\"line\":226,\"text\":\"[[ -z \\\"$(active_backup_restore)\\\" ]] || die \\\"ACTIVE_BACKUP_RESTORE_PRESENT\\\" 75\"},{\"line\":231,\"text\":\"printf 'HOST_PREFLIGHT_STATUS=OK\\\\nHOST=%s\\\\nSTAGING_FREE_BYTES=%s\\\\nREMOTE_A_FREE_BYTES=%s\\\\nREMOTE_B_FREE_BYTES=%s\\\\nACTIVE_BACKUP_RESTORE=0\\\\n' \\\"$HOST\\\" \\\"$free\\\" \\\"$a_free\\\" \\\"$b_free\\\"\"},{\"line\":234,\"text\":\"local vmid=\\\"$1\\\" dir latest gen\"},{\"line\":235,\"text\":\"assert_local_identity \\\"$vmid\\\"; dir=\\\"$STATE_ROOT/vm${vmid}\\\"\"},{\"line\":236,\"text\":\"[[ -d \\\"$dir\\\" ]] || die \\\"STATE_DIR_MISSING_$vmid\\\" 65\"},{\"line\":238,\"text\":\"[[ -n \\\"$latest\\\" && -s \\\"$latest\\\" && ! -L \\\"$latest\\\" ]] || die \\\"LATEST_STATE_MISSING_$vmid\\\" 65\"},{\"line\":239,\"text\":\"jq -e '.status==\\\"SEALED\\\" and .cloud_quorum==2 and .local_payload_present==false and .local_cleanup==\\\"OK\\\" and .seal_written==true' \\\"$latest\\\" >/dev/null || die \\\"LATEST_STATE_NOT_SEALED_$vmid\\\" 65\"},{\"line\":240,\"text\":\"gen=\\\"$(jq -er '.generation' \\\"$latest\\\")\\\"; restore_ok \\\"$vmid\\\" \\\"$gen\\\" || die \\\"LATEST_RESTORE_NOT_OK_$vmid\\\" 65\"},{\"line\":241,\"text\":\"printf 'LATEST_SEALED_STATUS=OK\\\\nVMID=%s\\\\nGENERATION=%s\\\\nSTATE_FILE=%s\\\\nRESTORE_EVIDENCE=%s\\\\n' \\\"$vmid\\\" \\\"$gen\\\" \\\"$latest\\\" \\\"$(restore_dir \\\"$vmid\\\")/$gen.json\\\"\"},{\"line\":244,\"text\":\"case \\\"$ACTION\\\" in\"},{\"line\":246,\"text\":\"[[ \\\"$#\\\" == 1 ]] || die \\\"USAGE_HOST_PREFLIGHT\\\" 64\"},{\"line\":249,\"text\":\"latest-sealed)\"},{\"line\":250,\"text\":\"[[ \\\"$#\\\" == 2 ]] || die \\\"USAGE_LATEST_SEALED\\\" 64\"},{\"line\":254,\"text\":\"[[ \\\"$#\\\" == 2 ]] || die \\\"USAGE_PLAN\\\" 64\"},{\"line\":257,\"text\":\"backup)\"},{\"line\":258,\"text\":\"[[ \\\"$#\\\" == 2 ]] || die \\\"USAGE_BACKUP\\\" 64\"},{\"line\":259,\"text\":\"backup_one \\\"$2\\\"\"},{\"line\":261,\"text\":\"restore-validate)\"},{\"line\":262,\"text\":\"[[ \\\"$#\\\" == 3 ]] || die \\\"USAGE_RESTORE_VALIDATE\\\" 64\"},{\"line\":263,\"text\":\"restore_validate \\\"$2\\\" \\\"$3\\\"\"},{\"line\":266,\"text\":\"[[ \\\"$#\\\" == 3 ]] || die \\\"USAGE_VERIFY\\\" 64\"}]\nNODEWORKER_CLI_CANDIDATES=[{\"kind\":\"dispatch\",\"text\":\"case \\\"$1\\\" in\"},{\"kind\":\"subcommand-token\",\"text\":\"backup\"},{\"kind\":\"subcommand-token\",\"text\":\"restore\"},{\"kind\":\"subcommand-token\",\"text\":\"latest-sealed\"}]\nDECISION=DIRECT_NODEWORKER_TARGETED_BACKUP_CLI_DISCOVERED\nNO_MUTATION=true\nTASK_RESULT=PASS_HOMELAB_BACKUP_NODEWORKER_CONTRACT_RCA_READONLY\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260921-HOMELAB-BACKUP-NODEWORKER-CONTRACT-RCA-READONLY-1104R1\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\nWORKERS2_NODEWORKER_CONTRACT_RCA_END=1\n"
|
|
}
|