CHAT_OUTPUT_BEGIN
COMMAND_ID=SUPPORT-260924-HOMELAB-MOLDOVA-BASE-RELEASE-AUTH-1147R1
STATUS=OK
RC=0
HOST=pve01
MODE=read-only
COMPONENT=homelab-moldova-base-release-auth
REFERENCE_REGISTER_CHECK=OK
REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66
ERROR_REGISTER_CHECK=OK
ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0
COMMAND_SHA256=f3fe1cb2e034d22c5917b5946f86b1c8ea517c0abd0a92891868a481e2aa5da7
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=add93d5fb111ea9426df8d172911f8506ad95531ae42be7e0c338901a61b8608
SANITIZED_OUTPUT_SHA256=e60b4493bf44bffbb9ab84838090dbefdb74cfb16219ea4cc0d3a9e834e59ae4
OUTPUT_BEGIN
WORKERS2_MOLDOVA_BASE_RELEASE_AUTH_BEGIN=1
COMMAND_ID=SUPPORT-260924-HOMELAB-MOLDOVA-BASE-RELEASE-AUTH-1147R1
MODE=read-only
COMPONENT=homelab-moldova-base-release-auth
MUTATION_BOUNDARY=NONE;ENTRY504_PROVENANCE_AND_LITERAL_BASE_RELEASE_STATIC_INSPECTION_ONLY;NO_MOLDOVA_CONNECTION;NO_REMOTE_SSH;NO_PROVIDER_CALL;NO_SYSTEMD_ACTION;NO_BACKUP_RUN;NO_BACKUP_MUTATION;NO_TARGET_POLICY_MUTATION;NO_NETBIRD_MUTATION;NO_MONITORING_MUTATION;NO_GIT_WRITE;NO_SECRET_VALUE_READOUT
PREDECESSOR_1146=PASS_MOLDOVA_1146_RELEASE_AUTH_EXACT_COLLECTED
PREDECESSOR_1146_CLASS=VPS_MD_HANDLER_NOT_LOCATED
CARRIER_BASELINE=KNOWN_GOOD_1137_BYTE_SEMANTICS
REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66
ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0
RUNNER_SHA256=b248a4c32c9cc64e5747e7dce6c7fc0a23f5124a77c71ce72e27a81aceae9d2d
TARGETS_SHA256=5cba5f1e14c65211c9fab6d11594c19279ab68369b4db3f7283708c368348288
ENTRY504_SHA256=ca6876fa9c3b1465b045344a8ad46962de16972c7dadc4ac6257c7d225047793
MD_RELAY_COUNT=1
MD_RELAY_ENABLED=false
ENTRY504_PROVENANCE_BLOCK_BEGIN=1
ENTRY504|line=20|text=        while True:
ENTRY504|line=21|text=            b=f.read(1<<20)
ENTRY504|line=22|text=            if not b: break
ENTRY504|line=23|text=            h.update(b)
ENTRY504|line=24|text=    return h.hexdigest()
ENTRY504|line=25|text=
ENTRY504|line=26|text=def _verify_base():
ENTRY504|line=27|text=    s=os.lstat(BASE)
ENTRY504|line=28|text=    if not stat.S_ISDIR(s.st_mode) or stat.S_ISLNK(s.st_mode) or s.st_uid!=0 or s.st_gid!=0:
ENTRY504|line=29|text=        raise RuntimeError('BASE_RELEASE_ROOT')
ENTRY504|line=30|text=    for rel,want in BASE_EXPECTED.items():
ENTRY504|line=31|text=        p=BASE/rel; st=os.lstat(p)
ENTRY504|line=32|text=        if not stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode) or st.st_uid!=0 or st.st_gid!=0 or _sha(p)!=want:
ENTRY504|line=33|text=            raise RuntimeError('BASE_RELEASE_FILE_'+rel)
ENTRY504|line=34|text=
ENTRY504|line=35|text=class _GlobalsProxy:
ENTRY504|line=36|text=    __slots__=('_g',)
ENTRY504|line=37|text=    def __init__(self,g): object.__setattr__(self,'_g',g)
ENTRY504|line=38|text=    def __getattr__(self,n):
ENTRY504|line=39|text=        try: return self._g[n]
ENTRY504|line=40|text=        except KeyError as e: raise AttributeError(n) from e
ENTRY504|line=41|text=    def __setattr__(self,n,v): self._g[n]=v
ENTRY504|line=42|text=
ENTRY504|line=43|text=def _wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,base=BASE):
ENTRY504|line=44|text=    legacy_path=(pathlib.Path(base)/'legacy_engine.py').resolve()
ENTRY504|line=45|text=    found={}
ENTRY504|line=46|text=    for value in vars(wrapper).values():
ENTRY504|line=47|text=        if isinstance(value,types.ModuleType):
ENTRY504|line=48|text=            g=vars(value); raw=g.get('__file__')
ENTRY504|line=49|text=        elif isinstance(value,types.FunctionType):
ENTRY504|line=50|text=            g=value.__globals__; raw=g.get('__file__')
ENTRY504|line=51|text=        else:
ENTRY504|line=52|text=            continue
ENTRY504|line=53|text=        if not isinstance(raw,str):
ENTRY504|line=54|text=            continue
ENTRY504|line=55|text=        try: gp=pathlib.Path(raw).resolve()
ENTRY504|line=56|text=        except Exception: continue
ENTRY504|line=57|text=        if gp==legacy_path:
ENTRY504|line=58|text=            found[id(g)]=g
ENTRY504|line=59|text=    if len(found)!=1:
ENTRY504|line=60|text=        raise RuntimeError('LEGACY_PROVENANCE_CARDINALITY')
ENTRY504|line=61|text=    g=next(iter(found.values()))
ENTRY504|line=62|text=    required=('capture_pve_guest','backup_target','load_targets','cluster_inventory','ssh_remote',
ENTRY504|line=63|text=              '_default_unprivileged_lxc','mapped_scratch_probe','_stream_argv_to_local','run',
ENTRY504|line=64|text=              'choose_due_target','write_state','epoch')
ENTRY504|line=65|text=    if any(not callable(g.get(n)) for n in required):
ENTRY504|line=66|text=        raise RuntimeError('LEGACY_PROVENANCE_API')
ENTRY504|line=67|text=    original=g['capture_pve_guest']
ENTRY504|line=68|text=    proxy=_GlobalsProxy(g)
ENTRY504|line=69|text=    if not isinstance(g.get('SCP'),str) or not g['SCP'].startswith('/'):
ENTRY504|line=70|text=        raise RuntimeError('LEGACY_SCP_API')
ENTRY504|line=71|text=    qemu_patched=qemu_adapter.bind(proxy,original)
ENTRY504|line=72|text=    if not callable(qemu_patched):
ENTRY504|line=73|text=        raise RuntimeError('QEMU_ADAPTER_BIND_RESULT')
ENTRY504|line=74|text=    patched=lxc_adapter.bind(proxy,qemu_patched)
ENTRY504|line=75|text=    if not callable(patched):
ENTRY504|line=76|text=        raise RuntimeError('LXC_ADAPTER_BIND_RESULT')
ENTRY504|line=77|text=    g['capture_pve_guest']=patched
ENTRY504|line=78|text=    scheduler_wired=scheduler_adapter.bind(proxy,g['choose_due_target'],g['write_state'])
ENTRY504|line=79|text=    if g.get('choose_due_target') is not scheduler_wired['choose_due_target'] or g.get('write_state') is not scheduler_wired['write_state']:
ENTRY504|line=80|text=        raise RuntimeError('SCHEDULER_ADAPTER_BIND_RESULT')
ENTRY504|line=81|text=    return {'legacy_globals':g,'legacy':proxy,'original_capture':original,'qemu_patched_capture':qemu_patched,'patched_capture':patched,'scheduler_wired':scheduler_wired}
ENTRY504|line=82|text=
ENTRY504|line=83|text=def _load():
ENTRY504|line=84|text=    _verify_base()
ENTRY504|line=85|text=    sys.dont_write_bytecode=True
ENTRY504|line=86|text=    sys.path.insert(0,str(BASE))
ENTRY504|line=87|text=    wrapper=importlib.import_module('wrapper')
ENTRY504|line=88|text=    # Baseline accepted wrapper selftest stays the compatibility gate; no full old legacy selftest is reintroduced.
ENTRY504|line=89|text=    wrapper.selftest()
ENTRY504|line=90|text=    sys.path.insert(0,str(HERE))
ENTRY504|line=91|text=    lxc_adapter=importlib.import_module('lxc_adapter')
ENTRY504|line=92|text=    qemu_adapter=importlib.import_module('qemu_adapter')
ENTRY504|line=93|text=    scheduler_adapter=importlib.import_module('scheduler_adapter')
ENTRY504|line=94|text=    if _sha(HERE/'lxc_adapter.py')!='3fa7d194010d76f7c8bc95035ae8876262e9337903e310f45f45df88c266dc8d':
ENTRY504|line=95|text=        raise RuntimeError('LXC_502_BYTE_IDENTITY')
ENTRY504|line=96|text=    wired=_wire(wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,BASE)
ENTRY504|line=97|text=    return wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired
ENTRY504|line=98|text=
ENTRY504|line=99|text=def _target(wrapper,lid):
ENTRY504|line=100|text=    rows=wrapper.load_targets(); hits=[x for x in rows if x.get('logical_id')==lid]
ENTRY504|line=101|text=    if len(hits)!=1: raise RuntimeError('TARGET_CARDINALITY')
ENTRY504|line=102|text=    return hits[0]
ENTRY504|line=103|text=
ENTRY504|line=104|text=def selftest():
ENTRY504|line=105|text=    wrapper,lxc_adapter,qemu_adapter,scheduler_adapter,wired=_load()
ENTRY504|line=106|text=    if wired['legacy_globals'].get('capture_pve_guest') is not wired['patched_capture']:
ENTRY504|line=107|text=        raise RuntimeError('PATCH_BINDING')
ENTRY504|line=108|text=    if wired['legacy_globals'].get('choose_due_target') is not wired['scheduler_wired']['choose_due_target']:
ENTRY504|line=109|text=        raise RuntimeError('SCHEDULER_CHOOSE_BINDING')
ENTRY504|line=110|text=    if wired['legacy_globals'].get('write_state') is not wired['scheduler_wired']['write_state']:
ENTRY504|line=111|text=        raise RuntimeError('SCHEDULER_WRITE_BINDING')
ENTRY504|line=112|text=    if [scheduler_adapter.backoff_seconds(n) for n in range(1,7)]!=[1800,3600,7200,14400,21600,21600]:
ENTRY504|line=113|text=        raise RuntimeError('SCHEDULER_BACKOFF_CONTRACT')
ENTRY504|line=114|text=    if not callable(wrapper.backup_target) or not callable(wrapper.main) or not callable(wrapper.load_targets):
ENTRY504|line=115|text=        raise RuntimeError('WRAPPER_PUBLIC_API')
ENTRY504|line=116|text=    print('SELFTEST_OVERLAY504=PASS',flush=True)
ENTRY504|line=117|text=    return 0
ENTRY504|line=118|text=
ENTRY504|line=119|text=def main(argv=None):
ENTRY504|line=120|text=    argv=list(sys.argv[1:] if argv is None else argv)
ENTRY504_PROVENANCE_BLOCK_END=1
ENTRY504_RELEASE_LITERAL_COUNT=1
ENTRY504_RELEASE_LITERAL=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1
BASE_CANDIDATE_COUNT=1
BASE_CANDIDATE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1|kind=dir|mode=500|uid=0|gid=0
BASE_PY_FILE_COUNT=21
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/adapter.py|bytes=2989|sha256=18eb29cef165371b48bcb78e1a456e1939e6eff253787218133162cc89ab9fa3|mode=500|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/guest266.py|bytes=7385|sha256=86433bc424d5fa5017c20f7a237c82874b02357a3283660d8a6b0039ef2bc868|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/large264.py|bytes=16514|sha256=5cc4641fc35e4dd554495a36146da7dbbb7f142d1450e04cc5d3c89678b8497a|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/nodeplan263.py|bytes=4603|sha256=db5c16ee24d25aa1694530332d3190ab7cc5d4f8eb69067d025e27ad5c995060|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py|bytes=12888|sha256=cd2f634414a8e38a3789015aeca5a9b47821f77d7d1fa61dcdbdc866172963be|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|bytes=19595|sha256=97015277a4f3f8129c0fd11eb70c06293026366f1f8232a97feeed513a2dbcef|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve282.py|bytes=6195|sha256=73c6cb7773eb8e82d1e7ed5ab4733b4afb88f74ae69c09125d0378d6e480e012|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/restore262.py|bytes=14701|sha256=56d1b961c8d5654d5e2ee2755268db46bd2202bca11e69788febf991cfaa79f1|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/stream263.py|bytes=8831|sha256=a83d03a86b93a855716658652dd073fcb281cd387fc6200fe4bc2a922f39ea16|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_guest266.py|bytes=10752|sha256=460b950924a475ce0a28dc759512e7dbe2323ae2cc42f7ef4c6181710a2a13da|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_perl270.py|bytes=5441|sha256=50fc10865078a7b9b255dc627059824184441a47c4ede52e23f24c1186e3512f|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|bytes=12215|sha256=a67d927cc428935791f9eecc3acf571d089f80761162f4589b7d684fba6b8af7|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve265.py|bytes=11781|sha256=16a9407d01bf73db687ef38684c59205fc2e6a9223cd9cee6ec6e8dde9d38707|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|bytes=12077|sha256=9fccd20b490613fdd5b14b4105cf0d9fd744f204e1ed1d6893e54c9f69bf6fb4|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve282.py|bytes=5785|sha256=1056407aab76e17181b05e043cb42c086058545a8e0027689ab4e03eee6531c4|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/transport261.py|bytes=15364|sha256=b9b92f957bf441cb5d1702f4881897328e6c0338f8c3f6d41d27d9a349b37688|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/v2core.py|bytes=11755|sha256=e285bf9a5678d07dcbb90261f9f93e7826ff524e04cfec780bf5a3c4b0dc29f2|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/ct112_handler.py|bytes=10955|sha256=8cac6e627d5e7abe5d3163cdd24911995a1e3f45c776f9373c2aa68784f5ec6c|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|bytes=59719|sha256=b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/representative_driver.py|bytes=4214|sha256=b3050a8f95e6d9826a4f0786cd3ca32012b6ab10486d10e4981b50b8a0affff2|mode=400|uid=0|gid=0
BASE_FILE|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|bytes=5055|sha256=2b5eb4fc0f6f466a0d3e5a007af987092b6c17baa3ff9241a6afc2c2e97df1d5|mode=400|uid=0|gid=0
BASE_AUTH_SNIPPETS_BEGIN=1
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/large264.py|line=12|text=import subprocess
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/large264.py|line=27|text=    p=subprocess.Popen(argv,stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/large264.py|line=41|text=    except subprocess.TimeoutExpired:raise t.Stop('STREAM_TIMEOUT') from None
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py|line=13|text=import subprocess
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py|line=144|text=    except subprocess.TimeoutExpired:
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py|line=160|text=        p=subprocess.Popen(argv,stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve265.py|line=176|text=        except subprocess.TimeoutExpired:raise PVEError('PRODUCER_TIMEOUT') from None
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=6|text=import hashlib,json,os,re,secrets,selectors,signal,stat,subprocess,sys,time
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=110|text=            p=subprocess.Popen(['/proc/self/fd/'+str(self.fd),*args],pass_fds=(self.fd,),
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=111|text=                    stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=124|text=        except subprocess.TimeoutExpired:raise old.PVEError('PERL_TIMEOUT') from None
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=217|text=                p=subprocess.run([sys.executable,'-I','-B','-c',code,*args],stdin=subprocess.DEVNULL,stdout=subprocess.DEVNULL,
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=218|text=                       stderr=subprocess.DEVNULL,env=dict(old.ENV),user=u,group=g,extra_groups=[],close_fds=True,timeout=15)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=247|text=        p=subprocess.Popen(argv,stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/pve270.py|line=266|text=        except subprocess.TimeoutExpired:raise old.PVEError('PRODUCER_TIMEOUT') from None
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|line=2|text=import copy,hashlib,json,os,stat,subprocess,sys,tempfile,time,unittest
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|line=10|text= return subprocess.run([sys.executable,'-I','-B','-c',code,*map(str,args)],user=uid,group=gid,extra_groups=[],stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,timeout=10)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|line=134|text= """Actual subprocess + tar/zstd, synthetic data; never runs vzdump on a guest."""
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|line=152|text=  code='''import os,sys,subprocess,shutil
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|line=158|text=a=subprocess.run(['/usr/bin/tar','-cf','-','-C',str(p),'./etc/vzdump/pct.conf'],user=100000,group=100000,extra_groups=[],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|line=161|text=z=subprocess.run(['/usr/bin/zstd','-q','-c'],input=a.stdout,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_producer282.py|line=193|text=  def crc(p):return subprocess.run(['/usr/bin/zstd','--test','--quiet',str(p)],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL).returncode==0
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve265.py|line=1|text="""Synthetic PVE fixtures; subprocess tests never execute real PVE tools."""
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|line=2|text=import copy,hashlib,json,os,stat,subprocess,sys,tempfile,time,unittest
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|line=10|text= return subprocess.run([sys.executable,'-I','-B','-c',code,*map(str,args)],user=uid,group=gid,extra_groups=[],stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,timeout=10)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|line=134|text= """Actual subprocess + tar/zstd, synthetic data; never runs vzdump on a guest."""
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|line=152|text=  code='''import os,sys,subprocess,shutil
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|line=157|text=a=subprocess.run(['/usr/bin/tar','-cf','-','-C',str(p),'./etc/vzdump/pct.conf'],user=100000,group=100000,extra_groups=[],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|line=160|text=z=subprocess.run(['/usr/bin/zstd','-q','-c'],input=a.stdout,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve270.py|line=192|text=  def crc(p):return subprocess.run(['/usr/bin/zstd','--test','--quiet',str(p)],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL).returncode==0
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/test_pve282.py|line=2|text=import copy, json, unittest, tempfile, time, subprocess
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/transport261.py|line=15|text=import subprocess
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/transport261.py|line=149|text=    p=subprocess.Popen(argv,stdin=subprocess.DEVNULL,stdout=subprocess.PIPE,stderr=subprocess.PIPE,
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/candidate411/transport261.py|line=163|text=    except subprocess.TimeoutExpired:raise Stop('PROCESS_TIMEOUT') from None
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/ct112_handler.py|line=3|text=import hashlib,json,os,secrets,shutil,stat,subprocess,sys,time
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/ct112_handler.py|line=26|text=    p=subprocess.run(argv,stdout=subprocess.PIPE,stderr=subprocess.PIPE,timeout=45,check=False,env=ENV)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/ct112_handler.py|line=166|text=        p=subprocess.run([str(ZSTD),'--test','--quiet','--',str(path)],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL,timeout=3600,check=False,env=ENV)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=2|text=import ast, base64, datetime as dt, hashlib, io, json, os, pathlib, random, re, select, shlex, shutil, stat, subprocess, sys, tarfile, tempfile, time
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=12|text=SSH=shutil.which('ssh') or '/usr/bin/ssh'
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=13|text=SCP=shutil.which('scp') or '/usr/bin/scp'
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=14|text=SSH_KEYSCAN=shutil.which('ssh-keyscan') or '/usr/bin/ssh-keyscan'
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=15|text=SSHPASS=shutil.which('sshpass') or '/usr/bin/sshpass'
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=16|text=OPERATOR_KEY=pathlib.Path('[SENSITIVE_PATH]
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=158|text=      {'logical_id':'md-relay','scope':'vps','type':'vps_md','host':'[ADDR]','port':22,'user':'ops','hostkey_fingerprint':'SHA256:DXJGwunC5tEVvnC3nRxyayTN8FXmyJcVgf+Oa6udQsY','due_seconds':d,'enabled':True,'green1':True},
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=159|text=      {'logical_id':'spb-ingress','scope':'vps','type':'vps_spb','host':'[ADDR]','port':22,'user':'edgeadmin','hostkey_fingerprint':'SHA256:Ef+HsZb8lIXoadvYBXuGKIL3H7NyJMmf9EYCoJRoSv8','due_seconds':d,'enabled':True,'green1':True},
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=160|text=      {'logical_id':'us-netbird','scope':'vps','type':'vps_us','host':'[ADDR]','port':22,'user':'root','hostkey_fingerprint':'SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE','due_seconds':d,'enabled':True,'green1':True},
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=191|text=        p=subprocess.run(argv,input=input,stdout=subprocess.PIPE,stderr=subprocess.PIPE,timeout=timeout,env=env)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=192|text=    except subprocess.TimeoutExpired: raise BackupError('COMMAND_TIMEOUT')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=199|text=        try:p=subprocess.run(argv,input=input,stdout=f,stderr=subprocess.PIPE,timeout=timeout)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=200|text=        except subprocess.TimeoutExpired: raise BackupError('STREAM_COMMAND_TIMEOUT')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=206|text=        src=subprocess.Popen(argv,stdin=subprocess.PIPE if input is not None else None,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=207|text=        z=subprocess.Popen([zstd,'-T0','-3','-q','-o',str(out_path)],stdin=src.stdout,stdout=subprocess.DEVNULL,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=213|text=        except subprocess.TimeoutExpired:
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=216|text=    except subprocess.TimeoutExpired:
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=236|text=def load_targets():
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=289|text=    p=subprocess.Popen(argv,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=311|text=    with subprocess.Popen(rclone_base_args()+['cat',remote_path,'--contimeout','20s','--timeout','5m'],stdout=subprocess.PIPE,stderr=subprocess.PIPE) as p:
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=365|text=            with subprocess.Popen(rclone_base_args()+['cat',base+'/parts/'+part['name'],'--contimeout','20s','--timeout','5m'],stdout=subprocess.PIPE,stderr=subprocess.PIPE) as p:
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=379|text=    p1=subprocess.Popen([zstd,'-dc',str(path)],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=380|text=    p2=subprocess.Popen([tar,'-tf','-'],stdin=p1.stdout,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=389|text=    if typ in ('pve_node_bundle','vps_md','vps_spb','vps_us','router'):
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=399|text=        p1=subprocess.Popen([zstd,'-dc',str(path)],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=400|text=        p2=subprocess.Popen([tar,'-xOf','-','db.sql'],stdin=p1.stdout,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=405|text=def cluster_inventory():
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=410|text=def ssh_remote(node,argv,input=None,timeout=1800,check=True):
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=413|text=    return run([SSH,'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node,cmd],input=input,timeout=timeout,check=check)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=430|text=    p=subprocess.run([sys.executable,'-B','-c',_HISTORICAL_HELPER,'import_all'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,env=env,cwd='/',timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=441|text=    p=subprocess.run([sys.executable,'-B','-c',_HISTORICAL_HELPER,'dump_argv',str(GUEST266)],input=canonical_json(req),stdout=subprocess.PIPE,stderr=subprocess.PIPE,env=env,cwd='/',timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=442|text=    if p.returncode!=0: raise BackupError('GUEST266_SUBPROCESS_FAILED',f'rc_{p.returncode}_stderr_sha256_{hashlib.sha256(p.stderr).hexdigest()}')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=444|text=    except Exception: raise BackupError('GUEST266_SUBPROCESS_JSON')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=476|text=    q=ssh_remote(node,['pct','config',str(vmid)],timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=484|text=    q=ssh_remote(node,pos,timeout=30,check=False)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=492|text=        cmd=[SSH,'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node,remote]
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=494|text=        try:p=subprocess.run(cmd,stdout=f,stderr=subprocess.PIPE,timeout=timeout)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=495|text=        except subprocess.TimeoutExpired:
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=514|text=        ssh_remote(node,['install','-d','-m','710','-o','0','-g','100000',scratch],timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=515|text=        q=ssh_remote(node,['stat','-c','%a:%u:%g',scratch],timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=524|text=            ssh_remote(node,['rm','-rf','--',scratch],timeout=60,check=False);raise
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=529|text=    ssh_remote(node,['install','-d','-m','700','-o','0','-g','0',srcdir],timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=531|text=        ssh_remote(node,['vzdump',str(vmid),'--mode','snapshot','--compress','zstd','--dumpdir',srcdir],timeout=7200)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=532|text=        p=ssh_remote(node,['find',srcdir,'-maxdepth','1','-type','f','-printf','%p\n'],timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=537|text=        else: run([SCP,'-q','-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node+':'+src,str(local)],timeout=7200)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=540|text=        ssh_remote(node,['rm','-rf','--',srcdir],timeout=60,check=False);raise
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=545|text=    p=run(['ssh-keygen','-lf',str(OPERATOR_KEY),'-E','sha256'],timeout=30)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=552|text=    p=run([SSH_KEYSCAN,'-T','8','-p',str(port),'-t','ed25519',host],timeout=15)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=557|text=        if len(f)<3 or f[1]!='ssh-ed25519': continue
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=568|text=        if t['type'] not in ('vps_md','vps_spb','vps_us'): continue
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=569|text=        lines.append(scan_hostkey_line(t['host'],t['port'],t['hostkey_fingerprint']))
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=572|text=def vps_ssh_argv(t, *, use_agent=False):
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=573|text=    a=[SSH,'-p',str(t['port']),'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','-o','UserKnownHostsFile='+str(VPS_KNOWN_HOSTS),'-o','ConnectTimeout=15']
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=575|text=        a += ['-o','IdentitiesOnly=no']
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=577|text=        a += ['-i',str(OPERATOR_KEY),'-o','IdentitiesOnly=yes','-o','IdentityAgent=none']
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=583|text=    return run(vps_ssh_argv(t,use_agent=use_agent)+[remote],input=input,timeout=timeout,check=check)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=588|text=    pub=run(['ssh-keygen','-y','-f',str(OPERATOR_KEY)],timeout=30).stdout.strip()+b'\n'
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=591|text=        if t['type'] not in ('vps_md','vps_spb'): continue
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=595|text=        if not os.environ.get('SSH_AUTH_SOCK'): raise BackupError('FORWARDED_AGENT_REQUIRED_FOR_BOOTSTRAP')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=596|text=        script=b"umask 077; mkdir -p \"$HOME/.ssh\"; chmod 700 \"$HOME/.ssh\"; touch \"$HOME/.ssh/authorized_keys\"; chmod 600 \"$HOME/.ssh/authorized_keys\"; IFS= read -r k; if grep -qF -- \"$k\" \"$HOME/.ssh/authorized_keys\"; then printf 'ALREADY\\n'; else printf '%s\\n' \"$k\" >> \"$HOME/.ssh/authorized_keys\"; printf 'ADDED\\n'; fi"
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=612|text=def capture_vps_md(t,gen,work):
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=617|text=    argv=vps_ssh_argv(t,use_agent=False)+[remote]
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=621|text=    return payload,{'generation':gen,'source_class':'vps_md','consistency':'FILESET_PRE_POST_HASH_STABILITY','hashset_sha256':pre},None
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=627|text=    argv=vps_ssh_argv(t,use_agent=False)+[remote]
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=664|text=    argv=vps_ssh_argv(t,use_agent=False)+[remote]
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=732|text=    pat=re.compile(r"\bsshpass\b[^\n]*?(?:^|\s)-f\s+(\"[^\"]*\"|'[^']*'|[^\s;]+)")
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=756|text=    roots=[pathlib.Path('/etc'),pathlib.Path('[SENSITIVE_PATH]'),pathlib.Path('/var/lib/homelab-backup'),pathlib.Path('/var/lib/homelab-backup-v2')]
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=784|text=    # sshpass requires password prompting to remain enabled; batch mode must stay off.
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=785|text=    # The proven SSHPASS_FILE credential path otherwise cannot be used.
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=786|text=    argv=[SSHPASS,'-f',str(pf),SSH,'-p','2222','-o','BatchMode=no','-o','NumberOfPasswordPrompts=1','-o','StrictHostKeyChecking=yes','-o','UserKnownHostsFile='+str(ROUTER_KNOWN_HOSTS),'-o','ConnectTimeout=15','routerbackup@'+target,'show running-config']
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=806|text=    p=ssh_remote(node,args,input=input_bytes,timeout=timeout+60)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=818|text=    return f'''import hashlib,json,os,pathlib,select,shutil,subprocess,tempfile,time\nroot={root!r}; db={db!r}; strategy={strategy!r}; token=[REDACTED] not root.startswith('/var/www/forums/') or not db.startswith('xf_'): raise SystemExit(20)\ntmp=pathlib.Path('/tmp/homelab-v2-xf-'+token); tmp.mkdir(mode=0o700,exist_ok=False)\ndump=tmp/'db.sql'; out=pathlib.Path('/tmp/homelab-v2-xf-'+token+'.tar.zst')\nlock=None\ntry:\n  if strategy=='global_read_lock':\n    lock=subprocess.Popen(['mariadb','--user=root','--batch','--skip-column-names','--unbuffered'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.DEVNULL,text=True,bufsize=1)\n    lock.stdin.write("FLUSH TABLES WITH READ LOCK; SELECT 'LOCKED';\\n"); lock.stdin.flush()\n    rr,_,_=select.select([lock.stdout],[],[],5)\n    if not rr or lock.stdout.readline().strip()!='LOCKED': raise RuntimeError('LOCK_ACQUIRE')\n    dump_timeout=15\n  else: dump_timeout=180\n  with open(dump,'wb') as f:\n    argv=['mariadb-dump','--user=ro...[TRUNCATED]
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=851|text=        if OPERATOR_KEY.exists(): p.append('root/.ssh/id_ed25519_netbird_operator')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=852|text=        if pathlib.Path(str(OPERATOR_KEY)+'.pub').exists(): p.append('root/.ssh/id_ed25519_netbird_operator.pub')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=859|text=        else: ok=(ssh_remote(node,['test','-e','/'+rel],timeout=20,check=False).returncode==0)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=868|text=        pipe_to_zstd([SSH,'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node,remote],payload,timeout=600)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=875|text=    if typ=='vps_md': return capture_vps_md(t,gen,work)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=885|text=        ssh_remote(cleanup['node'],['rm','-rf','--',cleanup['path']],timeout=60)
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=903|text=def backup_target(t,green_verify=False):
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=991|text=    assert {t['logical_id'] for t in default_targets() if t.get('green1')}=={'ct112','node-pve01','md-relay','spb-ingress','us-netbird','router-netcraze','xf-codevipe','xf-zakrutim','control-bootstrap-v2'}
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/representative_driver.py|line=17|text=    'md-relay',
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|line=7|text=LEGACY_IDS=('node-pve01','md-relay','spb-ingress','us-netbird','router-netcraze','xf-codevipe','xf-zakrutim','control-bootstrap-v2')
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|line=37|text=def load_targets():
BASE_SRC|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|line=40|text=def backup_target(t,green_verify=False):
BASE_AUTH_SNIPPET_COUNT=121
BASE_AUTH_SNIPPETS_END=1
BASE_KEY_FUNCTIONS_BEGIN=1
FUNCTION_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=load_targets|line=236
def load_targets():
    j=json.loads(TARGETS_PATH.read_text())
    if j.get('schema')!=1 or not isinstance(j.get('targets'),list): raise BackupError('TARGET_MANIFEST_SCHEMA')
    ids=[x.get('logical_id') for x in j['targets']]
    if len(ids)!=len(set(ids)): raise BackupError('TARGET_MANIFEST_DUPLICATE')
    return j['targets']
FUNCTION_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=load_targets
FUNCTION_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=cluster_inventory|line=405
def cluster_inventory():
    p=run(['pvesh','get','/cluster/resources','--type','vm','--output-format','json'],timeout=60)
    try:return json.loads(p.stdout)
    except Exception: raise BackupError('PVE_INVENTORY_JSON')
FUNCTION_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=cluster_inventory
FUNCTION_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=ssh_remote|line=410
def ssh_remote(node,argv,input=None,timeout=1800,check=True):
    cmd='PATH=/usr/sbin:/usr/bin:/sbin:/bin; export PATH; exec '+shlex.join([str(x) for x in argv])
    if node=='pve01': return run([str(x) for x in argv],input=input,timeout=timeout,check=check)
    return run([SSH,'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node,cmd],input=input,timeout=timeout,check=check)
FUNCTION_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=ssh_remote
FUNCTION_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=backup_target|line=903
def backup_target(t,green_verify=False):
    if t['type']=='control': return control_verify(t)
    gen=generation_id(t['logical_id']); work=ensure_dir(WORK_ROOT/gen,0o700)
    payload=None; cleanup=None; sealed=False
    try:
        payload,meta,cleanup=capture_target(t,gen,work); meta['generation']=gen
        manifest,msha,alloc=upload_and_seal(t,payload,meta); sealed=True
        # SEALED-first cleanup invariant: only now remove source/local payload.
        try:
            if pathlib.Path(payload).exists(): pathlib.Path(payload).unlink()
        finally: cleanup_source(cleanup)
        if green_verify:
            a=work/'verify-a.bin'; b=work/'verify-b.bin'
            ha=reconstruct_replica(manifest,manifest['replicas'][0],a); validate_payload(t,a)
            hb=reconstruct_replica(manifest,manifest['replicas'][1],b); validate_payload(t,b)
            if ha!=hb or ha!=manifest['payload_sha256']: raise BackupError('GREEN_REPLICA_COMPARE')
            a.unlink(missing_ok=True); b.unlink(missing_ok=True)
        shutil.rmtree(work,ignore_errors=True)
        write_state(t['logical_id'],'SUCCESS',generation=gen,payload_sha256=manifest['payload_sha256'],manifest_sha256=msha,replicas=manifest['replicas'],green_verified=bool(green_verify),last_success_epoch=epoch())
        return {'logical_id':t['logical_id'],'generation':gen,'result':'SUCCESS','payload_bytes':manifest['payload_bytes'],'replicas':2,'allocator_healthy':alloc['healthy']}
    except BackupError as e:
        result='PARTIAL_VALID' if sealed else 'FAIL'
        write_state(t['logical_id'],result,generation=gen,reason=e.code,sealed=sealed)
        raise
FUNCTION_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|name=backup_target
FUNCTION_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|name=load_targets|line=37
def load_targets():
    base=canonical_targets();return base+[_ct_descriptor(base)]
FUNCTION_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|name=load_targets
FUNCTION_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|name=backup_target|line=40
def backup_target(t,green_verify=False):
    if not isinstance(t,dict) or t.get('logical_id')!=CT_ID:
        return _legacy_backup_target(t,green_verify)
    try:
        r=ct112.run_target(t,state_writer=legacy.write_state)
        return {'logical_id':CT_ID,'generation':r['generation'],'result':'SUCCESS','payload_bytes':r['payload_bytes'],
                'replicas':2,'manifest_sha256':r['manifest_sha256'],'payload_sha256':r['payload_sha256']}
    except BaseException:
        try: legacy.write_state(CT_ID,'FAIL',reason='CT112_PIPELINE_FAILED')
        except BaseException: pass
        raise legacy.BackupError('CT112_PIPELINE_FAILED') from None
FUNCTION_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|name=backup_target
BASE_KEY_FUNCTION_COUNT=6
BASE_KEY_FUNCTIONS_END=1
BASE_VPS_MD_CONTEXT_BEGIN=1
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=158
146:def utcnow(): return dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace('+00:00','Z')
147:def epoch(): return int(time.time())
148:
149:def default_targets():
150:    d=86400
151:    out=[]
152:    # PVE guests. Source node is resolved live every run.
153:    for vmid,typ in [(110,'lxc'),(111,'lxc'),(112,'lxc'),(113,'lxc'),(130,'qemu'),(150,'qemu'),(160,'qemu'),(170,'qemu'),(171,'qemu'),(190,'qemu'),(210,'qemu'),(211,'qemu'),(9130,'qemu')]:
154:        out.append({'logical_id':('ct' if typ=='lxc' else 'vm')+str(vmid),'scope':'pve','type':'pve_guest','vmid':vmid,'guest_type':typ,'due_seconds':d,'enabled':True,'green1':vmid==112})
155:    for node in ('pve01','pve02','pve03'):
156:        out.append({'logical_id':'node-'+node,'scope':'node','type':'pve_node_bundle','node':node,'due_seconds':7*d,'enabled':True,'green1':node=='pve01'})
157:    out += [
158:      {'logical_id':'md-relay','scope':'vps','type':'vps_md','host':'[ADDR]','port':22,'user':'ops','hostkey_fingerprint':'SHA256:DXJGwunC5tEVvnC3nRxyayTN8FXmyJcVgf+Oa6udQsY','due_seconds':d,'enabled':True,'green1':True},
159:      {'logical_id':'spb-ingress','scope':'vps','type':'vps_spb','host':'[ADDR]','port':22,'user':'edgeadmin','hostkey_fingerprint':'SHA256:Ef+HsZb8lIXoadvYBXuGKIL3H7NyJMmf9EYCoJRoSv8','due_seconds':d,'enabled':True,'green1':True},
160:      {'logical_id':'us-netbird','scope':'vps','type':'vps_us','host':'[ADDR]','port':22,'user':'root','hostkey_fingerprint':'SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE','due_seconds':d,'enabled':True,'green1':True},
161:      {'logical_id':'router-netcraze','scope':'router','type':'router','due_seconds':d,'enabled':True,'green1':True},
162:    ]
163:    sites=[
164:      ('codevipe',160,'pve02','/var/www/forums/codevipe/public','xf_codevipe','single_transaction'),
165:      ('dsmods',160,'pve02','/var/www/forums/dsmods/public','xf_dsmods','single_transaction'),
166:      ('kingofwolk',160,'pve02','/var/www/forums/kingofwolk/public','xf_kingofwolk','single_transaction'),
167:      ('newfi',210,'pve01','/var/www/forums/newfi/public','xf_newfi','single_transaction'),
168:      ('gamevipe',160,'pve02','/var/www/forums/gamevipe/public','xf_gamevipe','global_read_lock'),
169:      ('hkmods',160,'pve02','/var/www/forums/hkmods/public','xf_hkmods','global_read_lock'),
170:      ('zakrutim',160,'pve02','/var/www/forums/zakrutim/public','xf_zakrutim','global_read_lock')]
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=158
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=389
377:    zstd=shutil.which('zstd') or '/usr/bin/zstd'; tar=shutil.which('tar') or '/usr/bin/tar'
378:    p=run([zstd,'-t','-q',str(path)],timeout=300)
379:    p1=subprocess.Popen([zstd,'-dc',str(path)],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
380:    p2=subprocess.Popen([tar,'-tf','-'],stdin=p1.stdout,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
381:    p1.stdout.close(); out,err2=p2.communicate(timeout=300); err1=p1.stderr.read(); r1=p1.wait()
382:    if r1!=0 or p2.returncode!=0: raise BackupError('TAR_ZST_LIST_FAILED')
383:    names=out.decode('utf-8','replace').splitlines()
384:    if not names: raise BackupError('TAR_ZST_EMPTY')
385:    if required_member and required_member not in names: raise BackupError('REQUIRED_MEMBER_MISSING')
386:
387:def validate_payload(t,path):
388:    typ=t['type']
389:    if typ in ('pve_node_bundle','vps_md','vps_spb','vps_us','router'):
390:        validate_tar_zst(path)
391:    elif typ=='pve_guest':
392:        if t['guest_type']=='lxc': validate_tar_zst(path)
393:        else:
394:            # Green set is intentionally CT-only. Scheduled QEMU backups still get dual remote byte readback.
395:            run([shutil.which('zstd') or '/usr/bin/zstd','-t','-q',str(path)],timeout=600)
396:    elif typ=='xenforo':
397:        validate_tar_zst(path,'db.sql')
398:        zstd=shutil.which('zstd') or '/usr/bin/zstd'; tar=shutil.which('tar') or '/usr/bin/tar'
399:        p1=subprocess.Popen([zstd,'-dc',str(path)],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
400:        p2=subprocess.Popen([tar,'-xOf','-','db.sql'],stdin=p1.stdout,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
401:        p1.stdout.close(); data,err=p2.communicate(timeout=300); p1.wait()
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=389
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=568
556:        f=line.split()
557:        if len(f)<3 or f[1]!='ssh-ed25519': continue
558:        try: blob=base64.b64decode(f[2])
559:        except Exception: continue
560:        fp='SHA256:'+base64.b64encode(hashlib.sha256(blob).digest()).decode().rstrip('=')
561:        if fp==expected: good.append(line)
562:    if len(good)!=1: raise BackupError('HOSTKEY_PIN_MISMATCH')
563:    return good[0]
564:
565:def ensure_vps_known_hosts(targets):
566:    lines=[]
567:    for t in targets:
568:        if t['type'] not in ('vps_md','vps_spb','vps_us'): continue
569:        lines.append(scan_hostkey_line(t['host'],t['port'],t['hostkey_fingerprint']))
570:    atomic_write(VPS_KNOWN_HOSTS,('\n'.join(lines)+'\n').encode(),0o600)
571:
572:def vps_ssh_argv(t, *, use_agent=False):
573:    a=[SSH,'-p',str(t['port']),'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','-o','UserKnownHostsFile='+str(VPS_KNOWN_HOSTS),'-o','ConnectTimeout=15']
574:    if use_agent:
575:        a += ['-o','IdentitiesOnly=no']
576:    else:
577:        a += ['-i',str(OPERATOR_KEY),'-o','IdentitiesOnly=yes','-o','IdentityAgent=none']
578:    a += [t['user']+'@'+t['host']]
579:    return a
580:
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=568
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=591
579:    return a
580:
581:def vps_run(t, remote_argv, *, input=None, timeout=300, use_agent=False, check=True):
582:    remote=shlex.join([str(x) for x in remote_argv])
583:    return run(vps_ssh_argv(t,use_agent=use_agent)+[remote],input=input,timeout=timeout,check=check)
584:
585:def bootstrap_vps_keys(targets):
586:    operator_key_fingerprint()
587:    ensure_vps_known_hosts(targets)
588:    pub=run(['ssh-keygen','-y','-f',str(OPERATOR_KEY)],timeout=30).stdout.strip()+b'\n'
589:    results={}
590:    for t in targets:
591:        if t['type'] not in ('vps_md','vps_spb'): continue
592:        probe=vps_run(t,['true'],timeout=30,use_agent=False,check=False)
593:        if probe.returncode==0:
594:            results[t['logical_id']]='ALREADY_OPERATOR_KEY'; continue
595:        if not os.environ.get('SSH_AUTH_SOCK'): raise BackupError('FORWARDED_AGENT_REQUIRED_FOR_BOOTSTRAP')
596:        script=b"umask 077; mkdir -p \"$HOME/.ssh\"; chmod 700 \"$HOME/.ssh\"; touch \"$HOME/.ssh/authorized_keys\"; chmod 600 \"$HOME/.ssh/authorized_keys\"; IFS= read -r k; if grep -qF -- \"$k\" \"$HOME/.ssh/authorized_keys\"; then printf 'ALREADY\\n'; else printf '%s\\n' \"$k\" >> \"$HOME/.ssh/authorized_keys\"; printf 'ADDED\\n'; fi"
597:        p=vps_run(t,['sh','-c',script.decode()],input=pub,timeout=45,use_agent=True)
598:        tag=p.stdout.decode().strip()
599:        if tag not in ('ADDED','ALREADY'): raise BackupError('VPS_AUTHORIZED_KEY_BOOTSTRAP_RESULT')
600:        vps_run(t,['true'],timeout=30,use_agent=False)
601:        results[t['logical_id']]=tag
602:    # US was already operator-key based; prove it agentless too.
603:    us=[x for x in targets if x['type']=='vps_us'][0]
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=591
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=612
600:        vps_run(t,['true'],timeout=30,use_agent=False)
601:        results[t['logical_id']]=tag
602:    # US was already operator-key based; prove it agentless too.
603:    us=[x for x in targets if x['type']=='vps_us'][0]
604:    vps_run(us,['true'],timeout=30,use_agent=False)
605:    results[us['logical_id']]='ALREADY_US_OPERATOR_KEY'
606:    return results
607:
608:def remote_hashset(t,command):
609:    p=vps_run(t,['sh','-c',command],timeout=120,use_agent=False)
610:    return sha256_bytes(p.stdout)
611:
612:def capture_vps_md(t,gen,work):
613:    files=['etc/netbird/install.conf','var/lib/netbird/state.json','var/lib/netbird/service.json','var/lib/netbird/active_profile.json','var/lib/netbird/default.json']
614:    cmd="sudo -n sha256sum -- "+' '.join(shlex.quote('/'+x) for x in files)
615:    pre=remote_hashset(t,cmd)
616:    remote=shlex.join(['sudo','-n','tar','--numeric-owner','-C','/','-cf','-']+files)
617:    argv=vps_ssh_argv(t,use_agent=False)+[remote]
618:    payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=600)
619:    post=remote_hashset(t,cmd)
620:    if pre!=post: raise BackupError('MD_SOURCE_CHANGED_DURING_CAPTURE')
621:    return payload,{'generation':gen,'source_class':'vps_md','consistency':'FILESET_PRE_POST_HASH_STABILITY','hashset_sha256':pre},None
622:
623:def capture_vps_spb(t,gen,work):
624:    hcmd="find /etc/nginx -xdev -type f -print0 | sort -z | xargs -0 sha256sum"
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=612
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=621
609:    p=vps_run(t,['sh','-c',command],timeout=120,use_agent=False)
610:    return sha256_bytes(p.stdout)
611:
612:def capture_vps_md(t,gen,work):
613:    files=['etc/netbird/install.conf','var/lib/netbird/state.json','var/lib/netbird/service.json','var/lib/netbird/active_profile.json','var/lib/netbird/default.json']
614:    cmd="sudo -n sha256sum -- "+' '.join(shlex.quote('/'+x) for x in files)
615:    pre=remote_hashset(t,cmd)
616:    remote=shlex.join(['sudo','-n','tar','--numeric-owner','-C','/','-cf','-']+files)
617:    argv=vps_ssh_argv(t,use_agent=False)+[remote]
618:    payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=600)
619:    post=remote_hashset(t,cmd)
620:    if pre!=post: raise BackupError('MD_SOURCE_CHANGED_DURING_CAPTURE')
621:    return payload,{'generation':gen,'source_class':'vps_md','consistency':'FILESET_PRE_POST_HASH_STABILITY','hashset_sha256':pre},None
622:
623:def capture_vps_spb(t,gen,work):
624:    hcmd="find /etc/nginx -xdev -type f -print0 | sort -z | xargs -0 sha256sum"
625:    pre=remote_hashset(t,hcmd)
626:    remote=shlex.join(['tar','--numeric-owner','-C','/','-cf','-','etc/nginx'])
627:    argv=vps_ssh_argv(t,use_agent=False)+[remote]
628:    payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=900)
629:    post=remote_hashset(t,hcmd)
630:    if pre!=post: raise BackupError('SPB_SOURCE_CHANGED_DURING_CAPTURE')
631:    return payload,{'generation':gen,'source_class':'vps_spb','consistency':'STATIC_CONFIG_FILESET_PRE_POST_HASH_STABILITY','tls_recovery':'REISSUE_TLS_ON_RESTORE','hashset_sha256':pre},None
632:
633:US_REMOTE_SCRIPT=r'''import io,os,sqlite3,sys,tarfile,time,json,hashlib
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=621
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=875
863:    payload=work/'payload.tar.zst'
864:    argv=['tar','--numeric-owner','--xattrs','--acls','-C','/','-cf','-']+paths
865:    if node=='pve01': pipe_to_zstd(argv,payload,timeout=300)
866:    else:
867:        remote='PATH=/usr/sbin:/usr/bin:/sbin:/bin; export PATH; exec '+shlex.join(argv)
868:        pipe_to_zstd([SSH,'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','root@'+node,remote],payload,timeout=600)
869:    return payload,{'generation':gen,'source_class':'pve_node_bundle','node':node,'recovery_policy':'CLEAN_INSTALL_JOIN_RECONCILE_NOT_BLIND_PMXCFS_OVERWRITE','member_roots':len(paths)},None
870:
871:def capture_target(t,gen,work):
872:    typ=t['type']
873:    if typ=='pve_guest': return capture_pve_guest(t,gen,work)
874:    if typ=='pve_node_bundle': return capture_node_bundle(t,gen,work)
875:    if typ=='vps_md': return capture_vps_md(t,gen,work)
876:    if typ=='vps_spb': return capture_vps_spb(t,gen,work)
877:    if typ=='vps_us': return capture_vps_us(t,gen,work)
878:    if typ=='router': return capture_router(t,gen,work)
879:    if typ=='xenforo': return capture_xenforo(t,gen,work)
880:    raise BackupError('CAPTURE_TYPE_UNKNOWN')
881:
882:def cleanup_source(cleanup):
883:    if not cleanup: return
884:    if cleanup.get('kind')=='pve_source_dir':
885:        ssh_remote(cleanup['node'],['rm','-rf','--',cleanup['path']],timeout=60)
886:
887:def control_verify(t):
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=875
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=991
979:            try:j=json.loads(q.stdout)
980:            except Exception: continue
981:            if j.get('status')=='SEALED' and j.get('generation')==g: bygen.setdefault(g,set()).add(physical)
982:    good=sorted(g for g,phys in bygen.items() if len(phys)>=2)
983:    print('DISCOVER_LOGICAL_ID='+logical_id); print('DISCOVER_TWO_PHYSICAL_SEALED_COUNT='+str(len(good)))
984:    for g in good[-20:]: print('DISCOVER_GENERATION='+g)
985:    return 0 if good else 2
986:
987:def selftest():
988:    assert PART_SIZE==536870912
989:    assert len(REMOTES)==13 and len({p for _,p in REMOTES})==13
990:    assert len(default_targets())>=28
991:    assert {t['logical_id'] for t in default_targets() if t.get('green1')}=={'ct112','node-pve01','md-relay','spb-ingress','us-netbird','router-netcraze','xf-codevipe','xf-zakrutim','control-bootstrap-v2'}
992:    assert _pve_dumpdir_spec('lxc')==(0o710,100000)
993:    assert _pve_dumpdir_spec('qemu')==(0o700,0)
994:    assert GUEST266_SHA=='86433bc424d5fa5017c20f7a237c82874b02357a3283660d8a6b0039ef2bc868'
995:    assert P282_SHA=='73c6cb7773eb8e82d1e7ed5ab4733b4afb88f74ae69c09125d0378d6e480e012'
996:    if GUEST266.is_file():
997:        assert _isolated_release_graph_selftest() is True
998:        av,_=proven_lxc_dump_argv({'vmid':112},{'maxdisk':8350298112,'maxmem':536870912,'status':'running','name':'unbound1'},'pve01','/var/tmp/homelab-vzdump-selftest')
999:        assert '--stdout' in av and '--tmpdir' in av and '/var/tmp/homelab-vzdump-selftest' in av
1000:    print('SELFTEST_ENGINE396=10')
1001:    return 0
1002:
1003:def main(argv):
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/legacy_engine.py|line=991
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/representative_driver.py|line=17
5:CT112 producer/cloud path. It routes CT112 to an explicitly supplied callback and
6:isolates legacy engine state writes into a candidate-owned state directory.
7:"""
8:from __future__ import annotations
9:
10:import json
11:import os
12:from pathlib import Path
13:from typing import Callable, Iterable, Mapping, Any
14:
15:LEGACY_IDS=(
16:    'node-pve01',
17:    'md-relay',
18:    'spb-ingress',
19:    'us-netbird',
20:    'router-netcraze',
21:    'xf-codevipe',
22:    'xf-zakrutim',
23:    'control-bootstrap-v2',
24:)
25:CT112_ID='guest-pve01-lxc-112'
26:REPRESENTATIVE_IDS=(CT112_ID,)+LEGACY_IDS
27:CANDIDATE_ROOT=Path(__file__).resolve().parent
28:STATE_ROOT=CANDIDATE_ROOT/'state'
29:
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/representative_driver.py|line=17
VPS_CONTEXT_BEGIN|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|line=7
1:#!/usr/bin/env python3
2:from __future__ import annotations
3:import errno,fcntl,importlib.util,os,sys
4:from pathlib import Path
5:ROOT=Path(__file__).resolve().parent
6:CT_ID='guest-pve01-lxc-112'
7:LEGACY_IDS=('node-pve01','md-relay','spb-ingress','us-netbird','router-netcraze','xf-codevipe','xf-zakrutim','control-bootstrap-v2')
8:LOCK=Path('/run/homelab-backup-heavy.lock')
9:
10:def _load(name,path):
11:    spec=importlib.util.spec_from_file_location(name,str(path))
12:    if spec is None or spec.loader is None: raise RuntimeError('MODULE_SPEC')
13:    mod=importlib.util.module_from_spec(spec);sys.modules[name]=mod;spec.loader.exec_module(mod);return mod
14:
15:legacy=_load('_backupv2_legacy486',ROOT/'legacy_engine.py')
16:ct112=_load('_backupv2_ct112_486',ROOT/'ct112_handler.py')
17:driver=_load('_backupv2_driver454_479',ROOT/'representative_driver.py')
18:_legacy_load_targets=legacy.load_targets
19:_legacy_backup_target=legacy.backup_target
VPS_CONTEXT_END|path=/opt/homelab-backup-v2/releases/backup-v2-accepted-486r1/wrapper.py|line=7
BASE_VPS_MD_CONTEXT_COUNT=10
BASE_VPS_MD_CONTEXT_END=1
BASE_RELEASE_AUTH_CLASS=BASE_VPS_MD_BACKUP_TARGET_LOCATED
DECISION=PASS_MOLDOVA_1147_BASE_RELEASE_AUTH_COLLECTED
NEXT_GATE=READ_EXACT_1147_AND_BUILD_REMOTE_ROLE_PREFLIGHT_WITH_PROVEN_LEGACY_AUTH
TASK_RESULT=PASS_MOLDOVA_BASE_RELEASE_AUTH
HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260924-HOMELAB-MOLDOVA-BASE-RELEASE-AUTH-1147R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null}
WORKERS2_MOLDOVA_BASE_RELEASE_AUTH_END=1

OUTPUT_END
CHAT_OUTPUT_END
