Files
dj/integration-work/deploy_panel_routing.py

39 lines
3.5 KiB
Python

import pathlib,json,sys,hashlib,datetime,shutil,subprocess,sqlite3
root=pathlib.Path('/home/ps/huobao-gpu-selection');work=root/'panel-8189'
assert (work/'deployed.json').exists(),'8189 has not passed node/history checks'
manifest=json.loads((root/'panel-routing-manifest.json').read_text())
stamp=datetime.datetime.now().strftime('%Y%m%d-%H%M%S');backup=root/('before-panel-routing-'+stamp);backup.mkdir(mode=0o700)
targets=[('general','canvas-h3-prompt-normalizer-healthy-20261026'),('vdn','huobao-vdn-normalizer')]
for short,name in targets:
p=root/(name+'.candidate.py');assert hashlib.sha256(p.read_bytes()).hexdigest()==manifest[short]['before'],'Live normalizer changed; review first'
candidate=root/(short+'-normalizer-panels.py');assert hashlib.sha256(candidate.read_bytes()).hexdigest()==manifest[short]['after'];compile(candidate.read_text(),str(candidate),'exec')
bridges=[('/home/ps/huobao-model-bridge','huobao-model-bridge','state'),('/home/ps/huobao-vdn/bridge','huobao-vdn-bridge','../bridge-state')]
for folder,_,_ in bridges:assert hashlib.sha256((pathlib.Path(folder)/'bridge.py').read_bytes()).hexdigest()==manifest['bridge']['before'],'Bridge changed; review first'
extra=root/'extra-providers.json';shutil.copy2(extra,backup/'extra-providers.json')
state=json.loads((root/'state.json').read_text());admission=pathlib.Path(state['admission']);shutil.copy2(admission,backup/'admission.json')
# Stage code that accepts both provider IDs before exposing the new provider entry.
for short,name in targets:
live=root/(name+'.candidate.py');shutil.copy2(live,backup/(name+'.py'))
live.write_bytes((root/(short+'-normalizer-panels.py')).read_bytes())
subprocess.run(['docker','restart','--timeout','60',name],check=True,stdout=subprocess.DEVNULL)
normalizer=json.loads(subprocess.check_output(['docker','inspect',targets[0][1]],text=True))[0]
tokens=pathlib.Path(next(m['Source'] for m in normalizer['Mounts'] if m['Destination']=='/run/h3-workers'))
token=tokens/'gpu1_8189.token';assert not token.exists(),'New token already exists; inspect first'
token.write_bytes((work/'control/canary.token').read_bytes());token.chmod(0o600)
subprocess.run(['setfacl','-m','u:65534:r--',str(token)],check=True)
assert token.stat().st_mode & 0o007==0
providers=json.loads(extra.read_text());providers.append({'id':'gpu1_8189','name':'ComfyUI GPU1 :8189','base_url':'http://192.168.110.111:8189','control_token_file':'/run/h3-workers/gpu1_8189.token'})
extra.write_text(json.dumps(providers));extra.chmod(0o644)
policy=json.loads(admission.read_text());policy['admit']=[i for i in policy['admit'] if i!='gpu1']+['gpu1_8189']
admission.write_text(json.dumps(policy))
# Preserve all old IDs and job tables; only new Huobao submissions use the panel pool.
candidate=root/'bridge-panels.py';assert hashlib.sha256(candidate.read_bytes()).hexdigest()==manifest['bridge']['after']
for folder,name,statefolder in bridges:
p=pathlib.Path(folder);dest=backup/name;dest.mkdir(mode=0o700)
shutil.copy2(p/'bridge.py',dest/'bridge.py');shutil.copy2(p/'config.json',dest/'config.json')
with sqlite3.connect(p/statefolder/'jobs.sqlite3') as src,sqlite3.connect(dest/'jobs.sqlite3') as target:src.backup(target)
(p/'bridge.py').write_bytes(candidate.read_bytes())
subprocess.run(['docker','restart','--timeout','60',name],check=True,stdout=subprocess.DEVNULL)
(root/'panel-routing-deployed.json').write_text(json.dumps({'backup':str(backup),'ports':{'gpu1':8189,'gpu2':8188,'gpu3':8191},'legacy_worker_retained':True}))
print(json.dumps({'backup':str(backup),'new_submission_ports':[8188,8189,8191],'legacy_jobs_preserved':True}))