from pathlib import Path import hashlib import json import sqlite3 import subprocess import sys import tarfile import tempfile import urllib.request root = Path('/mnt/data/ikar_server') release = root / 'releases/20261006-1.0.1' if (root / 'current').resolve() != release: raise RuntimeError('Unexpected current release') expected = { '/ikar_server_asr': 'f7fdc9848d8b', '/ikar_server_turn': '10c1e2dd2d58', '/qsfera-cloud-server': '52625bbe300a', '/src-photo-recognition-1': 'ef2290a383e2', '/argus': '5247530887e0', '/gitea': 'a5452ab93785', } identifiers = subprocess.check_output(['docker', 'ps', '-q'], text=True).split() services = json.loads(subprocess.check_output(['docker', 'inspect', *identifiers], text=True)) protected = {item['Name']: {'id': item['Id'], 'startedAt': item['State']['StartedAt']} for item in services if item['Name'] in expected} if set(protected) != set(expected) or not all(protected[name]['id'].startswith(prefix) for name, prefix in expected.items()): raise RuntimeError('Protected containers changed') binary_sha = hashlib.sha256((release / 'publish/Ikar.Server.dll').read_bytes()).hexdigest() if binary_sha != sys.argv[1]: raise RuntimeError('Deployed server differs from published build') backup = root / 'backups/ikar-20261006T173034Z.tar.gz' with tempfile.TemporaryDirectory() as temp: target = Path(temp) / 'ikar.db' with tarfile.open(backup) as archive: target.write_bytes(archive.extractfile('data/ikar.db').read()) with sqlite3.connect(target) as connection: if connection.execute('PRAGMA quick_check').fetchall() != [('ok',)]: raise RuntimeError('Backup integrity failed') with urllib.request.urlopen('http://127.0.0.1:5099/health') as response: health = json.load(response) if health['status'] != 'ok': raise RuntimeError('API health failed') report = { 'passed': True, 'release': str(release), 'previousRelease': str(root / 'releases/20261006'), 'backup': str(backup), 'backupIntegrity': 'ok', 'serverSha256': binary_sha, 'health': health, 'protectedServicesUnchanged': True, 'protectedServices': protected, } (root / 'deployment-1.0.1.json').write_text(json.dumps(report, indent=2)) print(json.dumps(report))