ocibuild_registry (ocibuild v0.10.4)

View Source

OCI Distribution registry client.

Implements the OCI Distribution Specification for pulling and pushing container images to registries like Docker Hub, GHCR, etc.

See: https://github.com/opencontainers/distribution-spec

Summary

Functions

Check if a blob exists in the registry.

Check if an error is retriable (transient network/server issues).

Pull a blob from a registry.

Pull a blob from a registry with authentication.

Pull a blob from a registry with options including progress callback.

Pull a manifest and config from a registry.

Pull a manifest and config from a registry with authentication.

Pull a manifest and config from a registry with options.

Pull manifests and configs for multiple platforms.

Push an image to a registry. Returns the manifest digest on success.

Push an image to a registry with options (supports chunked uploads). Returns the manifest digest on success.

Push a pre-built image from raw blobs to a registry.

Push multiple pre-built images as a multi-platform image.

Push multiple platform-specific images as a single multi-platform image.

Push a cosign-compatible signature as a referrer to an image manifest.

Stop the fallback httpc to allow clean VM exit.

Tag an existing manifest with a new tag.

Execute a function with retry logic for transient failures.

Types

operation_scope()

-type operation_scope() :: pull | push.

progress_callback()

-type progress_callback() :: fun((progress_info()) -> ok).

progress_info()

-type progress_info() ::
          #{phase := progress_phase(),
            layer_index => non_neg_integer(),
            total_layers => non_neg_integer(),
            bytes_received := non_neg_integer(),
            bytes_sent => non_neg_integer(),
            total_bytes := non_neg_integer() | unknown}.

progress_phase()

-type progress_phase() :: manifest | config | layer | uploading.

pull_opts()

-type pull_opts() ::
          #{progress => progress_callback(),
            auth => map(),
            size => non_neg_integer(),
            layer_index => non_neg_integer(),
            total_layers => non_neg_integer()}.

push_blobs_input()

-type push_blobs_input() ::
          #{manifest := binary(),
            config := binary(),
            layers :=
                [#{digest := binary(),
                   size := non_neg_integer(),
                   get_data := fun(() -> {ok, binary()} | {error, term()})}]}.

push_opts()

-type push_opts() ::
          #{chunk_size => pos_integer(),
            progress => progress_callback(),
            layer_index => non_neg_integer(),
            total_layers => non_neg_integer()}.

upload_session()

-type upload_session() :: #{upload_url := string(), bytes_uploaded := non_neg_integer()}.

Functions

check_blob_exists(Registry, Repo, Digest, Auth)

-spec check_blob_exists(binary(), binary(), binary(), map()) -> boolean().

Check if a blob exists in the registry.

digest_to_signature_tag(Digest)

-spec digest_to_signature_tag(binary()) -> binary().

discover_auth(Registry, Repo, Auth)

-spec discover_auth(binary(), binary(), map()) ->
                       {ok, binary() | {basic, binary()} | none} | {error, term()}.

format_content_range(Start, End)

-spec format_content_range(non_neg_integer(), non_neg_integer()) -> string().

get_target_platform()

-spec get_target_platform() -> {binary(), binary()}.

http_get(Url, Headers)

-spec http_get(string(), [{string(), string()}]) -> {ok, binary()} | {error, term()}.

http_get_for_token(Url, Headers)

-spec http_get_for_token(string(), [{string(), string()}]) -> {ok, binary()} | {error, term()}.

http_get_with_content_type(Url, Headers)

-spec http_get_with_content_type(string(), [{string(), string()}]) ->
                                    {ok, binary(), string()} | {error, term()}.

http_head(Url, Headers)

-spec http_head(string(), [{string(), string()}]) -> {ok, [{string(), string()}]} | {error, term()}.

http_patch(Url, Headers, Body, Timeout)

-spec http_patch(string(), [{string(), string()}], binary(), pos_integer()) ->
                    {ok, integer(), [{string(), string()}]} | {error, term()}.

http_post(Url, Headers, Body)

-spec http_post(string(), [{string(), string()}], binary()) ->
                   {ok, binary(), [{string(), string()}]} | {error, term()}.

http_put(Url, Headers, Body)

-spec http_put(string(), [{string(), string()}], binary()) -> {ok, binary()} | {error, term()}.

http_put(Url, Headers, Body, Timeout)

-spec http_put(string(), [{string(), string()}], binary(), pos_integer()) ->
                  {ok, binary()} | {error, term()}.

is_retriable_error/1

-spec is_retriable_error(term()) -> boolean().

Check if an error is retriable (transient network/server issues).

Returns true for connection failures, timeouts, and server errors (5xx).

parse_range_header(Value)

-spec parse_range_header(string()) -> {ok, non_neg_integer()} | error.

pull_blob(Registry, Repo, Digest)

-spec pull_blob(binary(), binary(), binary()) -> {ok, binary()} | {error, term()}.

Pull a blob from a registry.

pull_blob(Registry, Repo, Digest, Auth)

-spec pull_blob(binary(), binary(), binary(), map()) -> {ok, binary()} | {error, term()}.

Pull a blob from a registry with authentication.

pull_blob(Registry, Repo, Digest, Auth, Opts)

-spec pull_blob(binary(), binary(), binary(), map(), pull_opts()) -> {ok, binary()} | {error, term()}.

Pull a blob from a registry with options including progress callback.

pull_manifest(Registry, Repo, Ref)

-spec pull_manifest(binary(), binary(), binary()) ->
                       {ok, Manifest :: map(), Config :: map()} | {error, term()}.

Pull a manifest and config from a registry.

pull_manifest(Registry, Repo, Ref, Auth)

-spec pull_manifest(binary(), binary(), binary(), map()) ->
                       {ok, Manifest :: map(), Config :: map()} | {error, term()}.

Pull a manifest and config from a registry with authentication.

pull_manifest(Registry, Repo, Ref, Auth, Opts)

-spec pull_manifest(binary(), binary(), binary(), map(), pull_opts()) ->
                       {ok, Manifest :: map(), Config :: map()} | {error, term()}.

Pull a manifest and config from a registry with options.

pull_manifests_for_platforms(Registry, Repo, Ref, Auth, Platforms)

-spec pull_manifests_for_platforms(binary(), binary(), binary(), map(), [ocibuild:platform()]) ->
                                      {ok, [{ocibuild:platform(), map(), map()}]} | {error, term()}.

Pull manifests and configs for multiple platforms.

Given a list of platforms, this function pulls the manifest and config for each platform from the base image. Used for multi-platform builds.

Returns a list of {Platform, Manifest, Config} tuples, one for each requested platform.

push(Image, Registry, Repo, Tag, Auth)

-spec push(ocibuild:image(), binary(), binary(), binary(), map()) ->
              {ok, Digest :: binary()} | {error, term()}.

Push an image to a registry. Returns the manifest digest on success.

push(Image, Registry, Repo, Tag, Auth, Opts)

-spec push(ocibuild:image(), binary(), binary(), binary(), map(), push_opts()) ->
              {ok, Digest :: binary()} | {error, term()}.

Push an image to a registry with options (supports chunked uploads). Returns the manifest digest on success.

push_blob(BaseUrl, Repo, Digest, Data, Token)

-spec push_blob(string(), binary(), binary(), binary(), binary()) -> ok | {error, term()}.

push_blob(BaseUrl, Repo, Digest, Data, Token, Opts)

-spec push_blob(string(), binary(), binary(), binary(), binary(), push_opts()) -> ok | {error, term()}.

push_blobs(Registry, Repo, Tag, Blobs, Auth)

-spec push_blobs(binary(), binary(), binary(), push_blobs_input(), map()) ->
                    {ok, Digest :: binary()} | {error, term()}.

Push a pre-built image from raw blobs to a registry.

This function is used to push images loaded from tarballs without rebuilding. It reuses all existing push infrastructure (authentication, progress callbacks, chunked uploads, etc.).

Blobs contains:

  • manifest: Raw manifest JSON
  • config: Raw config JSON
  • layers: List of layer info with lazy get_data functions

Returns the manifest digest on success.

push_blobs(Registry, Repo, Tag, Blobs, Auth, Opts)

-spec push_blobs(binary(), binary(), binary(), push_blobs_input(), map(), push_opts()) ->
                    {ok, Digest :: binary()} | {error, term()}.

push_blobs_multi(Registry, Repo, Tag, BlobsList, Auth)

-spec push_blobs_multi(binary(), binary(), binary(), [push_blobs_input()], map()) ->
                          {ok, Digest :: binary()} | {error, term()}.

Push multiple pre-built images as a multi-platform image.

Each image in the list should have platform information. Creates an image index referencing all platform manifests.

push_blobs_multi/6

-spec push_blobs_multi(binary(), binary(), binary(), [push_blobs_input()], map(), push_opts()) ->
                          {ok, Digest :: binary()} | {error, term()}.

