Stevedore.Registry (Stevedore v0.1.0)

Copy Markdown View Source

A daemonless client for the OCI/Docker Distribution v2 API (the docker:// transport).

Fetches and pushes manifests and blobs: it performs the bearer-token handshake (a 401 challenge exchanged at the token endpoint, requesting pull/push scope as the server asks), negotiates manifest media types via Accept, honors Docker-Content-Digest, and verifies every blob against its digest. Manifest bytes move raw so their digest stays stable.

This module requires the optional :req dependency; calling it without req raises a clear error. The functions return the shapes a runtime (e.g. Tank) consumes directly.

Spec: OCI distribution-spec (pull, push, blob uploads, cross-repo mount).

Summary

Functions

Fetches a blob (config or layer) for ref by digest, verifying the bytes against it.

Deletes a manifest by tag or digest.

Whether the registry already has the blob for digest (a HEAD on the blob).

Lists all tags for ref's repository, following Link pagination.

Fetches a manifest (or index) for ref, by its tag or digest.

Attempts a cross-repo blob mount (POST ?mount=&from=). Returns :not_mounted (rather than an error) when the registry declines, so the caller can fall back to a normal upload.

Uploads a blob via a monolithic upload session (POST an upload, then PUT the bytes with ?digest=).

Pushes raw manifest bytes, tagged or by digest (ref is a tag, a Stevedore.Digest.t/0, or nil to use the computed digest). Returns the manifest digest.

Lists referrers to digest via the OCI 1.1 Referrers API, falling back to the tag-schema (<algo>-<hex>) referrers index for registries without the API. Returns the referrers index as raw bytes + decoded JSON.

Functions

blob(ref, digest, opts \\ [])

@spec blob(Stevedore.Reference.t(), Stevedore.Digest.t(), keyword()) ::
  {:ok, binary()} | {:error, Stevedore.Registry.Error.t()}

Fetches a blob (config or layer) for ref by digest, verifying the bytes against it.

Survives CDN redirects without leaking the registry token: req strips the Authorization header on any cross-host redirect.

delete_manifest(ref, target, opts \\ [])

@spec delete_manifest(Stevedore.Reference.t(), String.t(), keyword()) ::
  :ok | {:error, Stevedore.Registry.Error.t()}

Deletes a manifest by tag or digest.

has_blob?(ref, digest, opts \\ [])

Whether the registry already has the blob for digest (a HEAD on the blob).

list_tags(ref, opts \\ [])

@spec list_tags(
  Stevedore.Reference.t(),
  keyword()
) :: {:ok, [String.t()]} | {:error, Stevedore.Registry.Error.t()}

Lists all tags for ref's repository, following Link pagination.

manifest(ref, opts \\ [])

@spec manifest(
  Stevedore.Reference.t(),
  keyword()
) ::
  {:ok,
   %{
     media_type: String.t(),
     digest: Stevedore.Digest.t(),
     raw: binary(),
     json: map()
   }}
  | {:error, Stevedore.Registry.Error.t()}

Fetches a manifest (or index) for ref, by its tag or digest.

Returns the raw bytes, decoded JSON, resolved media type, and digest. When the registry sends Docker-Content-Digest, the bytes are verified against it.

Options: :creds (Stevedore.Auth.creds/0, default :anonymous), :scheme (default "https"), :max_retries, and :req_options (a keyword merged into the Req request, e.g. an :adapter for tests).

mount_blob(ref, digest, from_repo, opts \\ [])

@spec mount_blob(Stevedore.Reference.t(), Stevedore.Digest.t(), String.t(), keyword()) ::
  :ok | :not_mounted

Attempts a cross-repo blob mount (POST ?mount=&from=). Returns :not_mounted (rather than an error) when the registry declines, so the caller can fall back to a normal upload.

put_blob(ref, digest, data, opts \\ [])

@spec put_blob(Stevedore.Reference.t(), Stevedore.Digest.t(), iodata(), keyword()) ::
  :ok | {:error, Stevedore.Registry.Error.t()}

Uploads a blob via a monolithic upload session (POST an upload, then PUT the bytes with ?digest=).

put_manifest(ref, raw, media_type, opts \\ [])

@spec put_manifest(Stevedore.Reference.t(), binary(), String.t(), keyword()) ::
  {:ok, Stevedore.Digest.t()} | {:error, Stevedore.Registry.Error.t()}

Pushes raw manifest bytes, tagged or by digest (ref is a tag, a Stevedore.Digest.t/0, or nil to use the computed digest). Returns the manifest digest.

referrers(ref, digest, opts \\ [])

@spec referrers(Stevedore.Reference.t(), Stevedore.Digest.t(), keyword()) ::
  {:ok, %{raw: binary(), json: map()}} | {:error, Stevedore.Registry.Error.t()}

Lists referrers to digest via the OCI 1.1 Referrers API, falling back to the tag-schema (<algo>-<hex>) referrers index for registries without the API. Returns the referrers index as raw bytes + decoded JSON.