ocibuild_adapter behaviour (ocibuild v0.10.4)
View SourceBehaviour for OCI build system adapters.
This behaviour defines the interface that build system integrations (rebar3, Mix, Gleam, LFE, etc.) must implement to work with ocibuild.
Adapters are responsible for:
- Extracting configuration from the build system
- Finding release artifacts
- Logging messages in the build system's format
The common functionality (file collection, image building, save, push)
is provided by ocibuild_release.
Implementing an Adapter
-module(my_adapter).
-behaviour(ocibuild_adapter).
-export([get_config/1, find_release/2, info/2, console/2, error/2]).
get_config(State) ->
%% Extract and normalize config from your build system
#{base_image => ~"debian:stable-slim", ...}.
find_release(State, Opts) ->
%% Find the release directory
{ok, ~"myapp", "/path/to/release"}.
info(Format, Args) ->
%% Log info message
io:format(Format ++ "~n", Args).
console(Format, Args) ->
%% Print to console (user-facing)
io:format(Format ++ "~n", Args).
error(Format, Args) ->
%% Log error message
io:format(standard_error, Format ++ "~n", Args).
Summary
Callbacks
Print a message to the console.
Log an error message.
Find the release directory for the given configuration.
Get the application version from the build system.
Extract and normalize configuration from the build system.
Get dependencies from the build system's lock file.
Log an informational message.
Functions
Default chunk size for uploads in bytes.
Default chunk size for uploads in MB.
Get application version from an adapter, with fallback for optional callback.
Get dependencies from an adapter, with fallback for optional callback.
Maximum chunk size for uploads in bytes.
Maximum chunk size for uploads in MB.
Minimum chunk size for uploads in bytes.
Minimum chunk size for uploads in MB.
Types
-type config() :: #{base_image => binary(), workdir => binary(), env => #{binary() => binary()}, expose => [non_neg_integer()], labels => #{binary() => binary()}, cmd => binary(), tag => binary() | undefined, output => binary() | undefined, push => binary() | undefined, chunk_size => pos_integer() | undefined, uid => non_neg_integer() | undefined, app_version => binary() | undefined, vcs_annotations => boolean(), sbom => binary() | undefined, sign_key => binary() | undefined, annotations => #{binary() => binary()}}.
Callbacks
Print a message to the console.
Used for user-facing output like instructions on how to load the image.
Log an error message.
Used for error conditions that should be displayed to the user.
-callback find_release(State :: term(), Opts :: map()) -> {ok, ReleaseName :: binary(), ReleasePath :: file:filename()} | {error, term()}.
Find the release directory for the given configuration.
Returns the release name and path where the release artifacts are located. The Opts map may contain:
release- specific release name to use (if multiple configured)
Get the application version from the build system.
This is an optional callback. If not implemented, the version annotation
will not be added to the image. Adapters can implement this to provide
the application version for the org.opencontainers.image.version annotation.
For rebar3: Parse the .app.src file or relx config for version.
For Mix: Return Mix.Project.config()[:version].
Extract and normalize configuration from the build system.
The State parameter is build-system-specific (e.g., rebar_state:t() for rebar3, or a map for Mix).
Returns a normalized config map that ocibuild_release functions can use.
-callback get_dependencies(State :: term()) -> {ok, [#{name := binary(), version := binary(), source := binary()}]} | {error, term()}.
Get dependencies from the build system's lock file.
This is an optional callback. If not implemented, smart dependency layering is disabled and all files go into a single layer (backward compatible behavior).
Returns a list of dependency maps with name, version, and source. This data is used for:
- Smart layer classification (deps layer vs app layer)
- Future SBOM generation (P6)
For rebar3: Parse rebar.lock file.
For Mix: Parse mix.lock file.
Log an informational message.
Used for build progress messages like "Building OCI image: myapp:1.0.0".
Functions
-spec default_chunk_size() -> pos_integer().
Default chunk size for uploads in bytes.
-spec default_chunk_size_mb() -> pos_integer().
Default chunk size for uploads in MB.
Get application version from an adapter, with fallback for optional callback.
If the adapter implements get_app_version/1, calls it and returns the result.
If not implemented, returns undefined.
Example:
Version = ocibuild_adapter:get_app_version(ocibuild_rebar3, State).
-spec get_dependencies(module(), term()) -> [#{name := binary(), version := binary(), source := binary()}].
Get dependencies from an adapter, with fallback for optional callback.
If the adapter implements get_dependencies/1, calls it and returns the result.
If not implemented or returns error, returns an empty list (with a warning for errors).
The returned list contains maps with name, version, and source keys,
which can be used for smart layer classification and SBOM generation.
Example:
Deps = ocibuild_adapter:get_dependencies(ocibuild_rebar3, State).
%% Returns: [#{name => ~"cowboy", version => ~"2.10.0", source => ~"hex"}, ...]
-spec max_chunk_size() -> pos_integer().
Maximum chunk size for uploads in bytes.
-spec max_chunk_size_mb() -> pos_integer().
Maximum chunk size for uploads in MB.
-spec min_chunk_size() -> pos_integer().
Minimum chunk size for uploads in bytes.
-spec min_chunk_size_mb() -> pos_integer().
Minimum chunk size for uploads in MB.