from ops import *
import sys
BASE.mkdir(mode=0o700,exist_ok=True);PRIVATE.mkdir(mode=0o700)
sys.path.insert(0,'/workspace/contextra/runtime/deploy-tools/provider-20260927-r01')
from deployment_kit.site_guard import verify
site=verify('/workspace/contextra/runtime/state/site.json')
active=json.loads(Path('/workspace/contextra/runtime/state/active.json').read_text())
tx=Path(site['install_root'])/'state/transactions'/active['transaction']
doc=json.loads((tx/'compose.json').read_text());save('compose-before.json',doc,True)
save('site-before.json',site,True);save('active-before.json',active,True)
assert inspect(CONTAINER)['Image']==doc['services']['analytics']['image']
for name in ('site','runtime'):
    source=Path(site['storage'][name]['physical'])
    cmd(['cp','-a',str(source),str(PRIVATE/name)],timeout=60)
rows=api('/api/v1/streams')['streams'];save('baseline.json',dict(channels=[{k:r.get(k) for k in ('stream_id','state','run_id','run_generation','cleanup_pending')} for r in rows],
    ledger=ledger(),image=inspect(CONTAINER)['Image'],containers=[dict(name=c['Name'],id=c['Id'],image=c['Image'],started=c['State']['StartedAt'],state=c['State']['Status']) for c in json.loads(cmd(['docker','inspect',*cmd(['docker','ps','-aq']).split()]))]))
save('training-before.json',training())
save('hardware.json',dict(logical_cpus=os.cpu_count(),lscpu=json.loads(cmd(['lscpu','-J'])),kernel=cmd(['uname','-r']),
    gpu=cmd(['nvidia-smi','--query-gpu=name,driver_version,memory.total','--format=csv']),disk=cmd(['df','-B1','/','/backup','/training']),
    quota=inspect(CONTAINER)['HostConfig'].get('NanoCpus'),cpuset=inspect(CONTAINER)['HostConfig'].get('CpusetCpus')))
assert shutil.disk_usage('/').free>15*1024**3
# Existing channels may be stopped by this approved maintenance, never auto-restarted.
cmd(['docker','stop','--time','10','contextra-icerti-ai-gateway-1'],20)
targets=[r['stream_id'] for r in rows if r['state']!='stopped' or r.get('cleanup_pending')]
for sid in targets:request('/api/v1/streams/'+sid+'/stop',{})
until=time.monotonic()+120
while time.monotonic()<until:
    rows=api('/api/v1/streams')['streams']
    if all(r['state']=='stopped' and not r.get('cleanup_pending') for r in rows):break
    time.sleep(1)
else:raise RuntimeError('INITIAL_REAP_FAILED')
save('prepared.json',dict(stopped=len(rows),gateway='stopped',models_reused=True,transaction=str(tx)))
print(json.dumps(dict(prepared=True,stopped=len(rows),logical_cpus=os.cpu_count())),flush=True)
