Skip to content

Add OCI registry metadata support #61

Description

@andrew

Version: git-pkgs/registries current main at 418e68a.

Trying to create an OCI registry client after importing all registries currently returns unknown ecosystem: oci:

_, err := registries.New("oci", "https://registry.example.com/acme/widget", nil)

Add an oci registry for read-only metadata from registries implementing the OCI Distribution Specification. The configured URL should identify the physical repository, including its registry host and repository path. There is no default registry. This matches the oci PURL definition, where repository_url identifies the location, the version is the manifest digest, and a tag is a qualifier rather than the version.

Implement these requests:

  • List tags with GET /v2/<name>/tags/list, following Link: rel="next" pagination as specified by the distribution API.
  • Fetch each manifest by tag or digest with GET /v2/<name>/manifests/<tag-or-digest>. Send Accept values for OCI image manifests and indexes plus Docker schema 2 manifests and manifest lists. Check the response Content-Type, verify Docker-Content-Digest against the returned bytes, and verify the requested digest when the request used one. If an older registry omits the digest header, compute the manifest's SHA-256 digest from its bytes. These rules are set out in the manifest pull section.
  • Handle a 401 Bearer challenge by reading WWW-Authenticate, requesting a token from its realm with the supplied service and pull scope, then retrying the original request. The Distribution project documents that challenge and token exchange. Preserve caller-provided credentials for private token services without placing secrets in returned metadata.

The shared client currently fixes Accept to application/json and returns only response bytes from GetBody. Add a retry-aware request method, or an equivalent internal API, that accepts request headers and returns status, headers, and body. Keep the existing size limit, retry, rate-limit, safe HTTP, and caller-supplied transport behavior.

Use the digest as Version.Number, deduplicate tags that resolve to the same digest, and retain all tag aliases in Version.Metadata. Do not select a lexical tag as Package.LatestVersion; tags are mutable and the API supplies no ordering that makes one latest. Map standard OCI annotations such as description, source, URL, created time, version, licenses, and authors where they fit the shared types.

Preserve the manifest or index media type, artifact type, annotations, subject, config descriptor, layer descriptors, and platform descriptors in metadata. The OCI structs show the required manifest fields, index fields, and descriptor fields. This must retain ordinary container image descriptors and non-image artifacts. In particular, include Helm's config, chart layer, and provenance media types; Helm has a complete chart manifest fixture.

FetchDependencies should return no package dependencies because OCI descriptors are content links, not package dependency declarations. Keep those descriptors in metadata. FetchMaintainers may map a non-empty authors annotation as an unstructured name, without trying to split arbitrary contact text.

Follow the new ecosystem layout, register the package from all/all.go, and add it to the root ecosystem tests.

Tests should cover a public anonymous registry, Bearer authentication, caller credentials, paginated tags, two tags for one digest, manifest and index responses, Docker media types, platform descriptors, a Helm chart artifact, digest mismatches, content-type mismatches, missing headers from older registries, missing configured URL, and not-found repositories, tags, and digests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions