diff --git a/storagedriver/s3/README.md b/storagedriver/s3/README.md index 5a0cd03e..ac99d88d 100644 --- a/storagedriver/s3/README.md +++ b/storagedriver/s3/README.md @@ -19,4 +19,6 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz `secure`: (optional) Whether you would like to transfer data over ssl or not. Defaults to true (meaning transfering over ssl) if not specified. Note that while setting this to false will improve performance, it is not recommended due to security concerns. +`v4auth`: (optional) Whether you would like to use aws signature version 4 with your requests. This defaults to true if not specified (note that the eu-central-1 region does not work with version 2 signatures, so the driver will error out if initialized with this region and v4auth set to false) + `rootdirectory`: (optional) The root directory tree in which all registry files will be stored. Defaults to the empty string (bucket root). \ No newline at end of file diff --git a/storagedriver/s3/s3.go b/storagedriver/s3/s3.go index e8bebd00..a2a6758b 100644 --- a/storagedriver/s3/s3.go +++ b/storagedriver/s3/s3.go @@ -96,28 +96,35 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) { } } - secureBool := false + secureBool := true secure, ok := parameters["secure"] - if !ok { - secureBool = true - } else { + if ok { secureBool, ok = secure.(bool) if !ok { return nil, fmt.Errorf("The secure parameter should be a boolean") } } + v4AuthBool := true + v4Auth, ok := parameters["v4auth"] + if ok { + v4AuthBool, ok = v4Auth.(bool) + if !ok { + return nil, fmt.Errorf("The v4auth parameter should be a boolean") + } + } + rootDirectory, ok := parameters["rootdirectory"] if !ok { rootDirectory = "" } - return New(fmt.Sprint(accessKey), fmt.Sprint(secretKey), fmt.Sprint(bucket), fmt.Sprint(rootDirectory), region, encryptBool, secureBool) + return New(fmt.Sprint(accessKey), fmt.Sprint(secretKey), fmt.Sprint(bucket), fmt.Sprint(rootDirectory), region, encryptBool, secureBool, v4AuthBool) } // New constructs a new Driver with the given AWS credentials, region, encryption flag, and // bucketName -func New(accessKey, secretKey, bucketName, rootDirectory string, region aws.Region, encrypt, secure bool) (*Driver, error) { +func New(accessKey, secretKey, bucketName, rootDirectory string, region aws.Region, encrypt, secure, v4auth bool) (*Driver, error) { auth, err := aws.GetAuth(accessKey, secretKey, "", time.Time{}) if err != nil { return nil, err @@ -130,6 +137,14 @@ func New(accessKey, secretKey, bucketName, rootDirectory string, region aws.Regi s3obj := s3.New(auth, region) bucket := s3obj.Bucket(bucketName) + if v4auth { + s3obj.Signature = aws.V4Signature + } else { + if region.Name == "eu-central-1" { + return nil, fmt.Errorf("The eu-central-1 region only works with v4 authentication") + } + } + if _, err := bucket.List("", "", "", 1); err != nil { return nil, err } @@ -428,7 +443,7 @@ func (d *Driver) WriteStream(path string, offset int64, reader io.Reader) (total } else { // offset > currentLength >= chunkSize _, part, err = multi.PutPartCopy(partNumber, - s3.CopyOptions{CopySourceOptions: "bytes=0-" + strconv.FormatInt(currentLength-1, 10)}, + s3.CopyOptions{}, d.Bucket.Name+"/"+d.s3Path(path)) if err != nil { return 0, err diff --git a/storagedriver/s3/s3_test.go b/storagedriver/s3/s3_test.go index 1addf13b..e3c3e535 100644 --- a/storagedriver/s3/s3_test.go +++ b/storagedriver/s3/s3_test.go @@ -22,6 +22,7 @@ func init() { bucket := os.Getenv("S3_BUCKET") encrypt := os.Getenv("S3_ENCRYPT") secure := os.Getenv("S3_SECURE") + v4auth := os.Getenv("S3_USE_V4_AUTH") region := os.Getenv("AWS_REGION") root, err := ioutil.TempDir("", "driver-") if err != nil { @@ -29,9 +30,12 @@ func init() { } s3DriverConstructor := func(region aws.Region) (storagedriver.StorageDriver, error) { - encryptBool, err := strconv.ParseBool(encrypt) - if err != nil { - return nil, err + encryptBool := true + if encrypt != "" { + encryptBool, err = strconv.ParseBool(encrypt) + if err != nil { + return nil, err + } } secureBool := true @@ -41,7 +45,15 @@ func init() { return nil, err } } - return New(accessKey, secretKey, bucket, root, region, encryptBool, secureBool) + + v4AuthBool := true + if v4auth != "" { + v4AuthBool, err = strconv.ParseBool(v4auth) + if err != nil { + return nil, err + } + } + return New(accessKey, secretKey, bucket, root, region, encryptBool, secureBool, v4AuthBool) } // Skip S3 storage driver tests if environment variable parameters are not provided