runtime: publish SUPPORT-260918-INFRA-PVE1-MOLDOVA-KEYMAPPING-READONLY-552R1
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,253 @@
|
||||
CHAT_OUTPUT_BEGIN
|
||||
COMMAND_ID=SUPPORT-260918-INFRA-PVE1-MOLDOVA-KEYMAPPING-READONLY-552R1
|
||||
STATUS=OK
|
||||
RC=0
|
||||
HOST=pve01
|
||||
MODE=read-only
|
||||
COMPONENT=infra-pve1-moldova-keymapping-readonly
|
||||
REFERENCE_REGISTER_CHECK=OK
|
||||
REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66
|
||||
ERROR_REGISTER_CHECK=OK
|
||||
ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0
|
||||
COMMAND_SHA256=0fadfaf45ded2524c42751f3efe29300f054f11e12b445ef897607a6f6b3e448
|
||||
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=b3e7cbda886dbd253274af0d4c726c89e54425e5b793e9e1f149ea8412962c14
|
||||
SANITIZED_OUTPUT_SHA256=be1cde014d4680574aba7cefa652231f34f1db8d57c07b09e171b79b88530186
|
||||
OUTPUT_BEGIN
|
||||
ERROR_REGISTER_CHECK=OK
|
||||
REFERENCE_CHECK=OK
|
||||
AUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED
|
||||
ACCEPTED_ENGINE_PRESENT=True
|
||||
ACCEPTED_ENGINE_SHA256=b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7
|
||||
KEYMAPPING_MATCH_LINE_COUNT=17
|
||||
KEYMAPPING_MATCH_LINES=14,16,158,160,389,552,568,591,603,612,621,662,666,851,852,875,877
|
||||
KEYMAPPING_CONTEXT_01_RANGE=9-24
|
||||
KEYMAPPING_CONTEXT_01_LINE_0009=WORK_ROOT=pathlib.Path('/mnt/staging/homelab-backup-v2')
|
||||
KEYMAPPING_CONTEXT_01_LINE_0010=ENGINE_PATH=pathlib.Path('/usr/local/sbin/homelab-backup-v2')
|
||||
KEYMAPPING_CONTEXT_01_LINE_0011=RCLONE=shutil.which('rclone') or '/usr/bin/rclone'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0012=SSH=shutil.which('ssh') or '/usr/bin/ssh'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0013=SCP=shutil.which('scp') or '/usr/bin/scp'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0014=SSH_KEYSCAN=shutil.which('ssh-keyscan') or '/usr/bin/ssh-keyscan'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0015=SSHPASS=shutil.which('sshpass') or '/usr/bin/sshpass'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0016=OPERATOR_KEY=pathlib.Path('[SENSITIVE_PATH]
|
||||
KEYMAPPING_CONTEXT_01_LINE_0017=VPS_KNOWN_HOSTS=CONFIG_ROOT/'vps_known_hosts'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0018=ROUTER_KNOWN_HOSTS=CONFIG_ROOT/'router_known_hosts'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0019=ROUTER_LEGACY_SCRIPT=pathlib.Path('/usr/local/sbin/homelab-router-running-config-mail-cloud')
|
||||
KEYMAPPING_CONTEXT_01_LINE_0020=ROUTER_LEGACY_SHA='a0aeb0e1ec7e2714b3d6147c13c2af04d8d8118219541ec60b66df6919858dc7'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0021=ROUTER_TARGET_SHA='4f9da1283166a1e9f4e6bc7dd240c76aef85772177f717f92abb6e8e2bb8de90'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0022=ROUTER_FINGERPRINT='SHA256:2Tw4CU4kvwtXSIiym+699Y6W2VJVWzRUD4opXrSfOIs'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0023=ROUTER_KNOWN_HOSTS_SHA='02d4e1dad1620937b7a67416a73aa182f9e80ea9c4b11f777161bc7455cf234d'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0024=OPERATOR_KEY_FINGERPRINT='SHA256:wipXiBB3cpAwyWap9LcB185WjEEmDxtRJsI/UuMVAp0'
|
||||
KEYMAPPING_CONTEXT_02_RANGE=153-168
|
||||
KEYMAPPING_CONTEXT_02_LINE_0153=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')]:
|
||||
KEYMAPPING_CONTEXT_02_LINE_0154=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})
|
||||
KEYMAPPING_CONTEXT_02_LINE_0155=for node in ('pve01','pve02','pve03'):
|
||||
KEYMAPPING_CONTEXT_02_LINE_0156=out.append({'logical_id':'node-'+node,'scope':'node','type':'pve_node_bundle','node':node,'due_seconds':7*d,'enabled':True,'green1':node=='pve01'})
|
||||
KEYMAPPING_CONTEXT_02_LINE_0157=out += [
|
||||
KEYMAPPING_CONTEXT_02_LINE_0158={'logical_id':'md-relay','scope':'vps','type':'vps_md','host':'85.121.4.192','port':22,'user':'ops','hostkey_fingerprint':'SHA256:DXJGwunC5tEVvnC3nRxyayTN8FXmyJcVgf+Oa6udQsY','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0159={'logical_id':'spb-ingress','scope':'vps','type':'vps_spb','host':'185.225.35.6','port':22,'user':'edgeadmin','hostkey_fingerprint':'SHA256:Ef+HsZb8lIXoadvYBXuGKIL3H7NyJMmf9EYCoJRoSv8','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0160={'logical_id':'us-netbird','scope':'vps','type':'vps_us','host':'46.16.34.129','port':22,'user':'root','hostkey_fingerprint':'SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0161={'logical_id':'router-netcraze','scope':'router','type':'router','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0162=]
|
||||
KEYMAPPING_CONTEXT_02_LINE_0163=sites=[
|
||||
KEYMAPPING_CONTEXT_02_LINE_0164=('codevipe',160,'pve02','/var/www/forums/codevipe/public','xf_codevipe','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0165=('dsmods',160,'pve02','/var/www/forums/dsmods/public','xf_dsmods','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0166=('kingofwolk',160,'pve02','/var/www/forums/kingofwolk/public','xf_kingofwolk','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0167=('newfi',210,'pve01','/var/www/forums/newfi/public','xf_newfi','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0168=('gamevipe',160,'pve02','/var/www/forums/gamevipe/public','xf_gamevipe','global_read_lock'),
|
||||
KEYMAPPING_CONTEXT_03_RANGE=384-397
|
||||
KEYMAPPING_CONTEXT_03_LINE_0384=if not names: raise BackupError('TAR_ZST_EMPTY')
|
||||
KEYMAPPING_CONTEXT_03_LINE_0385=if required_member and required_member not in names: raise BackupError('REQUIRED_MEMBER_MISSING')
|
||||
KEYMAPPING_CONTEXT_03_LINE_0386=
|
||||
KEYMAPPING_CONTEXT_03_LINE_0387=def validate_payload(t,path):
|
||||
KEYMAPPING_CONTEXT_03_LINE_0388=typ=t['type']
|
||||
KEYMAPPING_CONTEXT_03_LINE_0389=if typ in ('pve_node_bundle','vps_md','vps_spb','vps_us','router'):
|
||||
KEYMAPPING_CONTEXT_03_LINE_0390=validate_tar_zst(path)
|
||||
KEYMAPPING_CONTEXT_03_LINE_0391=elif typ=='pve_guest':
|
||||
KEYMAPPING_CONTEXT_03_LINE_0392=if t['guest_type']=='lxc': validate_tar_zst(path)
|
||||
KEYMAPPING_CONTEXT_03_LINE_0393=else:
|
||||
KEYMAPPING_CONTEXT_03_LINE_0394=# Green set is intentionally CT-only. Scheduled QEMU backups still get dual remote byte readback.
|
||||
KEYMAPPING_CONTEXT_03_LINE_0395=run([shutil.which('zstd') or '/usr/bin/zstd','-t','-q',str(path)],timeout=600)
|
||||
KEYMAPPING_CONTEXT_03_LINE_0396=elif typ=='xenforo':
|
||||
KEYMAPPING_CONTEXT_03_LINE_0397=validate_tar_zst(path,'db.sql')
|
||||
KEYMAPPING_CONTEXT_04_RANGE=547-560
|
||||
KEYMAPPING_CONTEXT_04_LINE_0547=m=re.search(r'(SHA256:[A-Za-z0-9+/]+)',s)
|
||||
KEYMAPPING_CONTEXT_04_LINE_0548=if not m or m.group(1)!=OPERATOR_KEY_FINGERPRINT: raise BackupError('OPERATOR_KEY_FINGERPRINT_MISMATCH')
|
||||
KEYMAPPING_CONTEXT_04_LINE_0549=return m.group(1)
|
||||
KEYMAPPING_CONTEXT_04_LINE_0550=
|
||||
KEYMAPPING_CONTEXT_04_LINE_0551=def scan_hostkey_line(host,port,expected):
|
||||
KEYMAPPING_CONTEXT_04_LINE_0552=p=run([SSH_KEYSCAN,'-T','8','-p',str(port),'-t','ed25519',host],timeout=15)
|
||||
KEYMAPPING_CONTEXT_04_LINE_0553=lines=[x.strip() for x in p.stdout.decode().splitlines() if x.strip() and not x.startswith('#')]
|
||||
KEYMAPPING_CONTEXT_04_LINE_0554=good=[]
|
||||
KEYMAPPING_CONTEXT_04_LINE_0555=for line in lines:
|
||||
KEYMAPPING_CONTEXT_04_LINE_0556=f=line.split()
|
||||
KEYMAPPING_CONTEXT_04_LINE_0557=if len(f)<3 or f[1]!='ssh-ed25519': continue
|
||||
KEYMAPPING_CONTEXT_04_LINE_0558=try: blob=base64.b64decode(f[2])
|
||||
KEYMAPPING_CONTEXT_04_LINE_0559=except Exception: continue
|
||||
KEYMAPPING_CONTEXT_04_LINE_0560=fp='SHA256:'+base64.b64encode(hashlib.sha256(blob).digest()).decode().rstrip('=')
|
||||
KEYMAPPING_CONTEXT_05_RANGE=563-576
|
||||
KEYMAPPING_CONTEXT_05_LINE_0563=return good[0]
|
||||
KEYMAPPING_CONTEXT_05_LINE_0564=
|
||||
KEYMAPPING_CONTEXT_05_LINE_0565=def ensure_vps_known_hosts(targets):
|
||||
KEYMAPPING_CONTEXT_05_LINE_0566=lines=[]
|
||||
KEYMAPPING_CONTEXT_05_LINE_0567=for t in targets:
|
||||
KEYMAPPING_CONTEXT_05_LINE_0568=if t['type'] not in ('vps_md','vps_spb','vps_us'): continue
|
||||
KEYMAPPING_CONTEXT_05_LINE_0569=lines.append(scan_hostkey_line(t['host'],t['port'],t['hostkey_fingerprint']))
|
||||
KEYMAPPING_CONTEXT_05_LINE_0570=atomic_write(VPS_KNOWN_HOSTS,('\n'.join(lines)+'\n').encode(),0o600)
|
||||
KEYMAPPING_CONTEXT_05_LINE_0571=
|
||||
KEYMAPPING_CONTEXT_05_LINE_0572=def vps_ssh_argv(t, *, use_agent=False):
|
||||
KEYMAPPING_CONTEXT_05_LINE_0573=a=[SSH,'-p',str(t['port']),'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','-o','UserKnownHostsFile='+str(VPS_KNOWN_HOSTS),'-o','ConnectTimeout=15']
|
||||
KEYMAPPING_CONTEXT_05_LINE_0574=if use_agent:
|
||||
KEYMAPPING_CONTEXT_05_LINE_0575=a += ['-o','IdentitiesOnly=no']
|
||||
KEYMAPPING_CONTEXT_05_LINE_0576=else:
|
||||
KEYMAPPING_CONTEXT_06_RANGE=586-629
|
||||
KEYMAPPING_CONTEXT_06_LINE_0586=operator_key_fingerprint()
|
||||
KEYMAPPING_CONTEXT_06_LINE_0587=ensure_vps_known_hosts(targets)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0588=pub=run(['ssh-keygen','-y','-f',str(OPERATOR_KEY)],timeout=30).stdout.strip()+b'\n'
|
||||
KEYMAPPING_CONTEXT_06_LINE_0589=results={}
|
||||
KEYMAPPING_CONTEXT_06_LINE_0590=for t in targets:
|
||||
KEYMAPPING_CONTEXT_06_LINE_0591=if t['type'] not in ('vps_md','vps_spb'): continue
|
||||
KEYMAPPING_CONTEXT_06_LINE_0592=probe=vps_run(t,['true'],timeout=30,use_agent=False,check=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0593=if probe.returncode==0:
|
||||
KEYMAPPING_CONTEXT_06_LINE_0594=results[t['logical_id']]='ALREADY_OPERATOR_KEY'; continue
|
||||
KEYMAPPING_CONTEXT_06_LINE_0595=if not os.environ.get('SSH_AUTH_SOCK'): raise BackupError('FORWARDED_AGENT_REQUIRED_FOR_BOOTSTRAP')
|
||||
KEYMAPPING_CONTEXT_06_LINE_0596=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"
|
||||
KEYMAPPING_CONTEXT_06_LINE_0597=p=vps_run(t,['sh','-c',script.decode()],input=pub,timeout=45,use_agent=True)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0598=tag=p.stdout.decode().strip()
|
||||
KEYMAPPING_CONTEXT_06_LINE_0599=if tag not in ('ADDED','ALREADY'): raise BackupError('VPS_AUTHORIZED_KEY_BOOTSTRAP_RESULT')
|
||||
KEYMAPPING_CONTEXT_06_LINE_0600=vps_run(t,['true'],timeout=30,use_agent=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0601=results[t['logical_id']]=tag
|
||||
KEYMAPPING_CONTEXT_06_LINE_0602=# US was already operator-key based; prove it agentless too.
|
||||
KEYMAPPING_CONTEXT_06_LINE_0603=us=[x for x in targets if x['type']=='vps_us'][0]
|
||||
KEYMAPPING_CONTEXT_06_LINE_0604=vps_run(us,['true'],timeout=30,use_agent=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0605=results[us['logical_id']]='ALREADY_US_OPERATOR_KEY'
|
||||
KEYMAPPING_CONTEXT_06_LINE_0606=return results
|
||||
KEYMAPPING_CONTEXT_06_LINE_0607=
|
||||
KEYMAPPING_CONTEXT_06_LINE_0608=def remote_hashset(t,command):
|
||||
KEYMAPPING_CONTEXT_06_LINE_0609=p=vps_run(t,['sh','-c',command],timeout=120,use_agent=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0610=return sha256_bytes(p.stdout)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0611=
|
||||
KEYMAPPING_CONTEXT_06_LINE_0612=def capture_vps_md(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_06_LINE_0613=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']
|
||||
KEYMAPPING_CONTEXT_06_LINE_0614=cmd="sudo -n sha256sum -- "+' '.join(shlex.quote('/'+x) for x in files)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0615=pre=remote_hashset(t,cmd)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0616=remote=shlex.join(['sudo','-n','tar','--numeric-owner','-C','/','-cf','-']+files)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0617=argv=vps_ssh_argv(t,use_agent=False)+[remote]
|
||||
KEYMAPPING_CONTEXT_06_LINE_0618=payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=600)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0619=post=remote_hashset(t,cmd)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0620=if pre!=post: raise BackupError('MD_SOURCE_CHANGED_DURING_CAPTURE')
|
||||
KEYMAPPING_CONTEXT_06_LINE_0621=return payload,{'generation':gen,'source_class':'vps_md','consistency':'FILESET_PRE_POST_HASH_STABILITY','hashset_sha256':pre},None
|
||||
KEYMAPPING_CONTEXT_06_LINE_0622=
|
||||
KEYMAPPING_CONTEXT_06_LINE_0623=def capture_vps_spb(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_06_LINE_0624=hcmd="find /etc/nginx -xdev -type f -print0 | sort -z | xargs -0 sha256sum"
|
||||
KEYMAPPING_CONTEXT_06_LINE_0625=pre=remote_hashset(t,hcmd)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0626=remote=shlex.join(['tar','--numeric-owner','-C','/','-cf','-','etc/nginx'])
|
||||
KEYMAPPING_CONTEXT_06_LINE_0627=argv=vps_ssh_argv(t,use_agent=False)+[remote]
|
||||
KEYMAPPING_CONTEXT_06_LINE_0628=payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=900)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0629=post=remote_hashset(t,hcmd)
|
||||
KEYMAPPING_CONTEXT_07_RANGE=657-674
|
||||
KEYMAPPING_CONTEXT_07_LINE_0657=if dst.execute('pragma quick_check').fetchone()[0]!='ok': raise SystemExit(33)
|
||||
KEYMAPPING_CONTEXT_07_LINE_0658=b=dst.serialize(); dst.close(); src.close()
|
||||
KEYMAPPING_CONTEXT_07_LINE_0659=ti=tarfile.TarInfo(name=('sqlite-backups/'+name)); ti.size=len(b); ti.mode=0o600; ti.mtime=int(time.time()); tf.addfile(ti,io.BytesIO(b))
|
||||
KEYMAPPING_CONTEXT_07_LINE_0660='''
|
||||
KEYMAPPING_CONTEXT_07_LINE_0661=
|
||||
KEYMAPPING_CONTEXT_07_LINE_0662=def capture_vps_us(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_07_LINE_0663=remote=shlex.join(['python3','-I','-B','-c',US_REMOTE_SCRIPT])
|
||||
KEYMAPPING_CONTEXT_07_LINE_0664=argv=vps_ssh_argv(t,use_agent=False)+[remote]
|
||||
KEYMAPPING_CONTEXT_07_LINE_0665=payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=1200)
|
||||
KEYMAPPING_CONTEXT_07_LINE_0666=return payload,{'generation':gen,'source_class':'vps_us','consistency':'SQLITE_ONLINE_BACKUP_PLUS_NONDB_FILES','sqlite_count':4},None
|
||||
KEYMAPPING_CONTEXT_07_LINE_0667=
|
||||
KEYMAPPING_CONTEXT_07_LINE_0668=def _simple_shell_assignments(text):
|
||||
KEYMAPPING_CONTEXT_07_LINE_0669=vals={}
|
||||
KEYMAPPING_CONTEXT_07_LINE_0670=for line in text.splitlines():
|
||||
KEYMAPPING_CONTEXT_07_LINE_0671=m=re.match(r'^\s*(?:export\s+)?([A-Z_][A-Z0-9_]*)=(.*)$',line)
|
||||
KEYMAPPING_CONTEXT_07_LINE_0672=if not m: continue
|
||||
KEYMAPPING_CONTEXT_07_LINE_0673=v=m.group(2).strip()
|
||||
KEYMAPPING_CONTEXT_07_LINE_0674=if len(v)>=2 and v[0]==v[-1] and v[0] in ('\"',"'"): v=v[1:-1]
|
||||
KEYMAPPING_CONTEXT_08_RANGE=846-860
|
||||
KEYMAPPING_CONTEXT_08_LINE_0846=return local,{'generation':gen,'source_class':'xenforo','site':t['slug'],'vmid':t['vmid'],'node':t['node'],'dump_strategy':t['dump_strategy'],'db_dump_bytes':j.get('db_bytes')},None
|
||||
KEYMAPPING_CONTEXT_08_LINE_0847=
|
||||
KEYMAPPING_CONTEXT_08_LINE_0848=def node_bundle_paths(node):
|
||||
KEYMAPPING_CONTEXT_08_LINE_0849=p=['etc/network/interfaces','etc/hosts','etc/resolv.conf','etc/hostname','etc/pve/corosync.conf','etc/pve/storage.cfg','etc/pve/user.cfg','etc/pve/datacenter.cfg','etc/pve/firewall','etc/pve/nodes/'+node,'etc/apt/sources.list.d']
|
||||
KEYMAPPING_CONTEXT_08_LINE_0850=if node=='pve01':
|
||||
KEYMAPPING_CONTEXT_08_LINE_0851=if OPERATOR_KEY.exists(): p.append('root/.ssh/id_ed25519_netbird_operator')
|
||||
KEYMAPPING_CONTEXT_08_LINE_0852=if pathlib.Path(str(OPERATOR_KEY)+'.pub').exists(): p.append('root/.ssh/id_ed25519_netbird_operator.pub')
|
||||
KEYMAPPING_CONTEXT_08_LINE_0853=return p
|
||||
KEYMAPPING_CONTEXT_08_LINE_0854=
|
||||
KEYMAPPING_CONTEXT_08_LINE_0855=def capture_node_bundle(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_08_LINE_0856=node=t['node']; raw=node_bundle_paths(node); paths=[]
|
||||
KEYMAPPING_CONTEXT_08_LINE_0857=for rel in raw:
|
||||
KEYMAPPING_CONTEXT_08_LINE_0858=if node=='pve01': ok=(pathlib.Path('/')/rel).exists()
|
||||
KEYMAPPING_CONTEXT_08_LINE_0859=else: ok=(ssh_remote(node,['test','-e','/'+rel],timeout=20,check=False).returncode==0)
|
||||
KEYMAPPING_CONTEXT_08_LINE_0860=if ok: paths.append(rel)
|
||||
KEYMAPPING_CONTEXT_09_RANGE=870-885
|
||||
KEYMAPPING_CONTEXT_09_LINE_0870=
|
||||
KEYMAPPING_CONTEXT_09_LINE_0871=def capture_target(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_09_LINE_0872=typ=t['type']
|
||||
KEYMAPPING_CONTEXT_09_LINE_0873=if typ=='pve_guest': return capture_pve_guest(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0874=if typ=='pve_node_bundle': return capture_node_bundle(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0875=if typ=='vps_md': return capture_vps_md(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0876=if typ=='vps_spb': return capture_vps_spb(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0877=if typ=='vps_us': return capture_vps_us(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0878=if typ=='router': return capture_router(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0879=if typ=='xenforo': return capture_xenforo(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0880=raise BackupError('CAPTURE_TYPE_UNKNOWN')
|
||||
KEYMAPPING_CONTEXT_09_LINE_0881=
|
||||
KEYMAPPING_CONTEXT_09_LINE_0882=def cleanup_source(cleanup):
|
||||
KEYMAPPING_CONTEXT_09_LINE_0883=if not cleanup: return
|
||||
KEYMAPPING_CONTEXT_09_LINE_0884=if cleanup.get('kind')=='pve_source_dir':
|
||||
KEYMAPPING_CONTEXT_09_LINE_0885=ssh_remote(cleanup['node'],['rm','-rf','--',cleanup['path']],timeout=60)
|
||||
KEYMAPPING_RELEVANT_LINE_COUNT=15
|
||||
KEYMAPPING_RELEVANT_01_LINE=16
|
||||
KEYMAPPING_RELEVANT_01_TEXT=OPERATOR_KEY=pathlib.Path('[SENSITIVE_PATH]
|
||||
KEYMAPPING_RELEVANT_02_LINE=158
|
||||
KEYMAPPING_RELEVANT_02_TEXT={'logical_id':'md-relay','scope':'vps','type':'vps_md','host':'85.121.4.192','port':22,'user':'ops','hostkey_fingerprint':'SHA256:DXJGwunC5tEVvnC3nRxyayTN8FXmyJcVgf+Oa6udQsY','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_RELEVANT_03_LINE=160
|
||||
KEYMAPPING_RELEVANT_03_TEXT={'logical_id':'us-netbird','scope':'vps','type':'vps_us','host':'46.16.34.129','port':22,'user':'root','hostkey_fingerprint':'SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_RELEVANT_04_LINE=389
|
||||
KEYMAPPING_RELEVANT_04_TEXT=if typ in ('pve_node_bundle','vps_md','vps_spb','vps_us','router'):
|
||||
KEYMAPPING_RELEVANT_05_LINE=568
|
||||
KEYMAPPING_RELEVANT_05_TEXT=if t['type'] not in ('vps_md','vps_spb','vps_us'): continue
|
||||
KEYMAPPING_RELEVANT_06_LINE=591
|
||||
KEYMAPPING_RELEVANT_06_TEXT=if t['type'] not in ('vps_md','vps_spb'): continue
|
||||
KEYMAPPING_RELEVANT_07_LINE=603
|
||||
KEYMAPPING_RELEVANT_07_TEXT=us=[x for x in targets if x['type']=='vps_us'][0]
|
||||
KEYMAPPING_RELEVANT_08_LINE=612
|
||||
KEYMAPPING_RELEVANT_08_TEXT=def capture_vps_md(t,gen,work):
|
||||
KEYMAPPING_RELEVANT_09_LINE=621
|
||||
KEYMAPPING_RELEVANT_09_TEXT=return payload,{'generation':gen,'source_class':'vps_md','consistency':'FILESET_PRE_POST_HASH_STABILITY','hashset_sha256':pre},None
|
||||
KEYMAPPING_RELEVANT_10_LINE=662
|
||||
KEYMAPPING_RELEVANT_10_TEXT=def capture_vps_us(t,gen,work):
|
||||
KEYMAPPING_RELEVANT_11_LINE=666
|
||||
KEYMAPPING_RELEVANT_11_TEXT=return payload,{'generation':gen,'source_class':'vps_us','consistency':'SQLITE_ONLINE_BACKUP_PLUS_NONDB_FILES','sqlite_count':4},None
|
||||
KEYMAPPING_RELEVANT_12_LINE=851
|
||||
KEYMAPPING_RELEVANT_12_TEXT=if OPERATOR_KEY.exists(): p.append('root/.ssh/id_ed25519_netbird_operator')
|
||||
KEYMAPPING_RELEVANT_13_LINE=852
|
||||
KEYMAPPING_RELEVANT_13_TEXT=if pathlib.Path(str(OPERATOR_KEY)+'.pub').exists(): p.append('root/.ssh/id_ed25519_netbird_operator.pub')
|
||||
KEYMAPPING_RELEVANT_14_LINE=875
|
||||
KEYMAPPING_RELEVANT_14_TEXT=if typ=='vps_md': return capture_vps_md(t,gen,work)
|
||||
KEYMAPPING_RELEVANT_15_LINE=877
|
||||
KEYMAPPING_RELEVANT_15_TEXT=if typ=='vps_us': return capture_vps_us(t,gen,work)
|
||||
PVE1_KEY_ID_ED25519_PRESENT=True
|
||||
PVE1_KEY_ID_ED25519_FP=SHA256:s0CusF0IHQGVJ02oi7ejWkGhH9NkhTWonn3441toe5M
|
||||
PVE1_KEY_ID_ED25519_NETBIRD_OPERATOR_PRESENT=True
|
||||
PVE1_KEY_ID_ED25519_NETBIRD_OPERATOR_FP=SHA256:wipXiBB3cpAwyWap9LcB185WjEEmDxtRJsI/UuMVAp0
|
||||
VPS552R1_DECISION=HOLD_KEY_MAPPING_AMBIGUOUS
|
||||
VPS552R1_NEXT_GATE=PVE1_ACCEPTED_ENGINE_CALLPATH_PARSE
|
||||
HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260918-INFRA-PVE1-MOLDOVA-KEYMAPPING-READONLY-552R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null}
|
||||
|
||||
OUTPUT_END
|
||||
CHAT_OUTPUT_END
|
||||
+8
-8
File diff suppressed because one or more lines are too long
+221
-43
@@ -1,15 +1,15 @@
|
||||
CHAT_OUTPUT_BEGIN
|
||||
COMMAND_ID=SUPPORT-260918-INFRA-PVE1-MOLDOVA-ACCEPTED-ENGINE-CONTEXT-READONLY-551R2
|
||||
COMMAND_ID=SUPPORT-260918-INFRA-PVE1-MOLDOVA-KEYMAPPING-READONLY-552R1
|
||||
STATUS=OK
|
||||
RC=0
|
||||
HOST=pve01
|
||||
MODE=read-only
|
||||
COMPONENT=infra-pve1-moldova-accepted-engine-context-readonly
|
||||
COMPONENT=infra-pve1-moldova-keymapping-readonly
|
||||
REFERENCE_REGISTER_CHECK=OK
|
||||
REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66
|
||||
ERROR_REGISTER_CHECK=OK
|
||||
ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0
|
||||
COMMAND_SHA256=466b431b89ae334593305e1fbbdea6c6a21b439a2568b9ccdbb76fa98c59baa9
|
||||
COMMAND_SHA256=0fadfaf45ded2524c42751f3efe29300f054f11e12b445ef897607a6f6b3e448
|
||||
DUPLICATE_FAILED_COMMAND_BLOCKED=false
|
||||
EXECUTION_STARTED=true
|
||||
CHANGE_DECLARED=false
|
||||
@@ -24,52 +24,230 @@ MUTATION_OUTCOME=NO_MUTATION
|
||||
SANITIZED=yes
|
||||
SECRETS_INCLUDED=no
|
||||
PRIVATE_ADDRESSES_INCLUDED=no
|
||||
RAW_EVIDENCE_SHA256=ddd844d81c397e39417a2eb7724f43b3b134b5e6019653f7704be4a9a981af07
|
||||
SANITIZED_OUTPUT_SHA256=ddd844d81c397e39417a2eb7724f43b3b134b5e6019653f7704be4a9a981af07
|
||||
RAW_EVIDENCE_SHA256=b3e7cbda886dbd253274af0d4c726c89e54425e5b793e9e1f149ea8412962c14
|
||||
SANITIZED_OUTPUT_SHA256=be1cde014d4680574aba7cefa652231f34f1db8d57c07b09e171b79b88530186
|
||||
OUTPUT_BEGIN
|
||||
ERROR_REGISTER_CHECK=OK
|
||||
REFERENCE_CHECK=OK
|
||||
AUTHORITY_CHECK_SCOPE=READABILITY_ONLY_INCIDENTS_NOT_CLOSED
|
||||
ACCEPTED_ENGINE_PRESENT=True
|
||||
ACCEPTED_ENGINE_SHA256=b6e79f087b9f1d21dac4f77a7b46b743299bbb85bc716e80d2ea67c2e038bcd7
|
||||
MOLDOVA_MATCH_LINE_COUNT=1
|
||||
MOLDOVA_MATCH_LINES=160
|
||||
MOLDOVA_CONTEXT_RANGE=148-172
|
||||
MOLDOVA_CONTEXT_0148=
|
||||
MOLDOVA_CONTEXT_0149=def default_targets():
|
||||
MOLDOVA_CONTEXT_0150=d=86400
|
||||
MOLDOVA_CONTEXT_0151=out=[]
|
||||
MOLDOVA_CONTEXT_0152=# PVE guests. Source node is resolved live every run.
|
||||
MOLDOVA_CONTEXT_0153=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')]:
|
||||
MOLDOVA_CONTEXT_0154=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})
|
||||
MOLDOVA_CONTEXT_0155=for node in ('pve01','pve02','pve03'):
|
||||
MOLDOVA_CONTEXT_0156=out.append({'logical_id':'node-'+node,'scope':'node','type':'pve_node_bundle','node':node,'due_seconds':7*d,'enabled':True,'green1':node=='pve01'})
|
||||
MOLDOVA_CONTEXT_0157=out += [
|
||||
MOLDOVA_CONTEXT_0158={'logical_id':'md-relay','scope':'vps','type':'vps_md','host':'85.121.4.192','port':22,'user':'ops','hostkey_fingerprint':'SHA256:DXJGwunC5tEVvnC3nRxyayTN8FXmyJcVgf+Oa6udQsY','due_seconds':d,'enabled':True,'green1':True},
|
||||
MOLDOVA_CONTEXT_0159={'logical_id':'spb-ingress','scope':'vps','type':'vps_spb','host':'185.225.35.6','port':22,'user':'edgeadmin','hostkey_fingerprint':'SHA256:Ef+HsZb8lIXoadvYBXuGKIL3H7NyJMmf9EYCoJRoSv8','due_seconds':d,'enabled':True,'green1':True},
|
||||
MOLDOVA_CONTEXT_0160={'logical_id':'us-netbird','scope':'vps','type':'vps_us','host':'46.16.34.129','port':22,'user':'root','hostkey_fingerprint':'SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE','due_seconds':d,'enabled':True,'green1':True},
|
||||
MOLDOVA_CONTEXT_0161={'logical_id':'router-netcraze','scope':'router','type':'router','due_seconds':d,'enabled':True,'green1':True},
|
||||
MOLDOVA_CONTEXT_0162=]
|
||||
MOLDOVA_CONTEXT_0163=sites=[
|
||||
MOLDOVA_CONTEXT_0164=('codevipe',160,'pve02','/var/www/forums/codevipe/public','xf_codevipe','single_transaction'),
|
||||
MOLDOVA_CONTEXT_0165=('dsmods',160,'pve02','/var/www/forums/dsmods/public','xf_dsmods','single_transaction'),
|
||||
MOLDOVA_CONTEXT_0166=('kingofwolk',160,'pve02','/var/www/forums/kingofwolk/public','xf_kingofwolk','single_transaction'),
|
||||
MOLDOVA_CONTEXT_0167=('newfi',210,'pve01','/var/www/forums/newfi/public','xf_newfi','single_transaction'),
|
||||
MOLDOVA_CONTEXT_0168=('gamevipe',160,'pve02','/var/www/forums/gamevipe/public','xf_gamevipe','global_read_lock'),
|
||||
MOLDOVA_CONTEXT_0169=('hkmods',160,'pve02','/var/www/forums/hkmods/public','xf_hkmods','global_read_lock'),
|
||||
MOLDOVA_CONTEXT_0170=('zakrutim',160,'pve02','/var/www/forums/zakrutim/public','xf_zakrutim','global_read_lock')]
|
||||
MOLDOVA_CONTEXT_0171=for slug,vmid,node,root,db,strategy in sites:
|
||||
MOLDOVA_CONTEXT_0172=out.append({'logical_id':'xf-'+slug,'scope':'xenforo','type':'xenforo','slug':slug,'vmid':vmid,'node':node,'app_root':root,'db_name':db,'dump_strategy':strategy,'due_seconds':d,'enabled':True,'green1':slug in ('codevipe','zakrutim')})
|
||||
MOLDOVA_MIN_DICT_COUNT=1
|
||||
MOLDOVA_DICT_01_LINENO=160
|
||||
MOLDOVA_DICT_01_FIELD_HOST=46.16.34.129
|
||||
MOLDOVA_DICT_01_FIELD_PORT=22
|
||||
MOLDOVA_DICT_01_FIELD_USER=root
|
||||
MOLDOVA_DICT_01_FIELD_HOSTKEY_FINGERPRINT=SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE
|
||||
MOLDOVA_SAFE_FIELD_COUNT=4
|
||||
VPS551R2_DECISION=PASS_ACCEPTED_ENGINE_MOLDOVA_RECORD_FOUND
|
||||
VPS551R2_NEXT_GATE=PVE1_MOLDOVA_EXACT_ROUTE_TEST
|
||||
HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260918-INFRA-PVE1-MOLDOVA-ACCEPTED-ENGINE-CONTEXT-READONLY-551R2","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null}
|
||||
KEYMAPPING_MATCH_LINE_COUNT=17
|
||||
KEYMAPPING_MATCH_LINES=14,16,158,160,389,552,568,591,603,612,621,662,666,851,852,875,877
|
||||
KEYMAPPING_CONTEXT_01_RANGE=9-24
|
||||
KEYMAPPING_CONTEXT_01_LINE_0009=WORK_ROOT=pathlib.Path('/mnt/staging/homelab-backup-v2')
|
||||
KEYMAPPING_CONTEXT_01_LINE_0010=ENGINE_PATH=pathlib.Path('/usr/local/sbin/homelab-backup-v2')
|
||||
KEYMAPPING_CONTEXT_01_LINE_0011=RCLONE=shutil.which('rclone') or '/usr/bin/rclone'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0012=SSH=shutil.which('ssh') or '/usr/bin/ssh'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0013=SCP=shutil.which('scp') or '/usr/bin/scp'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0014=SSH_KEYSCAN=shutil.which('ssh-keyscan') or '/usr/bin/ssh-keyscan'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0015=SSHPASS=shutil.which('sshpass') or '/usr/bin/sshpass'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0016=OPERATOR_KEY=pathlib.Path('[SENSITIVE_PATH]
|
||||
KEYMAPPING_CONTEXT_01_LINE_0017=VPS_KNOWN_HOSTS=CONFIG_ROOT/'vps_known_hosts'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0018=ROUTER_KNOWN_HOSTS=CONFIG_ROOT/'router_known_hosts'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0019=ROUTER_LEGACY_SCRIPT=pathlib.Path('/usr/local/sbin/homelab-router-running-config-mail-cloud')
|
||||
KEYMAPPING_CONTEXT_01_LINE_0020=ROUTER_LEGACY_SHA='a0aeb0e1ec7e2714b3d6147c13c2af04d8d8118219541ec60b66df6919858dc7'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0021=ROUTER_TARGET_SHA='4f9da1283166a1e9f4e6bc7dd240c76aef85772177f717f92abb6e8e2bb8de90'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0022=ROUTER_FINGERPRINT='SHA256:2Tw4CU4kvwtXSIiym+699Y6W2VJVWzRUD4opXrSfOIs'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0023=ROUTER_KNOWN_HOSTS_SHA='02d4e1dad1620937b7a67416a73aa182f9e80ea9c4b11f777161bc7455cf234d'
|
||||
KEYMAPPING_CONTEXT_01_LINE_0024=OPERATOR_KEY_FINGERPRINT='SHA256:wipXiBB3cpAwyWap9LcB185WjEEmDxtRJsI/UuMVAp0'
|
||||
KEYMAPPING_CONTEXT_02_RANGE=153-168
|
||||
KEYMAPPING_CONTEXT_02_LINE_0153=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')]:
|
||||
KEYMAPPING_CONTEXT_02_LINE_0154=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})
|
||||
KEYMAPPING_CONTEXT_02_LINE_0155=for node in ('pve01','pve02','pve03'):
|
||||
KEYMAPPING_CONTEXT_02_LINE_0156=out.append({'logical_id':'node-'+node,'scope':'node','type':'pve_node_bundle','node':node,'due_seconds':7*d,'enabled':True,'green1':node=='pve01'})
|
||||
KEYMAPPING_CONTEXT_02_LINE_0157=out += [
|
||||
KEYMAPPING_CONTEXT_02_LINE_0158={'logical_id':'md-relay','scope':'vps','type':'vps_md','host':'85.121.4.192','port':22,'user':'ops','hostkey_fingerprint':'SHA256:DXJGwunC5tEVvnC3nRxyayTN8FXmyJcVgf+Oa6udQsY','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0159={'logical_id':'spb-ingress','scope':'vps','type':'vps_spb','host':'185.225.35.6','port':22,'user':'edgeadmin','hostkey_fingerprint':'SHA256:Ef+HsZb8lIXoadvYBXuGKIL3H7NyJMmf9EYCoJRoSv8','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0160={'logical_id':'us-netbird','scope':'vps','type':'vps_us','host':'46.16.34.129','port':22,'user':'root','hostkey_fingerprint':'SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0161={'logical_id':'router-netcraze','scope':'router','type':'router','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_CONTEXT_02_LINE_0162=]
|
||||
KEYMAPPING_CONTEXT_02_LINE_0163=sites=[
|
||||
KEYMAPPING_CONTEXT_02_LINE_0164=('codevipe',160,'pve02','/var/www/forums/codevipe/public','xf_codevipe','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0165=('dsmods',160,'pve02','/var/www/forums/dsmods/public','xf_dsmods','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0166=('kingofwolk',160,'pve02','/var/www/forums/kingofwolk/public','xf_kingofwolk','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0167=('newfi',210,'pve01','/var/www/forums/newfi/public','xf_newfi','single_transaction'),
|
||||
KEYMAPPING_CONTEXT_02_LINE_0168=('gamevipe',160,'pve02','/var/www/forums/gamevipe/public','xf_gamevipe','global_read_lock'),
|
||||
KEYMAPPING_CONTEXT_03_RANGE=384-397
|
||||
KEYMAPPING_CONTEXT_03_LINE_0384=if not names: raise BackupError('TAR_ZST_EMPTY')
|
||||
KEYMAPPING_CONTEXT_03_LINE_0385=if required_member and required_member not in names: raise BackupError('REQUIRED_MEMBER_MISSING')
|
||||
KEYMAPPING_CONTEXT_03_LINE_0386=
|
||||
KEYMAPPING_CONTEXT_03_LINE_0387=def validate_payload(t,path):
|
||||
KEYMAPPING_CONTEXT_03_LINE_0388=typ=t['type']
|
||||
KEYMAPPING_CONTEXT_03_LINE_0389=if typ in ('pve_node_bundle','vps_md','vps_spb','vps_us','router'):
|
||||
KEYMAPPING_CONTEXT_03_LINE_0390=validate_tar_zst(path)
|
||||
KEYMAPPING_CONTEXT_03_LINE_0391=elif typ=='pve_guest':
|
||||
KEYMAPPING_CONTEXT_03_LINE_0392=if t['guest_type']=='lxc': validate_tar_zst(path)
|
||||
KEYMAPPING_CONTEXT_03_LINE_0393=else:
|
||||
KEYMAPPING_CONTEXT_03_LINE_0394=# Green set is intentionally CT-only. Scheduled QEMU backups still get dual remote byte readback.
|
||||
KEYMAPPING_CONTEXT_03_LINE_0395=run([shutil.which('zstd') or '/usr/bin/zstd','-t','-q',str(path)],timeout=600)
|
||||
KEYMAPPING_CONTEXT_03_LINE_0396=elif typ=='xenforo':
|
||||
KEYMAPPING_CONTEXT_03_LINE_0397=validate_tar_zst(path,'db.sql')
|
||||
KEYMAPPING_CONTEXT_04_RANGE=547-560
|
||||
KEYMAPPING_CONTEXT_04_LINE_0547=m=re.search(r'(SHA256:[A-Za-z0-9+/]+)',s)
|
||||
KEYMAPPING_CONTEXT_04_LINE_0548=if not m or m.group(1)!=OPERATOR_KEY_FINGERPRINT: raise BackupError('OPERATOR_KEY_FINGERPRINT_MISMATCH')
|
||||
KEYMAPPING_CONTEXT_04_LINE_0549=return m.group(1)
|
||||
KEYMAPPING_CONTEXT_04_LINE_0550=
|
||||
KEYMAPPING_CONTEXT_04_LINE_0551=def scan_hostkey_line(host,port,expected):
|
||||
KEYMAPPING_CONTEXT_04_LINE_0552=p=run([SSH_KEYSCAN,'-T','8','-p',str(port),'-t','ed25519',host],timeout=15)
|
||||
KEYMAPPING_CONTEXT_04_LINE_0553=lines=[x.strip() for x in p.stdout.decode().splitlines() if x.strip() and not x.startswith('#')]
|
||||
KEYMAPPING_CONTEXT_04_LINE_0554=good=[]
|
||||
KEYMAPPING_CONTEXT_04_LINE_0555=for line in lines:
|
||||
KEYMAPPING_CONTEXT_04_LINE_0556=f=line.split()
|
||||
KEYMAPPING_CONTEXT_04_LINE_0557=if len(f)<3 or f[1]!='ssh-ed25519': continue
|
||||
KEYMAPPING_CONTEXT_04_LINE_0558=try: blob=base64.b64decode(f[2])
|
||||
KEYMAPPING_CONTEXT_04_LINE_0559=except Exception: continue
|
||||
KEYMAPPING_CONTEXT_04_LINE_0560=fp='SHA256:'+base64.b64encode(hashlib.sha256(blob).digest()).decode().rstrip('=')
|
||||
KEYMAPPING_CONTEXT_05_RANGE=563-576
|
||||
KEYMAPPING_CONTEXT_05_LINE_0563=return good[0]
|
||||
KEYMAPPING_CONTEXT_05_LINE_0564=
|
||||
KEYMAPPING_CONTEXT_05_LINE_0565=def ensure_vps_known_hosts(targets):
|
||||
KEYMAPPING_CONTEXT_05_LINE_0566=lines=[]
|
||||
KEYMAPPING_CONTEXT_05_LINE_0567=for t in targets:
|
||||
KEYMAPPING_CONTEXT_05_LINE_0568=if t['type'] not in ('vps_md','vps_spb','vps_us'): continue
|
||||
KEYMAPPING_CONTEXT_05_LINE_0569=lines.append(scan_hostkey_line(t['host'],t['port'],t['hostkey_fingerprint']))
|
||||
KEYMAPPING_CONTEXT_05_LINE_0570=atomic_write(VPS_KNOWN_HOSTS,('\n'.join(lines)+'\n').encode(),0o600)
|
||||
KEYMAPPING_CONTEXT_05_LINE_0571=
|
||||
KEYMAPPING_CONTEXT_05_LINE_0572=def vps_ssh_argv(t, *, use_agent=False):
|
||||
KEYMAPPING_CONTEXT_05_LINE_0573=a=[SSH,'-p',str(t['port']),'-o','BatchMode=yes','-o','StrictHostKeyChecking=yes','-o','UserKnownHostsFile='+str(VPS_KNOWN_HOSTS),'-o','ConnectTimeout=15']
|
||||
KEYMAPPING_CONTEXT_05_LINE_0574=if use_agent:
|
||||
KEYMAPPING_CONTEXT_05_LINE_0575=a += ['-o','IdentitiesOnly=no']
|
||||
KEYMAPPING_CONTEXT_05_LINE_0576=else:
|
||||
KEYMAPPING_CONTEXT_06_RANGE=586-629
|
||||
KEYMAPPING_CONTEXT_06_LINE_0586=operator_key_fingerprint()
|
||||
KEYMAPPING_CONTEXT_06_LINE_0587=ensure_vps_known_hosts(targets)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0588=pub=run(['ssh-keygen','-y','-f',str(OPERATOR_KEY)],timeout=30).stdout.strip()+b'\n'
|
||||
KEYMAPPING_CONTEXT_06_LINE_0589=results={}
|
||||
KEYMAPPING_CONTEXT_06_LINE_0590=for t in targets:
|
||||
KEYMAPPING_CONTEXT_06_LINE_0591=if t['type'] not in ('vps_md','vps_spb'): continue
|
||||
KEYMAPPING_CONTEXT_06_LINE_0592=probe=vps_run(t,['true'],timeout=30,use_agent=False,check=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0593=if probe.returncode==0:
|
||||
KEYMAPPING_CONTEXT_06_LINE_0594=results[t['logical_id']]='ALREADY_OPERATOR_KEY'; continue
|
||||
KEYMAPPING_CONTEXT_06_LINE_0595=if not os.environ.get('SSH_AUTH_SOCK'): raise BackupError('FORWARDED_AGENT_REQUIRED_FOR_BOOTSTRAP')
|
||||
KEYMAPPING_CONTEXT_06_LINE_0596=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"
|
||||
KEYMAPPING_CONTEXT_06_LINE_0597=p=vps_run(t,['sh','-c',script.decode()],input=pub,timeout=45,use_agent=True)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0598=tag=p.stdout.decode().strip()
|
||||
KEYMAPPING_CONTEXT_06_LINE_0599=if tag not in ('ADDED','ALREADY'): raise BackupError('VPS_AUTHORIZED_KEY_BOOTSTRAP_RESULT')
|
||||
KEYMAPPING_CONTEXT_06_LINE_0600=vps_run(t,['true'],timeout=30,use_agent=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0601=results[t['logical_id']]=tag
|
||||
KEYMAPPING_CONTEXT_06_LINE_0602=# US was already operator-key based; prove it agentless too.
|
||||
KEYMAPPING_CONTEXT_06_LINE_0603=us=[x for x in targets if x['type']=='vps_us'][0]
|
||||
KEYMAPPING_CONTEXT_06_LINE_0604=vps_run(us,['true'],timeout=30,use_agent=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0605=results[us['logical_id']]='ALREADY_US_OPERATOR_KEY'
|
||||
KEYMAPPING_CONTEXT_06_LINE_0606=return results
|
||||
KEYMAPPING_CONTEXT_06_LINE_0607=
|
||||
KEYMAPPING_CONTEXT_06_LINE_0608=def remote_hashset(t,command):
|
||||
KEYMAPPING_CONTEXT_06_LINE_0609=p=vps_run(t,['sh','-c',command],timeout=120,use_agent=False)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0610=return sha256_bytes(p.stdout)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0611=
|
||||
KEYMAPPING_CONTEXT_06_LINE_0612=def capture_vps_md(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_06_LINE_0613=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']
|
||||
KEYMAPPING_CONTEXT_06_LINE_0614=cmd="sudo -n sha256sum -- "+' '.join(shlex.quote('/'+x) for x in files)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0615=pre=remote_hashset(t,cmd)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0616=remote=shlex.join(['sudo','-n','tar','--numeric-owner','-C','/','-cf','-']+files)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0617=argv=vps_ssh_argv(t,use_agent=False)+[remote]
|
||||
KEYMAPPING_CONTEXT_06_LINE_0618=payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=600)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0619=post=remote_hashset(t,cmd)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0620=if pre!=post: raise BackupError('MD_SOURCE_CHANGED_DURING_CAPTURE')
|
||||
KEYMAPPING_CONTEXT_06_LINE_0621=return payload,{'generation':gen,'source_class':'vps_md','consistency':'FILESET_PRE_POST_HASH_STABILITY','hashset_sha256':pre},None
|
||||
KEYMAPPING_CONTEXT_06_LINE_0622=
|
||||
KEYMAPPING_CONTEXT_06_LINE_0623=def capture_vps_spb(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_06_LINE_0624=hcmd="find /etc/nginx -xdev -type f -print0 | sort -z | xargs -0 sha256sum"
|
||||
KEYMAPPING_CONTEXT_06_LINE_0625=pre=remote_hashset(t,hcmd)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0626=remote=shlex.join(['tar','--numeric-owner','-C','/','-cf','-','etc/nginx'])
|
||||
KEYMAPPING_CONTEXT_06_LINE_0627=argv=vps_ssh_argv(t,use_agent=False)+[remote]
|
||||
KEYMAPPING_CONTEXT_06_LINE_0628=payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=900)
|
||||
KEYMAPPING_CONTEXT_06_LINE_0629=post=remote_hashset(t,hcmd)
|
||||
KEYMAPPING_CONTEXT_07_RANGE=657-674
|
||||
KEYMAPPING_CONTEXT_07_LINE_0657=if dst.execute('pragma quick_check').fetchone()[0]!='ok': raise SystemExit(33)
|
||||
KEYMAPPING_CONTEXT_07_LINE_0658=b=dst.serialize(); dst.close(); src.close()
|
||||
KEYMAPPING_CONTEXT_07_LINE_0659=ti=tarfile.TarInfo(name=('sqlite-backups/'+name)); ti.size=len(b); ti.mode=0o600; ti.mtime=int(time.time()); tf.addfile(ti,io.BytesIO(b))
|
||||
KEYMAPPING_CONTEXT_07_LINE_0660='''
|
||||
KEYMAPPING_CONTEXT_07_LINE_0661=
|
||||
KEYMAPPING_CONTEXT_07_LINE_0662=def capture_vps_us(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_07_LINE_0663=remote=shlex.join(['python3','-I','-B','-c',US_REMOTE_SCRIPT])
|
||||
KEYMAPPING_CONTEXT_07_LINE_0664=argv=vps_ssh_argv(t,use_agent=False)+[remote]
|
||||
KEYMAPPING_CONTEXT_07_LINE_0665=payload=work/'payload.tar.zst'; pipe_to_zstd(argv,payload,timeout=1200)
|
||||
KEYMAPPING_CONTEXT_07_LINE_0666=return payload,{'generation':gen,'source_class':'vps_us','consistency':'SQLITE_ONLINE_BACKUP_PLUS_NONDB_FILES','sqlite_count':4},None
|
||||
KEYMAPPING_CONTEXT_07_LINE_0667=
|
||||
KEYMAPPING_CONTEXT_07_LINE_0668=def _simple_shell_assignments(text):
|
||||
KEYMAPPING_CONTEXT_07_LINE_0669=vals={}
|
||||
KEYMAPPING_CONTEXT_07_LINE_0670=for line in text.splitlines():
|
||||
KEYMAPPING_CONTEXT_07_LINE_0671=m=re.match(r'^\s*(?:export\s+)?([A-Z_][A-Z0-9_]*)=(.*)$',line)
|
||||
KEYMAPPING_CONTEXT_07_LINE_0672=if not m: continue
|
||||
KEYMAPPING_CONTEXT_07_LINE_0673=v=m.group(2).strip()
|
||||
KEYMAPPING_CONTEXT_07_LINE_0674=if len(v)>=2 and v[0]==v[-1] and v[0] in ('\"',"'"): v=v[1:-1]
|
||||
KEYMAPPING_CONTEXT_08_RANGE=846-860
|
||||
KEYMAPPING_CONTEXT_08_LINE_0846=return local,{'generation':gen,'source_class':'xenforo','site':t['slug'],'vmid':t['vmid'],'node':t['node'],'dump_strategy':t['dump_strategy'],'db_dump_bytes':j.get('db_bytes')},None
|
||||
KEYMAPPING_CONTEXT_08_LINE_0847=
|
||||
KEYMAPPING_CONTEXT_08_LINE_0848=def node_bundle_paths(node):
|
||||
KEYMAPPING_CONTEXT_08_LINE_0849=p=['etc/network/interfaces','etc/hosts','etc/resolv.conf','etc/hostname','etc/pve/corosync.conf','etc/pve/storage.cfg','etc/pve/user.cfg','etc/pve/datacenter.cfg','etc/pve/firewall','etc/pve/nodes/'+node,'etc/apt/sources.list.d']
|
||||
KEYMAPPING_CONTEXT_08_LINE_0850=if node=='pve01':
|
||||
KEYMAPPING_CONTEXT_08_LINE_0851=if OPERATOR_KEY.exists(): p.append('root/.ssh/id_ed25519_netbird_operator')
|
||||
KEYMAPPING_CONTEXT_08_LINE_0852=if pathlib.Path(str(OPERATOR_KEY)+'.pub').exists(): p.append('root/.ssh/id_ed25519_netbird_operator.pub')
|
||||
KEYMAPPING_CONTEXT_08_LINE_0853=return p
|
||||
KEYMAPPING_CONTEXT_08_LINE_0854=
|
||||
KEYMAPPING_CONTEXT_08_LINE_0855=def capture_node_bundle(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_08_LINE_0856=node=t['node']; raw=node_bundle_paths(node); paths=[]
|
||||
KEYMAPPING_CONTEXT_08_LINE_0857=for rel in raw:
|
||||
KEYMAPPING_CONTEXT_08_LINE_0858=if node=='pve01': ok=(pathlib.Path('/')/rel).exists()
|
||||
KEYMAPPING_CONTEXT_08_LINE_0859=else: ok=(ssh_remote(node,['test','-e','/'+rel],timeout=20,check=False).returncode==0)
|
||||
KEYMAPPING_CONTEXT_08_LINE_0860=if ok: paths.append(rel)
|
||||
KEYMAPPING_CONTEXT_09_RANGE=870-885
|
||||
KEYMAPPING_CONTEXT_09_LINE_0870=
|
||||
KEYMAPPING_CONTEXT_09_LINE_0871=def capture_target(t,gen,work):
|
||||
KEYMAPPING_CONTEXT_09_LINE_0872=typ=t['type']
|
||||
KEYMAPPING_CONTEXT_09_LINE_0873=if typ=='pve_guest': return capture_pve_guest(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0874=if typ=='pve_node_bundle': return capture_node_bundle(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0875=if typ=='vps_md': return capture_vps_md(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0876=if typ=='vps_spb': return capture_vps_spb(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0877=if typ=='vps_us': return capture_vps_us(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0878=if typ=='router': return capture_router(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0879=if typ=='xenforo': return capture_xenforo(t,gen,work)
|
||||
KEYMAPPING_CONTEXT_09_LINE_0880=raise BackupError('CAPTURE_TYPE_UNKNOWN')
|
||||
KEYMAPPING_CONTEXT_09_LINE_0881=
|
||||
KEYMAPPING_CONTEXT_09_LINE_0882=def cleanup_source(cleanup):
|
||||
KEYMAPPING_CONTEXT_09_LINE_0883=if not cleanup: return
|
||||
KEYMAPPING_CONTEXT_09_LINE_0884=if cleanup.get('kind')=='pve_source_dir':
|
||||
KEYMAPPING_CONTEXT_09_LINE_0885=ssh_remote(cleanup['node'],['rm','-rf','--',cleanup['path']],timeout=60)
|
||||
KEYMAPPING_RELEVANT_LINE_COUNT=15
|
||||
KEYMAPPING_RELEVANT_01_LINE=16
|
||||
KEYMAPPING_RELEVANT_01_TEXT=OPERATOR_KEY=pathlib.Path('[SENSITIVE_PATH]
|
||||
KEYMAPPING_RELEVANT_02_LINE=158
|
||||
KEYMAPPING_RELEVANT_02_TEXT={'logical_id':'md-relay','scope':'vps','type':'vps_md','host':'85.121.4.192','port':22,'user':'ops','hostkey_fingerprint':'SHA256:DXJGwunC5tEVvnC3nRxyayTN8FXmyJcVgf+Oa6udQsY','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_RELEVANT_03_LINE=160
|
||||
KEYMAPPING_RELEVANT_03_TEXT={'logical_id':'us-netbird','scope':'vps','type':'vps_us','host':'46.16.34.129','port':22,'user':'root','hostkey_fingerprint':'SHA256:805Q9eh/fePUci42dfY58I6q0lFiiPHn0/M+mckypmE','due_seconds':d,'enabled':True,'green1':True},
|
||||
KEYMAPPING_RELEVANT_04_LINE=389
|
||||
KEYMAPPING_RELEVANT_04_TEXT=if typ in ('pve_node_bundle','vps_md','vps_spb','vps_us','router'):
|
||||
KEYMAPPING_RELEVANT_05_LINE=568
|
||||
KEYMAPPING_RELEVANT_05_TEXT=if t['type'] not in ('vps_md','vps_spb','vps_us'): continue
|
||||
KEYMAPPING_RELEVANT_06_LINE=591
|
||||
KEYMAPPING_RELEVANT_06_TEXT=if t['type'] not in ('vps_md','vps_spb'): continue
|
||||
KEYMAPPING_RELEVANT_07_LINE=603
|
||||
KEYMAPPING_RELEVANT_07_TEXT=us=[x for x in targets if x['type']=='vps_us'][0]
|
||||
KEYMAPPING_RELEVANT_08_LINE=612
|
||||
KEYMAPPING_RELEVANT_08_TEXT=def capture_vps_md(t,gen,work):
|
||||
KEYMAPPING_RELEVANT_09_LINE=621
|
||||
KEYMAPPING_RELEVANT_09_TEXT=return payload,{'generation':gen,'source_class':'vps_md','consistency':'FILESET_PRE_POST_HASH_STABILITY','hashset_sha256':pre},None
|
||||
KEYMAPPING_RELEVANT_10_LINE=662
|
||||
KEYMAPPING_RELEVANT_10_TEXT=def capture_vps_us(t,gen,work):
|
||||
KEYMAPPING_RELEVANT_11_LINE=666
|
||||
KEYMAPPING_RELEVANT_11_TEXT=return payload,{'generation':gen,'source_class':'vps_us','consistency':'SQLITE_ONLINE_BACKUP_PLUS_NONDB_FILES','sqlite_count':4},None
|
||||
KEYMAPPING_RELEVANT_12_LINE=851
|
||||
KEYMAPPING_RELEVANT_12_TEXT=if OPERATOR_KEY.exists(): p.append('root/.ssh/id_ed25519_netbird_operator')
|
||||
KEYMAPPING_RELEVANT_13_LINE=852
|
||||
KEYMAPPING_RELEVANT_13_TEXT=if pathlib.Path(str(OPERATOR_KEY)+'.pub').exists(): p.append('root/.ssh/id_ed25519_netbird_operator.pub')
|
||||
KEYMAPPING_RELEVANT_14_LINE=875
|
||||
KEYMAPPING_RELEVANT_14_TEXT=if typ=='vps_md': return capture_vps_md(t,gen,work)
|
||||
KEYMAPPING_RELEVANT_15_LINE=877
|
||||
KEYMAPPING_RELEVANT_15_TEXT=if typ=='vps_us': return capture_vps_us(t,gen,work)
|
||||
PVE1_KEY_ID_ED25519_PRESENT=True
|
||||
PVE1_KEY_ID_ED25519_FP=SHA256:s0CusF0IHQGVJ02oi7ejWkGhH9NkhTWonn3441toe5M
|
||||
PVE1_KEY_ID_ED25519_NETBIRD_OPERATOR_PRESENT=True
|
||||
PVE1_KEY_ID_ED25519_NETBIRD_OPERATOR_FP=SHA256:wipXiBB3cpAwyWap9LcB185WjEEmDxtRJsI/UuMVAp0
|
||||
VPS552R1_DECISION=HOLD_KEY_MAPPING_AMBIGUOUS
|
||||
VPS552R1_NEXT_GATE=PVE1_ACCEPTED_ENGINE_CALLPATH_PARSE
|
||||
HOMELAB_RESULT_CONTRACT={"version":1,"command_id":"SUPPORT-260918-INFRA-PVE1-MOLDOVA-KEYMAPPING-READONLY-552R1","status":"OK","changes_made":false,"rollback_started":false,"rollback_restored":null}
|
||||
|
||||
OUTPUT_END
|
||||
CHAT_OUTPUT_END
|
||||
|
||||
Reference in New Issue
Block a user