feat(blossom): optional S3-compatible blob storage #12

Closed
userAdityaa wants to merge 1 commits from userAdityaa/zooid:storage-support into master
Contributor

Summary

Allows each host/relay to choose local filesystem (default) or S3-compatible object storage for Blossom blobs via blossom.file_storage and [blossom.s3].

Changes

  • Config: blossom.file_storage (local | s3, empty = local); nested BlossomS3Settings with endpoint, region, bucket, keys, optional key_prefix, use_path_style.
  • Load/Save: secret_key mirrored to a private field after load (like relay secret); restored only when writing TOML.
  • Validation: validateBlossomFileStorage from LoadConfigFromPath and APIHandler.validateConfig when Blossom is enabled and storage is s3.
  • Runtime: BlossomStore.Enable branches local vs S3; AWS SDK for Go v2 S3 client with optional custom BaseEndpoint.

closes #10

### Summary Allows each host/relay to choose **local filesystem** (default) or **S3-compatible object storage** for Blossom blobs via `blossom.file_storage` and `[blossom.s3]`. ### Changes - **Config**: `blossom.file_storage` (`local` | `s3`, empty = local); nested `BlossomS3Settings` with endpoint, region, bucket, keys, optional `key_prefix`, `use_path_style`. - **Load/Save**: `secret_key` mirrored to a private field after load (like relay `secret`); restored only when writing TOML. - **Validation**: `validateBlossomFileStorage` from `LoadConfigFromPath` and `APIHandler.validateConfig` when Blossom is enabled and storage is `s3`. - **Runtime**: `BlossomStore.Enable` branches local vs S3; AWS SDK for Go v2 S3 client with optional custom `BaseEndpoint`. closes #10
hodlbod requested changes 2026-05-11 20:36:22 +00:00
zooid/blossom.go Outdated
@@ -21,0 +34,4 @@
}
awsCfg, err := awsconfig.LoadDefaultConfig(ctx,
awsconfig.WithRegion(strings.TrimSpace(s.Region)),
Owner

Again, normalization should be done when parsing config

Again, normalization should be done when parsing config
zooid/blossom.go Outdated
@@ -33,1 +63,3 @@
file, err := fs.Create(dir + "/" + sha256)
fs := strings.ToLower(strings.TrimSpace(bl.Config.Blossom.FileStorage))
if fs == "" {
fs = "local"
Owner

Fallback when parsing config, also normalize there, we shouldn't have to normalize here.

Fallback when parsing config, also normalize there, we shouldn't have to normalize here.
zooid/blossom.go Outdated
@@ -34,0 +96,4 @@
return osfs.Remove(filepath.Join(dir, sha256))
}
case "s3":
Owner

Separate these into separate functions instead of factoring out newBlossomS3Client

Separate these into separate functions instead of factoring out newBlossomS3Client
zooid/config.go Outdated
@@ -61,1 +63,3 @@
secret nostr.SecretKey
path string
secret nostr.SecretKey
blossomS3SecretKey string
Owner

Let's not do this, s3 secret isn't super sensitive, just leave it in the s3 settings struct

Let's not do this, s3 secret isn't super sensitive, just leave it in the s3 settings struct
@@ -157,0 +218,4 @@
[blossom]
enabled = true
file_storage = "s3"
Owner

Rename this to backend

Rename this to `backend`
@@ -157,0 +226,4 @@
access_key = "AKIA"
secret_key = "topsecret"
endpoint = "http://127.0.0.1:9000"
use_path_style = true
Owner

This should probably not be configurable, just use what makes sense.

This should probably not be configurable, just use what makes sense.
userAdityaa force-pushed storage-support from 4f3addc4a4 to f46ba28aef 2026-05-12 10:57:14 +00:00 Compare
userAdityaa added 1 commit 2026-05-12 11:05:27 +00:00
userAdityaa force-pushed storage-support from f46ba28aef to 732f9b6209 2026-05-12 11:05:27 +00:00 Compare
Owner

Merged via f40e909863

Merged via f40e90986368ec6c2e8ea2cc73766b50961dd5fa
hodlbod closed this pull request 2026-05-12 21:14:11 +00:00
Owner

Also take a look at ea145079f4 for how I refactored this — there was a lot of confusing aliasing and ordering of utility functions that made the code hard to follow. I also cleaned up api.go which was adding to the confusion over where validation belongs.

Also take a look at ea145079f4cfbc34de4135b40b805a1d8da90f80 for how I refactored this — there was a lot of confusing aliasing and ordering of utility functions that made the code hard to follow. I also cleaned up api.go which was adding to the confusion over where validation belongs.

Pull request closed

Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: coracle/zooid#12