From 04df7d47df736c2784b3534576756f7762d73a6c Mon Sep 17 00:00:00 2001 From: homelab-runtime-publisher Date: Sun, 27 Sep 2026 19:07:27 +0000 Subject: [PATCH] runtime: publish SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1 --- ...BACKUP-CT110-HELPER-STATIC-RCA-1224R1.json | 38 ++ ...-BACKUP-CT110-HELPER-STATIC-RCA-1224R1.txt | 304 +++++++++++++++ runtime/latest.json | 16 +- runtime/latest.txt | 348 ++++++++++++++---- 4 files changed, 623 insertions(+), 83 deletions(-) create mode 100644 runtime/history/SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1.json create mode 100644 runtime/history/SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1.txt diff --git a/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1.json b/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1.json new file mode 100644 index 00000000..da732225 --- /dev/null +++ b/runtime/history/SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1.json @@ -0,0 +1,38 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1", + "status": "OK", + "rc": 0, + "host": "pve01", + "mode": "read-only", + "component": "homelab-backup-ct110-helper-static-rca", + "started_at_utc": "2026-09-27T19:07:26Z", + "finished_at_utc": "2026-09-27T19:07:27Z", + "reference_register_checked": true, + "reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66", + "error_register_checked": true, + "error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0", + "command_sha256": "faba4e1f6f97021372c410262f26fab58019db46970c85c6114fe565805b743c", + "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": "e993a99af1682917d2eff9792b35263a335005e41b0df60d3121979071b61d52", + "sanitized_output_sha256": "e993a99af1682917d2eff9792b35263a335005e41b0df60d3121979071b61d52", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "BACKUP_CT110_HELPER_STATIC_RCA_BEGIN=true\nCOMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-CT110-HELPER-STATIC-RCA-1224R1\nMODE=read-only\nCOMPONENT=homelab-backup-ct110-helper-static-rca\nMUTATION_BOUNDARY=PURE_STATIC_SOURCE_AND_AST_ANALYSIS;NO_PROJECT_MODULE_IMPORT;NO_HELPER_EXECUTION;NO_VZDUMP;NO_SYSTEMD_ACTION;NO_BACKUP;NO_AUDIT_RUN;NO_FILE_WRITE_EXCEPT_RUNNER_TEMP;NO_LOCK_BREAK;NO_GIT_WRITE;NO_NETBIRD_SKLADCHIK_CHANGE\nHOST=pve01\nCLUSTER_QUORATE=Yes\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nSOURCE_1223_STATUS=OK\nSOURCE_1223_DECISION=HOLD_HELPER_REPLAY_SAFETY_GATE\nSOURCE_1223_NEXT_GATE=READ_EXACT_1223_AND_DESIGN_NONEXECUTING_HELPER_RCA\n=== FILE_IDENTITY ===\nHELPER_EXISTS=true\nHELPER_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\nHELPER_SHA256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\nHELPER_SHA_MATCH=true\nLXC_EXISTS=true\nLXC_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nLXC_SHA256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\nLXC_SHA_MATCH=true\nPVE265_EXISTS=true\nPVE265_PATH=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py\nPVE265_SHA256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be\nPVE265_SHA_MATCH=true\n=== STATIC_AST ===\nHELPER_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py\nHELPER_SHA256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011\nHELPER_BYTES=2320\nHELPER_IMPORTS=[{\"kind\":\"from\",\"level\":0,\"lineno\":1,\"module\":\"__future__\",\"names\":[{\"as\":null,\"name\":\"annotations\"}]},{\"kind\":\"import\",\"lineno\":2,\"names\":[{\"as\":null,\"name\":\"base64\"},{\"as\":null,\"name\":\"hashlib\"},{\"as\":null,\"name\":\"json\"},{\"as\":null,\"name\":\"pathlib\"},{\"as\":null,\"name\":\"sys\"}]},{\"kind\":\"import\",\"lineno\":19,\"names\":[{\"as\":null,\"name\":\"adapter\"}]}]\nHELPER_ALL_CALLS=[{\"argc\":1,\"func\":\"pathlib.Path\",\"kw\":[],\"lineno\":4},{\"argc\":0,\"func\":\"hexdigest\",\"kw\":[],\"lineno\":9},{\"argc\":1,\"func\":\"RuntimeError\",\"kw\":[],\"lineno\":12},{\"argc\":2,\"func\":\"sys.path.insert\",\"kw\":[],\"lineno\":18},{\"argc\":0,\"func\":\"adapter.verify_sources\",\"kw\":[],\"lineno\":20},{\"argc\":0,\"func\":\"adapter.load_graph\",\"kw\":[],\"lineno\":21},{\"argc\":1,\"func\":\"sys.stdin.buffer.read\",\"kw\":[],\"lineno\":22},{\"argc\":1,\"func\":\"json.loads\",\"kw\":[],\"lineno\":24},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":26},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":26},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":26},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":26},{\"argc\":6,\"func\":\"pve265.make_plan\",\"kw\":[\"node\"],\"lineno\":30},{\"argc\":2,\"func\":\"pve265.validate_job\",\"kw\":[],\"lineno\":34},{\"argc\":2,\"func\":\"guest266.no_active_tasks\",\"kw\":[],\"lineno\":37},{\"argc\":4,\"func\":\"pve265.dump_argv\",\"kw\":[],\"lineno\":38},{\"argc\":1,\"func\":\"sys.stdout.write\",\"kw\":[],\"lineno\":41},{\"argc\":1,\"func\":\"SystemExit\",\"kw\":[],\"lineno\":45},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":15},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":15},{\"argc\":0,\"func\":\"p.is_symlink\",\"kw\":[],\"lineno\":17},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":17},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":18},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":23},{\"argc\":1,\"func\":\"data.decode\",\"kw\":[],\"lineno\":24},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":25},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":25},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":27},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":28},{\"argc\":1,\"func\":\"base64.b64decode\",\"kw\":[],\"lineno\":29},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":30},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":30},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":30},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":32},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":32},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"fail\",\"kw\":[],\"lineno\":36},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":37},{\"argc\":0,\"func\":\"main\",\"kw\":[],\"lineno\":45},{\"argc\":1,\"func\":\"hashlib.sha256\",\"kw\":[],\"lineno\":9},{\"argc\":0,\"func\":\"p.is_file\",\"kw\":[],\"lineno\":17},{\"argc\":1,\"func\":\"sha\",\"kw\":[],\"lineno\":17},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":23},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":27},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":27},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":27},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":27},{\"argc\":2,\"func\":\"raw.get\",\"kw\":[],\"lineno\":28},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":29},{\"argc\":1,\"func\":\"raw.get\",\"kw\":[],\"lineno\":30},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":36},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":36},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":40},{\"argc\":1,\"func\":\"json.dumps\",\"kw\":[\"separators\",\"sort_keys\"],\"lineno\":41},{\"argc\":0,\"func\":\"p.read_bytes\",\"kw\":[],\"lineno\":9},{\"argc\":1,\"func\":\"j.get\",\"kw\":[],\"lineno\":31}]\nHELPER_DANGEROUS_CALL_HITS=[]\nHELPER_DANGEROUS_LITERALS=[\"vzdump\"]\nLXC_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py\nLXC_SHA256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d\nLXC_BYTES=13825\nLXC_IMPORTS=[{\"kind\":\"from\",\"level\":0,\"lineno\":1,\"module\":\"__future__\",\"names\":[{\"as\":null,\"name\":\"annotations\"}]},{\"kind\":\"import\",\"lineno\":2,\"names\":[{\"as\":null,\"name\":\"base64\"},{\"as\":null,\"name\":\"hashlib\"},{\"as\":null,\"name\":\"json\"},{\"as\":null,\"name\":\"os\"},{\"as\":null,\"name\":\"pathlib\"},{\"as\":null,\"name\":\"re\"},{\"as\":null,\"name\":\"selectors\"},{\"as\":null,\"name\":\"shlex\"},{\"as\":null,\"name\":\"signal\"},{\"as\":null,\"name\":\"stat\"},{\"as\":null,\"name\":\"subprocess\"},{\"as\":null,\"name\":\"sys\"},{\"as\":null,\"name\":\"time\"}]}]\nLXC_ALL_CALLS=[{\"argc\":0,\"func\":\"hashlib.sha256\",\"kw\":[],\"lineno\":23},{\"argc\":0,\"func\":\"h.hexdigest\",\"kw\":[],\"lineno\":26},{\"argc\":1,\"func\":\"memoryview\",\"kw\":[],\"lineno\":29},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":36},{\"argc\":0,\"func\":\"split\",\"kw\":[],\"lineno\":37},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":38},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":42},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":43},{\"argc\":2,\"func\":\"_j\",\"kw\":[],\"lineno\":44},{\"argc\":2,\"func\":\"_j\",\"kw\":[],\"lineno\":45},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":46},{\"argc\":2,\"func\":\"_j\",\"kw\":[],\"lineno\":55},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":56},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\",\"check\"],\"lineno\":57},{\"argc\":1,\"func\":\"os.statvfs\",\"kw\":[],\"lineno\":61},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":61},{\"argc\":1,\"func\":\"encode\",\"kw\":[],\"lineno\":66},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":67},{\"argc\":1,\"func\":\"subprocess.run\",\"kw\":[\"input\",\"capture_output\",\"timeout\",\"cwd\",\"env\"],\"lineno\":68},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":69},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":72},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":76},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":80},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":81},{\"argc\":1,\"func\":\"row.get\",\"kw\":[],\"lineno\":82},{\"argc\":1,\"func\":\"row.get\",\"kw\":[],\"lineno\":82},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":83},{\"argc\":2,\"func\":\"legacy._default_unprivileged_lxc\",\"kw\":[],\"lineno\":84},{\"argc\":1,\"func\":\"_helper\",\"kw\":[],\"lineno\":85},{\"argc\":1,\"func\":\"_helper\",\"kw\":[],\"lineno\":85},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":86},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":87},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":88},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":92},{\"argc\":0,\"func\":\"encode\",\"kw\":[],\"lineno\":94},{\"argc\":1,\"func\":\"subprocess.run\",\"kw\":[\"input\",\"capture_output\",\"timeout\",\"cwd\",\"env\"],\"lineno\":95},{\"argc\":2,\"func\":\"isinstance\",\"kw\":[],\"lineno\":102},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":104},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":104},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":105},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":118},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":119},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":120},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":121},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":122},{\"argc\":1,\"func\":\"pathlib.Path\",\"kw\":[],\"lineno\":123},{\"argc\":1,\"func\":\"os.lstat\",\"kw\":[],\"lineno\":124},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":124},{\"argc\":3,\"func\":\"os.open\",\"kw\":[],\"lineno\":126},{\"argc\":3,\"func\":\"os.open\",\"kw\":[],\"lineno\":126},{\"argc\":1,\"func\":\"os.fstat\",\"kw\":[],\"lineno\":127},{\"argc\":0,\"func\":\"hashlib.sha256\",\"kw\":[],\"lineno\":128},{\"argc\":0,\"func\":\"hashlib.sha256\",\"kw\":[],\"lineno\":128},{\"argc\":1,\"func\":\"print\",\"kw\":[\"flush\"],\"lineno\":187},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":190},{\"argc\":0,\"func\":\"resolve\",\"kw\":[],\"lineno\":6},{\"argc\":0,\"func\":\"resolve\",\"kw\":[],\"lineno\":7},{\"argc\":1,\"func\":\"__init__\",\"kw\":[],\"lineno\":13},{\"argc\":1,\"func\":\"AdapterError\",\"kw\":[],\"lineno\":16},{\"argc\":1,\"func\":\"json.loads\",\"kw\":[],\"lineno\":19},{\"argc\":2,\"func\":\"open\",\"kw\":[\"buffering\"],\"lineno\":24},{\"argc\":2,\"func\":\"iter\",\"kw\":[],\"lineno\":25},{\"argc\":2,\"func\":\"os.write\",\"kw\":[],\"lineno\":31},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":44},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":45},{\"argc\":2,\"func\":\"_j\",\"kw\":[],\"lineno\":52},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":53},{\"argc\":1,\"func\":\"configs.append\",\"kw\":[],\"lineno\":54},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":55},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":62},{\"argc\":1,\"func\":\"json.loads\",\"kw\":[],\"lineno\":70},{\"argc\":4,\"func\":\"_live_inputs\",\"kw\":[],\"lineno\":85},{\"argc\":4,\"func\":\"_live_inputs\",\"kw\":[],\"lineno\":85},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":93},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":93},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":93},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":97},{\"argc\":1,\"func\":\"json.loads\",\"kw\":[],\"lineno\":98},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":101},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":101},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":102},{\"argc\":1,\"func\":\"summary.update\",\"kw\":[],\"lineno\":102},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":103},{\"argc\":2,\"func\":\"os.killpg\",\"kw\":[],\"lineno\":109},{\"argc\":0,\"func\":\"p.wait\",\"kw\":[\"timeout\"],\"lineno\":111},{\"argc\":1,\"func\":\"shlex.join\",\"kw\":[],\"lineno\":129},{\"argc\":0,\"func\":\"time.monotonic\",\"kw\":[],\"lineno\":131},{\"argc\":1,\"func\":\"subprocess.Popen\",\"kw\":[\"stdin\",\"stdout\",\"stderr\",\"cwd\",\"env\",\"start_new_session\",\"close_fds\"],\"lineno\":133},{\"argc\":0,\"func\":\"selectors.DefaultSelector\",\"kw\":[],\"lineno\":134},{\"argc\":0,\"func\":\"sel.get_map\",\"kw\":[],\"lineno\":136},{\"argc\":0,\"func\":\"p.wait\",\"kw\":[\"timeout\"],\"lineno\":150},{\"argc\":1,\"func\":\"os.fstat\",\"kw\":[],\"lineno\":153},{\"argc\":1,\"func\":\"os.stat\",\"kw\":[\"follow_symlinks\"],\"lineno\":153},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":156},{\"argc\":2,\"func\":\"os.fchmod\",\"kw\":[],\"lineno\":157},{\"argc\":1,\"func\":\"os.fsync\",\"kw\":[],\"lineno\":157},{\"argc\":1,\"func\":\"os.fsync\",\"kw\":[],\"lineno\":157},{\"argc\":1,\"func\":\"os.close\",\"kw\":[],\"lineno\":173},{\"argc\":1,\"func\":\"os.close\",\"kw\":[],\"lineno\":173},{\"argc\":1,\"func\":\"callable\",\"kw\":[],\"lineno\":190},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":193},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":194},{\"argc\":1,\"func\":\"row.get\",\"kw\":[],\"lineno\":195},{\"argc\":1,\"func\":\"row.get\",\"kw\":[],\"lineno\":195},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":196},{\"argc\":2,\"func\":\"legacy._default_unprivileged_lxc\",\"kw\":[],\"lineno\":197},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":199},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":200},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":201},{\"argc\":1,\"func\":\"AdapterError\",\"kw\":[],\"lineno\":20},{\"argc\":1,\"func\":\"h.update\",\"kw\":[],\"lineno\":25},{\"argc\":1,\"func\":\"AdapterError\",\"kw\":[],\"lineno\":32},{\"argc\":0,\"func\":\"strip\",\"kw\":[],\"lineno\":37},{\"argc\":3,\"func\":\"_remote_sha\",\"kw\":[],\"lineno\":42},{\"argc\":3,\"func\":\"_remote_sha\",\"kw\":[],\"lineno\":43},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":50},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":52},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\"],\"lineno\":59},{\"argc\":1,\"func\":\"AdapterError\",\"kw\":[],\"lineno\":60},{\"argc\":0,\"func\":\"time.time\",\"kw\":[],\"lineno\":62},{\"argc\":1,\"func\":\"decode\",\"kw\":[],\"lineno\":63},{\"argc\":1,\"func\":\"json.dumps\",\"kw\":[\"separators\",\"sort_keys\"],\"lineno\":66},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":67},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":68},{\"argc\":1,\"func\":\"AdapterError\",\"kw\":[],\"lineno\":71},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":76},{\"argc\":0,\"func\":\"job.items\",\"kw\":[],\"lineno\":77},{\"argc\":0,\"func\":\"legacy.cluster_inventory\",\"kw\":[],\"lineno\":80},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":81},{\"argc\":1,\"func\":\"t.get\",\"kw\":[],\"lineno\":83},{\"argc\":1,\"func\":\"_stable_job\",\"kw\":[],\"lineno\":86},{\"argc\":1,\"func\":\"_stable_job\",\"kw\":[],\"lineno\":86},{\"argc\":3,\"func\":\"_remote_sha\",\"kw\":[],\"lineno\":88},{\"argc\":1,\"func\":\"json.dumps\",\"kw\":[\"separators\",\"sort_keys\"],\"lineno\":94},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":95},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":96},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":100},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":103},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":104},{\"argc\":0,\"func\":\"is_file\",\"kw\":[],\"lineno\":105},{\"argc\":1,\"func\":\"result.get\",\"kw\":[],\"lineno\":106},{\"argc\":0,\"func\":\"p.wait\",\"kw\":[],\"lineno\":115},{\"argc\":1,\"func\":\"all\",\"kw\":[],\"lineno\":119},{\"argc\":3,\"func\":\"_remote_sha\",\"kw\":[],\"lineno\":122},{\"argc\":1,\"func\":\"stat.S_ISDIR\",\"kw\":[],\"lineno\":124},{\"argc\":2,\"func\":\"os.set_blocking\",\"kw\":[],\"lineno\":135},{\"argc\":2,\"func\":\"sel.register\",\"kw\":[],\"lineno\":135},{\"argc\":0,\"func\":\"time.monotonic\",\"kw\":[],\"lineno\":137},{\"argc\":1,\"func\":\"sel.select\",\"kw\":[],\"lineno\":139},{\"argc\":0,\"func\":\"time.monotonic\",\"kw\":[],\"lineno\":148},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":149},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":151},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":152},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":155},{\"argc\":0,\"func\":\"digest.hexdigest\",\"kw\":[],\"lineno\":158},{\"argc\":0,\"func\":\"eh.hexdigest\",\"kw\":[],\"lineno\":159},{\"argc\":1,\"func\":\"summary.update\",\"kw\":[],\"lineno\":164},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":164},{\"argc\":0,\"func\":\"sel.close\",\"kw\":[],\"lineno\":170},{\"argc\":1,\"func\":\"os.fsync\",\"kw\":[],\"lineno\":171},{\"argc\":1,\"func\":\"os.fsync\",\"kw\":[],\"lineno\":171},{\"argc\":0,\"func\":\"eh.hexdigest\",\"kw\":[],\"lineno\":175},{\"argc\":0,\"func\":\"encode\",\"kw\":[],\"lineno\":177},{\"argc\":3,\"func\":\"os.open\",\"kw\":[],\"lineno\":178},{\"argc\":1,\"func\":\"json.dumps\",\"kw\":[\"separators\",\"sort_keys\"],\"lineno\":187},{\"argc\":1,\"func\":\"t.get\",\"kw\":[],\"lineno\":192},{\"argc\":3,\"func\":\"original\",\"kw\":[],\"lineno\":192},{\"argc\":2,\"func\":\"legacy.mapped_scratch_probe\",\"kw\":[],\"lineno\":203},{\"argc\":3,\"func\":\"plan_only\",\"kw\":[],\"lineno\":204},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":204},{\"argc\":2,\"func\":\"_need\",\"kw\":[],\"lineno\":210},{\"argc\":2,\"func\":\"_emit_diag\",\"kw\":[],\"lineno\":211},{\"argc\":1,\"func\":\"row.get\",\"kw\":[],\"lineno\":215},{\"argc\":1,\"func\":\"pathlib.Path\",\"kw\":[],\"lineno\":6},{\"argc\":1,\"func\":\"pathlib.Path\",\"kw\":[],\"lineno\":7},{\"argc\":0,\"func\":\"super\",\"kw\":[],\"lineno\":13},{\"argc\":1,\"func\":\"f.read\",\"kw\":[],\"lineno\":25},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":38},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":46},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":46},{\"argc\":2,\"func\":\"isinstance\",\"kw\":[],\"lineno\":49},{\"argc\":1,\"func\":\"r.get\",\"kw\":[],\"lineno\":49},{\"argc\":1,\"func\":\"r.get\",\"kw\":[],\"lineno\":49},{\"argc\":1,\"func\":\"r.get\",\"kw\":[],\"lineno\":50},{\"argc\":1,\"func\":\"AdapterError\",\"kw\":[],\"lineno\":51},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":53},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":56},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":56},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":69},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":80},{\"argc\":0,\"func\":\"hexdigest\",\"kw\":[],\"lineno\":97},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":97},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":105},{\"argc\":2,\"func\":\"os.killpg\",\"kw\":[],\"lineno\":113},{\"argc\":2,\"func\":\"re.fullmatch\",\"kw\":[],\"lineno\":118},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":119},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":121},{\"argc\":1,\"func\":\"stat.S_ISLNK\",\"kw\":[],\"lineno\":124},{\"argc\":1,\"func\":\"stat.S_IMODE\",\"kw\":[],\"lineno\":124},{\"argc\":0,\"func\":\"pipe.fileno\",\"kw\":[],\"lineno\":135},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":138},{\"argc\":2,\"func\":\"min\",\"kw\":[],\"lineno\":139},{\"argc\":2,\"func\":\"os.read\",\"kw\":[],\"lineno\":140},{\"argc\":3,\"func\":\"_remote_sha\",\"kw\":[],\"lineno\":156},{\"argc\":1,\"func\":\"_kill\",\"kw\":[],\"lineno\":161},{\"argc\":0,\"func\":\"eh.hexdigest\",\"kw\":[],\"lineno\":163},{\"argc\":0,\"func\":\"p.poll\",\"kw\":[],\"lineno\":167},{\"argc\":1,\"func\":\"_kill\",\"kw\":[],\"lineno\":167},{\"argc\":0,\"func\":\"p.stdout.close\",\"kw\":[],\"lineno\":168},{\"argc\":0,\"func\":\"p.stderr.close\",\"kw\":[],\"lineno\":169},{\"argc\":2,\"func\":\"_write_all\",\"kw\":[],\"lineno\":179},{\"argc\":1,\"func\":\"os.fsync\",\"kw\":[],\"lineno\":179},{\"argc\":1,\"func\":\"os.close\",\"kw\":[],\"lineno\":180},{\"argc\":0,\"func\":\"legacy.cluster_inventory\",\"kw\":[],\"lineno\":193},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":194},{\"argc\":1,\"func\":\"t.get\",\"kw\":[],\"lineno\":196},{\"argc\":0,\"func\":\"strip\",\"kw\":[],\"lineno\":201},{\"argc\":1,\"func\":\"pathlib.Path\",\"kw\":[],\"lineno\":204},{\"argc\":2,\"func\":\"legacy.ssh_remote\",\"kw\":[\"timeout\",\"check\"],\"lineno\":213},{\"argc\":2,\"func\":\"p.stdout.decode\",\"kw\":[],\"lineno\":37},{\"argc\":1,\"func\":\"base64.b64encode\",\"kw\":[],\"lineno\":63},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"out.get\",\"kw\":[],\"lineno\":72},{\"argc\":2,\"func\":\"r.get\",\"kw\":[],\"lineno\":80},{\"argc\":0,\"func\":\"hexdigest\",\"kw\":[],\"lineno\":100},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":100},{\"argc\":1,\"func\":\"pathlib.Path\",\"kw\":[],\"lineno\":105},{\"argc\":0,\"func\":\"stat\",\"kw\":[],\"lineno\":105},{\"argc\":2,\"func\":\"result.get\",\"kw\":[],\"lineno\":105},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":118},{\"argc\":2,\"func\":\"max\",\"kw\":[],\"lineno\":139},{\"argc\":0,\"func\":\"key.fileobj.fileno\",\"kw\":[],\"lineno\":140},{\"argc\":1,\"func\":\"sel.unregister\",\"kw\":[],\"lineno\":141},{\"argc\":2,\"func\":\"_write_all\",\"kw\":[],\"lineno\":144},{\"argc\":1,\"func\":\"digest.update\",\"kw\":[],\"lineno\":144},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":144},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":146},{\"argc\":1,\"func\":\"eh.update\",\"kw\":[],\"lineno\":146},{\"argc\":0,\"func\":\"p.poll\",\"kw\":[],\"lineno\":161},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":193},{\"argc\":6,\"func\":\"_execute_local\",\"kw\":[],\"lineno\":206},{\"argc\":6,\"func\":\"_execute_remote\",\"kw\":[],\"lineno\":206},{\"argc\":2,\"func\":\"_emit_diag\",\"kw\":[],\"lineno\":208},{\"argc\":1,\"func\":\"legacy.BackupError\",\"kw\":[],\"lineno\":209},{\"argc\":0,\"func\":\"local.is_file\",\"kw\":[],\"lineno\":210},{\"argc\":1,\"func\":\"hashlib.sha256\",\"kw\":[],\"lineno\":97},{\"argc\":1,\"func\":\"argv.index\",\"kw\":[],\"lineno\":120},{\"argc\":2,\"func\":\"ExecFailure\",\"kw\":[],\"lineno\":143},{\"argc\":2,\"func\":\"_write_all\",\"kw\":[],\"lineno\":147},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":147},{\"argc\":1,\"func\":\"json.dumps\",\"kw\":[\"separators\",\"sort_keys\"],\"lineno\":177},{\"argc\":2,\"func\":\"r.get\",\"kw\":[],\"lineno\":193},{\"argc\":0,\"func\":\"q.stdout.decode\",\"kw\":[],\"lineno\":201},{\"argc\":1,\"func\":\"hashlib.sha256\",\"kw\":[],\"lineno\":100},{\"argc\":1,\"func\":\"pathlib.Path\",\"kw\":[],\"lineno\":105},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":119},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":143},{\"argc\":2,\"func\":\"max\",\"kw\":[],\"lineno\":146},{\"argc\":0,\"func\":\"local.stat\",\"kw\":[],\"lineno\":210}]\nLXC_DANGEROUS_CALL_HITS=[{\"argc\":1,\"func\":\"subprocess.run\",\"kw\":[\"input\",\"capture_output\",\"timeout\",\"cwd\",\"env\"],\"lineno\":68},{\"argc\":1,\"func\":\"subprocess.run\",\"kw\":[\"input\",\"capture_output\",\"timeout\",\"cwd\",\"env\"],\"lineno\":95},{\"argc\":3,\"func\":\"os.open\",\"kw\":[],\"lineno\":126},{\"argc\":3,\"func\":\"os.open\",\"kw\":[],\"lineno\":126},{\"argc\":2,\"func\":\"open\",\"kw\":[\"buffering\"],\"lineno\":24},{\"argc\":1,\"func\":\"subprocess.Popen\",\"kw\":[\"stdin\",\"stdout\",\"stderr\",\"cwd\",\"env\",\"start_new_session\",\"close_fds\"],\"lineno\":133},{\"argc\":3,\"func\":\"os.open\",\"kw\":[],\"lineno\":178}]\nLXC_DANGEROUS_LITERALS=[\"vzdump\"]\nPVE265_PATH=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py\nPVE265_SHA256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be\nPVE265_BYTES=12888\nPVE265_IMPORTS=[{\"kind\":\"import\",\"lineno\":6,\"names\":[{\"as\":null,\"name\":\"hashlib\"}]},{\"kind\":\"import\",\"lineno\":7,\"names\":[{\"as\":null,\"name\":\"os\"}]},{\"kind\":\"from\",\"level\":0,\"lineno\":8,\"module\":\"pathlib\",\"names\":[{\"as\":null,\"name\":\"Path\"}]},{\"kind\":\"import\",\"lineno\":9,\"names\":[{\"as\":null,\"name\":\"re\"}]},{\"kind\":\"import\",\"lineno\":10,\"names\":[{\"as\":null,\"name\":\"selectors\"}]},{\"kind\":\"import\",\"lineno\":11,\"names\":[{\"as\":null,\"name\":\"signal\"}]},{\"kind\":\"import\",\"lineno\":12,\"names\":[{\"as\":null,\"name\":\"stat\"}]},{\"kind\":\"import\",\"lineno\":13,\"names\":[{\"as\":null,\"name\":\"subprocess\"}]},{\"kind\":\"import\",\"lineno\":14,\"names\":[{\"as\":null,\"name\":\"time\"}]},{\"kind\":\"import\",\"lineno\":15,\"names\":[{\"as\":\"core\",\"name\":\"v2core\"}]},{\"kind\":\"import\",\"lineno\":16,\"names\":[{\"as\":\"t\",\"name\":\"transport261\"}]},{\"kind\":\"import\",\"lineno\":17,\"names\":[{\"as\":\"stream\",\"name\":\"stream263\"}]},{\"kind\":\"import\",\"lineno\":18,\"names\":[{\"as\":\"np\",\"name\":\"nodeplan263\"}]}]\nPVE265_ALL_CALLS=[{\"argc\":1,\"func\":\"re.compile\",\"kw\":[],\"lineno\":24},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":38},{\"argc\":0,\"func\":\"set\",\"kw\":[],\"lineno\":43},{\"argc\":0,\"func\":\"set\",\"kw\":[],\"lineno\":43},{\"argc\":0,\"func\":\"text.splitlines\",\"kw\":[],\"lineno\":44},{\"argc\":1,\"func\":\"sorted\",\"kw\":[],\"lineno\":55},{\"argc\":1,\"func\":\"sorted\",\"kw\":[],\"lineno\":55},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":58},{\"argc\":1,\"func\":\"dict\",\"kw\":[],\"lineno\":59},{\"argc\":0,\"func\":\"out.items\",\"kw\":[],\"lineno\":60},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":67},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":68},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":69},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":70},{\"argc\":2,\"func\":\"np.guests\",\"kw\":[],\"lineno\":71},{\"argc\":1,\"func\":\"np.storages\",\"kw\":[],\"lineno\":71},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"defaults_summary\",\"kw\":[],\"lineno\":73},{\"argc\":1,\"func\":\"t.sha\",\"kw\":[],\"lineno\":120},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":123},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":124},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":125},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":126},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":127},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":128},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":129},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":130},{\"argc\":2,\"func\":\"validate_job\",\"kw\":[],\"lineno\":133},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":134},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":151},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":152},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":153},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":154},{\"argc\":0,\"func\":\"check\",\"kw\":[],\"lineno\":154},{\"argc\":1,\"func\":\"Path\",\"kw\":[],\"lineno\":155},{\"argc\":1,\"func\":\"stream.private_dir\",\"kw\":[],\"lineno\":155},{\"argc\":0,\"func\":\"hashlib.sha256\",\"kw\":[],\"lineno\":156},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":193},{\"argc\":0,\"func\":\"tools.values\",\"kw\":[],\"lineno\":194},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":205},{\"argc\":0,\"func\":\"guard\",\"kw\":[],\"lineno\":205},{\"argc\":2,\"func\":\"validate_job\",\"kw\":[],\"lineno\":205},{\"argc\":1,\"func\":\"validate_tools\",\"kw\":[],\"lineno\":205},{\"argc\":1,\"func\":\"Path\",\"kw\":[],\"lineno\":206},{\"argc\":1,\"func\":\"stream.private_dir\",\"kw\":[],\"lineno\":206},{\"argc\":1,\"func\":\"t.make_dir\",\"kw\":[\"exclusive\"],\"lineno\":209},{\"argc\":0,\"func\":\"free_guard\",\"kw\":[],\"lineno\":213},{\"argc\":5,\"func\":\"capture_archive\",\"kw\":[],\"lineno\":214},{\"argc\":0,\"func\":\"guard\",\"kw\":[],\"lineno\":215},{\"argc\":1,\"func\":\"validate_tools\",\"kw\":[],\"lineno\":215},{\"argc\":4,\"func\":\"t.bounded_process\",\"kw\":[],\"lineno\":216},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":217},{\"argc\":2,\"func\":\"stream.hash_file\",\"kw\":[],\"lineno\":218},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":219},{\"argc\":0,\"func\":\"guard\",\"kw\":[],\"lineno\":220},{\"argc\":1,\"func\":\"validate_tools\",\"kw\":[],\"lineno\":220},{\"argc\":1,\"func\":\"PVEError\",\"kw\":[],\"lineno\":32},{\"argc\":2,\"func\":\"isinstance\",\"kw\":[],\"lineno\":35},{\"argc\":0,\"func\":\"is_absolute\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"all\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"raw.decode\",\"kw\":[],\"lineno\":41},{\"argc\":0,\"func\":\"line.strip\",\"kw\":[],\"lineno\":45},{\"argc\":2,\"func\":\"re.fullmatch\",\"kw\":[],\"lineno\":47},{\"argc\":0,\"func\":\"m.groups\",\"kw\":[],\"lineno\":49},{\"argc\":1,\"func\":\"seen.add\",\"kw\":[],\"lineno\":51},{\"argc\":1,\"func\":\"np.valid_id\",\"kw\":[],\"lineno\":67},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":76},{\"argc\":1,\"func\":\"normalized_config\",\"kw\":[],\"lineno\":77},{\"argc\":2,\"func\":\"np.config_summary\",\"kw\":[],\"lineno\":77},{\"argc\":1,\"func\":\"t.sha\",\"kw\":[],\"lineno\":78},{\"argc\":1,\"func\":\"any\",\"kw\":[],\"lineno\":83},{\"argc\":1,\"func\":\"sum\",\"kw\":[],\"lineno\":99},{\"argc\":2,\"func\":\"max\",\"kw\":[],\"lineno\":103},{\"argc\":2,\"func\":\"min\",\"kw\":[],\"lineno\":104},{\"argc\":1,\"func\":\"sorted\",\"kw\":[],\"lineno\":106},{\"argc\":1,\"func\":\"jobs.append\",\"kw\":[],\"lineno\":113},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":114},{\"argc\":1,\"func\":\"all\",\"kw\":[],\"lineno\":116},{\"argc\":1,\"func\":\"core.canonical_bytes\",\"kw\":[],\"lineno\":120},{\"argc\":1,\"func\":\"core.valid_hash\",\"kw\":[],\"lineno\":128},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":135},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":135},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":137},{\"argc\":2,\"func\":\"os.killpg\",\"kw\":[],\"lineno\":141},{\"argc\":0,\"func\":\"p.wait\",\"kw\":[\"timeout\"],\"lineno\":143},{\"argc\":1,\"func\":\"callable\",\"kw\":[],\"lineno\":154},{\"argc\":0,\"func\":\"time.monotonic\",\"kw\":[],\"lineno\":156},{\"argc\":3,\"func\":\"os.open\",\"kw\":[\"dir_fd\"],\"lineno\":158},{\"argc\":1,\"func\":\"os.fstat\",\"kw\":[],\"lineno\":159},{\"argc\":1,\"func\":\"subprocess.Popen\",\"kw\":[\"stdin\",\"stdout\",\"stderr\",\"env\",\"start_new_session\",\"close_fds\"],\"lineno\":160},{\"argc\":0,\"func\":\"selectors.DefaultSelector\",\"kw\":[],\"lineno\":162},{\"argc\":0,\"func\":\"sel.get_map\",\"kw\":[],\"lineno\":165},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":174},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":177},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":177},{\"argc\":0,\"func\":\"check\",\"kw\":[],\"lineno\":177},{\"argc\":1,\"func\":\"os.fstat\",\"kw\":[],\"lineno\":178},{\"argc\":1,\"func\":\"os.stat\",\"kw\":[\"dir_fd\",\"follow_symlinks\"],\"lineno\":178},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":179},{\"argc\":2,\"func\":\"os.fchmod\",\"kw\":[],\"lineno\":181},{\"argc\":1,\"func\":\"os.fsync\",\"kw\":[],\"lineno\":181},{\"argc\":1,\"func\":\"os.fsync\",\"kw\":[],\"lineno\":181},{\"argc\":1,\"func\":\"os.close\",\"kw\":[],\"lineno\":190},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":195},{\"argc\":2,\"func\":\"t.read_secure\",\"kw\":[],\"lineno\":196},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":197},{\"argc\":1,\"func\":\"callable\",\"kw\":[],\"lineno\":205},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":205},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":207},{\"argc\":1,\"func\":\"os.close\",\"kw\":[],\"lineno\":208},{\"argc\":1,\"func\":\"os.statvfs\",\"kw\":[],\"lineno\":212},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":212},{\"argc\":4,\"func\":\"dump_argv\",\"kw\":[],\"lineno\":214},{\"argc\":1,\"func\":\"dict\",\"kw\":[],\"lineno\":216},{\"argc\":2,\"func\":\"min\",\"kw\":[],\"lineno\":216},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":221},{\"argc\":1,\"func\":\"t.sha\",\"kw\":[],\"lineno\":39},{\"argc\":1,\"func\":\"line.startswith\",\"kw\":[],\"lineno\":46},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":48},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":50},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":52},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":58},{\"argc\":1,\"func\":\"DISK_RE.fullmatch\",\"kw\":[],\"lineno\":61},{\"argc\":1,\"func\":\"v.startswith\",\"kw\":[],\"lineno\":62},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":70},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":72},{\"argc\":1,\"func\":\"core.canonical_bytes\",\"kw\":[],\"lineno\":78},{\"argc\":1,\"func\":\"set\",\"kw\":[],\"lineno\":79},{\"argc\":1,\"func\":\"set\",\"kw\":[],\"lineno\":79},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":80},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":81},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":82},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":84},{\"argc\":1,\"func\":\"stores.get\",\"kw\":[],\"lineno\":95},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":100},{\"argc\":2,\"func\":\"min\",\"kw\":[],\"lineno\":102},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":105},{\"argc\":1,\"func\":\"bool\",\"kw\":[],\"lineno\":109},{\"argc\":1,\"func\":\"bool\",\"kw\":[],\"lineno\":110},{\"argc\":1,\"func\":\"np.valid_id\",\"kw\":[],\"lineno\":125},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":128},{\"argc\":1,\"func\":\"path_ok\",\"kw\":[],\"lineno\":134},{\"argc\":1,\"func\":\"path_ok\",\"kw\":[],\"lineno\":134},{\"argc\":0,\"func\":\"p.wait\",\"kw\":[],\"lineno\":147},{\"argc\":1,\"func\":\"all\",\"kw\":[],\"lineno\":151},{\"argc\":2,\"func\":\"os.set_blocking\",\"kw\":[],\"lineno\":163},{\"argc\":2,\"func\":\"sel.register\",\"kw\":[],\"lineno\":163},{\"argc\":0,\"func\":\"time.monotonic\",\"kw\":[],\"lineno\":166},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":166},{\"argc\":1,\"func\":\"sel.select\",\"kw\":[],\"lineno\":168},{\"argc\":0,\"func\":\"p.wait\",\"kw\":[\"timeout\"],\"lineno\":175},{\"argc\":0,\"func\":\"digest.hexdigest\",\"kw\":[],\"lineno\":182},{\"argc\":1,\"func\":\"list\",\"kw\":[],\"lineno\":182},{\"argc\":0,\"func\":\"p.wait\",\"kw\":[],\"lineno\":186},{\"argc\":0,\"func\":\"p.stdout.close\",\"kw\":[],\"lineno\":187},{\"argc\":0,\"func\":\"p.stderr.close\",\"kw\":[],\"lineno\":187},{\"argc\":0,\"func\":\"sel.close\",\"kw\":[],\"lineno\":188},{\"argc\":1,\"func\":\"os.close\",\"kw\":[],\"lineno\":189},{\"argc\":1,\"func\":\"Path\",\"kw\":[],\"lineno\":196},{\"argc\":0,\"func\":\"time.time\",\"kw\":[],\"lineno\":205},{\"argc\":1,\"func\":\"int\",\"kw\":[],\"lineno\":214},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":216},{\"argc\":1,\"func\":\"Path\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"Path\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":53},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":61},{\"argc\":1,\"func\":\"v.startswith\",\"kw\":[],\"lineno\":63},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":68},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":69},{\"argc\":1,\"func\":\"split\",\"kw\":[],\"lineno\":87},{\"argc\":1,\"func\":\"field.partition\",\"kw\":[],\"lineno\":88},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":91},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":96},{\"argc\":1,\"func\":\"sizes.append\",\"kw\":[],\"lineno\":98},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":123},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":123},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":124},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":125},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":125},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":126},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":126},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":127},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":129},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":130},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":130},{\"argc\":2,\"func\":\"os.killpg\",\"kw\":[],\"lineno\":145},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":151},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":152},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":153},{\"argc\":1,\"func\":\"dict\",\"kw\":[],\"lineno\":161},{\"argc\":0,\"func\":\"pipe.fileno\",\"kw\":[],\"lineno\":163},{\"argc\":0,\"func\":\"check\",\"kw\":[],\"lineno\":167},{\"argc\":2,\"func\":\"min\",\"kw\":[],\"lineno\":168},{\"argc\":2,\"func\":\"os.read\",\"kw\":[],\"lineno\":169},{\"argc\":0,\"func\":\"time.monotonic\",\"kw\":[],\"lineno\":174},{\"argc\":1,\"func\":\"PVEError\",\"kw\":[],\"lineno\":176},{\"argc\":1,\"func\":\"t.ident\",\"kw\":[],\"lineno\":182},{\"argc\":1,\"func\":\"terminate\",\"kw\":[],\"lineno\":185},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":193},{\"argc\":1,\"func\":\"set\",\"kw\":[],\"lineno\":193},{\"argc\":1,\"func\":\"path_ok\",\"kw\":[],\"lineno\":195},{\"argc\":1,\"func\":\"core.valid_hash\",\"kw\":[],\"lineno\":195},{\"argc\":1,\"func\":\"bool\",\"kw\":[],\"lineno\":197},{\"argc\":1,\"func\":\"os.listdir\",\"kw\":[],\"lineno\":207},{\"argc\":0,\"func\":\"time.time\",\"kw\":[],\"lineno\":214},{\"argc\":1,\"func\":\"list\",\"kw\":[],\"lineno\":219},{\"argc\":1,\"func\":\"ord\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"str\",\"kw\":[],\"lineno\":35},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":38},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":38},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":54},{\"argc\":2,\"func\":\"re.match\",\"kw\":[],\"lineno\":83},{\"argc\":1,\"func\":\"block.add\",\"kw\":[],\"lineno\":97},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":124},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":127},{\"argc\":1,\"func\":\"job.get\",\"kw\":[],\"lineno\":129},{\"argc\":2,\"func\":\"max\",\"kw\":[],\"lineno\":168},{\"argc\":0,\"func\":\"key.fileobj.fileno\",\"kw\":[],\"lineno\":169},{\"argc\":1,\"func\":\"sel.unregister\",\"kw\":[],\"lineno\":170},{\"argc\":2,\"func\":\"need\",\"kw\":[],\"lineno\":172},{\"argc\":2,\"func\":\"stream.write_all\",\"kw\":[],\"lineno\":173},{\"argc\":1,\"func\":\"digest.update\",\"kw\":[],\"lineno\":173},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":173},{\"argc\":1,\"func\":\"t.ident\",\"kw\":[],\"lineno\":179},{\"argc\":1,\"func\":\"t.ident\",\"kw\":[],\"lineno\":179},{\"argc\":1,\"func\":\"os.fstat\",\"kw\":[],\"lineno\":182},{\"argc\":0,\"func\":\"p.poll\",\"kw\":[],\"lineno\":185},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":195},{\"argc\":1,\"func\":\"set\",\"kw\":[],\"lineno\":195},{\"argc\":1,\"func\":\"t.sha\",\"kw\":[],\"lineno\":197},{\"argc\":1,\"func\":\"type\",\"kw\":[],\"lineno\":151},{\"argc\":0,\"func\":\"time.monotonic\",\"kw\":[],\"lineno\":175},{\"argc\":1,\"func\":\"len\",\"kw\":[],\"lineno\":172}]\nPVE265_DANGEROUS_CALL_HITS=[{\"argc\":3,\"func\":\"os.open\",\"kw\":[\"dir_fd\"],\"lineno\":158},{\"argc\":1,\"func\":\"subprocess.Popen\",\"kw\":[\"stdin\",\"stdout\",\"stderr\",\"env\",\"start_new_session\",\"close_fds\"],\"lineno\":160}]\nPVE265_DANGEROUS_LITERALS=[\"vzdump\"]\n=== HELPER_FULL_SOURCE_BEGIN ===\n0001:from __future__ import annotations\n0002:import base64, hashlib, json, pathlib, sys\n0003:\n0004:BASE_RELEASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')\n0005:C411=BASE_RELEASE/'candidate411'\n0006:PVE265_SHA='cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be'\n0007:\n0008:def sha(p:pathlib.Path)->str:\n0009: return hashlib.sha256(p.read_bytes()).hexdigest()\n0010:\n0011:def fail(code:str):\n0012: raise RuntimeError(code)\n0013:\n0014:def main()->int:\n0015: if len(sys.argv)!=1: fail('HELPER_ARGC')\n0016: p=C411/'pve265.py'\n0017: if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')\n0018: sys.path.insert(0,str(C411))\n0019: import adapter\n0020: adapter.verify_sources()\n0021: guest266,pve265,_pve270,_pve282=adapter.load_graph()\n0022: data=sys.stdin.buffer.read(4_000_001)\n0023: if not data or len(data)>4_000_000: fail('INPUT_BOUND')\n0024: raw=json.loads(data.decode('utf-8'))\n0025: if type(raw) is not dict: fail('INPUT_SCHEMA')\n0026: node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')\n0027: 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')\n0028: configs={int(k):v for k,v in raw.get('configs',[])}\n0029: defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64'])\n0030: plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)\n0031: jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]\n0032: if len(jobs)!=1: fail('JOB_CARDINALITY')\n0033: job=jobs[0]\n0034: pve265.validate_job(job,now)\n0035: if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')\n0036: if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY')\n0037: guest266.no_active_tasks(raw.get('tasks'),vmid)\n0038: argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now)\n0039: 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')\n0040: out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}}\n0041: sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\\n')\n0042: return 0\n0043:\n0044:if __name__=='__main__':\n0045: raise SystemExit(main())\n=== HELPER_FULL_SOURCE_END ===\nHELPER_PVE265_CALLS=dump_argv,make_plan,validate_job\nPVE265_REACHABLE_FUNCTIONS=defaults_summary,dump_argv,make_plan,need,normalized_config,path_ok,validate_job\nPVE265_REACHABLE_EDGES=[[\"defaults_summary\",\"need\"],[\"dump_argv\",\"need\"],[\"dump_argv\",\"path_ok\"],[\"dump_argv\",\"path_ok\"],[\"dump_argv\",\"validate_job\"],[\"make_plan\",\"defaults_summary\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"normalized_config\"],[\"normalized_config\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"]]\n=== PVE265_FUNC_defaults_summary_BEGIN ===\n0001:def defaults_summary(raw):\n0002: need(raw is None or type(raw) is bytes and len(raw)<=262144,'DEFAULTS_BOUND')\n0003: result={'present':raw is not None,'sha256':t.sha(raw) if raw is not None else None,'keys':[],'blockers':[]}\n0004: if raw is None:return result\n0005: try:text=raw.decode('utf-8-sig')\n0006: except UnicodeError:result['blockers']=['GLOBAL_DEFAULT_PARSE'];return result\n0007: seen=set();block=set()\n0008: for line in text.splitlines():\n0009: line=line.strip()\n0010: if not line or line.startswith('#'):continue\n0011: m=re.fullmatch(r'([a-z][a-z0-9_-]*)\\s*:\\s*(.*)',line)\n0012: if not m:block.add('GLOBAL_DEFAULT_PARSE');continue\n0013: key,value=m.groups()\n0014: if key in seen:block.add('GLOBAL_DEFAULT_DUPLICATE')\n0015: seen.add(key)\n0016: if key=='script':block.add('GLOBAL_DEFAULT_SCRIPT')\n0017: elif key=='exclude-path':block.add('GLOBAL_DEFAULT_EXCLUDE_PATH')\n0018: elif key not in OVERRIDDEN:block.add('GLOBAL_DEFAULT_UNREVIEWED')\n0019: result['keys']=sorted(seen);result['blockers']=sorted(block);return result\n=== PVE265_FUNC_defaults_summary_END ===\n=== PVE265_FUNC_dump_argv_BEGIN ===\n0001:def dump_argv(job,executable,tmpdir,now):\n0002: validate_job(job,now)\n0003: need(path_ok(executable) and path_ok(tmpdir),'EXECUTION_PATH')\n0004: return [str(executable),str(job['vmid']),'--node',job['node'],'--mode','snapshot','--stdout','1',\n0005: '--compress','zstd','--zstd','1','--remove','0','--prune-backups','keep-all=1',\n0006: '--stdexcludes','0','--lockwait','0','--bwlimit','32768','--ionice','7','--tmpdir',str(tmpdir)]\n=== PVE265_FUNC_dump_argv_END ===\n=== PVE265_FUNC_make_plan_BEGIN ===\n0001:def make_plan(rows,configs,storage_rows,defaults,staging_free,now,node='pve01'):\n0002: need(np.valid_id(node),'NODE_NAME')\n0003: need(type(staging_free) is int and 0<=staging_free<=2**63-1,'SPACE_VALUE')\n0004: need(type(now) is int and now>=0,'PLAN_TIME')\n0005: need(type(configs) is dict,'CONFIGS_SCHEMA')\n0006: guests=np.guests(rows,node);ss=np.storages(storage_rows)\n0007: need(len({x['storage'] for x in ss})==len(ss),'DUPLICATE_STORAGE')\n0008: stores={x['storage']:x for x in ss};global_summary=defaults_summary(defaults)\n0009: jobs=[]\n0010: for g in guests:\n0011: need(g['vmid'] in configs,'GUEST_CONFIG_MISSING')\n0012: original=configs[g['vmid']];cfg=normalized_config(original);summary=np.config_summary(cfg,g['type'])\n0013: summary['config_sha256']=t.sha(core.canonical_bytes(original))\n0014: block=set(summary['blockers'])|set(global_summary['blockers']);sizes=[]\n0015: if not summary['disks']:block.add('NO_BACKUP_DISKS')\n0016: if g['template']:block.add('TEMPLATE_REQUIRES_SEPARATE_POLICY')\n0017: if g['status']!='running':block.add('GUEST_NOT_RUNNING')\n0018: if any(k=='args' or re.match(r'hostpci\\d+|usb\\d+|virtiofs\\d+|dev\\d+|lxc\\.',k) for k in cfg):\n0019: block.add('EXTERNAL_DEVICE_OR_CUSTOM_CONFIG')\n0020: for disk in summary['disks']:\n0021: slot=disk['slot'];opts={}\n0022: for field in cfg[slot].split(',')[1:]:\n0023: k,sep,v=field.partition('=')\n0024: if sep:opts[k]=v\n0025: if 'backup' in opts and opts['backup'] not in ('0','1','yes','no','on','off','true','false'):\n0026: block.add('BACKUP_FLAG_UNKNOWN')\n0027: if disk['backup_setting']=='default_unproven':\n0028: if g['type']=='qemu':disk['backup_setting']='included_default_qemu'\n0029: elif slot=='rootfs':disk['backup_setting']='included_default_rootfs'\n0030: st=stores.get(disk['storage'])\n0031: if st is None or st['active'] is not True or st['enabled'] is not True:block.add('STORAGE_NOT_AVAILABLE')\n0032: elif g['type']=='lxc' and st['type'] not in ('lvmthin','zfspool'):block.add('LXC_SNAPSHOT_SUPPORT_UNPROVEN')\n0033: if disk['configured_size_bytes'] is not None:sizes.append(disk['configured_size_bytes'])\n0034: total=sum(sizes)\n0035: if total>stream.MAX_BYTES:block.add('GUEST_SIZE_EXCEEDS_CORE_BOUND')\n0036: # Policy ceiling, not an estimate of compression ratio. Actual byte cap is enforced at read/write.\n0037: configured_bound=min(stream.MAX_BYTES,total+(total+9)//10+64*1024**2) if total else 0\n0038: capacity=max(0,(staging_free-LOCAL_RESERVE)//4)\n0039: cap=min(configured_bound,capacity)\n0040: if cap<=0:block.add('STAGING_CAPACITY_ZERO')\n0041: summary['blockers']=sorted(block)\n0042: job={**g,**summary,'observed_at':now,'global_defaults_sha256':global_summary['sha256'],\n0043: 'configured_disk_bytes':total,'configured_archive_bound_bytes':configured_bound,\n0044: 'archive_cap_bytes':cap,'configured_full_cycle_fits':bool(configured_bound and 4*configured_bound+LOCAL_RESERVE<=staging_free),\n0045: 'compression_dependent':bool(configured_bound and capstr: +0009: return hashlib.sha256(p.read_bytes()).hexdigest() +0010: +0011:def fail(code:str): +0012: raise RuntimeError(code) +0013: +0014:def main()->int: +0015: if len(sys.argv)!=1: fail('HELPER_ARGC') +0016: p=C411/'pve265.py' +0017: if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY') +0018: sys.path.insert(0,str(C411)) +0019: import adapter +0020: adapter.verify_sources() +0021: guest266,pve265,_pve270,_pve282=adapter.load_graph() +0022: data=sys.stdin.buffer.read(4_000_001) +0023: if not data or len(data)>4_000_000: fail('INPUT_BOUND') +0024: raw=json.loads(data.decode('utf-8')) +0025: if type(raw) is not dict: fail('INPUT_SCHEMA') +0026: node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now') +0027: 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') +0028: configs={int(k):v for k,v in raw.get('configs',[])} +0029: defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64']) +0030: plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node) +0031: jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid] +0032: if len(jobs)!=1: fail('JOB_CARDINALITY') +0033: job=jobs[0] +0034: pve265.validate_job(job,now) +0035: if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY') +0036: if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY') +0037: guest266.no_active_tasks(raw.get('tasks'),vmid) +0038: argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now) +0039: 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') +0040: out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}} +0041: sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\n') +0042: return 0 +0043: +0044:if __name__=='__main__': +0045: raise SystemExit(main()) +=== HELPER_FULL_SOURCE_END === +HELPER_PVE265_CALLS=dump_argv,make_plan,validate_job +PVE265_REACHABLE_FUNCTIONS=defaults_summary,dump_argv,make_plan,need,normalized_config,path_ok,validate_job +PVE265_REACHABLE_EDGES=[["defaults_summary","need"],["dump_argv","need"],["dump_argv","path_ok"],["dump_argv","path_ok"],["dump_argv","validate_job"],["make_plan","defaults_summary"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","normalized_config"],["normalized_config","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"]] +=== PVE265_FUNC_defaults_summary_BEGIN === +0001:def defaults_summary(raw): +0002: need(raw is None or type(raw) is bytes and len(raw)<=262144,'DEFAULTS_BOUND') +0003: result={'present':raw is not None,'sha256':t.sha(raw) if raw is not None else None,'keys':[],'blockers':[]} +0004: if raw is None:return result +0005: try:text=raw.decode('utf-8-sig') +0006: except UnicodeError:result['blockers']=['GLOBAL_DEFAULT_PARSE'];return result +0007: seen=set();block=set() +0008: for line in text.splitlines(): +0009: line=line.strip() +0010: if not line or line.startswith('#'):continue +0011: m=re.fullmatch(r'([a-z][a-z0-9_-]*)\s*:\s*(.*)',line) +0012: if not m:block.add('GLOBAL_DEFAULT_PARSE');continue +0013: key,value=m.groups() +0014: if key in seen:block.add('GLOBAL_DEFAULT_DUPLICATE') +0015: seen.add(key) +0016: if key=='script':block.add('GLOBAL_DEFAULT_SCRIPT') +0017: elif key=='exclude-path':block.add('GLOBAL_DEFAULT_EXCLUDE_PATH') +0018: elif key not in OVERRIDDEN:block.add('GLOBAL_DEFAULT_UNREVIEWED') +0019: result['keys']=sorted(seen);result['blockers']=sorted(block);return result +=== PVE265_FUNC_defaults_summary_END === +=== PVE265_FUNC_dump_argv_BEGIN === +0001:def dump_argv(job,executable,tmpdir,now): +0002: validate_job(job,now) +0003: need(path_ok(executable) and path_ok(tmpdir),'EXECUTION_PATH') +0004: return [str(executable),str(job['vmid']),'--node',job['node'],'--mode','snapshot','--stdout','1', +0005: '--compress','zstd','--zstd','1','--remove','0','--prune-backups','keep-all=1', +0006: '--stdexcludes','0','--lockwait','0','--bwlimit','32768','--ionice','7','--tmpdir',str(tmpdir)] +=== PVE265_FUNC_dump_argv_END === +=== PVE265_FUNC_make_plan_BEGIN === +0001:def make_plan(rows,configs,storage_rows,defaults,staging_free,now,node='pve01'): +0002: need(np.valid_id(node),'NODE_NAME') +0003: need(type(staging_free) is int and 0<=staging_free<=2**63-1,'SPACE_VALUE') +0004: need(type(now) is int and now>=0,'PLAN_TIME') +0005: need(type(configs) is dict,'CONFIGS_SCHEMA') +0006: guests=np.guests(rows,node);ss=np.storages(storage_rows) +0007: need(len({x['storage'] for x in ss})==len(ss),'DUPLICATE_STORAGE') +0008: stores={x['storage']:x for x in ss};global_summary=defaults_summary(defaults) +0009: jobs=[] +0010: for g in guests: +0011: need(g['vmid'] in configs,'GUEST_CONFIG_MISSING') +0012: original=configs[g['vmid']];cfg=normalized_config(original);summary=np.config_summary(cfg,g['type']) +0013: summary['config_sha256']=t.sha(core.canonical_bytes(original)) +0014: block=set(summary['blockers'])|set(global_summary['blockers']);sizes=[] +0015: if not summary['disks']:block.add('NO_BACKUP_DISKS') +0016: if g['template']:block.add('TEMPLATE_REQUIRES_SEPARATE_POLICY') +0017: if g['status']!='running':block.add('GUEST_NOT_RUNNING') +0018: if any(k=='args' or re.match(r'hostpci\d+|usb\d+|virtiofs\d+|dev\d+|lxc\.',k) for k in cfg): +0019: block.add('EXTERNAL_DEVICE_OR_CUSTOM_CONFIG') +0020: for disk in summary['disks']: +0021: slot=disk['slot'];opts={} +0022: for field in cfg[slot].split(',')[1:]: +0023: k,sep,v=field.partition('=') +0024: if sep:opts[k]=v +0025: if 'backup' in opts and opts['backup'] not in ('0','1','yes','no','on','off','true','false'): +0026: block.add('BACKUP_FLAG_UNKNOWN') +0027: if disk['backup_setting']=='default_unproven': +0028: if g['type']=='qemu':disk['backup_setting']='included_default_qemu' +0029: elif slot=='rootfs':disk['backup_setting']='included_default_rootfs' +0030: st=stores.get(disk['storage']) +0031: if st is None or st['active'] is not True or st['enabled'] is not True:block.add('STORAGE_NOT_AVAILABLE') +0032: elif g['type']=='lxc' and st['type'] not in ('lvmthin','zfspool'):block.add('LXC_SNAPSHOT_SUPPORT_UNPROVEN') +0033: if disk['configured_size_bytes'] is not None:sizes.append(disk['configured_size_bytes']) +0034: total=sum(sizes) +0035: if total>stream.MAX_BYTES:block.add('GUEST_SIZE_EXCEEDS_CORE_BOUND') +0036: # Policy ceiling, not an estimate of compression ratio. Actual byte cap is enforced at read/write. +0037: configured_bound=min(stream.MAX_BYTES,total+(total+9)//10+64*1024**2) if total else 0 +0038: capacity=max(0,(staging_free-LOCAL_RESERVE)//4) +0039: cap=min(configured_bound,capacity) +0040: if cap<=0:block.add('STAGING_CAPACITY_ZERO') +0041: summary['blockers']=sorted(block) +0042: job={**g,**summary,'observed_at':now,'global_defaults_sha256':global_summary['sha256'], +0043: 'configured_disk_bytes':total,'configured_archive_bound_bytes':configured_bound, +0044: 'archive_cap_bytes':cap,'configured_full_cycle_fits':bool(configured_bound and 4*configured_bound+LOCAL_RESERVE<=staging_free), +0045: 'compression_dependent':bool(configured_bound and capstr:\n0009: return hashlib.sha256(p.read_bytes()).hexdigest()\n0010:\n0011:def fail(code:str):\n0012: raise RuntimeError(code)\n0013:\n0014:def main()->int:\n0015: if len(sys.argv)!=1: fail('HELPER_ARGC')\n0016: p=C411/'pve265.py'\n0017: if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')\n0018: sys.path.insert(0,str(C411))\n0019: import adapter\n0020: adapter.verify_sources()\n0021: guest266,pve265,_pve270,_pve282=adapter.load_graph()\n0022: data=sys.stdin.buffer.read(4_000_001)\n0023: if not data or len(data)>4_000_000: fail('INPUT_BOUND')\n0024: raw=json.loads(data.decode('utf-8'))\n0025: if type(raw) is not dict: fail('INPUT_SCHEMA')\n0026: node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')\n0027: 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')\n0028: configs={int(k):v for k,v in raw.get('configs',[])}\n0029: defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64'])\n0030: plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)\n0031: jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]\n0032: if len(jobs)!=1: fail('JOB_CARDINALITY')\n0033: job=jobs[0]\n0034: pve265.validate_job(job,now)\n0035: if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')\n0036: if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY')\n0037: guest266.no_active_tasks(raw.get('tasks'),vmid)\n0038: argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now)\n0039: 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')\n0040: out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}}\n0041: sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\\n')\n0042: return 0\n0043:\n0044:if __name__=='__main__':\n0045: raise SystemExit(main())\n=== HELPER_FULL_SOURCE_END ===\nHELPER_PVE265_CALLS=dump_argv,make_plan,validate_job\nPVE265_REACHABLE_FUNCTIONS=defaults_summary,dump_argv,make_plan,need,normalized_config,path_ok,validate_job\nPVE265_REACHABLE_EDGES=[[\"defaults_summary\",\"need\"],[\"dump_argv\",\"need\"],[\"dump_argv\",\"path_ok\"],[\"dump_argv\",\"path_ok\"],[\"dump_argv\",\"validate_job\"],[\"make_plan\",\"defaults_summary\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"need\"],[\"make_plan\",\"normalized_config\"],[\"normalized_config\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"],[\"validate_job\",\"need\"]]\n=== PVE265_FUNC_defaults_summary_BEGIN ===\n0001:def defaults_summary(raw):\n0002: need(raw is None or type(raw) is bytes and len(raw)<=262144,'DEFAULTS_BOUND')\n0003: result={'present':raw is not None,'sha256':t.sha(raw) if raw is not None else None,'keys':[],'blockers':[]}\n0004: if raw is None:return result\n0005: try:text=raw.decode('utf-8-sig')\n0006: except UnicodeError:result['blockers']=['GLOBAL_DEFAULT_PARSE'];return result\n0007: seen=set();block=set()\n0008: for line in text.splitlines():\n0009: line=line.strip()\n0010: if not line or line.startswith('#'):continue\n0011: m=re.fullmatch(r'([a-z][a-z0-9_-]*)\\s*:\\s*(.*)',line)\n0012: if not m:block.add('GLOBAL_DEFAULT_PARSE');continue\n0013: key,value=m.groups()\n0014: if key in seen:block.add('GLOBAL_DEFAULT_DUPLICATE')\n0015: seen.add(key)\n0016: if key=='script':block.add('GLOBAL_DEFAULT_SCRIPT')\n0017: elif key=='exclude-path':block.add('GLOBAL_DEFAULT_EXCLUDE_PATH')\n0018: elif key not in OVERRIDDEN:block.add('GLOBAL_DEFAULT_UNREVIEWED')\n0019: result['keys']=sorted(seen);result['blockers']=sorted(block);return result\n=== PVE265_FUNC_defaults_summary_END ===\n=== PVE265_FUNC_dump_argv_BEGIN ===\n0001:def dump_argv(job,executable,tmpdir,now):\n0002: validate_job(job,now)\n0003: need(path_ok(executable) and path_ok(tmpdir),'EXECUTION_PATH')\n0004: return [str(executable),str(job['vmid']),'--node',job['node'],'--mode','snapshot','--stdout','1',\n0005: '--compress','zstd','--zstd','1','--remove','0','--prune-backups','keep-all=1',\n0006: '--stdexcludes','0','--lockwait','0','--bwlimit','32768','--ionice','7','--tmpdir',str(tmpdir)]\n=== PVE265_FUNC_dump_argv_END ===\n=== PVE265_FUNC_make_plan_BEGIN ===\n0001:def make_plan(rows,configs,storage_rows,defaults,staging_free,now,node='pve01'):\n0002: need(np.valid_id(node),'NODE_NAME')\n0003: need(type(staging_free) is int and 0<=staging_free<=2**63-1,'SPACE_VALUE')\n0004: need(type(now) is int and now>=0,'PLAN_TIME')\n0005: need(type(configs) is dict,'CONFIGS_SCHEMA')\n0006: guests=np.guests(rows,node);ss=np.storages(storage_rows)\n0007: need(len({x['storage'] for x in ss})==len(ss),'DUPLICATE_STORAGE')\n0008: stores={x['storage']:x for x in ss};global_summary=defaults_summary(defaults)\n0009: jobs=[]\n0010: for g in guests:\n0011: need(g['vmid'] in configs,'GUEST_CONFIG_MISSING')\n0012: original=configs[g['vmid']];cfg=normalized_config(original);summary=np.config_summary(cfg,g['type'])\n0013: summary['config_sha256']=t.sha(core.canonical_bytes(original))\n0014: block=set(summary['blockers'])|set(global_summary['blockers']);sizes=[]\n0015: if not summary['disks']:block.add('NO_BACKUP_DISKS')\n0016: if g['template']:block.add('TEMPLATE_REQUIRES_SEPARATE_POLICY')\n0017: if g['status']!='running':block.add('GUEST_NOT_RUNNING')\n0018: if any(k=='args' or re.match(r'hostpci\\d+|usb\\d+|virtiofs\\d+|dev\\d+|lxc\\.',k) for k in cfg):\n0019: block.add('EXTERNAL_DEVICE_OR_CUSTOM_CONFIG')\n0020: for disk in summary['disks']:\n0021: slot=disk['slot'];opts={}\n0022: for field in cfg[slot].split(',')[1:]:\n0023: k,sep,v=field.partition('=')\n0024: if sep:opts[k]=v\n0025: if 'backup' in opts and opts['backup'] not in ('0','1','yes','no','on','off','true','false'):\n0026: block.add('BACKUP_FLAG_UNKNOWN')\n0027: if disk['backup_setting']=='default_unproven':\n0028: if g['type']=='qemu':disk['backup_setting']='included_default_qemu'\n0029: elif slot=='rootfs':disk['backup_setting']='included_default_rootfs'\n0030: st=stores.get(disk['storage'])\n0031: if st is None or st['active'] is not True or st['enabled'] is not True:block.add('STORAGE_NOT_AVAILABLE')\n0032: elif g['type']=='lxc' and st['type'] not in ('lvmthin','zfspool'):block.add('LXC_SNAPSHOT_SUPPORT_UNPROVEN')\n0033: if disk['configured_size_bytes'] is not None:sizes.append(disk['configured_size_bytes'])\n0034: total=sum(sizes)\n0035: if total>stream.MAX_BYTES:block.add('GUEST_SIZE_EXCEEDS_CORE_BOUND')\n0036: # Policy ceiling, not an estimate of compression ratio. Actual byte cap is enforced at read/write.\n0037: configured_bound=min(stream.MAX_BYTES,total+(total+9)//10+64*1024**2) if total else 0\n0038: capacity=max(0,(staging_free-LOCAL_RESERVE)//4)\n0039: cap=min(configured_bound,capacity)\n0040: if cap<=0:block.add('STAGING_CAPACITY_ZERO')\n0041: summary['blockers']=sorted(block)\n0042: job={**g,**summary,'observed_at':now,'global_defaults_sha256':global_summary['sha256'],\n0043: 'configured_disk_bytes':total,'configured_archive_bound_bytes':configured_bound,\n0044: 'archive_cap_bytes':cap,'configured_full_cycle_fits':bool(configured_bound and 4*configured_bound+LOCAL_RESERVE<=staging_free),\n0045: 'compression_dependent':bool(configured_bound and capstr: +0009: return hashlib.sha256(p.read_bytes()).hexdigest() +0010: +0011:def fail(code:str): +0012: raise RuntimeError(code) +0013: +0014:def main()->int: +0015: if len(sys.argv)!=1: fail('HELPER_ARGC') +0016: p=C411/'pve265.py' +0017: if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY') +0018: sys.path.insert(0,str(C411)) +0019: import adapter +0020: adapter.verify_sources() +0021: guest266,pve265,_pve270,_pve282=adapter.load_graph() +0022: data=sys.stdin.buffer.read(4_000_001) +0023: if not data or len(data)>4_000_000: fail('INPUT_BOUND') +0024: raw=json.loads(data.decode('utf-8')) +0025: if type(raw) is not dict: fail('INPUT_SCHEMA') +0026: node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now') +0027: 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') +0028: configs={int(k):v for k,v in raw.get('configs',[])} +0029: defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64']) +0030: plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node) +0031: jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid] +0032: if len(jobs)!=1: fail('JOB_CARDINALITY') +0033: job=jobs[0] +0034: pve265.validate_job(job,now) +0035: if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY') +0036: if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY') +0037: guest266.no_active_tasks(raw.get('tasks'),vmid) +0038: argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now) +0039: 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') +0040: out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}} +0041: sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\n') +0042: return 0 +0043: +0044:if __name__=='__main__': +0045: raise SystemExit(main()) +=== HELPER_FULL_SOURCE_END === +HELPER_PVE265_CALLS=dump_argv,make_plan,validate_job +PVE265_REACHABLE_FUNCTIONS=defaults_summary,dump_argv,make_plan,need,normalized_config,path_ok,validate_job +PVE265_REACHABLE_EDGES=[["defaults_summary","need"],["dump_argv","need"],["dump_argv","path_ok"],["dump_argv","path_ok"],["dump_argv","validate_job"],["make_plan","defaults_summary"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","need"],["make_plan","normalized_config"],["normalized_config","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"],["validate_job","need"]] +=== PVE265_FUNC_defaults_summary_BEGIN === +0001:def defaults_summary(raw): +0002: need(raw is None or type(raw) is bytes and len(raw)<=262144,'DEFAULTS_BOUND') +0003: result={'present':raw is not None,'sha256':t.sha(raw) if raw is not None else None,'keys':[],'blockers':[]} +0004: if raw is None:return result +0005: try:text=raw.decode('utf-8-sig') +0006: except UnicodeError:result['blockers']=['GLOBAL_DEFAULT_PARSE'];return result +0007: seen=set();block=set() +0008: for line in text.splitlines(): +0009: line=line.strip() +0010: if not line or line.startswith('#'):continue +0011: m=re.fullmatch(r'([a-z][a-z0-9_-]*)\s*:\s*(.*)',line) +0012: if not m:block.add('GLOBAL_DEFAULT_PARSE');continue +0013: key,value=m.groups() +0014: if key in seen:block.add('GLOBAL_DEFAULT_DUPLICATE') +0015: seen.add(key) +0016: if key=='script':block.add('GLOBAL_DEFAULT_SCRIPT') +0017: elif key=='exclude-path':block.add('GLOBAL_DEFAULT_EXCLUDE_PATH') +0018: elif key not in OVERRIDDEN:block.add('GLOBAL_DEFAULT_UNREVIEWED') +0019: result['keys']=sorted(seen);result['blockers']=sorted(block);return result +=== PVE265_FUNC_defaults_summary_END === +=== PVE265_FUNC_dump_argv_BEGIN === +0001:def dump_argv(job,executable,tmpdir,now): +0002: validate_job(job,now) +0003: need(path_ok(executable) and path_ok(tmpdir),'EXECUTION_PATH') +0004: return [str(executable),str(job['vmid']),'--node',job['node'],'--mode','snapshot','--stdout','1', +0005: '--compress','zstd','--zstd','1','--remove','0','--prune-backups','keep-all=1', +0006: '--stdexcludes','0','--lockwait','0','--bwlimit','32768','--ionice','7','--tmpdir',str(tmpdir)] +=== PVE265_FUNC_dump_argv_END === +=== PVE265_FUNC_make_plan_BEGIN === +0001:def make_plan(rows,configs,storage_rows,defaults,staging_free,now,node='pve01'): +0002: need(np.valid_id(node),'NODE_NAME') +0003: need(type(staging_free) is int and 0<=staging_free<=2**63-1,'SPACE_VALUE') +0004: need(type(now) is int and now>=0,'PLAN_TIME') +0005: need(type(configs) is dict,'CONFIGS_SCHEMA') +0006: guests=np.guests(rows,node);ss=np.storages(storage_rows) +0007: need(len({x['storage'] for x in ss})==len(ss),'DUPLICATE_STORAGE') +0008: stores={x['storage']:x for x in ss};global_summary=defaults_summary(defaults) +0009: jobs=[] +0010: for g in guests: +0011: need(g['vmid'] in configs,'GUEST_CONFIG_MISSING') +0012: original=configs[g['vmid']];cfg=normalized_config(original);summary=np.config_summary(cfg,g['type']) +0013: summary['config_sha256']=t.sha(core.canonical_bytes(original)) +0014: block=set(summary['blockers'])|set(global_summary['blockers']);sizes=[] +0015: if not summary['disks']:block.add('NO_BACKUP_DISKS') +0016: if g['template']:block.add('TEMPLATE_REQUIRES_SEPARATE_POLICY') +0017: if g['status']!='running':block.add('GUEST_NOT_RUNNING') +0018: if any(k=='args' or re.match(r'hostpci\d+|usb\d+|virtiofs\d+|dev\d+|lxc\.',k) for k in cfg): +0019: block.add('EXTERNAL_DEVICE_OR_CUSTOM_CONFIG') +0020: for disk in summary['disks']: +0021: slot=disk['slot'];opts={} +0022: for field in cfg[slot].split(',')[1:]: +0023: k,sep,v=field.partition('=') +0024: if sep:opts[k]=v +0025: if 'backup' in opts and opts['backup'] not in ('0','1','yes','no','on','off','true','false'): +0026: block.add('BACKUP_FLAG_UNKNOWN') +0027: if disk['backup_setting']=='default_unproven': +0028: if g['type']=='qemu':disk['backup_setting']='included_default_qemu' +0029: elif slot=='rootfs':disk['backup_setting']='included_default_rootfs' +0030: st=stores.get(disk['storage']) +0031: if st is None or st['active'] is not True or st['enabled'] is not True:block.add('STORAGE_NOT_AVAILABLE') +0032: elif g['type']=='lxc' and st['type'] not in ('lvmthin','zfspool'):block.add('LXC_SNAPSHOT_SUPPORT_UNPROVEN') +0033: if disk['configured_size_bytes'] is not None:sizes.append(disk['configured_size_bytes']) +0034: total=sum(sizes) +0035: if total>stream.MAX_BYTES:block.add('GUEST_SIZE_EXCEEDS_CORE_BOUND') +0036: # Policy ceiling, not an estimate of compression ratio. Actual byte cap is enforced at read/write. +0037: configured_bound=min(stream.MAX_BYTES,total+(total+9)//10+64*1024**2) if total else 0 +0038: capacity=max(0,(staging_free-LOCAL_RESERVE)//4) +0039: cap=min(configured_bound,capacity) +0040: if cap<=0:block.add('STAGING_CAPACITY_ZERO') +0041: summary['blockers']=sorted(block) +0042: job={**g,**summary,'observed_at':now,'global_defaults_sha256':global_summary['sha256'], +0043: 'configured_disk_bytes':total,'configured_archive_bound_bytes':configured_bound, +0044: 'archive_cap_bytes':cap,'configured_full_cycle_fits':bool(configured_bound and 4*configured_bound+LOCAL_RESERVE<=staging_free), +0045: 'compression_dependent':bool(configured_bound and cap