All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m12s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 0s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 16s
CD Pipeline / build-and-deploy (push) Successful in 4m13s
CD Pipeline / post-deploy-checks (push) Successful in 1m55s
104 lines
3.4 KiB
Python
104 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Build a no-secret Windows99 VMX source repair check-mode package.
|
|
|
|
This package turns the reboot SLO scorecard's Windows99 VMX blockers into a
|
|
bounded source-repair plan. It never starts VMs, edits Windows, restarts
|
|
services, reads secrets, or applies registry/task changes.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import sys
|
|
import urllib.request
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
_REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
_API_ROOT = _REPO_ROOT / "apps" / "api"
|
|
if str(_API_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(_API_ROOT))
|
|
|
|
# This CLI is a no-DB, check-mode reboot recovery tool. The API package import
|
|
# still validates settings, so provide a harmless placeholder when running
|
|
# outside the service container.
|
|
os.environ.setdefault("DATABASE_URL", "postgresql+asyncpg://test:test@localhost/test")
|
|
|
|
from src.services.reboot_auto_recovery_slo_scorecard import ( # noqa: E402
|
|
_build_windows99_vmx_source_repair_package,
|
|
_taipei_now_iso,
|
|
)
|
|
|
|
DEFAULT_SCORECARD_URL = (
|
|
"https://awoooi.wooo.work/api/v1/agents/reboot-auto-recovery-slo-scorecard"
|
|
)
|
|
|
|
|
|
def _dict(value: Any) -> dict[str, Any]:
|
|
return value if isinstance(value, dict) else {}
|
|
|
|
|
|
def _load_json_file(path: Path) -> dict[str, Any]:
|
|
with path.open(encoding="utf-8") as handle:
|
|
payload = json.load(handle)
|
|
return payload if isinstance(payload, dict) else {}
|
|
|
|
|
|
def _fetch_json_url(url: str, timeout_seconds: float) -> dict[str, Any]:
|
|
request = urllib.request.Request(
|
|
url,
|
|
headers={"User-Agent": "awoooi-windows99-vmx-package/1.0"},
|
|
)
|
|
with urllib.request.urlopen(request, timeout=timeout_seconds) as response:
|
|
payload = json.load(response)
|
|
return payload if isinstance(payload, dict) else {}
|
|
|
|
|
|
def build_package(scorecard: dict[str, Any], *, generated_at: str | None = None) -> dict[str, Any]:
|
|
existing_package = _dict(scorecard.get("windows99_vmx_source_repair_package"))
|
|
if existing_package and generated_at is None:
|
|
return existing_package
|
|
|
|
return _build_windows99_vmx_source_repair_package(
|
|
_dict(scorecard.get("windows99_vmware_autostart")),
|
|
generated_at=generated_at
|
|
or str(scorecard.get("generated_at") or _taipei_now_iso()),
|
|
)
|
|
|
|
|
|
def parse_args(argv: list[str]) -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(
|
|
description=(
|
|
"Build a no-secret Windows99 VMX source repair check-mode package "
|
|
"from a reboot SLO scorecard."
|
|
)
|
|
)
|
|
parser.add_argument("--scorecard-file", type=Path)
|
|
parser.add_argument("--scorecard-url", default=DEFAULT_SCORECARD_URL)
|
|
parser.add_argument("--timeout-seconds", type=float, default=20.0)
|
|
parser.add_argument("--generated-at")
|
|
parser.add_argument("--output", type=Path)
|
|
return parser.parse_args(argv)
|
|
|
|
|
|
def main(argv: list[str]) -> int:
|
|
args = parse_args(argv)
|
|
scorecard = (
|
|
_load_json_file(args.scorecard_file)
|
|
if args.scorecard_file
|
|
else _fetch_json_url(args.scorecard_url, args.timeout_seconds)
|
|
)
|
|
package = build_package(scorecard, generated_at=args.generated_at)
|
|
text = json.dumps(package, ensure_ascii=False, indent=2) + "\n"
|
|
if args.output:
|
|
args.output.write_text(text, encoding="utf-8")
|
|
else:
|
|
sys.stdout.write(text)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main(sys.argv[1:]))
|