Ankusa.BlobStore backed by Google Cloud Storage's JSON API, via
Req. Works against real GCS or the
floci-gcp emulator in docker-compose.integration.yml.
This adapter deliberately carries no OAuth2 dependency: :token_provider
is a callback you point at whatever your deployment already uses (Goth, ADC),
rather than a bundled OAuth2 client. On GCE/GKE the built-in
Ankusa.BlobStore.GCS.MetadataServer needs no configuration.
opts:
:bucket— required:endpoint— default"https://storage.googleapis.com"; pointat `http://localhost:4588` for floci-gcp:token_provider—{module, fun, args}, applied per request, mustreturn `{:ok, bearer_token} | :error`. Omit for the emulator (unauthenticated). **Required against real GCS**: `{Ankusa.BlobStore.GCS.MetadataServer, :token, []}` on GCE/GKE, or your own source (Goth, ADC). On a `401` the adapter calls the module's `invalidate/n` (same arguments) when it exports one and sends the request once more with the fresh token:timeout_ms— default10_000, for both connect and response ofone request that carries at most 1 MiB:upload_timeout_ms,:op_deadline_ms,:multipart_threshold_bytes,:multipart_part_bytes,:breaker_*,:pool_*— one deadline peroperation, resumable upload above a size, a breaker per bucket and a connection pool per endpoint. See `Ankusa.BlobStore.Options`:req_options— transport options for the HTTP client, e.g. a customFinch pool, a proxy, or `plug:` for `Req.Test` in tests. See `Ankusa.HttpClient` for the accepted keys:retries— default2: extra attempts after a transport erroror a `408`/`429`/`5xx`, each with a fresh token from `:token_provider`. See `Ankusa.BlobStore.Retry`:sse—%{type: :kms, key_id: key_resource_name}: every uploadnames the Cloud KMS key that encrypts the object (`x-goog-encryption-kms-key-name` and `kmsKeyName`). GCS encrypts everything at rest anyway; this picks the key. See `Ankusa.BlobStore.SSE`
put_if_absent/4 is ifGenerationMatch=0 (a 412 is :already_exists);
every upload carries x-goog-hash: md5=… and a GET verifies the
x-goog-hash md5 it is sent (Ankusa.BlobStore.Checksum); a body over
multipart_threshold_bytes is a resumable upload in multipart_part_bytes
chunks.
Local dev
config :ankusa,
storage: %{
blob_store:
{Ankusa.BlobStore.GCS, bucket: "ankusa-segments-dev", endpoint: "http://localhost:4588"}
}docker compose -f docker-compose.integration.yml up -d floci-gcp gcs-bootstrap brings up
the emulator and creates the bucket.