1
0
Files
homelab-public-context/runtime/latest.json
T

39 lines
12 KiB
JSON

{
"schema_version": 1,
"channel": "homelab-runtime",
"command_id": "SUPPORT-260915-INFRA-DR-BACKUPV2-CT112-PROVEN-PRODUCER-CONTRACT-RCA-393R1",
"status": "OK",
"rc": 0,
"host": "pve01",
"mode": "read-only",
"component": "infra-dr-backupv2-ct112-proven-producer-contract-rca",
"started_at_utc": "2026-09-15T04:46:08Z",
"finished_at_utc": "2026-09-15T04:46:20Z",
"reference_register_checked": true,
"reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66",
"error_register_checked": true,
"error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0",
"command_sha256": "988c99c9bc6150d1f9dfc568332e87c814789ff4079280ff82d6acfbc8719f10",
"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": "d7ffb79efa33fd264096ea556839aa44ab14119d53e059b3d29d9f8f66115b35",
"sanitized_output_sha256": "d7ffb79efa33fd264096ea556839aa44ab14119d53e059b3d29d9f8f66115b35",
"output_truncated_in_json": false,
"full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt",
"output": "COMMAND_ID=SUPPORT-260915-INFRA-DR-BACKUPV2-CT112-PROVEN-PRODUCER-CONTRACT-RCA-393R1\nMODE=READ_ONLY_CT112_PROVEN_PRODUCER_CONTRACT_RCA\nNO_BACKUP_EXECUTION=YES\nNO_FILE_MUTATION=YES\nCURRENT_ID_GITEA_FRESHNESS=404_404_PASS\nERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0\nREFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66\nRUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d\nP270_SHA256=97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef\nP282_SHA256=73c6cb7773eb8e82d1e7ed5ab4733b4afb88f74ae69c09125d0378d6e480e012\nENGINE392_SHA256=7d96b9842de06277ea1be45e1f58e35c8a116a922425317954d339a333fe84f0\nSOURCE_AND_ENGINE_IDENTITIES=PASS\nANCHOR_270_BINDING=PASS\nANCHOR_282_BINDING=PASS\nANCHOR_392A_BINDING=PASS\nP270_FLAGS={\"has_100000\":true,\"has_dumpdir\":false,\"has_lxc_usernsexec\":false,\"has_perl\":true,\"has_proc_fd\":true,\"has_tmpdir\":false,\"has_var_tmp\":true,\"has_vzdump\":true}\nP282_FLAGS={\"has_100000\":false,\"has_dumpdir\":false,\"has_lxc_usernsexec\":false,\"has_perl\":true,\"has_proc_fd\":false,\"has_tmpdir\":false,\"has_var_tmp\":false,\"has_vzdump\":true}\nENGINE392_FLAGS={\"has_100000\":true,\"has_dumpdir\":true,\"has_lxc_usernsexec\":false,\"has_perl\":false,\"has_proc_fd\":false,\"has_tmpdir\":false,\"has_var_tmp\":true,\"has_vzdump\":true}\nP270_RELEVANT_LINES=[\"4:Only explicit produce() executes vzdump. Private bounded stderr/exit metadata retained.\",\"18:need(type(d) is dict and set(d)=={'root_uid','root_gid','id_map'},'IDMAP_SCHEMA')\",\"19:need(type(d['root_uid']) is int and type(d['root_gid']) is int,'IDMAP_VALUE')\",\"20:need(d['root_uid']==d['root_gid']==100000,'ONLY_DEFAULT_UNPRIVILEGED_IDMAP')\",\"21:expect=[['u',0,100000,65536],['g',0,100000,65536]]\",\"22:need(type(d['id_map']) is list and len(d['id_map'])==2,'IDMAP_ROWS')\",\"24:need(type(row) is list and len(row)==4 and type(row[0]) is str and all(type(n) is int for n in row[1:]) and row==exp,'IDMAP_NONDEFAULT')\",\"25:return d['root_uid'],d['root_gid']\",\"35:need(not any(s['name']=='vzdump' for s in snaps),'EXISTING_VZDUMP_SNAPSHOT_NO_AUTOCLEAN')\",\"52:class PerlPin:\",\"53:\\\"\\\"\\\"Dedicated read/execute-only pin for the observed system Perl hardlink pair.\",\"61:need(self.path.name=='perl' and self.alias.name=='perl5.40.1' and self.path.parent==self.alias.parent,'PERL_PATH_POLICY')\",\"62:need(self.path.is_absolute() and '..' not in self.path.parts,'PERL_PATH_POLICY')\",\"69:need(s.st_uid==0 and not s.st_mode&0o022,'PERL_PARENT_UNTRUSTED')\",\"72:need(stat.S_ISREG(s.st_mode) and s.st_uid==s.st_gid==0 and s.st_nlink==2,'PERL_SYSTEM_IDENTITY')\",\"73:need(stat.S_IMODE(s.st_mode)==0o755,'PERL_SYSTEM_PERMISSIONS')\",\"74:need(0<s.st_size<=32*1024**2,'PERL_SIZE_BOUND')\",\"75:need(os.pread(self.fd,4,0)==b'\\\\x7fELF','PERL_ELF_REQUIRED')\",\"81:s=os.fstat(self.fd);need(0<s.st_size<=32*1024**2,'PERL_SIZE_BOUND')\",\"85:need(bool(b),'PERL_SHORT_READ');h.update(b);offset+=len(b)\",\"88:need(self.fd is not None and self.parent is not None,'PERL_CLOSED')\",\"92:need(t.ident(s)+(s.st_nlink,)==self.identity,'PERL_IDENTITY_CHANGED')\",\"93:need(self._digest()==self.sha256,'PERL_CONTENT_CHANGED')\",\"100:need(s.st_uid==0 and not s.st_mode&0o022,'PERL_PARENT_UNTRUSTED')\",\"102:need((a.st_dev,a.st_ino)==(b.st_dev,b.st_ino),'PERL_PARENT_CHANGED')\",\"104:except OSError:raise old.PVEError('PERL_PATH_CHANGED') from None\",\"106:need(type(args) is list and all(type(x) is str and '\\\\x00' not in x for x in args),'PERL_ARGV')\",\"107:need(type(seconds) in (int,float) and 0<seconds<=30,'PERL_DEADLINE')\",\"110:p=subprocess.Popen(['/proc/self/fd/'+str(self.fd),*args],pass_fds=(self.fd,),\",\"116:left=deadline-time.monotonic();need(left>0,'PERL_TIMEOUT')\",\"121:need(len(out)+len(b)<=16384,'PERL_STDOUT_BOUND');out.extend(b)\",\"122:left=deadline-time.monotonic();need(left>0,'PERL_TIMEOUT')\",\"124:except subprocess.TimeoutExpired:raise old.PVEError('PERL_TIMEOUT') from None\",\"143:('/usr/share/perl5/PVE/LXC.pm','/usr/share/perl5/PVE/VZDump/LXC.pm')}\",\"145:'print JSON::PP->new->canonical->encode({root_uid=>0+$u,root_gid=>0+$g,'\",\"147:with PerlPin('/usr/bin/perl','/usr/bin/perl5.40.1') as pin:\",\"149:need(rc==0,'PVE_IDMAP_READ_FAILED')\",\"153:except (ValueError,UnicodeError):raise old.PVEError('PVE_IDMAP_JSON') from None\",\"164:need(s.st_uid==0,'TEMP_PARENT_OWNER')\",\"171:class MappedScratch:\",\"172:\\\"\\\"\\\"Root-owned, mapped-GID traverse-only, no access for others. No recursive cleanup.\\\"\\\"\\\"\",\"173:def __init__(self,gid,base='/var/tmp'):\",\"174:need(type(gid) is int and gid==100000,'TEMP_GID_POLICY')\",\"175:self.parent=_parent(base);self.fd=None;self.gid=gid\",\"181:os.fchown(self.fd,0,gid);os.fchmod(self.fd,0o710)\",\"192:need(a.st_uid==b.st_uid==0 and a.st_gid==b.st_gid==self.gid and stat.S_IMODE(a.st_mode)==stat.S_IMODE(b.st_mode)==0o710,'TEMP_PERMISSIONS_CHANGED')\",\"197:def probe(self,uid,private_path):\",\"198:need(type(uid) is int and uid==100000,'TEMP_UID_POLICY');self.check()\",\"216:for code,u,g,args in ((positive,uid,self.gid,[str(self.path),str(private_path)]),(negative,uid+1,self.gid+1,[str(self.path)])):\",\"219:need(p.returncode==0,'MAPPED_TEMP_PERMISSION_PROBE_FAILED')\",\"295:uid,gid=validate_mapping(mapping)\",\"303:scratch=MappedScratch(gid)\",\"304:emit('PVE_TEMP_DIRECTORY',scratch.path);emit('PVE_TEMP_MODE','0710');emit('PVE_TEMP_GID',gid)\",\"305:t.create(work/'PVE_TEMP.json',core.canonical_bytes({'path':str(scratch.path),'mode':'0710','uid':0,'gid':gid,'identity':list(scratch.identity)}))\",\"306:scratch.probe(uid,work);emit('MAPPED_UID_ACCESS_AND_ISOLATION_PROBE','PASS')\",\"312:result=capture_archive(old.dump_argv(job,tools['vzdump']['path'],scratch.path,int(time.time())),dest,job['archive_cap_bytes'],seconds,free_guard)\",\"325:emit('VZDUMP_PROCESS_STARTED','YES' if info.get('process_started') else 'NO')\",\"326:emit('VZDUMP_PROCESS_RC',info.get('producer_rc'));emit('PRIVATE_STDERR_BYTES',info.get('stderr_bytes_retained'))\"]\nP282_RELEVANT_LINES=[\"1:\\\"\\\"\\\"282R1 bounded CT112 adapter; proven 270 capture/temp/Perl implementation unchanged.\",\"14:PerlPin=proven.PerlPin\",\"18:MappedScratch=proven.MappedScratch\",\"68:uid,gid=validate_mapping(mapping)\",\"76:scratch=MappedScratch(gid)\",\"77:emit('PVE_TEMP_DIRECTORY',scratch.path);emit('PVE_TEMP_MODE','0710');emit('PVE_TEMP_GID',gid)\",\"78:t.create(work/'PVE_TEMP.json',core.canonical_bytes({'path':str(scratch.path),'mode':'0710','uid':0,'gid':gid,'identity':list(scratch.identity)}))\",\"79:scratch.probe(uid,work);emit('MAPPED_UID_ACCESS_AND_ISOLATION_PROBE','PASS')\",\"85:result=capture_archive(old.dump_argv(job,tools['vzdump']['path'],scratch.path,int(time.time())),dest,job['archive_cap_bytes'],seconds,free_guard)\",\"98:emit('VZDUMP_PROCESS_STARTED','YES' if info.get('process_started') else 'NO')\",\"99:emit('VZDUMP_PROCESS_RC',info.get('producer_rc'));emit('PRIVATE_STDERR_BYTES',info.get('stderr_bytes_retained'))\"]\nENGINE392_RELEVANT_LINES=[\"366:def _pve_dumpdir_spec(guest_type):\",\"367:if guest_type=='lxc': return (0o710,100000)\",\"376:# Use a direct /var/tmp child exactly like the accepted CT110/CT112 producer class.\",\"377:# A mapped LXC root must be able to traverse every parent component; a root-only\",\"379:srcdir=f'/var/tmp/homelab-vzdump-v2-{gen}'\",\"380:mode,gid=_pve_dumpdir_spec(typ)\",\"381:ssh_remote(node,['install','-d','-m',f'{mode:o}','-o','0','-g',str(gid),srcdir],timeout=30)\",\"383:if q.stdout.decode().strip()!=f'{mode:o}:0:{gid}': raise BackupError('PVE_DUMPDIR_ACCESS_CONTRACT')\",\"386:ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200)\",\"389:if len(files)!=1: raise BackupError('VZDUMP_OUTPUT_NOT_UNIQUE')\",\"396:if not pathlib.Path(local).is_file() or pathlib.Path(local).stat().st_size<=0: raise BackupError('VZDUMP_PAYLOAD_MISSING')\",\"610:if p.is_file() and not p.is_symlink() and st.st_uid==0 and (st.st_mode & 0o777)==0o600: safe.append(p)\",\"852:assert _pve_dumpdir_spec('lxc')==(0o710,100000)\",\"853:assert _pve_dumpdir_spec('qemu')==(0o700,0)\"]\nP282_RELEVANT_CALLS=[\"MappedScratch(gid)\",\"capture_archive(old.dump_argv(job,tools['vzdump']['path'],scratch.path,int(time.time())),dest,job['archive_cap_bytes'],seconds,free_guard)\",\"core.canonical_bytes({'path':str(scratch.path),'mode':'0710','uid':0,'gid':gid,'identity':list(scratch.identity)})\",\"emit('MAPPED_UID_ACCESS_AND_ISOLATION_PROBE','PASS')\",\"emit('PVE_TEMP_GID',gid)\",\"emit('VZDUMP_PROCESS_RC',info.get('producer_rc'))\",\"emit('VZDUMP_PROCESS_STARTED','YES' if info.get('process_started') else 'NO')\",\"old.dump_argv(job,tools['vzdump']['path'],scratch.path,int(time.time()))\",\"scratch.probe(uid,work)\",\"t.create(work/'PVE_TEMP.json',core.canonical_bytes({'path':str(scratch.path),'mode':'0710','uid':0,'gid':gid,'identity':list(scratch.identity)}))\"]\nENGINE392_RELEVANT_CALLS=[\"BackupError('PVE_DUMPDIR_ACCESS_CONTRACT')\",\"BackupError('VZDUMP_OUTPUT_NOT_UNIQUE')\",\"BackupError('VZDUMP_PAYLOAD_MISSING')\",\"_pve_dumpdir_spec('lxc')\",\"_pve_dumpdir_spec('qemu')\",\"_pve_dumpdir_spec(typ)\",\"ssh_remote(node,['install','-d','-m',f'{mode:o}','-o','0','-g',str(gid),srcdir],timeout=30)\",\"ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200)\",\"str(gid)\"]\nP282_ENGINE392_STRUCTURAL_DIFF=[\"has_100000:P282=False:ENGINE392=True\",\"has_dumpdir:P282=False:ENGINE392=True\",\"has_perl:P282=True:ENGINE392=False\",\"has_var_tmp:P282=False:ENGINE392=True\"]\nHOMELAB_APP_CLOUD_QUORUM_QUEUE_TIMER_ENABLED=enabled\nHOMELAB_APP_CLOUD_QUORUM_QUEUE_TIMER_ACTIVE=active\nHOMELAB_VM_CLOUD_QUORUM_QUEUE_TIMER_ENABLED=enabled\nHOMELAB_VM_CLOUD_QUORUM_QUEUE_TIMER_ACTIVE=active\nHOMELAB_CONTROL_BACKUP_TIMER_ENABLED=enabled\nHOMELAB_CONTROL_BACKUP_TIMER_ACTIVE=active\nHOMELAB_BACKUP_V2_TIMER_ENABLED=disabled\nHOMELAB_BACKUP_V2_TIMER_ACTIVE=inactive\nRCA_READY=YES\nNEXT_GATE=CT112_MINIMAL_PROVEN_CONTRACT_FIX_THEN_REPEATED_GREEN_CUTOVER_CLOSURE\nSTATUS=OK\nPHASE=COMPLETE\nREASON=NONE\nCHANGES_MADE=false\nMUTATION_OUTCOME=NO_MUTATION\nBACKUP_EXECUTIONS=0\nCLOUD_WRITES=0\nCLOUD_DELETIONS=0\nSYSTEMD_MUTATIONS=0\nSCHEDULER_CUTOVER=NO\nLEGACY_BACKUP_DISABLES=0\nHOMELAB_RESULT_CONTRACT={\"changes_made\":false,\"command_id\":\"SUPPORT-260915-INFRA-DR-BACKUPV2-CT112-PROVEN-PRODUCER-CONTRACT-RCA-393R1\",\"rollback_restored\":null,\"rollback_started\":false,\"status\":\"OK\",\"version\":1}\n"
}