206 lines
14 KiB
Plaintext
206 lines
14 KiB
Plaintext
CHAT_OUTPUT_BEGIN
|
|
COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1
|
|
STATUS=OK
|
|
RC=0
|
|
HOST=pve01
|
|
MODE=read-only
|
|
COMPONENT=homelab-backup-overlay-hotfix-source-rca
|
|
REFERENCE_REGISTER_CHECK=OK
|
|
REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66
|
|
ERROR_REGISTER_CHECK=OK
|
|
ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0
|
|
COMMAND_SHA256=2dc27b7a91ac007c80176806c837e4a05af12349ce8d90549bb634a60b4976fb
|
|
DUPLICATE_FAILED_COMMAND_BLOCKED=false
|
|
EXECUTION_STARTED=true
|
|
CHANGE_DECLARED=false
|
|
RESULT_CONTRACT_VALID=true
|
|
RESULT_CONTRACT_STATUS=NOT_APPLICABLE
|
|
RESULT_CONTRACT_ERROR=NONE
|
|
COMMAND_RC=0
|
|
CHANGES_MADE=false
|
|
ROLLBACK_STARTED=false
|
|
ROLLBACK_RESTORED=null
|
|
MUTATION_OUTCOME=NO_MUTATION
|
|
SANITIZED=yes
|
|
SECRETS_INCLUDED=no
|
|
PRIVATE_ADDRESSES_INCLUDED=no
|
|
RAW_EVIDENCE_SHA256=104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5
|
|
SANITIZED_OUTPUT_SHA256=104229289b0d44d96b4f38fe3259b6ccba08188a68213a0d0bd59e3a2eadfec5
|
|
OUTPUT_BEGIN
|
|
BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_BEGIN=true
|
|
COMMAND_ID=SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1
|
|
MODE=read-only
|
|
COMPONENT=homelab-backup-overlay-hotfix-source-rca
|
|
MUTATION_BOUNDARY=READ_ONLY_SOURCE_AUTHORITY_AND_DEPLOYMENT_TOPOLOGY;NO_GIT_FETCH_NO_GIT_WRITE_NO_CONFIG_WRITE_NO_RELEASE_WRITE_NO_WRAPPER_WRITE_NO_BACKUP_NO_AUDIT_RUN_NO_SYSTEMD_ACTION_NO_LOCK_BREAK_NO_MAIL_NO_NETBIRD_SKLADCHIK_CHANGE
|
|
HOST=pve01
|
|
CLUSTER_QUORATE=Yes
|
|
RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d
|
|
SOURCE_1228_STATUS=OK
|
|
SOURCE_1228_DECISION=PASS_VZDUMP_GLOBAL_DEFAULT_RCA_COLLECTED
|
|
SOURCE_1228_NEXT_GATE=READ_EXACT_1228_AND_FIX_ONLY_PROVEN_GLOBAL_DEFAULT_CAUSE
|
|
=== LIVE_AUTHORITY ===
|
|
LIVE_WRAPPER_PATH=/usr/local/sbin/homelab-backup-v2
|
|
LIVE_WRAPPER_SHA256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2
|
|
LIVE_WRAPPER_MATCH=true
|
|
LIVE_HELPER_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/fresh_lxc_helper.py
|
|
LIVE_HELPER_SHA256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011
|
|
LIVE_HELPER_MATCH=true
|
|
LIVE_LXC_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/lxc_adapter.py
|
|
LIVE_LXC_SHA256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d
|
|
LIVE_LXC_MATCH=true
|
|
LIVE_ENTRY_PATH=/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b/entry504.py
|
|
LIVE_ENTRY_SHA256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793
|
|
LIVE_ENTRY_MATCH=true
|
|
LIVE_PVE265_PATH=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py
|
|
LIVE_PVE265_SHA256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be
|
|
LIVE_PVE265_MATCH=true
|
|
LIVE_VZDUMP_CONF_SHA256=027e4b04852a4b83d558eb861d432b6fad4f234e12ab77d327f274d0fdedbfad
|
|
LIVE_VZDUMP_CONF_MATCH=true
|
|
=== GIT_SOURCE_AUTHORITY ===
|
|
SOURCE_WORKTREE_EXISTS=true
|
|
SOURCE_WORKTREE=/root/homelab-ops-cr-2026-1005
|
|
SOURCE_TOPLEVEL=/root/homelab-ops-cr-2026-1005
|
|
SOURCE_BRANCH=cr-2026-1005-backup-v2-health-alerting-remediation
|
|
SOURCE_HEAD=e5f577d1abe9feeafcd48b1482990ce3aa242e45
|
|
SOURCE_UPSTREAM=NONE
|
|
SOURCE_STATUS_COUNT=0
|
|
SOURCE_STATUS_BEGIN
|
|
|
|
SOURCE_STATUS_END
|
|
SOURCE_WORKTREE_CLEAN=true
|
|
SOURCE_REMOTES_BEGIN
|
|
origin
|
|
SOURCE_REMOTES_END
|
|
SOURCE_LOG_HEAD_BEGIN
|
|
e5f577d1abe9feeafcd48b1482990ce3aa242e45|2026-09-25T11:53:41+03:00|backup alert: debounce transient health mail
|
|
6401ea1e99988b9d2550de544c9e45bd7e829bdd|2026-09-22T12:19:14+03:00|CR-2026-1005: canonicalize Cloud B audit proof
|
|
4e59d5afaa670899c56f87a84bc887175f299614|2026-09-21T07:52:31+03:00|CR-2026-1005: seal backup health alerting and DR closure
|
|
47b9be72cf2487ba66295d7da998016bbeea57be|2026-09-21T06:31:05+03:00|CR-2026-1005: close V2 backup scheduling and retention gaps
|
|
50bf24f8ee27f3d2e0d1cbc6c17b62c69ff06bae|2026-09-21T05:51:10+03:00|CR-2026-1005: hold retention timer during GFS apply
|
|
46c6f9aaf8fa93ce9f0cee686f948704c1a61336|2026-09-21T05:14:29+03:00|CR-2026-1005: add controlled GFS lifecycle remediation task
|
|
0d62d4a2077047b9b040a9378085ece09dd15883|2026-09-21T04:50:07+03:00|CR-2026-1005: make GFS critical policy lifecycle-safe
|
|
326622a4864fa9b5f43b69981733236bb42c4d7b|2026-09-01T09:09:31Z|Merge pull request 'CR0108 record Gitea reconciler production closure' (#46) from cr-2026-0108-gitea-reconciler-production-closure into main
|
|
6c970c4f1ee618149cf225b690e7a411c1b00df5|2026-09-01T11:30:57+03:00|CR0108 record Gitea reconciler production closure
|
|
030d2bcf232a43e5673684b2116c7382da3ee412|2026-09-01T07:51:45Z|Merge pull request 'CR0107 invoke staged reconciler selftest through bash' (#45) from cr-2026-0107-gitea-reconciler-selftest-bash-invocation into main
|
|
2ffbe030c6b5ebc9af1aa3aefb10520ad31153ed|2026-09-01T10:51:04+03:00|CR0107 invoke reconciler selftest through bash
|
|
c6114944985f813794821629f889d7a8c6677743|2026-09-01T06:26:03Z|Merge pull request 'CR0106 harden Gitea reconciler token lifecycle' (#44) from cr-2026-0106-gitea-reconciler-token-lifecycle-hardening into main
|
|
1d63b2607eea5dd5a8a390cd8b22e07a39aed7be|2026-09-01T09:16:48+03:00|CR0106 harden Gitea reconciler token lifecycle
|
|
69acde73c234db97f6e2e080a0f725e8abd970d6|2026-09-01T08:27:21+03:00|CR0106 define Gitea reconciler token lifecycle contract (RED)
|
|
b7adc4b1747e1ae2ab930392e2952d5d3b3a1a7e|2026-09-01T04:52:17Z|Merge pull request 'CR0105 add Gitea repository access reconciler' (#43) from cr-2026-0105-gitea-repo-access-reconciler into main
|
|
f30216d8aa7a41de534499c48fa9174cc12242c9|2026-09-01T07:10:34+03:00|CR0105 make fake-token test CI-safe
|
|
fd4273b3fc09c1b5f4497662cb3a79bf2180798a|2026-09-01T06:40:38+03:00|CR0105 implement VM170 Gitea access reconciler
|
|
68a3fd045049038bd72c4f8f06b37e644aec0438|2026-09-01T00:54:22+03:00|CR0105 define Gitea access reconciler contract (RED)
|
|
649b4b54e14281007264dda8eb4fd7d07623ad3c|2026-08-31T19:24:44Z|Merge pull request 'CR0104 record production closure' (#42) from cr-2026-0104-production-closure into main
|
|
07f709b6fc06acad11b93e66ecd9367a3396f4f1|2026-08-31T22:23:17+03:00|CR0104 record production closure
|
|
SOURCE_LOG_HEAD_END
|
|
=== EXACT_SOURCE_FILE_CANDIDATES ===
|
|
SOURCE_CANDIDATE|name=entry504.py|exact=true|sha256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/entry504.py
|
|
SOURCE_CANDIDATE|name=fresh_lxc_helper.py|exact=true|sha256=dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py
|
|
SOURCE_CANDIDATE|name=homelab-backup-v2|exact=true|sha256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2
|
|
SOURCE_CANDIDATE|name=lxc_adapter.py|exact=true|sha256=3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d|path=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py
|
|
SOURCE_CANDIDATE_TOTAL|name=entry504.py|count=1|exact_count=1
|
|
SOURCE_CANDIDATE_TOTAL|name=fresh_lxc_helper.py|count=1|exact_count=1
|
|
SOURCE_CANDIDATE_TOTAL|name=homelab-backup-v2|count=1|exact_count=1
|
|
SOURCE_CANDIDATE_TOTAL|name=lxc_adapter.py|count=1|exact_count=1
|
|
SOURCE_CANDIDATE_TOTAL|name=pve265.py|count=0|exact_count=0
|
|
=== RELEVANT_SOURCE_GREP ===
|
|
tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py:6:PVE265_SHA='cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be'
|
|
tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/fresh_lxc_helper.py:17: if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')
|
|
tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:6:HELPER=pathlib.Path(__file__).resolve().parent/'fresh_lxc_helper.py'
|
|
tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2:4:ACCEPTED=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b')
|
|
tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2:5:EXPECTED={'fresh_lxc_helper.py': 'dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011', 'producer_exec_helper.py': 'b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3', 'lxc_adapter.py': '3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d', 'qemu_adapter.py': '1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b', 'scheduler_adapter.py': 'a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96', 'entry504.py': 'ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793'}
|
|
=== BASELINE_WRAPPER_AUTHORITY ===
|
|
BASELINE_WRAPPER_PATH=/root/homelab-ops-cr-2026-1005/tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/homelab-backup-v2
|
|
BASELINE_WRAPPER_EXISTS=true
|
|
BASELINE_WRAPPER_SHA256=5077444065c732451cb84898680f62361b21a24ef9eb4f191253e82ead524ea2
|
|
BASELINE_WRAPPER_MATCH_LIVE=true
|
|
=== CHANGE1207_SOURCE_HINTS ===
|
|
tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:57: q=legacy.ssh_remote(node,['test','-f','/etc/vzdump.conf'],timeout=30,check=False)
|
|
tasks/backup-v2-health-alerting-remediation-v1/assets/baseline/backup-v2-release/lxc_adapter.py:59: if q.returncode==0: defaults=legacy.ssh_remote(node,['cat','--','/etc/vzdump.conf'],timeout=30).stdout
|
|
=== CURRENT_WRAPPER_SOURCE ===
|
|
#!/usr/bin/python3
|
|
from __future__ import annotations
|
|
import hashlib, importlib, os, pathlib, stat, sys
|
|
ACCEPTED=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-overlay-504r1-ca6876fa9c3b')
|
|
EXPECTED={'fresh_lxc_helper.py': 'dbb3e6dbb71b10797df736431d9501a752a0f8c439163c9a0bddb7f76747f011', 'producer_exec_helper.py': 'b3b97099bcd7126670f866e81faae6a42a96d869d9989e6a67f6ea6c871c90b3', 'lxc_adapter.py': '3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d', 'qemu_adapter.py': '1906db42bd34bbe85eb46fd9797b3572d46e0a41c29d1c29be5f9df5e448f15b', 'scheduler_adapter.py': 'a6f67159a64067773323f028126e3109e15cf17a8142cea5e6129970f1d4da96', 'entry504.py': 'ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793'}
|
|
def sha(p):
|
|
h=hashlib.sha256()
|
|
with open(p,'rb',buffering=0) as f:
|
|
while True:
|
|
b=f.read(1048576)
|
|
if not b: break
|
|
h.update(b)
|
|
return h.hexdigest()
|
|
def main():
|
|
st=os.lstat(ACCEPTED)
|
|
if not stat.S_ISDIR(st.st_mode) or stat.S_ISLNK(st.st_mode) or st.st_uid!=0 or st.st_gid!=0 or stat.S_IMODE(st.st_mode)!=0o500: raise SystemExit('RELEASE_ROOT_IDENTITY')
|
|
names=sorted(p.name for p in ACCEPTED.iterdir())
|
|
if names!=sorted(EXPECTED): raise SystemExit('RELEASE_FILESET')
|
|
for name,want in EXPECTED.items():
|
|
p=ACCEPTED/name; s=os.lstat(p)
|
|
if not stat.S_ISREG(s.st_mode) or stat.S_ISLNK(s.st_mode) or s.st_uid!=0 or s.st_gid!=0 or stat.S_IMODE(s.st_mode)!=0o400 or sha(p)!=want: raise SystemExit('RELEASE_FILE_IDENTITY_'+name)
|
|
sys.dont_write_bytecode=True
|
|
sys.path.insert(0,str(ACCEPTED))
|
|
e=importlib.import_module('entry504')
|
|
return int(e.main())
|
|
if __name__=='__main__': raise SystemExit(main())
|
|
=== CURRENT_HELPER_SOURCE ===
|
|
from __future__ import annotations
|
|
import base64, hashlib, json, pathlib, sys
|
|
|
|
BASE_RELEASE=pathlib.Path('/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1')
|
|
C411=BASE_RELEASE/'candidate411'
|
|
PVE265_SHA='cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be'
|
|
|
|
def sha(p:pathlib.Path)->str:
|
|
return hashlib.sha256(p.read_bytes()).hexdigest()
|
|
|
|
def fail(code:str):
|
|
raise RuntimeError(code)
|
|
|
|
def main()->int:
|
|
if len(sys.argv)!=1: fail('HELPER_ARGC')
|
|
p=C411/'pve265.py'
|
|
if not p.is_file() or p.is_symlink() or sha(p)!=PVE265_SHA: fail('PVE265_IDENTITY')
|
|
sys.path.insert(0,str(C411))
|
|
import adapter
|
|
adapter.verify_sources()
|
|
guest266,pve265,_pve270,_pve282=adapter.load_graph()
|
|
data=sys.stdin.buffer.read(4_000_001)
|
|
if not data or len(data)>4_000_000: fail('INPUT_BOUND')
|
|
raw=json.loads(data.decode('utf-8'))
|
|
if type(raw) is not dict: fail('INPUT_SCHEMA')
|
|
node=raw.get('node'); vmid=raw.get('vmid'); scratch=raw.get('scratch'); now=raw.get('now')
|
|
if type(node) is not str or type(vmid) is not int or type(scratch) is not str or type(now) is not int: fail('INPUT_FIELDS')
|
|
configs={int(k):v for k,v in raw.get('configs',[])}
|
|
defaults=None if raw.get('defaults_b64') is None else base64.b64decode(raw['defaults_b64'])
|
|
plan=pve265.make_plan(raw.get('rows'),configs,raw.get('storage_rows'),defaults,int(raw.get('staging_free')),now,node=node)
|
|
jobs=[j for j in plan['jobs'] if j.get('vmid')==vmid]
|
|
if len(jobs)!=1: fail('JOB_CARDINALITY')
|
|
job=jobs[0]
|
|
pve265.validate_job(job,now)
|
|
if job.get('type')!='lxc' or job.get('node')!=node: fail('JOB_IDENTITY')
|
|
if job.get('configured_full_cycle_fits') is not True or job.get('compression_dependent') is not False: fail('JOB_CAPACITY_POLICY')
|
|
guest266.no_active_tasks(raw.get('tasks'),vmid)
|
|
argv=pve265.dump_argv(job,'/usr/bin/vzdump',scratch,now)
|
|
keep=('vmid','type','node','status','template','config_sha256','disks','configured_disk_bytes','configured_archive_bound_bytes','archive_cap_bytes','global_defaults_sha256','blockers','coverage_eligible')
|
|
out={'schema':1,'argv':argv,'job':{k:job.get(k) for k in keep}}
|
|
sys.stdout.write(json.dumps(out,separators=(',',':'),sort_keys=True)+'\n')
|
|
return 0
|
|
|
|
if __name__=='__main__':
|
|
raise SystemExit(main())
|
|
=== SOURCE_CLASSIFICATION ===
|
|
SOURCE_HELPER_EXACT_COUNT=1
|
|
SOURCE_LXC_EXACT_COUNT=1
|
|
SOURCE_ENTRY_EXACT_COUNT=1
|
|
SOURCE_PVE265_EXACT_COUNT=0
|
|
SOURCE_AUTHORITY_READY=false
|
|
TASK_RESULT=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED
|
|
DECISION=PASS_BACKUP_OVERLAY_HOTFIX_SOURCE_RCA_COLLECTED
|
|
NEXT_GATE=READ_EXACT_1229_AND_BUILD_IMMUTABLE_NOTIFICATION_POLICY_COMPAT_HOTFIX
|
|
HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260927-HOMELAB-BACKUP-OVERLAY-HOTFIX-SOURCE-RCA-1229R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null}
|
|
|
|
OUTPUT_END
|
|
CHAT_OUTPUT_END
|