import json,pathlib,subprocess,datetime,os,hashlib,shutil def run(*a):return subprocess.check_output(a,text=True,stderr=subprocess.STDOUT) root=pathlib.Path('/home/ps/huobao-gpu-selection');root.mkdir(exist_ok=True,mode=0o700);root.chmod(0o700) state=root/'state.json' if state.exists(): raise SystemExit('Preparation already recorded; inspect state instead of repeating') backup=root/('backup-'+datetime.datetime.now().strftime('%Y%m%d-%H%M%S'));backup.mkdir(mode=0o700) for name in ('comfyui','h3-caption-gpu3-canary-8a5f','canvas-h3-prompt-normalizer-healthy-20261026','huobao-vdn-normalizer','huobao-model-bridge','huobao-vdn-bridge'): (backup/(name+'.inspect.json')).write_text(run('docker','inspect',name)) for name in ('canvas-h3-prompt-normalizer-healthy-20261026','huobao-vdn-normalizer'): (backup/(name+'.app.py')).write_text(run('docker','exec',name,'cat','/app/app.py')) d=json.loads((backup/'canvas-h3-prompt-normalizer-healthy-20261026.inspect.json').read_text())[0] env=dict(x.split('=',1) for x in d['Config']['Env']);fn=env['COMFY_ADMISSION_FILE'] m=next(m for m in d['Mounts'] if fn.startswith(m['Destination']+'/')) admission=pathlib.Path(m['Source'])/fn[len(m['Destination'])+1:] raw=admission.read_bytes();value=json.loads(raw) assert value=={'schema':1,'admit':['default','gpu3']},'Unexpected admission; no change made' (backup/'admission.json').write_bytes(raw) data={'backup':str(backup),'admission':str(admission),'original_admission_sha256':hashlib.sha256(raw).hexdigest(),'phase':'prepared'} state.write_text(json.dumps(data,indent=2));state.chmod(0o600) tmp=admission.with_name('admission.huobao-tmp.json');tmp.write_text(json.dumps({'schema':1,'admit':['default']}));tmp.chmod(admission.stat().st_mode & 0o777);os.replace(tmp,admission) data['phase']='gpu3-draining';state.write_text(json.dumps(data,indent=2)) print('Backed up service definitions and temporarily stopped new GPU3 admission; existing jobs continue.',backup)