OCI.Storage.Adapter behaviour (oci v0.0.6)
View SourceBehaviour for OCI registry storage backends.
This module defines the interface that storage adapters must implement to work with OCI (Open Container Initiative) registries. A storage adapter is responsible for storing and retrieving container images and their components.
Key Concepts
- Repository: A collection of related container images (e.g., "myapp/backend")
- Blob: Binary data that represents layers of a container image or configuration
- Manifest: A JSON document that describes a container image, including its layers and configuration
- Digest: A unique identifier for a blob, typically a SHA-256 hash
- Reference: A human-readable identifier for a manifest (e.g., "latest", "v1.0.0")
Implementation Guide
When implementing this behaviour, you'll need to handle:
- Repository initialization and management
- Blob storage and retrieval
- Manifest storage and retrieval
- Tag management
- Upload handling for large blobs
Example Usage
defmodule MyStorageAdapter do
@behaviour OCI.Storage.Adapter
defstruct [:path] # Define your struct fields here
# Implement all callbacks here
end
Summary
Callbacks
Checks if a blob exists in the repository and returns its size if found.
Cancels an ongoing blob upload session.
Finalizes a blob upload and verifies the digest.
Deletes a blob from the repository.
Deletes a manifest from the repository.
Retrieves a blob's content from the repository.
Gets the total size of an ongoing blob upload.
Gets the status of an ongoing blob upload.
Retrieves a manifest from the repository.
Initializes a new storage adapter instance with the given configuration.
Initiates a blob upload session.
Lists tags in a repository with pagination support.
Gets metadata about a manifest without retrieving its content.
Mounts a blob from one repository to another.
Checks if a repository exists.
Stores a manifest in the repository.
Uploads a chunk of data to an ongoing blob upload.
Checks if an upload exists.
Types
Callbacks
@callback blob_exists?( storage :: t(), repo :: String.t(), digest :: String.t(), ctx :: OCI.Context.t() ) :: boolean()
Checks if a blob exists in the repository and returns its size if found.
@callback cancel_blob_upload( storage :: t(), repo :: String.t(), uuid :: String.t(), ctx :: OCI.Context.t() ) :: :ok | {:error, :BLOB_UPLOAD_UNKNOWN} | {:error, :BLOB_UPLOAD_UNKNOWN, error_details_t()}
Cancels an ongoing blob upload session.
@callback complete_blob_upload( storage :: t(), repo :: String.t(), upload_id :: String.t(), digest :: String.t(), ctx :: OCI.Context.t() ) :: :ok | {:error, atom()} | {:error, atom(), error_details_t()}
Finalizes a blob upload and verifies the digest.
@callback delete_blob( storage :: t(), repo :: String.t(), digest :: String.t(), ctx :: OCI.Context.t() ) :: :ok | {:error, :BLOB_UNKNOWN} | {:error, :BLOB_UNKNOWN, error_details_t()}
Deletes a blob from the repository.
@callback delete_manifest( storage :: t(), repo :: String.t(), reference :: String.t(), ctx :: OCI.Context.t() ) :: :ok | {:error, atom()}
Deletes a manifest from the repository.
@callback get_blob( storage :: t(), repo :: String.t(), digest :: String.t(), ctx :: OCI.Context.t() ) :: {:ok, content :: binary()} | {:error, :BLOB_UNKNOWN} | {:error, :BLOB_UNKNOWN, error_details_t()}
Retrieves a blob's content from the repository.
@callback get_blob_upload_offset( storage :: t(), repo :: String.t(), uuid :: String.t(), ctx :: OCI.Context.t() ) :: {:ok, size :: non_neg_integer()} | {:error, term()} | {:error, term(), error_details_t()}
Gets the total size of an ongoing blob upload.
@callback get_blob_upload_status( storage :: t(), repo :: String.t(), uuid :: String.t(), ctx :: OCI.Context.t() ) :: {:ok, range :: String.t()} | {:error, term()} | {:error, term(), error_details_t()}
Gets the status of an ongoing blob upload.
@callback get_manifest( storage :: t(), repo :: String.t(), reference :: String.t(), ctx :: OCI.Context.t() ) :: {:ok, manifest :: binary(), content_type :: String.t()} | {:error, atom(), error_details_t()}
Retrieves a manifest from the repository.
@callback init(config :: map()) :: {:ok, storage :: t()} | {:error, term()} | {:error, term(), error_details_t()}
Initializes a new storage adapter instance with the given configuration.
@callback initiate_blob_upload(storage :: t(), repo :: String.t(), ctx :: OCI.Context.t()) :: {:ok, upload_id :: String.t()} | {:error, term()} | {:error, term(), error_details_t()}
Initiates a blob upload session.
@callback list_tags( storage :: t(), repo :: String.t(), pagination :: OCI.Pagination.t(), ctx :: OCI.Context.t() ) :: {:ok, tags :: [String.t()]} | {:error, :NAME_UNKNOWN} | {:error, :NAME_UNKNOWN, error_details_t()}
Lists tags in a repository with pagination support.
@callback manifest_exists?( storage :: t(), repo :: String.t(), reference :: String.t(), ctx :: OCI.Context.t() ) :: boolean()
Gets metadata about a manifest without retrieving its content.
@callback mount_blob( storage :: t(), repo :: String.t(), digest :: String.t(), from_repo :: String.t(), ctx :: OCI.Context.t() ) :: :ok | {:error, :BLOB_UNKNOWN} | {:error, :BLOB_UNKNOWN, error_details_t()}
Mounts a blob from one repository to another.
@callback repo_exists?(storage :: t(), repo :: String.t(), ctx :: OCI.Context.t()) :: boolean()
Checks if a repository exists.
@callback store_manifest( storage :: t(), repo :: String.t(), reference :: String.t(), manifest :: map(), manifest_digest :: String.t(), ctx :: OCI.Context.t() ) :: :ok | {:error, :MANIFEST_BLOB_UNKNOWN | :MANIFEST_INVALID | :NAME_UNKNOWN, error_details_t()}
Stores a manifest in the repository.
@callback upload_blob_chunk( storage :: t(), repo :: String.t(), uuid :: String.t(), chunk :: binary(), content_range :: String.t(), ctx :: OCI.Context.t() ) :: {:ok, range :: String.t()} | {:error, atom()} | {:error, atom(), error_details_t()}
Uploads a chunk of data to an ongoing blob upload.
@callback upload_exists?( storage :: t(), repo :: String.t(), uuid :: String.t(), ctx :: OCI.Context.t() ) :: boolean()
Checks if an upload exists.