#!/usr/bin/env python3 """Apply the Catalog-owned PingCAP region-owner Seed module.""" from __future__ import annotations import argparse import json import os from pathlib import Path import sys import time from typing import Any SCRIPT_DIR = Path(__file__).resolve().parent REPO_ROOT = SCRIPT_DIR.parent RUNTIME_DIR = REPO_ROOT / "deployments" / "offline" / "runtime" if str(RUNTIME_DIR) not in sys.path: sys.path.insert(0, str(RUNTIME_DIR)) import deploy_offline_env # noqa: E402 MODULE_ID = "pingcap_region_owner_rules" SUMMARY_FILENAME = "summary.json" SUMMARY_FORMAT = "deploy-seed-script-v1" PLANNED_COUNTS = {"baseline_records": 6, "lookup_records": 6} class RegionOwnerSeedAdapterError(RuntimeError): """Raised when the scripted Seed adapter contract is violated.""" def parse_args(argv: list[str] | None = None) -> argparse.Namespace: parser = argparse.ArgumentParser(description="Apply PingCAP region-owner Seed data.") parser.add_argument("--source-root", required=True) parser.add_argument("--module-id", required=True) parser.add_argument("--invocation-id", required=True) parser.add_argument("--data-source", action="append", required=True) parser.add_argument("--selection-json", required=True) parser.add_argument("--output-dir", required=True) parser.add_argument("--dry-run", action="store_true") return parser.parse_args(argv) def _selection(raw: str) -> dict[str, Any]: try: selection = json.loads(raw) except json.JSONDecodeError as exc: raise RegionOwnerSeedAdapterError("selection must be valid JSON") from exc if selection != {}: raise RegionOwnerSeedAdapterError("PingCAP region-owner Seed does not accept a selection") return selection def _seed_file(source_root: Path, data_sources: list[str]) -> Path: if len(data_sources) != 1: raise RegionOwnerSeedAdapterError("PingCAP region-owner Seed requires one data source") expected = ( source_root / "deployments" / "offline" / "runtime" / "seeds" / "pingcap-region-owner-rules.seed.yaml" ).resolve(strict=True) actual = Path(data_sources[0]).expanduser().resolve(strict=True) if actual != expected: raise RegionOwnerSeedAdapterError("data source is not the reviewed region-owner Seed") return actual def _write_summary(path: Path, payload: dict[str, Any]) -> None: path.write_text( json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8", ) def run_adapter(args: argparse.Namespace) -> tuple[dict[str, Any], Path]: started = time.perf_counter() source_root = Path(args.source_root).expanduser().resolve(strict=True) if args.module_id != MODULE_ID: raise RegionOwnerSeedAdapterError("module id is not the region-owner Seed module") _selection(args.selection_json) seed_file = _seed_file(source_root, args.data_source) rules = deploy_offline_env.load_pingcap_region_owner_rules(seed_file) if len(rules) != PLANNED_COUNTS["baseline_records"]: raise RegionOwnerSeedAdapterError("region-owner Seed count does not match the contract") output_dir = Path(args.output_dir).expanduser().resolve() output_dir.mkdir(parents=True, exist_ok=False) applied_counts = {name: 0 for name in PLANNED_COUNTS} verification_status = "planned" if not args.dry_run: environment = dict(os.environ) backend_port = environment.get("BACKEND_PORT", "").strip() if not backend_port: raise RegionOwnerSeedAdapterError("BACKEND_PORT is required in apply mode") base_url = f"http://127.0.0.1:{backend_port}" access_token = deploy_offline_env.request_exp_local_access_token(environment) payload = deploy_offline_env.apply_pingcap_region_owner_rules_via_api( base_url, access_token, seed_file=seed_file, ) applied_counts = { "baseline_records": len(payload.get("applied_records", []) or []) + len(payload.get("hydrated_skipped_records", []) or []), "lookup_records": len(payload.get("resolved_lookups", []) or []), } require_verification = not args.invocation_id.startswith("exp.") should_verify = require_verification or deploy_offline_env.bool_env( environment, "VERIFY_PINGCAP_REGION_OWNER_RULES", True, ) if should_verify: deploy_offline_env.verify_pingcap_region_owner_rules( environment, seed_file=seed_file, require_lead_assignment_verify=False, ) verification_status = "passed" else: deploy_offline_env.log( "skipping PingCAP region owner rule verification " "(VERIFY_PINGCAP_REGION_OWNER_RULES=0)" ) verification_status = "skipped" summary = { "schema_version": 1, "format": SUMMARY_FORMAT, "module_id": MODULE_ID, "dry_run": args.dry_run, "apply_engine": "rest_api", "planned_counts": dict(PLANNED_COUNTS), "applied_counts": applied_counts, "coverage_complete": applied_counts == PLANNED_COUNTS if not args.dry_run else True, "verification_status": verification_status, "duration_ms": round((time.perf_counter() - started) * 1000), } summary_path = output_dir / SUMMARY_FILENAME _write_summary(summary_path, summary) print(json.dumps(summary, ensure_ascii=False, indent=2, sort_keys=True)) return summary, summary_path def main(argv: list[str] | None = None) -> int: args = parse_args(argv) try: run_adapter(args) except (OSError, deploy_offline_env.DeployError, RegionOwnerSeedAdapterError) as exc: print(f"PingCAP region-owner Seed adapter failed: {exc}", file=sys.stderr) return 2 return 0 if __name__ == "__main__": raise SystemExit(main())