release: freeze Nexus One AI 1.0.0-rc1
This commit is contained in:
1 parent
63acefd890
commit
4f1419ca93
152 files changed
+9445
-828
No files matched your search
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Resolve source snapshot and AMD64 OCI metadata into a Gate 2 candidate lock."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import gzip
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import tarfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def sha256_file(path: Path) -> str:
|
||||
digest = hashlib.sha256()
|
||||
with path.open("rb") as stream:
|
||||
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
|
||||
digest.update(chunk)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def deterministic_source_archive(source: Path, output: Path) -> dict:
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
excluded_parts = {".git", "__pycache__", ".pytest_cache", "node_modules", ".venv", "venv"}
|
||||
files = sorted(
|
||||
path for path in source.rglob("*")
|
||||
if path.is_file()
|
||||
and not excluded_parts.intersection(path.relative_to(source).parts)
|
||||
and path.suffix != ".iso"
|
||||
and path.name != "how-it-flows.gif"
|
||||
)
|
||||
with output.open("wb") as raw:
|
||||
with gzip.GzipFile(filename="", mode="wb", fileobj=raw, mtime=0) as compressed:
|
||||
with tarfile.open(fileobj=compressed, mode="w") as archive:
|
||||
for path in files:
|
||||
relative = path.relative_to(source)
|
||||
info = archive.gettarinfo(str(path), arcname=str(Path("aipackage") / relative))
|
||||
info.uid = info.gid = 0
|
||||
info.uname = info.gname = "root"
|
||||
info.mtime = 0
|
||||
with path.open("rb") as stream:
|
||||
archive.addfile(info, stream)
|
||||
return {
|
||||
"id": "nexus-one-ai-source-snapshot",
|
||||
"version": os.environ.get("OFFLINE_SOURCE_COMMIT", "exported-snapshot"),
|
||||
"architecture": "all",
|
||||
"source": "local-reviewed-source-snapshot",
|
||||
"target": "payload/source/aipackage.tar.gz",
|
||||
"sha256": sha256_file(output),
|
||||
"bytes": output.stat().st_size,
|
||||
"bytes_basis": "measured",
|
||||
"license": "Proprietary-Cezen-Technologies",
|
||||
"file_count": len(files),
|
||||
}
|
||||
|
||||
|
||||
def manifest_records(reference: str) -> list[dict]:
|
||||
result = subprocess.run(
|
||||
["docker", "manifest", "inspect", "--verbose", reference],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
parsed = json.loads(result.stdout)
|
||||
return parsed if isinstance(parsed, list) else [parsed]
|
||||
|
||||
|
||||
def resolve_container(item: dict) -> dict:
|
||||
records = manifest_records(item["source"])
|
||||
matches = [
|
||||
record for record in records
|
||||
if record.get("Descriptor", {}).get("platform", {}).get("os") == "linux"
|
||||
and record.get("Descriptor", {}).get("platform", {}).get("architecture") == "amd64"
|
||||
]
|
||||
if len(matches) != 1:
|
||||
raise RuntimeError(f"{item['source']}: expected one linux/amd64 manifest, found {len(matches)}")
|
||||
record = matches[0]
|
||||
descriptor = record["Descriptor"]
|
||||
digest = descriptor["digest"]
|
||||
manifest = record.get("SchemaV2Manifest") or {}
|
||||
content = [manifest.get("config", {})] + list(manifest.get("layers", []))
|
||||
declared_bytes = sum(entry.get("size", 0) for entry in content)
|
||||
return {
|
||||
"id": item["id"],
|
||||
"version": item["version"],
|
||||
"architecture": "amd64",
|
||||
"source": f"{item['source'].split(':')[0]}@{digest}",
|
||||
"resolved_from": item["source"],
|
||||
"target": f"payload/containers/{item['id']}.oci.tar",
|
||||
"sha256": digest.removeprefix("sha256:"),
|
||||
"bytes": declared_bytes,
|
||||
"bytes_basis": "registry-declared-content",
|
||||
"license": item["license"],
|
||||
"manifest_bytes": descriptor.get("size"),
|
||||
"config": manifest.get("config"),
|
||||
"layers": manifest.get("layers", []),
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--candidate", type=Path, required=True)
|
||||
parser.add_argument("--source-root", type=Path, required=True)
|
||||
parser.add_argument("--container-sources", type=Path, required=True)
|
||||
parser.add_argument("--staging", type=Path, required=True)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
lock = json.loads(args.candidate.read_text(encoding="utf-8"))
|
||||
source_object = deterministic_source_archive(
|
||||
args.source_root.resolve(), args.staging / "source" / "aipackage.tar.gz"
|
||||
)
|
||||
declarations = json.loads(args.container_sources.read_text(encoding="utf-8"))
|
||||
containers = [resolve_container(item) for item in declarations]
|
||||
lock["objects"]["source"] = [source_object]
|
||||
lock["objects"]["containers"] = containers
|
||||
lock["unresolved"] = [
|
||||
item for item in lock["unresolved"]
|
||||
if item not in {"source snapshot archive bytes and digest", "OCI image manifests and layers by digest"}
|
||||
]
|
||||
lock["unresolved"].extend([
|
||||
"OCI archive bytes and SHA-256 after digest-pinned acquisition",
|
||||
"license review for container entries marked REVIEW-REQUIRED",
|
||||
"replace mutable container source tags with approved release tags before final review"
|
||||
])
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(json.dumps(lock, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
||||
print(f"Wrote Gate 2 candidate lock: {args.output}")
|
||||
print(f"Source files: {source_object['file_count']}; source bytes: {source_object['bytes']}")
|
||||
print(f"AMD64 OCI manifests resolved: {len(containers)}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user