diff --git a/docs/configuration.md b/docs/configuration.md index 8cd72cae3..af50a6a57 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -118,6 +118,7 @@ storage: secretkey: awssecretkey region: us-west-1 regionendpoint: http://myobjects.local + forcepathstyle: true accelerate: false bucket: bucketname encrypt: true @@ -423,6 +424,7 @@ storage: secretkey: awssecretkey region: us-west-1 regionendpoint: http://myobjects.local + forcepathstyle: true accelerate: false bucket: bucketname encrypt: true diff --git a/docs/storage-drivers/s3.md b/docs/storage-drivers/s3.md index 6e5caaa7c..3122a8979 100644 --- a/docs/storage-drivers/s3.md +++ b/docs/storage-drivers/s3.md @@ -13,8 +13,9 @@ Amazon S3 or S3 compatible services for object storage. |:--------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `accesskey` | no | Your AWS Access Key. If you use [IAM roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html), omit to fetch temporary credentials from IAM. | | `secretkey` | no | Your AWS Secret Key. If you use [IAM roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html), omit to fetch temporary credentials from IAM. | -| `region` | yes | The AWS region in which your bucket exists. For the moment, the Go AWS library in use does not use the newer DNS based bucket routing. | +| `region` | yes | The AWS region in which your bucket exists. | | `regionendpoint` | no | Endpoint for S3 compatible storage services (Minio, etc). | +| `forcepathstyle` | no | To enable path-style addressing when the value is set to `true`. The default is `true`. | | `bucket` | yes | The bucket name in which you want to store the registry's data. | | `encrypt` | no | Specifies whether the registry stores the image in encrypted format or not. A boolean value. The default is `false`. | | `keyid` | no | Optional KMS key ID to use for encryption (encrypt must be true, or this parameter is ignored). The default is `none`. | @@ -35,6 +36,8 @@ Amazon S3 or S3 compatible services for object storage. `regionendpoint`: (optional) Endpoint URL for S3 compatible APIs. This should not be provided when using Amazon S3. +`forcepathstyle`: (optional) The force path style for S3 compatible APIs. Some manufacturers only support force path style, while others only support DNS based bucket routing. Amazon S3 supports both. + `bucket`: The name of your S3 bucket where you wish to store objects. The bucket must exist prior to the driver initialization. `encrypt`: (optional) Whether you would like your data encrypted on the server side (defaults to false if not specified). diff --git a/registry/storage/driver/s3-aws/s3.go b/registry/storage/driver/s3-aws/s3.go index ba76f4248..2e1401b4f 100644 --- a/registry/storage/driver/s3-aws/s3.go +++ b/registry/storage/driver/s3-aws/s3.go @@ -88,6 +88,7 @@ type DriverParameters struct { Bucket string Region string RegionEndpoint string + ForcePathStyle bool Encrypt bool KeyID string Secure bool @@ -189,6 +190,23 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) { regionEndpoint = "" } + forcePathStyleBool := true + forcePathStyle := parameters["forcepathstyle"] + switch forcePathStyle := forcePathStyle.(type) { + case string: + b, err := strconv.ParseBool(forcePathStyle) + if err != nil { + return nil, fmt.Errorf("the forcePathStyle parameter should be a boolean") + } + forcePathStyleBool = b + case bool: + forcePathStyleBool = forcePathStyle + case nil: + // do nothing + default: + return nil, fmt.Errorf("the forcePathStyle parameter should be a boolean") + } + regionName := parameters["region"] if regionName == nil || fmt.Sprint(regionName) == "" { return nil, fmt.Errorf("no region parameter provided") @@ -401,6 +419,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) { fmt.Sprint(bucket), region, fmt.Sprint(regionEndpoint), + forcePathStyleBool, encryptBool, fmt.Sprint(keyID), secureBool, @@ -473,8 +492,8 @@ func New(params DriverParameters) (*Driver, error) { } if params.RegionEndpoint != "" { - awsConfig.WithS3ForcePathStyle(true) awsConfig.WithEndpoint(params.RegionEndpoint) + awsConfig.WithS3ForcePathStyle(params.ForcePathStyle) } awsConfig.WithS3UseAccelerate(params.Accelerate) diff --git a/registry/storage/driver/s3-aws/s3_test.go b/registry/storage/driver/s3-aws/s3_test.go index 41a5fc7da..e5c6e11ad 100644 --- a/registry/storage/driver/s3-aws/s3_test.go +++ b/registry/storage/driver/s3-aws/s3_test.go @@ -41,6 +41,7 @@ func init() { objectACL := os.Getenv("S3_OBJECT_ACL") root, err := ioutil.TempDir("", "driver-") regionEndpoint := os.Getenv("REGION_ENDPOINT") + forcePathStyle := os.Getenv("AWS_S3_FORCE_PATH_STYLE") sessionToken := os.Getenv("AWS_SESSION_TOKEN") useDualStack := os.Getenv("S3_USE_DUALSTACK") combineSmallPart := os.Getenv("MULTIPART_COMBINE_SMALL_PART") @@ -82,6 +83,13 @@ func init() { return nil, err } } + forcePathStyleBool := true + if forcePathStyle != "" { + forcePathStyleBool, err = strconv.ParseBool(forcePathStyle) + if err != nil { + return nil, err + } + } useDualStackBool := false if useDualStack != "" { @@ -110,6 +118,7 @@ func init() { bucket, region, regionEndpoint, + forcePathStyleBool, encryptBool, keyID, secureBool,