diff --git a/autocert/s3cache/s3cache.go b/autocert/s3cache/s3cache.go index 3b56cab2..74f836f0 100644 --- a/autocert/s3cache/s3cache.go +++ b/autocert/s3cache/s3cache.go @@ -8,8 +8,8 @@ import ( "path" "github.com/aws/aws-sdk-go-v2/aws" - awsConfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" + storage "github.com/tigrisdata/storage-go" "golang.org/x/crypto/acme/autocert" ) @@ -19,15 +19,11 @@ type Options struct { } func New(ctx context.Context, opts Options) (autocert.Cache, error) { - cfg, err := awsConfig.LoadDefaultConfig(ctx) + s3c, err := storage.New(ctx, storage.WithGlobalEndpoint(), storage.WithPathStyle(true)) if err != nil { return nil, err } - s3c := s3.NewFromConfig(cfg, func(o *s3.Options) { - o.UsePathStyle = true - }) - return &impl{ cli: s3c, bucket: opts.Bucket, @@ -36,7 +32,7 @@ func New(ctx context.Context, opts Options) (autocert.Cache, error) { } type impl struct { - cli *s3.Client + cli *storage.Client bucket, prefix string } diff --git a/cmd/future-sight/main.go b/cmd/future-sight/main.go index a9024ace..ae70c003 100644 --- a/cmd/future-sight/main.go +++ b/cmd/future-sight/main.go @@ -16,16 +16,15 @@ import ( "buf.build/go/protovalidate" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/nats-io/nats.go" "github.com/redis/go-redis/v9" + storage "github.com/tigrisdata/storage-go" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/proto" pb "within.website/x/gen/within/website/x/futuresight/v1" "within.website/x/internal" "within.website/x/internal/xesite" - "within.website/x/web/useragent" ) var ( @@ -49,18 +48,15 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - creds := credentials.NewStaticCredentialsProvider(*awsAccessKeyID, *awsSecretKey, "") - - s3c := s3.New(s3.Options{ - AppID: useragent.GenUserAgent("future-sight-push", "https://xeiaso.net"), - BaseEndpoint: awsEndpointS3, - ClientLogMode: aws.LogRetries | aws.LogRequest | aws.LogResponse, - Credentials: creds, - EndpointResolver: s3.EndpointResolverFromURL(*awsEndpointS3), - //Logger: logging.NewStandardLogger(os.Stderr), - UsePathStyle: *usePathStyle, - Region: *awsRegion, - }) + s3c, err := storage.New(ctx, + storage.WithEndpoint(*awsEndpointS3), + storage.WithRegion(*awsRegion), + storage.WithPathStyle(*usePathStyle), + storage.WithAccessKeypair(*awsAccessKeyID, *awsSecretKey), + ) + if err != nil { + log.Fatal(err) + } slog.Debug("details", "awsAccessKeyID", *awsAccessKeyID, @@ -148,7 +144,7 @@ func main() { } type Server struct { - s3c *s3.Client + s3c *storage.Client vk *redis.Client nc *nats.Conn zs *xesite.ZipServer diff --git a/cmd/relayd/telemetry.go b/cmd/relayd/telemetry.go index be3ba3b6..4557b033 100644 --- a/cmd/relayd/telemetry.go +++ b/cmd/relayd/telemetry.go @@ -10,9 +10,9 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/aws" - awsConfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/google/uuid" + storage "github.com/tigrisdata/storage-go" "within.website/x/bundler" relayd "within.website/x/gen/within/website/x/relayd/v1" ) @@ -20,7 +20,6 @@ import ( var ( telemetryEnable = flag.Bool("telemetry-enable", false, "if true, enable request telemetry bundling to object storage") telemetryBucket = flag.String("telemetry-bucket", "relayd-logs", "object storage bucket to dump logs to") - telemetryPathStyle = flag.Bool("telemetry-path-style", false, "if true, use s3 path style") telemetryHost = flag.String("telemetry-host", "", "hostname to disambiguate telemetry") telemetryBundleCount = flag.Int("telemetry-bundle-count", 512, "maximum number of items per telemetry bundle") telemetryContextDeadline = flag.Duration("telemetry-context-deadline", time.Minute, "maximum time for the telemetry context deadline") @@ -28,7 +27,7 @@ var ( type TelemetrySink struct { sink *bundler.Bundler[*relayd.RequestLog] - s3c *s3.Client + s3c *storage.Client host string } @@ -39,15 +38,11 @@ func NewTelemetrySink(ctx context.Context) (*TelemetrySink, error) { slog.Info("telemetry enabled") - cfg, err := awsConfig.LoadDefaultConfig(ctx) + s3c, err := storage.New(ctx, storage.WithGlobalEndpoint(), storage.WithPathStyle(true)) if err != nil { return nil, err } - s3c := s3.NewFromConfig(cfg, func(o *s3.Options) { - o.UsePathStyle = true - }) - result := &TelemetrySink{ s3c: s3c, host: *telemetryHost, diff --git a/cmd/stickers/main.go b/cmd/stickers/main.go index 04c35e4e..3d83d661 100644 --- a/cmd/stickers/main.go +++ b/cmd/stickers/main.go @@ -15,10 +15,7 @@ import ( "time" "github.com/a-h/templ" - "github.com/aws/aws-sdk-go-v2/aws" - v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - awsConfig "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/s3" + simplestorage "github.com/tigrisdata/storage-go/simplestorage" "within.website/x/htmx" "within.website/x/internal" "within.website/x/xess" @@ -44,18 +41,14 @@ func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - cfg, err := awsConfig.LoadDefaultConfig(ctx) + sc, err := simplestorage.New(ctx, + simplestorage.WithBucket(*bucketName), + simplestorage.WithFlyEndpoint(), + ) if err != nil { log.Fatal(err) } - s3c := s3.NewFromConfig(cfg, func(o *s3.Options) { - o.UsePathStyle = false - }) - - presigner := Presigner{s3.NewPresignClient(s3c)} - _ = presigner - mux := http.NewServeMux() htmx.Mount(mux) xess.Mount(mux) @@ -91,10 +84,7 @@ func main() { key := fmt.Sprintf("%s/%s/%s.%s", *folderName, name, mood, format) if !inCache(name, mood) { - _, err := s3c.HeadObject(r.Context(), &s3.HeadObjectInput{ - Bucket: aws.String(*bucketName), - Key: aws.String(key), - }) + _, err := sc.Head(r.Context(), key) if err != nil { slog.Error("can't head key", "format", format, "bucket", *bucketName, "key", key, "err", err) @@ -123,7 +113,7 @@ func main() { setCache(name, mood) } - req, err := presigner.GetObject(r.Context(), key, 3600) + url, err := sc.PresignURL(r.Context(), http.MethodGet, key, time.Hour) if err != nil { slog.Error("can't presign get for key", "format", format, "bucket", *bucketName, "key", key, "err", err) @@ -152,7 +142,7 @@ func main() { w.Header().Add("Cache-Control", "max-age=3599") w.Header().Add("Expires", time.Now().Add(time.Hour-time.Second).Format(http.TimeFormat)) - brandedURL := strings.ReplaceAll(req.URL, "xedn.fly.storage.tigris.dev", "files.xeiaso.net") + brandedURL := strings.ReplaceAll(url, "xedn.fly.storage.tigris.dev", "files.xeiaso.net") http.Redirect(w, r, brandedURL, http.StatusTemporaryRedirect) }) @@ -161,34 +151,6 @@ func main() { log.Fatal(http.ListenAndServe(*bind, mux)) } -// Presigner encapsulates the Amazon Simple Storage Service (Amazon S3) presign actions -// used in the examples. -// It contains PresignClient, a client that is used to presign requests to Amazon S3. -// Presigned requests contain temporary credentials and can be made from any HTTP client. -type Presigner struct { - PresignClient *s3.PresignClient -} - -// GetObject makes a presigned request that can be used to get an object from a bucket. -// The presigned request is valid for the specified number of seconds. -func (presigner Presigner) GetObject( - ctx context.Context, - objectKey string, - lifetimeSecs int64, -) (*v4.PresignedHTTPRequest, error) { - request, err := presigner.PresignClient.PresignGetObject(ctx, &s3.GetObjectInput{ - Bucket: aws.String(*bucketName), - Key: aws.String(objectKey), - }, func(opts *s3.PresignOptions) { - opts.Expires = time.Duration(lifetimeSecs * int64(time.Second)) - }) - if err != nil { - log.Printf("Couldn't get a presigned request to get %v:%v. Here's why: %v\n", - bucketName, objectKey, err) - } - return request, err -} - func inCache(character, mood string) bool { cacheLock.RLock() defer cacheLock.RUnlock() diff --git a/cmd/uploud/main.go b/cmd/uploud/main.go index 2d990a13..bcdfa1aa 100644 --- a/cmd/uploud/main.go +++ b/cmd/uploud/main.go @@ -17,13 +17,13 @@ import ( "path/filepath" "github.com/aws/aws-sdk-go-v2/aws" - awsConfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/disintegration/imaging" "github.com/gen2brain/avif" _ "github.com/gen2brain/heic" "github.com/gen2brain/jpegxl" "github.com/gen2brain/webp" + storage "github.com/tigrisdata/storage-go" "golang.org/x/sync/errgroup" "within.website/x/internal" ) @@ -93,15 +93,11 @@ func main() { log.Fatal(err) } - cfg, err := awsConfig.LoadDefaultConfig(ctx) + s3c, err := storage.New(ctx, storage.WithGlobalEndpoint(), storage.WithPathStyle(true)) if err != nil { log.Fatal(err) } - s3c := s3.NewFromConfig(cfg, func(o *s3.Options) { - o.UsePathStyle = true - }) - for _, finfo := range files { log.Printf("uploading %s", finfo.Name()) fin, err := os.Open(filepath.Join(td, finfo.Name())) diff --git a/cmd/xedn/uplodr/main.go b/cmd/xedn/uplodr/main.go index 3776baa3..e57c93c9 100644 --- a/cmd/xedn/uplodr/main.go +++ b/cmd/xedn/uplodr/main.go @@ -17,17 +17,16 @@ import ( "time" "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/disintegration/imaging" "github.com/gen2brain/avif" _ "github.com/gen2brain/heic" "github.com/gen2brain/jpegxl" "github.com/gen2brain/webp" + storage "github.com/tigrisdata/storage-go" "google.golang.org/grpc" pb "within.website/x/gen/within/website/x/xedn/uplodr/v1" "within.website/x/internal" - "within.website/x/tigris" ) var ( @@ -81,19 +80,22 @@ func main() { } type Server struct { - tc *s3.Client - b2c *s3.Client + tc *storage.Client + b2c *storage.Client pb.UnimplementedImageServer } func New(ctx context.Context) (*Server, error) { - tc, err := tigris.Client(ctx) + tc, err := storage.New(ctx, storage.WithFlyEndpoint()) if err != nil { return nil, fmt.Errorf("failed to create Tigris client: %w", err) } - b2c := mkB2Client() + b2c, err := mkB2Client(ctx) + if err != nil { + return nil, fmt.Errorf("failed to create Backblaze B2 client: %w", err) + } return &Server{ tc: tc, @@ -327,15 +329,11 @@ var mimeTypes = map[string]string{ ".css": "text/css", } -func mkB2Client() *s3.Client { - s3Config := aws.Config{ - Credentials: credentials.NewStaticCredentialsProvider(*b2KeyID, *b2KeySecret, ""), - BaseEndpoint: aws.String("https://s3.us-west-001.backblazeb2.com"), - Region: "us-west-001", - } - s3Client := s3.NewFromConfig(s3Config, (func(o *s3.Options) { - o.UsePathStyle = true - o.Region = "us-west-001" - })) - return s3Client +func mkB2Client(ctx context.Context) (*storage.Client, error) { + return storage.New(ctx, + storage.WithEndpoint("https://s3.us-west-001.backblazeb2.com"), + storage.WithRegion("us-west-001"), + storage.WithPathStyle(true), + storage.WithAccessKeypair(*b2KeyID, *b2KeySecret), + ) } diff --git a/docs/plans/2026-06-18-storage-go.md b/docs/plans/2026-06-18-storage-go.md new file mode 100644 index 00000000..1adffafd --- /dev/null +++ b/docs/plans/2026-06-18-storage-go.md @@ -0,0 +1,158 @@ +# Migrate AWS S3 SDK client construction to `tigrisdata/storage-go` + +## Context + +The repo constructs raw AWS S3 SDK v2 clients in 8 places and ships its own +`within.website/x/tigris` helper package that wraps the S3 SDK for Tigris. The +official `github.com/tigrisdata/storage-go` library (already an _indirect_ +dependency at v0.7.0) now supersedes that custom code: its `storage.Client` +**embeds `*s3.Client`** (so every standard S3 op works unchanged) and its +`tigrisheaders` subpackage contains verbatim copies of every helper in our +`tigris` package, including the `Region` type. + +Goal: route all S3 client _construction_ through `storage-go`, delete the +now-redundant `tigris` package, and keep behavior equivalent. Per the user: +migrate **all** clients (including non-Tigris ones — Backblaze B2 and +future-sight's configurable endpoint), and for Tigris clients that currently +resolve their endpoint from the `AWS_ENDPOINT_URL_S3` env var, pin the +**global** endpoint (`storage.WithGlobalEndpoint()` → `t3.storage.dev`). + +Most files use the low-level `storage.Client` (embeds `*s3.Client`). +**`cmd/stickers` is the exception**: it switches to the high-level +`storage-go/simplestorage` package and drops every AWS SDK import (see below). + +## Key facts that shape the migration + +- `storage.Client` embeds `*s3.Client`. Replacing a `*s3.Client` field/var with + `*storage.Client` is drop-in for `PutObject`/`GetObject`/`HeadObject`/ + `DeleteObject`/`ListObjectsV2` calls — **no call-site changes** beyond the type. +- The `aws-sdk-go-v2/service/s3` and `aws-sdk-go-v2/aws` imports must **stay** in + files that build `s3.*Input` structs or call `aws.String`/`aws.Int64`. + Only the construction imports go away: `aws-sdk-go-v2/config` and + `aws-sdk-go-v2/credentials`. +- `storage.New` credential resolution is backward-compatible: it uses + `TIGRIS_STORAGE_ACCESS_KEY_ID`/`_SECRET_ACCESS_KEY` if set, otherwise falls + back to `LoadDefaultConfig` (the existing `AWS_*` env behavior). +- No code in the repo uses the `tigris.WithX` helpers or `Region` type — only + `tigris.Client`. So no `tigrisheaders` import is needed anywhere; those + helpers simply move to their library home if ever needed later. + +## Per-file changes + +### Delete: `tigris/tigris.go` (and the empty `tigris/` dir) + +Fully redundant. Its only importer is `cmd/xedn/uplodr/main.go` (updated below). + +### `cmd/xedn/uplodr/main.go` + +- Imports: drop `within.website/x/tigris` and `aws-sdk-go-v2/credentials`; add + `storage "github.com/tigrisdata/storage-go"`. Keep `service/s3` + `aws`. +- Struct fields `tc`, `b2c`: `*s3.Client` → `*storage.Client`. +- Tigris client: `tc, err := storage.New(ctx, storage.WithFlyEndpoint())` + (preserves the existing fly endpoint that the `tigris` package hardcoded; + xedn deploys on fly.io — this client was never env-driven). +- B2 client: replace `mkB2Client()` with + `storage.New(ctx, storage.WithEndpoint("https://s3.us-west-001.backblazeb2.com"), storage.WithRegion("us-west-001"), storage.WithPathStyle(true), storage.WithAccessKeypair(*b2KeyID, *b2KeySecret))`. + This now takes `ctx` and returns an error — fold into `New(ctx)` accordingly. +- `s.tc.PutObject(...)` / `s.b2c.PutObject(...)` call sites unchanged. + +### `store/s3api.go` + +- Replace `LoadDefaultConfig` + `s3.NewFromConfig` in `NewS3API` with + `storage.New(ctx, storage.WithGlobalEndpoint())` (path-style stays false / + vhost, the storage-go default). Drop `aws-sdk-go-v2/config` import. +- `S3API.s3`: `*s3.Client` → `*storage.Client`. Keep `s3`/`aws` imports + (input structs, `aws.String`). + +### `autocert/s3cache/s3cache.go` + +- `New`: `storage.New(ctx, storage.WithGlobalEndpoint(), storage.WithPathStyle(true))` + (preserves the existing path-style=true). Drop `config` import. +- `impl.cli`: `*s3.Client` → `*storage.Client`. (Consumer: + `cmd/sakurajima/internal/entrypoint/router.go` — no change needed.) + +### `cmd/relayd/telemetry.go` + +- Replace construction with + `storage.New(ctx, storage.WithGlobalEndpoint(), storage.WithPathStyle(true))`. + Drop `config` import; keep `s3`/`aws`. +- `TelemetrySink.s3c`: `*s3.Client` → `*storage.Client`. + +### `cmd/uploud/main.go` + +- Replace construction with + `storage.New(ctx, storage.WithGlobalEndpoint(), storage.WithPathStyle(true))`. + Drop `config` import; keep `s3`/`aws` (PutObjectInput, checksums). +- Local `s3c` var type changes to `*storage.Client`; call sites unchanged. + +### `cmd/future-sight/main.go` + +- Replace `s3.New(s3.Options{...})` with + `storage.New(ctx, storage.WithEndpoint(*awsEndpointS3), storage.WithRegion(*awsRegion), storage.WithPathStyle(*usePathStyle), storage.WithAccessKeypair(*awsAccessKeyID, *awsSecretKey))`. + Keep the existing flags (`--aws-endpoint-url-s3` default `localhost:9000`, etc.). +- Drop `aws-sdk-go-v2/credentials` import. Keep `s3`/`aws` (`aws.String` for keys). +- **Behavior note:** the custom `AppID` user-agent and `ClientLogMode` + (`LogRetries|LogRequest|LogResponse`) are not exposed by `storage.New` and + will be dropped — these are cosmetic (UA string + verbose request logging). + Call this out at implementation; acceptable per "everything via storage-go". + +### `cmd/stickers/main.go` — use the high-level `simplestorage` package + +This program is the exception: instead of the low-level `storage.Client`, it +uses `github.com/tigrisdata/storage-go/simplestorage`, whose string-keyed `Head` +and `PresignURL` calls replace everything stickers does. This lets it drop +**all** AWS SDK imports. + +- Imports: remove `aws-sdk-go-v2/config`, `aws-sdk-go-v2/service/s3`, + `aws-sdk-go-v2/aws`, and `aws-sdk-go-v2/aws/signer/v4` (`v4`). Add + `simplestorage "github.com/tigrisdata/storage-go/simplestorage"`. `net/http` + and `time` are already imported. +- Construction (in `main`): + `sc, err := simplestorage.New(ctx, simplestorage.WithBucket(*bucketName), simplestorage.WithFlyEndpoint())`. + **Fly endpoint is required, not global** — the handler rebrands the presigned + URL via `strings.ReplaceAll(url, "xedn.fly.storage.tigris.dev", "files.xeiaso.net")`, + which only matches the fly vhost host. `WithBucket(*bucketName)` binds the + bucket the flag used to pass on every call (default still `xedn`). +- Existence probe: replace the `s3c.HeadObject(&s3.HeadObjectInput{...})` block + with `if _, err := sc.Head(r.Context(), key); err != nil { ... }` — same + not-found fallback logic. +- Presigned URL: replace `presigner.GetObject(r.Context(), key, 3600)` with + `url, err := sc.PresignURL(r.Context(), http.MethodGet, key, time.Hour)`. + `PresignURL` returns a plain `string`, so `req.URL` becomes `url` directly in + the `ReplaceAll`/`http.Redirect`. +- **Delete** the `Presigner` struct and its `GetObject` method (lines ~164-190) + and the `_ = presigner` line — fully superseded by `PresignURL`. +- Net result: `cmd/stickers/main.go` has zero AWS SDK imports. + +### `go.mod` / `go.sum` + +- `github.com/tigrisdata/storage-go` moves from indirect to direct. +- Run `go mod tidy` — the AWS `config`/`credentials` modules may drop to indirect + (or out) automatically; `service/s3` and `aws` remain direct. + +## Verification + +1. `go build ./...` — compiles cleanly. +2. `npm run generate` then `go test ./...` (the repo's `npm test`) — all pass. + Pay attention to `store`, `autocert/s3cache`, and `cmd/...` packages. +3. `go vet ./...` — no vet issues from the type swaps. +4. `npm run format` — goimports tidies any leftover unused imports + Prettier. +5. Confirm `tigris/` directory is gone and `grep -rn "within.website/x/tigris"` + returns nothing. +6. Sanity check that no `s3.NewFromConfig` / `s3.New(` / `awsConfig.LoadDefaultConfig` + construction remains: `grep -rn "NewFromConfig\|LoadDefaultConfig\|s3.New(" --include=*.go`. +7. Confirm `cmd/stickers/main.go` no longer imports any `aws-sdk-go-v2` package, + and that its presigned-URL rebrand still matches (fly endpoint → `xedn.fly.storage.tigris.dev`). + +## Commit (when approved) + +Conventional Commit, signed off: + +``` +refactor(storage): replace AWS S3 SDK client setup with tigrisdata/storage-go + +Migrate all S3 client construction to github.com/tigrisdata/storage-go and +remove the redundant within.website/x/tigris package. + +Signed-off-by: Xe Iaso +``` diff --git a/go.mod b/go.mod index 1951c9e9..a2533cd0 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module within.website/x -go 1.25.7 +go 1.26 require ( al.essio.dev/pkg/shellescape v1.6.0 @@ -14,7 +14,7 @@ require ( github.com/NYTimes/gziphandler v1.1.1 github.com/a-h/templ v0.3.865 github.com/adrg/frontmatter v0.2.0 - github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 + github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1 github.com/bluesky-social/indigo v0.0.0-20240905024844-a4f38639767f github.com/bluesky-social/jetstream v0.0.0-20241022030937-75fdbaa83787 github.com/bwmarrin/discordgo v0.29.0 @@ -74,6 +74,7 @@ require ( github.com/stoewer/go-strcase v1.3.0 github.com/tetratelabs/wazero v1.9.0 github.com/thoj/go-ircevent v0.0.0-20210723090443-73e444401d64 + github.com/tigrisdata/storage-go v0.7.0 github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef github.com/twitchtv/twirp v8.1.3+incompatible github.com/whyrusleeping/go-did v0.0.0-20230824162731-404d1707d5d6 @@ -112,11 +113,13 @@ require ( github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 // indirect github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect github.com/bytedance/sonic v1.12.6 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect @@ -286,18 +289,17 @@ require ( ) require ( - github.com/aws/aws-sdk-go-v2 v1.41.5 - github.com/aws/aws-sdk-go-v2/config v1.27.13 - github.com/aws/aws-sdk-go-v2/credentials v1.17.67 - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect - github.com/aws/smithy-go v1.24.2 + github.com/aws/aws-sdk-go-v2 v1.41.6 + github.com/aws/aws-sdk-go-v2/config v1.32.16 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.15 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 // indirect + github.com/aws/smithy-go v1.25.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/go.sum b/go.sum index 6b906215..de659460 100644 --- a/go.sum +++ b/go.sum @@ -147,42 +147,44 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY= -github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI= -github.com/aws/aws-sdk-go-v2/config v1.27.13 h1:WbKW8hOzrWoOA/+35S5okqO/2Ap8hkkFUzoW8Hzq24A= -github.com/aws/aws-sdk-go-v2/config v1.27.13/go.mod h1:XLiyiTMnguytjRER7u5RIkhIqS8Nyz41SwAWb4xEjxs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM= -github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo= -github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= -github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= -github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2 v1.41.6 h1:1AX0AthnBQzMx1vbmir3Y4WsnJgiydmnJjiLu+LvXOg= +github.com/aws/aws-sdk-go-v2 v1.41.6/go.mod h1:dy0UzBIfwSeot4grGvY1AqFWN5zgziMmWGzysDnHFcQ= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9 h1:adBsCIIpLbLmYnkQU+nAChU5yhVTvu5PerROm+/Kq2A= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9/go.mod h1:uOYhgfgThm/ZyAuJGNQ5YgNyOlYfqnGpTHXvk3cpykg= +github.com/aws/aws-sdk-go-v2/config v1.32.16 h1:Q0iQ7quUgJP0F/SCRTieScnaMdXr9h/2+wze1u3cNeM= +github.com/aws/aws-sdk-go-v2/config v1.32.16/go.mod h1:duCCnJEFqpt2RC6no1iK6q+8HpwOAkiUua0pY507dQc= +github.com/aws/aws-sdk-go-v2/credentials v1.19.15 h1:fyvgWTszojq8hEnMi8PPBTvZdTtEVmAVyo+NFLHBhH4= +github.com/aws/aws-sdk-go-v2/credentials v1.19.15/go.mod h1:gJiYyMOjNg8OEdRWOf3CrFQxM2a98qmrtjx1zuiQfB8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 h1:IOGsJ1xVWhsi+ZO7/NW8OuZZBtMJLZbk4P5HDjJO0jQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22/go.mod h1:b+hYdbU+jGKfXE8kKM6g1+h+L/Go3vMvzlxBsiuGsxg= +github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.17 h1:95y7/EqethAhFwMKJ9cDutzBhsS1h8uBwkJ5rp8pNTU= +github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager v0.1.17/go.mod h1:77baheqr62SkTw77HWH8qpdWTd2gXKN0xg0qLvDSkpk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 h1:GmLa5Kw1ESqtFpXsx5MmC84QWa/ZrLZvlJGa2y+4kcQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22/go.mod h1:6sW9iWm9DK9YRpRGga/qzrzNLgKpT2cIxb7Vo2eNOp0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 h1:dY4kWZiSaXIzxnKlj17nHnBcXXBfac6UlsAx2qL6XrU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22/go.mod h1:KIpEUx0JuRZLO7U6cbV204cWAEco2iC3l061IxlwLtI= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 h1:FPXsW9+gMuIeKmz7j6ENWcWtBGTe1kH8r9thNt5Uxx4= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23/go.mod h1:7J8iGMdRKk6lw2C+cMIphgAnT8uTwBwNOsGkyOCm80U= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 h1:HtOTYcbVcGABLOVuPYaIihj6IlkqubBwFj10K5fxRek= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8/go.mod h1:VsK9abqQeGlzPgUr+isNWzPlK2vKe9INMLWnY65f5Xs= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14 h1:xnvDEnw+pnj5mctWiYuFbigrEzSm35x7k4KS/ZkCANg= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.14/go.mod h1:yS5rNogD8e0Wu9+l3MUwr6eENBzEeGejvINpN5PAYfY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 h1:PUmZeJU6Y1Lbvt9WFuJ0ugUK2xn6hIWUBBbKuOWF30s= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22/go.mod h1:nO6egFBoAaoXze24a2C0NjQCvdpk8OueRoYimvEB9jo= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22 h1:SE+aQ4DEqG53RRCAIHlCf//B2ycxGH7jFkpnAh/kKPM= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.22/go.mod h1:ES3ynECd7fYeJIL6+oax+uIEljmfps0S70BaQzbMd/o= +github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1 h1:kU/eBN5+MWNo/LcbNa4hWDdN76hdcd7hocU5kvu7IsU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1/go.mod h1:Fw9aqhJicIVee1VytBBjH+l+5ov6/PhbtIK/u3rt/ls= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 h1:a1Fq/KXn75wSzoJaPQTgZO0wHGqE9mjFnylnqEPTchA= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.10/go.mod h1:p6+MXNxW7IA6dMgHfTAzljuwSKD0NCm/4lbS4t6+7vI= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 h1:x6bKbmDhsgSZwv6q19wY/u3rLk/3FGjJWyqKcIRufpE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.16/go.mod h1:CudnEVKRtLn0+3uMV0yEXZ+YZOKnAtUJ5DmDhilVnIw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 h1:oK/njaL8GtyEihkWMD4k3VgHCT64RQKkZwh0DG5j8ak= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20/go.mod h1:JHs8/y1f3zY7U5WcuzoJ/yAYGYtNIVPKLIbp61euvmg= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 h1:ks8KBcZPh3PYISr5dAiXCM5/Thcuxk8l+PG4+A0exds= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.0/go.mod h1:pFw33T0WLvXU3rw1WBkpMlkgIn54eCB5FYLhjDc9Foo= +github.com/aws/smithy-go v1.25.0 h1:Sz/XJ64rwuiKtB6j98nDIPyYrV1nVNJ4YU74gttcl5U= +github.com/aws/smithy-go v1.25.0/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY= github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -993,6 +995,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/tigrisdata/storage-go v0.7.0 h1:3NnOKDCyPkkiZCmph/nOF38pn6AOSoBa14g05Ue8Bu8= +github.com/tigrisdata/storage-go v0.7.0/go.mod h1:2o4/3bv+BTKpmOiI7uF286CKC5eFNspSQw2l+qeOMQk= github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef h1:7D6Nm4D6f0ci9yttWaKjM1TMAXrH5Su72dojqYGntFY= github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef/go.mod h1:WLFStEdnJXpjK8kd4qKLwQKX/1vrDzp5BcDyiZJBHJM= github.com/turnage/redditproto v0.0.0-20151223012412-afedf1b6eddb h1:qR56NGRvs2hTUbkn6QF8bEJzxPIoMw3Np3UigBeJO5A= diff --git a/internal/confyg/read.go b/internal/confyg/read.go index c581b514..9d6037e5 100644 --- a/internal/confyg/read.go +++ b/internal/confyg/read.go @@ -312,7 +312,7 @@ func (in *input) lex(sym *symType) int { in.readRune() c = in.peekRune() if c != '#' { - in.Error(fmt.Sprintf("unexpected input character %#q", c)) + in.Error(fmt.Sprintf("unexpected input character %q", rune(c))) } // Consume comment. @@ -397,7 +397,7 @@ func (in *input) lex(sym *symType) int { // Checked all punctuation. Must be identifier token. if c := in.peekRune(); !isIdent(c) { - in.Error(fmt.Sprintf("unexpected input character %#q", c)) + in.Error(fmt.Sprintf("unexpected input character %q", rune(c))) } // Scan over identifier. diff --git a/store/s3api.go b/store/s3api.go index f2a37ad4..f42e82a5 100644 --- a/store/s3api.go +++ b/store/s3api.go @@ -7,20 +7,16 @@ import ( "io" "github.com/aws/aws-sdk-go-v2/aws" - awsConfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" + storage "github.com/tigrisdata/storage-go" ) func NewS3API(ctx context.Context, bucket string) (Interface, error) { - cfg, err := awsConfig.LoadDefaultConfig(ctx) + client, err := storage.New(ctx, storage.WithGlobalEndpoint()) if err != nil { - return nil, fmt.Errorf("can't load AWS config from environment: %w", err) + return nil, fmt.Errorf("can't create Tigris client: %w", err) } - client := s3.NewFromConfig(cfg, func(o *s3.Options) { - o.UsePathStyle = false // Tigris needs vhost style - }) - return &S3API{ s3: client, bucket: bucket, @@ -28,7 +24,7 @@ func NewS3API(ctx context.Context, bucket string) (Interface, error) { } type S3API struct { - s3 *s3.Client + s3 *storage.Client bucket string } diff --git a/tigris/tigris.go b/tigris/tigris.go deleted file mode 100644 index 2940d82e..00000000 --- a/tigris/tigris.go +++ /dev/null @@ -1,126 +0,0 @@ -// Package tigris contains a Tigris client and helpers for interacting with Tigris. -// -// Tigris is a cloud storage service that provides a simple, scalable, and secure object storage solution. It is based on the S3 API, but has additional features that need these helpers. -package tigris - -import ( - "context" - "fmt" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - awsConfig "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/s3" - "github.com/aws/smithy-go/transport/http" -) - -// WithHeader sets an arbitrary HTTP header on the request. -func WithHeader(key, value string) func(*s3.Options) { - return func(options *s3.Options) { - options.APIOptions = append(options.APIOptions, http.AddHeaderValue(key, value)) - } -} - -// Region is a Tigris region from the documentation. -// -// https://www.tigrisdata.com/docs/concepts/regions/ -type Region string - -// Possible Tigris regions. -const ( - FRA Region = "fra" // Frankfurt, Germany - GRU Region = "gru" // São Paulo, Brazil - HKG Region = "hkg" // Hong Kong, China - IAD Region = "iad" // Ashburn, Virginia, USA - JNB Region = "jnb" // Johannesburg, South Africa - LHR Region = "lhr" // London, UK - MAD Region = "mad" // Madrid, Spain - NRT Region = "nrt" // Tokyo (Narita), Japan - ORD Region = "ord" // Chicago, Illinois, USA - SIN Region = "sin" // Singapore - SJC Region = "sjc" // San Jose, California, USA - SYD Region = "syd" // Sydney, Australia -) - -// WithStaticReplicationRegions sets the regions where the object will be replicated. -// -// Note that this will cause you to be charged multiple times for the same object, once per region. -func WithStaticReplicationRegions(regions []Region) func(*s3.Options) { - regionsString := make([]string, 0, len(regions)) - for _, r := range regions { - regionsString = append(regionsString, string(r)) - } - - return WithHeader("X-Tigris-Regions", strings.Join(regionsString, ",")) -} - -// WithQuery lets you filter objects in a ListObjectsV2 request. -// -// This functions like the WHERE clause in SQL, but for S3 objects. For more information, see the Tigris documentation[1]. -// -// [1]: https://www.tigrisdata.com/docs/objects/query-metadata/ -func WithQuery(query string) func(*s3.Options) { - return WithHeader("X-Tigris-Query", query) -} - -// WithCreateIfNotExists will create the object if it doesn't exist. -// -// See the Tigris documentation[1] for more information. -// -// [1]: https://www.tigrisdata.com/docs/objects/conditionals/ -func WithCreateObjectIfNotExists() func(*s3.Options) { - return WithHeader("If-Match", `""`) -} - -// WithIfEtagMatches sets the ETag that the object must match. -// -// See the Tigris documentation[1] for more information. -// -// [1]: https://www.tigrisdata.com/docs/objects/conditionals/ -func WithIfEtagMatches(etag string) func(*s3.Options) { - return WithHeader("If-Match", etag) -} - -// WithModifiedSince lets you proceed with operation if object was modified after provided date (RFC1123). -// -// See the Tigris documentation[1] for more information. -// -// [1]: https://www.tigrisdata.com/docs/objects/conditionals/ -func WithModifiedSince(modifiedSince time.Time) func(*s3.Options) { - return WithHeader("If-Modified-Since", modifiedSince.Format(time.RFC1123)) -} - -// WithUnmodifiedSince lets you proceed with operation if object was not modified after provided date (RFC1123). -// -// See the Tigris documentation[1] for more information. -// -// [1]: https://www.tigrisdata.com/docs/objects/conditionals/ -func WithUnmodifiedSince(unmodifiedSince time.Time) func(*s3.Options) { - return WithHeader("If-Unmodified-Since", unmodifiedSince.Format(time.RFC1123)) -} - -// WithCompareAndSwap tells Tigris to skip the cache and read the object from its designated region. -// -// This is only used on GET requests. -// -// See the Tigris documentation[1] for more information. -// -// [1]: https://www.tigrisdata.com/docs/objects/conditionals/ -func WithCompareAndSwap() func(*s3.Options) { - return WithHeader("X-Tigris-CAS", "true") -} - -// Client returns a new S3 client wired up for Tigris. -func Client(ctx context.Context) (*s3.Client, error) { - cfg, err := awsConfig.LoadDefaultConfig(ctx) - if err != nil { - return nil, fmt.Errorf("failed to load Tigris config: %w", err) - } - - return s3.NewFromConfig(cfg, func(o *s3.Options) { - o.BaseEndpoint = aws.String("https://fly.storage.tigris.dev") - o.Region = "auto" - o.UsePathStyle = false - }), nil -}