70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import hashlib
|
|
import io
|
|
import json
|
|
import subprocess
|
|
import tarfile
|
|
from pathlib import Path
|
|
|
|
from aios_release_controller.manifest import validate_source_manifest
|
|
|
|
|
|
def sha256(path: Path) -> str:
|
|
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
|
|
|
|
def archive_names(path: Path) -> set[str]:
|
|
raw = subprocess.check_output(["zstd", "-dc", str(path)])
|
|
with tarfile.open(fileobj=io.BytesIO(raw), mode="r:") as archive:
|
|
return {member.name for member in archive.getmembers()}
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--repo-root", type=Path, required=True)
|
|
parser.add_argument("--target-oid", required=True)
|
|
parser.add_argument("--base-oid", required=True)
|
|
parser.add_argument("--artifact", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
repo = args.repo_root
|
|
head = subprocess.check_output(["git", "-C", str(repo), "rev-parse", "HEAD"], text=True).strip()
|
|
if head != args.target_oid:
|
|
raise SystemExit("target_oid_does_not_match_HEAD")
|
|
source = validate_source_manifest(repo / "release-manifests" / "V2R1C6.json", args.base_oid)
|
|
receipt = json.loads(next(args.artifact.parent.glob("*.manifest.json")).read_text(encoding="utf-8"))
|
|
if receipt["target_oid"] != args.target_oid or receipt["base_oid"] != args.base_oid:
|
|
raise SystemExit("receipt_binding_mismatch")
|
|
if receipt["artifact_sha256"] != sha256(args.artifact) or receipt["artifact_size"] != args.artifact.stat().st_size:
|
|
raise SystemExit("receipt_artifact_mismatch")
|
|
required = {
|
|
"payload/VERSION",
|
|
"payload/active-runtime/app/v2r1c6_privacy_tools.py",
|
|
"payload/deploy/aios-v2/systemd/aios-v2r1c6-production.service",
|
|
"payload/release-manifests/V2R1C6.json",
|
|
"payload/services/aios-release-controller/aios_release_controller/manifest.py",
|
|
"payload/BUILD-METADATA.json",
|
|
"payload/ARTIFACT-MANIFEST.json",
|
|
"payload/ROLLBACK-METADATA.json",
|
|
}
|
|
names = archive_names(args.artifact)
|
|
missing = sorted(required - names)
|
|
if missing:
|
|
raise SystemExit("artifact_members_missing:" + ",".join(missing))
|
|
print(json.dumps({
|
|
"status": "PASS",
|
|
"version": source["version"],
|
|
"target_oid": args.target_oid,
|
|
"base_oid": args.base_oid,
|
|
"artifact_sha256": sha256(args.artifact),
|
|
"production_deployed": False,
|
|
"tag_created": False,
|
|
"baseline_changed": False,
|
|
}, sort_keys=True))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|