#!/usr/bin/env python3 """Create a one-user SQLite handoff without exposing the legacy database to HLCC.""" from __future__ import annotations import argparse import json import os import pathlib import pwd import sqlite3 import tempfile OWNER_NAME = "bingshuo" def prepare(source: pathlib.Path, destination: pathlib.Path, owner: str) -> None: if not source.is_file(): raise RuntimeError("legacy database unavailable") destination.parent.mkdir(parents=True, exist_ok=True) legacy = sqlite3.connect(f"file:{source}?mode=ro", uri=True, timeout=15) try: schema = legacy.execute( "select sql from sqlite_master where type = 'table' and name = 'user'" ).fetchone() row = legacy.execute( "select * from user where lower_name = ?", (OWNER_NAME,), ).fetchall() if not schema or not schema[0] or len(row) != 1: raise RuntimeError("legacy owner identity mismatch") file_descriptor, temporary_name = tempfile.mkstemp( prefix=".owner-identity-source.", suffix=".db", dir=destination.parent, ) os.close(file_descriptor) temporary = pathlib.Path(temporary_name) try: handoff = sqlite3.connect(temporary) try: handoff.execute(schema[0]) columns = [item[1] for item in legacy.execute("pragma table_info(user)")] placeholders = ",".join("?" for _column in columns) column_sql = ",".join(f'"{column}"' for column in columns) handoff.execute( f"insert into user ({column_sql}) values ({placeholders})", row[0], ) handoff.commit() finally: handoff.close() temporary.chmod(0o600) identity = pwd.getpwnam(owner) os.chown(temporary, identity.pw_uid, identity.pw_gid) temporary.replace(destination) finally: temporary.unlink(missing_ok=True) finally: legacy.close() receipt = destination.with_suffix(".receipt.json") receipt.write_text( json.dumps( { "schema": "guanghu.hlcc-owner-identity-handoff/v1", "owner": OWNER_NAME, "rows": 1, "contains_repository_data": False, "contains_access_tokens": False, "result": "PREPARED", }, ensure_ascii=False, indent=2, ) + "\n", encoding="utf-8", ) identity = pwd.getpwnam(owner) os.chown(receipt, identity.pw_uid, identity.pw_gid) receipt.chmod(0o600) def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--source", required=True, type=pathlib.Path) parser.add_argument("--destination", required=True, type=pathlib.Path) parser.add_argument("--owner", default="guanghu") arguments = parser.parse_args() prepare(arguments.source, arguments.destination, arguments.owner) print("OWNER_IDENTITY_SOURCE_PREPARED rows=1 tokens=0 repositories=0") if __name__ == "__main__": main()