Stevedore.Manifest (Stevedore v0.2.0)

Copy Markdown View Source

An image manifest or an image index (multi-arch manifest list).

The decoded json is kept alongside the raw bytes it was parsed from, because a manifest's digest is computed over those exact bytes — re-serializing JSON would change the digest. Always move manifests by their raw field.

Handles both OCI and Docker schema-2 vocabularies, and recognizes (read-only) legacy Docker schema-1 manifests.

Spec: OCI manifest and image-index.

Summary

Functions

The config descriptor of an image manifest.

The host platform as a keyword (os, architecture), mapping the BEAM's architecture string to OCI/Go naming (x86_64amd64, aarch64arm64, …).

Whether the manifest is a single image (:manifest) or a multi-arch index (:index).

The ordered layer descriptors of an image manifest.

The per-platform manifest descriptors of an index.

Parses raw manifest bytes, using content_type (the registry's Content-Type) when given and otherwise sniffing the media type from the JSON. The digest is computed over raw.

Selects the manifest descriptor from an index matching a platform.

Types

kind()

@type kind() :: :manifest | :index

t()

@type t() :: %Stevedore.Manifest{
  digest: Stevedore.Digest.t() | nil,
  json: map(),
  media_type: String.t(),
  raw: binary()
}

Functions

config(m)

@spec config(t()) ::
  {:ok, Stevedore.Descriptor.t()}
  | {:error, :not_a_manifest | {:bad_input, term()}}

The config descriptor of an image manifest.

host_platform()

@spec host_platform() :: keyword()

The host platform as a keyword (os, architecture), mapping the BEAM's architecture string to OCI/Go naming (x86_64amd64, aarch64arm64, …).

kind(manifest)

@spec kind(t()) :: kind()

Whether the manifest is a single image (:manifest) or a multi-arch index (:index).

layers(m)

@spec layers(t()) ::
  {:ok, [Stevedore.Descriptor.t()]}
  | {:error, :not_a_manifest | {:bad_input, term()}}

The ordered layer descriptors of an image manifest.

manifests(m)

@spec manifests(t()) ::
  {:ok, [Stevedore.Descriptor.t()]}
  | {:error, :not_an_index | {:bad_input, term()}}

The per-platform manifest descriptors of an index.

parse(raw, content_type \\ nil)

@spec parse(binary(), String.t() | nil) :: {:ok, t()} | {:error, {:bad_input, term()}}

Parses raw manifest bytes, using content_type (the registry's Content-Type) when given and otherwise sniffing the media type from the JSON. The digest is computed over raw.

Examples

iex> raw = ~s({"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[]})
iex> {:ok, m} = Stevedore.Manifest.parse(raw)
iex> Stevedore.Manifest.kind(m)
:index

select(m, platform \\ [])

@spec select(
  t(),
  keyword()
) ::
  {:ok, Stevedore.Descriptor.t()}
  | {:error, :no_match | :not_an_index | {:bad_input, term()}}

Selects the manifest descriptor from an index matching a platform.

platform is a keyword of :os, :architecture, and optional :variant; it defaults to the host platform. Errors with :not_an_index for a single manifest and :no_match when no entry matches.

Examples

iex> raw = ~s({"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[
...>   {"mediaType":"application/vnd.oci.image.manifest.v1+json","size":1,
...>    "digest":"sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
...>    "platform":{"os":"linux","architecture":"arm64"}}]})
iex> {:ok, m} = Stevedore.Manifest.parse(raw)
iex> {:ok, d} = Stevedore.Manifest.select(m, os: "linux", architecture: "arm64")
iex> d.platform.architecture
"arm64"