Files
IKAR/tool/verify_pi.py
T

38 lines
2.9 KiB
Python

from pathlib import Path
import datetime, json, os, sqlite3, subprocess, urllib.request
root=Path('/mnt/data/ikar_server')
baseline=root/'rollback/services-before.jsonl'
before=[json.loads(line) for line in baseline.read_text().splitlines() if line.strip()]
current={x['Names']:x for x in map(json.loads,subprocess.check_output(['docker','ps','--format','{{json .}}'],text=True).splitlines())}
protected=[]
for previous in before:
name=previous['Names']
assert current[name]['ID']==previous['ID']
state=json.loads(subprocess.check_output(['docker','inspect','--format','{{json .State}}',name],text=True))
assert state['Running']
started=datetime.datetime.fromisoformat(state['StartedAt'].replace('Z','+00:00')).timestamp()
assert started<baseline.stat().st_mtime
health=state.get('Health',{}).get('Status','running')
assert health in ('running','healthy')
protected.append({'name':name,'containerId':current[name]['ID'],'health':health,'startedAt':state['StartedAt'],'notRestarted':True})
units={name:subprocess.check_output(['systemctl','is-active',name],text=True).strip() for name in ['ikar_server.service','ikar_server-backup.timer','caddy','tb-paper.service']}
assert all(x=='active' for x in units.values())
with sqlite3.connect(f'file:{root / "shared/data/ikar.db"}?mode=ro',uri=True) as db:
assert db.execute('pragma quick_check').fetchone()[0]=='ok'
messages=db.execute('select count(*) from Messages').fetchone()[0]
transcripts=db.execute('select count(*) from Messages where IkarTranscriptText is not null').fetchone()[0]
assert messages>0 and transcripts>0
health=json.load(urllib.request.urlopen('http://127.0.0.1:5099/health',timeout=15))
assert health['status']=='ok' and health['backup']=='ok'
asr=json.loads(subprocess.check_output(['docker','exec','ikar_server_asr','python','-c','import urllib.request; print(urllib.request.urlopen("http://127.0.0.1:8766/health").read().decode())'],text=True))
assert asr['status']=='ok'
old_names=set(subprocess.check_output(['docker','ps','-a','--format','{{.Names}}'],text=True).splitlines())
assert 'ikar-server' not in old_names and 'ikar-turn' not in old_names
assert all(not Path(p).exists() for p in ['/mnt/data/ikar-deploy','/mnt/data/ikar-data','/mnt/data/ikar-builds'])
assert os.path.ismount('/mnt/data') and (root/'shared/data/.ikar-volume').is_file()
report={'server':'ikar_server','externalDisk':'/mnt/data','release':str((root/'current').resolve()),'health':health,'asr':asr,'units':units,'protectedPrograms':protected,'oldInstallationRemoved':True,'rollback':json.loads((root/'rollback/cleanup.json').read_text()),'persistenceAfterServerReplacement':{'databaseIntegrity':'ok','storedMessages':messages,'storedTranscripts':transcripts},'timestamp':datetime.datetime.now(datetime.timezone.utc).isoformat()}
(root/'verification.json').write_text(json.dumps(report,indent=2))
print(json.dumps(report))