defmodule GitGud.Storage do
@moduledoc """
Object storage abstraction for blobs that don't belong in Postgres —
CI artifacts, LFS objects, OCI registry manifests/blobs (if we ever
want to mirror outside of zot).
Default impl is `GitGud.Storage.Garage`, which speaks S3 via `ExAws.S3`
pointed at a Garage cluster. Set `config :git_gud, GitGud.Storage,
impl: SomeOtherModule` to swap.
"""
@type bucket :: String.t()
@type key :: String.t()
@type opts :: keyword()
@callback put(bucket(), key(), iodata(), opts()) :: :ok | {:error, term()}
@callback get(bucket(), key()) :: {:ok, binary()} | {:error, term()}
@callback delete(bucket(), key()) :: :ok | {:error, term()}
@callback presign_url(bucket(), key(), :get | :put, opts()) ::
{:ok, String.t()} | {:error, term()}
@doc "Upload an object."
def put(bucket, key, body, opts \\ []),
do: impl().put(bucket, key, body, opts)
@doc "Fetch an object."
def get(bucket, key), do: impl().get(bucket, key)
@doc "Delete an object."
def delete(bucket, key), do: impl().delete(bucket, key)
@doc """
Generate a presigned URL the client uploads/downloads directly to/from
Garage. Use this for large blobs (LFS, artifacts) so Phoenix doesn't
proxy the bytes.
"""
def presign_url(bucket, key, method, opts \\ []),
do: impl().presign_url(bucket, key, method, opts)
defp impl do
Application.get_env(:git_gud, __MODULE__, [])
|> Keyword.get(:impl, GitGud.Storage.Garage)
end
end
1.5 KiB · text
5af55d9