push_multi/6

-spec push_multi([ocibuild:image()], binary(), binary(), binary(), map(), push_opts()) ->
                    {ok, Digest :: binary()} | {error, term()}.

Push multiple platform-specific images as a single multi-platform image.

This function:

  1. Pushes all layers, configs, and manifests for each platform
  2. Creates an OCI image index referencing all platform manifests
  3. Tags the index so the registry serves the correct platform to clients

Each image in the list must have a platform field set.

Returns the digest of the image index on success.

push_referrer(ArtifactData, ArtifactType, Registry, Repo, SubjectDigest, SubjectSize, Auth)

-spec push_referrer(ArtifactData :: binary(),
                    ArtifactType :: binary(),
                    Registry :: binary(),
                    Repo :: binary(),
                    SubjectDigest :: binary(),
                    SubjectSize :: non_neg_integer(),
                    Auth :: map()) ->
                       ok | {error, term()}.

Push an artifact as a referrer to an image manifest.

This implements the OCI Referrers API, attaching artifacts (like SBOMs) to an existing image manifest. The artifact manifest includes a subject field that references the target image.

ArtifactData is the raw artifact content (e.g., SPDX JSON). ArtifactType is the media type (e.g., "application/spdx+json"). SubjectDigest is the digest of the image manifest this artifact refers to. SubjectSize is the size of the subject manifest.

Returns ok on success, or {error, {referrernot_supported, }} if the registry doesn't support the referrers API.

push_referrer(ArtifactData, ArtifactType, Registry, Repo, SubjectDigest, SubjectSize, Auth, Opts)

-spec push_referrer(ArtifactData :: binary(),
                    ArtifactType :: binary(),
                    Registry :: binary(),
                    Repo :: binary(),
                    SubjectDigest :: binary(),
                    SubjectSize :: non_neg_integer(),
                    Auth :: map(),
                    Opts :: push_opts()) ->
                       ok | {error, term()}.

Push a referrer artifact with options.

push_signature(PayloadJson, Signature, Registry, Repo, SubjectDigest, SubjectSize, Auth)

-spec push_signature(PayloadJson :: binary(),
                     Signature :: binary(),
                     Registry :: binary(),
                     Repo :: binary(),
                     SubjectDigest :: binary(),
                     SubjectSize :: non_neg_integer(),
                     Auth :: map()) ->
                        ok | {error, term()}.

Push a cosign-compatible signature as a referrer to an image manifest.

The signature is attached using the OCI referrers API with:

  • artifactType: application/vnd.dev.cosign.simplesigning.v1+json
  • Signature stored as base64 in layer annotation
  • Payload stored as config blob

Returns ok on success, or {error, {referrernot_supported, }} if the registry doesn't support the referrers API.

push_signature(PayloadJson, Signature, Registry, Repo, SubjectDigest, SubjectSize, Auth, Opts)

-spec push_signature(PayloadJson :: binary(),
                     Signature :: binary(),
                     Registry :: binary(),
                     Repo :: binary(),
                     SubjectDigest :: binary(),
                     SubjectSize :: non_neg_integer(),
                     Auth :: map(),
                     Opts :: push_opts()) ->
                        ok | {error, term()}.

Push a cosign signature with options.

stop_httpc()

-spec stop_httpc() -> ok.

Stop the fallback httpc to allow clean VM exit.

Note: When using the supervised HTTP pool (ocibuild_http), this is not needed as cleanup happens automatically through OTP supervision.

tag_from_digest(Registry, Repo, Digest, Tag, Auth)

-spec tag_from_digest(binary(), binary(), binary(), binary(), map()) -> {ok, binary()} | {error, term()}.

Tag an existing manifest with a new tag.

This function fetches a manifest by its digest from the registry and pushes it to a new tag. This is efficient because it doesn't re-upload blobs - it only creates a new tag reference to the same manifest.

This is used to push an image with multiple tags: the first tag does a full push (blobs + manifest), and additional tags use this function to just create new tag references.

with_retry(Fun, MaxRetries)

-spec with_retry(fun(() -> {ok, T} | {error, term()}), non_neg_integer()) -> {ok, T} | {error, term()}
                    when T :: term().

Execute a function with retry logic for transient failures.

Takes a zero-arity function that returns {ok, Result} or {error, Reason}. Retries up to MaxRetries times with exponential backoff for retriable errors.

Example:

with_retry(fun() -> pull_blob(R, Repo, D, Auth, Opts) end, 3)