#!/usr/bin/env python3 """Deterministic data-only declaration for the registered NAS map access domain.""" import argparse import gzip import hashlib import io import json import re import tarfile from pathlib import Path ROOT = Path(__file__).resolve().parents[2] def build(patch, state="enabled"): if not re.fullmatch(r"[A-Za-z0-9._-]{1,96}", patch) or state not in ("enabled", "disabled"): raise ValueError("Invalid map access release") descriptor = json.loads((ROOT / "deployment/mission-core-map-access/access.json").read_text()) if descriptor != {"schemaVersion": "nodedc.mission-core-map-access.v1", "state": "enabled"}: raise ValueError("Unexpected source contract") descriptor["state"] = state members = { "manifest.env": f"id={patch}\ncomponent=mission-core-map-access\ntype=app-overlay\n".encode(), "files.txt": b"access.json\n", "payload/access.json": (json.dumps(descriptor, sort_keys=True, separators=(",", ":")) + "\n").encode(), } result = io.BytesIO() with gzip.GzipFile(fileobj=result, mode="wb", filename="", mtime=0) as compressed: with tarfile.open(fileobj=compressed, mode="w", format=tarfile.USTAR_FORMAT) as archive: for name, content in members.items(): member = tarfile.TarInfo(name); member.mode = 0o644; member.size = len(content) archive.addfile(member, io.BytesIO(content)) return result.getvalue() if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("patch") parser.add_argument("--state", choices=("enabled", "disabled"), default="enabled") args = parser.parse_args() raw = build(args.patch, args.state) target = ROOT / "infra/deploy-artifacts" / ("nodedc-" + args.patch + ".tgz") target.parent.mkdir(parents=True, exist_ok=True) with target.open("xb") as output: output.write(raw) digest = hashlib.sha256(raw).hexdigest() target.with_suffix(target.suffix + ".sha256").write_text(digest + " " + target.name + "\n") print(json.dumps({"artifact": str(target), "sha256": digest, "bytes": len(raw)}))