@@ -83,6 +83,22 @@ func (er *endpointsResolver) EndpointFor(service, region string, opts ...func(*e
83
83
return endpoints .DefaultResolver ().EndpointFor (service , region , opts ... )
84
84
}
85
85
86
+ func isUnknownEndpointError (err error ) bool {
87
+ _ , ok := err .(endpoints.UnknownEndpointError )
88
+ return ok
89
+ }
90
+
91
+ func regionHasDualStackS3 (region string ) (bool , error ) {
92
+ _ , err := endpoints .DefaultResolver ().EndpointFor ("s3" , region , endpoints .UseDualStackEndpointOption )
93
+ if isUnknownEndpointError (err ) {
94
+ return false , nil
95
+ }
96
+ if err != nil {
97
+ return false , err
98
+ }
99
+ return true , nil
100
+ }
101
+
86
102
type driver struct {
87
103
Context context.Context
88
104
Config * imageregistryv1.ImageRegistryConfigStorageS3
@@ -237,6 +253,18 @@ func (d *driver) CABundle() (string, bool, error) {
237
253
}
238
254
}
239
255
256
+ // useDualStack returns true if the driver should use dual-stack endpoints
257
+ func (d * driver ) useDualStack () (bool , error ) {
258
+ if d .Config .RegionEndpoint != "" {
259
+ return true , nil
260
+ }
261
+ ok , err := regionHasDualStackS3 (d .Config .Region )
262
+ if err != nil {
263
+ return false , fmt .Errorf ("failed to determine if region %s has dual stack S3: %w" , d .Config .Region , err )
264
+ }
265
+ return ok , nil
266
+ }
267
+
240
268
// getS3Service returns a client that allows us to interact
241
269
// with the aws S3 service
242
270
func (d * driver ) getS3Service () (* s3.S3 , error ) {
@@ -309,7 +337,14 @@ func (d *driver) getS3Service() (*s3.S3, error) {
309
337
awsOptions .Config .HTTPClient .Transport = d .roundTripper
310
338
}
311
339
312
- awsOptions .Config .WithUseDualStack (true )
340
+ useDualStack , err := d .useDualStack ()
341
+ if err != nil {
342
+ return nil , err
343
+ }
344
+ if useDualStack {
345
+ awsOptions .Config .WithUseDualStack (true )
346
+ }
347
+
313
348
if d .Config .RegionEndpoint != "" {
314
349
if ! d .Config .VirtualHostedStyle {
315
350
awsOptions .Config .WithS3ForcePathStyle (true )
@@ -377,10 +412,17 @@ func (d *driver) ConfigEnv() (envs envvar.List, err error) {
377
412
envvar.EnvVar {Name : "REGISTRY_STORAGE_S3_REGION" , Value : d .Config .Region },
378
413
envvar.EnvVar {Name : "REGISTRY_STORAGE_S3_ENCRYPT" , Value : d .Config .Encrypt },
379
414
envvar.EnvVar {Name : "REGISTRY_STORAGE_S3_VIRTUALHOSTEDSTYLE" , Value : d .Config .VirtualHostedStyle },
380
- envvar.EnvVar {Name : "REGISTRY_STORAGE_S3_USEDUALSTACK" , Value : true },
381
415
envvar.EnvVar {Name : "REGISTRY_STORAGE_S3_CREDENTIALSCONFIGPATH" , Value : filepath .Join (imageRegistrySecretMountpoint , imageRegistrySecretDataKey )},
382
416
)
383
417
418
+ useDualStack , err := d .useDualStack ()
419
+ if err != nil {
420
+ return nil , err
421
+ }
422
+ if useDualStack {
423
+ envs = append (envs , envvar.EnvVar {Name : "REGISTRY_STORAGE_S3_USEDUALSTACK" , Value : true })
424
+ }
425
+
384
426
if d .Config .CloudFront != nil {
385
427
// Use structs to make ordering deterministic
386
428
type cloudFrontOptions struct {
0 commit comments