mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-03 16:56:56 +00:00
try and use pull_zone
This commit is contained in:
@@ -31,6 +31,8 @@ storage:
|
||||
bucket: ""
|
||||
# Custom S3 endpoint for non-AWS providers (e.g. "https://gateway.storjshare.io").
|
||||
endpoint: ""
|
||||
# CDN pull zone URL for downloads. When set, presigned GET/HEAD URLs use this host instead of the S3 endpoint. Uploads and API calls still use the S3 endpoint.
|
||||
pull_zone: ""
|
||||
# HTTP server and identity settings.
|
||||
server:
|
||||
# Listen address, e.g. ":8080" or "0.0.0.0:8080".
|
||||
@@ -39,6 +41,8 @@ server:
|
||||
public_url: ""
|
||||
# Allow unauthenticated blob reads. If false, readers need crew membership.
|
||||
public: false
|
||||
# DID of successor hold for migration. Appview redirects all requests to the successor.
|
||||
successor: ""
|
||||
# Use localhost for OAuth redirects during development.
|
||||
test_mode: false
|
||||
# Request crawl from this relay on startup to make the embedded PDS discoverable.
|
||||
|
||||
@@ -13,10 +13,12 @@ storage:
|
||||
region: "{{.S3Region}}"
|
||||
bucket: "{{.S3Bucket}}"
|
||||
endpoint: "{{.S3Endpoint}}"
|
||||
pull_zone: ""
|
||||
server:
|
||||
addr: :8080
|
||||
public_url: "https://{{.HoldDomain}}"
|
||||
public: false
|
||||
successor: ""
|
||||
test_mode: false
|
||||
relay_endpoint: ""
|
||||
read_timeout: 5m0s
|
||||
@@ -35,6 +37,8 @@ database:
|
||||
libsql_sync_interval: 1m0s
|
||||
admin:
|
||||
enabled: true
|
||||
gc:
|
||||
enabled: false
|
||||
quota:
|
||||
tiers:
|
||||
deckhand:
|
||||
|
||||
@@ -81,6 +81,9 @@ type StorageConfig struct {
|
||||
// Custom S3 endpoint for non-AWS providers.
|
||||
Endpoint string `yaml:"endpoint" comment:"Custom S3 endpoint for non-AWS providers (e.g. \"https://gateway.storjshare.io\")."`
|
||||
|
||||
// CDN pull zone URL for presigned download URLs.
|
||||
PullZone string `yaml:"pull_zone" comment:"CDN pull zone URL for downloads. When set, presigned GET/HEAD URLs use this host instead of the S3 endpoint. Uploads and API calls still use the S3 endpoint."`
|
||||
|
||||
// Internal distribution storage config, built from the above fields.
|
||||
distStorage configuration.Storage `yaml:"-"`
|
||||
}
|
||||
@@ -188,6 +191,7 @@ func setHoldDefaults(v *viper.Viper) {
|
||||
v.SetDefault("storage.region", "us-east-1")
|
||||
v.SetDefault("storage.bucket", "")
|
||||
v.SetDefault("storage.endpoint", "")
|
||||
v.SetDefault("storage.pull_zone", "")
|
||||
|
||||
// GC defaults
|
||||
v.SetDefault("gc.enabled", false)
|
||||
@@ -244,6 +248,7 @@ func LoadConfig(yamlPath string) (*Config, error) {
|
||||
_ = v.BindEnv("storage.region", "AWS_REGION")
|
||||
_ = v.BindEnv("storage.bucket", "S3_BUCKET")
|
||||
_ = v.BindEnv("storage.endpoint", "S3_ENDPOINT")
|
||||
_ = v.BindEnv("storage.pull_zone", "S3_PULL_ZONE")
|
||||
|
||||
// Bind legacy GC env vars (backward compat)
|
||||
_ = v.BindEnv("gc.enabled", "GC_ENABLED")
|
||||
@@ -298,6 +303,9 @@ func buildStorageConfigFromFields(sc StorageConfig) configuration.Storage {
|
||||
params["regionendpoint"] = sc.Endpoint
|
||||
params["forcepathstyle"] = true
|
||||
}
|
||||
if sc.PullZone != "" {
|
||||
params["pullzone"] = sc.PullZone
|
||||
}
|
||||
|
||||
storageCfg := configuration.Storage{}
|
||||
storageCfg["s3"] = configuration.Parameters(params)
|
||||
|
||||
+22
-4
@@ -33,8 +33,9 @@ type S3Client interface {
|
||||
|
||||
// RealS3Client wraps AWS SDK v2 *s3.Client to implement S3Client interface
|
||||
type RealS3Client struct {
|
||||
client *awss3.Client
|
||||
presign *awss3.PresignClient
|
||||
client *awss3.Client
|
||||
presign *awss3.PresignClient
|
||||
pullZone string // CDN pull zone URL for presigned GET/HEAD URLs
|
||||
}
|
||||
|
||||
// NewRealS3Client creates a new RealS3Client wrapper
|
||||
@@ -64,6 +65,11 @@ func (r *RealS3Client) AbortMultipartUpload(ctx context.Context, input *awss3.Ab
|
||||
func (r *RealS3Client) PresignGetObject(ctx context.Context, input *awss3.GetObjectInput, expires time.Duration) (string, error) {
|
||||
result, err := r.presign.PresignGetObject(ctx, input, func(opts *awss3.PresignOptions) {
|
||||
opts.Expires = expires
|
||||
if r.pullZone != "" {
|
||||
opts.ClientOptions = append(opts.ClientOptions, func(o *awss3.Options) {
|
||||
o.BaseEndpoint = aws.String(r.pullZone)
|
||||
})
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -75,6 +81,11 @@ func (r *RealS3Client) PresignGetObject(ctx context.Context, input *awss3.GetObj
|
||||
func (r *RealS3Client) PresignHeadObject(ctx context.Context, input *awss3.HeadObjectInput, expires time.Duration) (string, error) {
|
||||
result, err := r.presign.PresignHeadObject(ctx, input, func(opts *awss3.PresignOptions) {
|
||||
opts.Expires = expires
|
||||
if r.pullZone != "" {
|
||||
opts.ClientOptions = append(opts.ClientOptions, func(o *awss3.Options) {
|
||||
o.BaseEndpoint = aws.String(r.pullZone)
|
||||
})
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -162,14 +173,21 @@ func NewS3Service(params map[string]any) (*S3Service, error) {
|
||||
s3PathPrefix = strings.TrimPrefix(rootDir, "/")
|
||||
}
|
||||
|
||||
// CDN pull zone for presigned download URLs
|
||||
pullZone, _ := params["pullzone"].(string)
|
||||
|
||||
slog.Info("S3 presigned URLs enabled",
|
||||
"bucket", bucket,
|
||||
"region", region,
|
||||
"pathPrefix", s3PathPrefix)
|
||||
"pathPrefix", s3PathPrefix,
|
||||
"pullZone", pullZone)
|
||||
|
||||
// Create S3 client wrapped in RealS3Client for interface compatibility
|
||||
realClient := NewRealS3Client(client)
|
||||
realClient.pullZone = pullZone
|
||||
|
||||
return &S3Service{
|
||||
Client: NewRealS3Client(client),
|
||||
Client: realClient,
|
||||
Bucket: bucket,
|
||||
PathPrefix: s3PathPrefix,
|
||||
}, nil
|
||||
|
||||
Reference in New Issue
Block a user