Stevedore (Stevedore v0.1.0)

Copy Markdown View Source

A library-first, daemonless OCI toolkit for Elixir — everything you can do to a container image except run it.

Stevedore handles OCI artifacts at rest (as bytes): fetch, inspect, copy, mirror, build, modify, analyze, sign, verify, and serve images. Running them (namespaces, mounts, cgroups) is out of scope.

Layers

The library is a pure core with optional shells:

The functions below are the high-level verbs. See docs/EXAMPLES.md for a cookbook of task-oriented recipes.

Nothing here starts a process; adding :stevedore as a dependency is weightless.

Summary

Functions

Copies an image from source to dest, preserving digests. Returns {:ok, %{digest: ...}}.

Deletes the manifest named by endpoint (a transport-prefixed string or {transport, ref}).

Fetches and parses the manifest for ref from its registry.

Lists the tags in ref's repository.

Computes the digest of a manifest from its raw bytes (or a Stevedore.Manifest.t/0).

Starts the standalone /v2 registry server (Stevedore.Server).

Copies many images from a declarative list of jobs. Each job is {source, dest} or a map with :source/:dest (and optional per-job :opts). Returns a result per job.

Functions

copy(source, dest, opts \\ [])

@spec copy(Stevedore.Copy.endpoint(), Stevedore.Copy.endpoint(), keyword()) ::
  {:ok, %{digest: Stevedore.Digest.t()}} | {:error, term()}

Copies an image from source to dest, preserving digests. Returns {:ok, %{digest: ...}}.

Endpoints are transport-prefixed strings (docker://, oci:, dir:, docker-archive:, oci-archive:, static:) or {transport, ref} tuples. Options: :all (copy a whole index), :platform/:platforms (select from an index), plus transport options like :creds.

Examples

Stevedore.copy("docker://alpine:3.20", "oci:./alpine:3.20")
Stevedore.copy("docker://alpine:3.20", "docker://ghcr.io/me/alpine:3.20", all: true)

delete(endpoint, opts \\ [])

@spec delete(
  Stevedore.Copy.endpoint(),
  keyword()
) :: :ok | {:error, term()}

Deletes the manifest named by endpoint (a transport-prefixed string or {transport, ref}).

inspect(ref, opts \\ [])

@spec inspect(
  Stevedore.Reference.t(),
  keyword()
) ::
  {:ok, Stevedore.Manifest.t() | binary() | Stevedore.Config.t()}
  | {:error, term()}

Fetches and parses the manifest for ref from its registry.

Options:

  • :raw — return the raw manifest bytes instead of a Stevedore.Manifest.t/0.
  • :config — fetch and parse the image config, returning a Stevedore.Config.t/0 (selecting the host platform, or :platform, when ref is a multi-arch index).
  • :platform — a keyword (os/architecture/variant) used with :config on an index.
  • plus any Stevedore.Registry option (:creds, :scheme, …).

list_tags(ref, opts \\ [])

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

Lists the tags in ref's repository.

manifest_digest(raw)

@spec manifest_digest(binary() | Stevedore.Manifest.t()) :: Stevedore.Digest.t()

Computes the digest of a manifest from its raw bytes (or a Stevedore.Manifest.t/0).

Examples

iex> digest = Stevedore.manifest_digest(~s({"schemaVersion":2}))
iex> digest.algorithm
:sha256

start_link(opts \\ [])

@spec start_link(keyword()) :: Supervisor.on_start()

Starts the standalone /v2 registry server (Stevedore.Server).

The only thing in Stevedore that boots a process tree, and only when called. Requires the optional :bandit/:plug deps. See Stevedore.Server for options (:store, :port, :authorize, …).

sync(jobs, opts \\ [])

@spec sync(
  [{Stevedore.Copy.endpoint(), Stevedore.Copy.endpoint()} | map()],
  keyword()
) :: {:ok, [{term(), term()}]}

Copies many images from a declarative list of jobs. Each job is {source, dest} or a map with :source/:dest (and optional per-job :opts). Returns a result per job.