s3

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package s3 is the S3-compatible blob.Store backend, on minio-go so one implementation speaks to MinIO, AWS S3, Ceph RGW, or anything else with the S3 wire protocol — never a MinIO-specific API (an operator must be able to swap the vendor without touching this package).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Endpoint  string // host:port, no scheme
	AccessKey string
	SecretKey string
	Bucket    string
	Region    string // some S3 endpoints require it on bucket create; required by BucketPrecreated
	TLS       bool

	// BucketPrecreated asserts that the bucket already exists, so New neither
	// checks for it nor creates it. The check is a bucket-level read
	// (storage.buckets.get on GCS, granted by roles/storage.legacyBucketReader;
	// s3:ListBucket on AWS) that a pre-provisioned deployment can only ever
	// answer "yes", so demanding it at startup widens the identity for nothing
	// (#241, and docs/plan/20_gcp-deployment.md Decision 11).
	//
	// What that buys depends on the endpoint, and on AWS it is less than it
	// sounds. S3 answers a GET for a missing key with 403 AccessDenied rather
	// than 404 NoSuchKey unless the caller holds s3:ListBucket on the bucket,
	// and blob.Store's ErrNotFound rests on that 404 — so an AWS deployment
	// keeps s3:ListBucket whatever this setting says, and what the setting drops
	// is s3:CreateBucket. On GCS, where roles/storage.objectAdmin already makes
	// a missing object answer 404, it drops the bucket privilege outright, which
	// is what it was built for.
	//
	// It requires Region, because the construction check is not the only
	// bucket-level call: a client with no region resolves the bucket's location
	// before the first object request and caches it (bucket-cache.go), so the
	// mode would trade a bucket call at startup for one at first use. New
	// rejects the pair rather than half-keeping the promise. The requirement is
	// deliberately blunt — minio-go does derive a region from an AWS regional
	// endpoint's own hostname, so a few endpoints would have been safe without
	// one — because "set the region" is a rule an operator can follow and
	// "set it unless your endpoint spells it out" is not. The region must also be the *right* one: minio-go recovers from
	// a wrong region only while its own is empty (api.go's
	// AuthorizationHeaderMalformed retry), so a mistyped one now fails the
	// first object request instead of self-correcting.
	//
	// One endpoint is outside the promise. Against an Amazon endpoint with an
	// S3 Express directory bucket, minio-go mints session credentials for every
	// object request — a bucket-root GET ?session (api.go, create-session.go) —
	// which needs s3express:CreateSession on the bucket. That call is the
	// client's, not this package's, and it is made with or without this
	// setting; the mode simply cannot remove it.
	//
	// The check is also the one call New makes, so this is a trade: with it
	// skipped, an unreachable endpoint, a wrong credential, a wrong region or a
	// misspelled bucket surfaces on first use rather than at startup. That is
	// the right way round for a deployment whose bucket is provisioned out of
	// band, and the wrong one for the bundled MinIO, which starts empty — hence
	// a per-deployment setting rather than a change of default.
	BucketPrecreated bool
}

Config is everything needed to reach one bucket, supplied by deployment configuration (config-driven per CLAUDE.md principle 4 — no default endpoint exists).

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store implements blob.Store against one S3 bucket.

func New

func New(ctx context.Context, cfg Config) (*Store, error)

New connects and ensures the bucket exists, so every later operation can assume it (the bundled MinIO starts empty; creating the bucket here keeps deployment free of a separate bootstrap step). Idempotent across processes: two racing creators both succeed. Config.BucketPrecreated takes the operator's word for that instead, and New then issues no request at all — see the field for what that does and does not promise about the object work that follows.

func (*Store) Delete

func (s *Store) Delete(ctx context.Context, key string) error

func (*Store) Get

func (s *Store) Get(ctx context.Context, key string) (io.ReadCloser, int64, error)

func (*Store) Put

func (s *Store) Put(ctx context.Context, key string, r io.Reader, size int64, contentType string) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL