"""Which platform images a published reference has, for bin/sign.sh. base-os publishes an index of amd64 and arm64; netork's dev images are a single amd64 manifest, and a release joins arm64 to it under a new index. Every platform image gets its own CIS result and SBOM, so sign.sh needs each one's architecture and digest, whatever shape the reference has. """ from __future__ import annotations import json import pytest from image_tools.platforms import platforms AMD = "sha256:" + "a" * 64 ARM = "sha256:" + "b" * 64 ATT = "sha256:" + "c" * 64 SELF = "sha256:" + "d" * 64 def _index(*manifests: dict) -> str: return json.dumps( {"mediaType": "application/vnd.oci.image.index.v1+json", "manifests": list(manifests)} ) def _entry(digest: str, arch: str | None, os: str = "linux") -> dict: entry: dict = {"digest": digest, "mediaType": "application/vnd.oci.image.manifest.v1+json"} if arch: entry["platform"] = {"os": os, "architecture": arch} return entry def test_an_index_names_each_linux_platform(): raw = _index(_entry(AMD, "amd64"), _entry(ARM, "arm64")) assert platforms(raw, "{}", SELF) == [("amd64", AMD), ("arm64", ARM)] def test_buildx_attestation_manifests_are_no_platform(): raw = _index(_entry(AMD, "amd64"), _entry(ATT, "unknown", os="unknown"), _entry(ATT, None)) assert platforms(raw, "{}", SELF) == [("amd64", AMD)] def test_a_single_manifest_is_its_own_platform(): raw = json.dumps({"mediaType": "application/vnd.oci.image.manifest.v1+json", "layers": []}) image = json.dumps({"architecture": "amd64", "os": "linux"}) assert platforms(raw, image, SELF) == [("amd64", SELF)] def test_a_docker_v2_manifest_list_counts_as_an_index(): raw = json.dumps( { "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [_entry(ARM, "arm64")], } ) assert platforms(raw, "{}", SELF) == [("arm64", ARM)] @pytest.mark.parametrize( "raw", [ _index(_entry(ATT, "unknown", os="unknown")), json.dumps({"mediaType": "application/vnd.oci.image.manifest.v1+json"}), ], ids=["index without an image", "manifest without an architecture"], ) def test_nothing_to_sign_is_an_error(raw): with pytest.raises(ValueError): platforms(raw, "{}", SELF) def test_an_architecture_not_built_here_is_an_error(): """Only amd64 and arm64 are built (#934); anything else would be signed blind.""" with pytest.raises(ValueError, match="riscv64"): platforms(_index(_entry(AMD, "riscv64")), "{}", SELF)