Adds "storageclass" configuration parameter for S3 driver.

Defaults to STANDARD, also supports REDUCED_REDUNDANCY.

Signed-off-by: Brian Bland <brian.bland@docker.com>
This commit is contained in:
Brian Bland 2016-01-28 15:48:49 -08:00
parent 2fc586d2a4
commit 4688d1adc2
3 changed files with 46 additions and 9 deletions

View file

@ -124,6 +124,17 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
This is a prefix that will be applied to all S3 keys to allow you to segment data in your bucket if necessary. This is a prefix that will be applied to all S3 keys to allow you to segment data in your bucket if necessary.
</td> </td>
</tr> </tr>
<tr>
<td>
<code>storageclass</code>
</td>
<td>
no
</td>
<td>
The S3 storage class applied to each registry file. The default value is STANDARD.
</td>
</tr>
</table> </table>
@ -147,6 +158,8 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
`rootdirectory`: (optional) The root directory tree in which all registry files will be stored. Defaults to the empty string (bucket root). `rootdirectory`: (optional) The root directory tree in which all registry files will be stored. Defaults to the empty string (bucket root).
`storageclass`: (optional) The storage class applied to each registry file. Defaults to STANDARD. Valid options are STANDARD and REDUCED_REDUNDANCY.
# CloudFront as Middleware with S3 backend # CloudFront as Middleware with S3 backend
## Use Case ## Use Case

View file

@ -1,7 +1,7 @@
// Package s3 provides a storagedriver.StorageDriver implementation to // Package s3 provides a storagedriver.StorageDriver implementation to
// store blobs in Amazon S3 cloud storage. // store blobs in Amazon S3 cloud storage.
// //
// This package leverages the AdRoll/goamz client library for interfacing with // This package leverages the docker/goamz client library for interfacing with
// s3. // s3.
// //
// Because s3 is a key, value store the Stat call does not support last modification // Because s3 is a key, value store the Stat call does not support last modification
@ -59,6 +59,7 @@ type DriverParameters struct {
V4Auth bool V4Auth bool
ChunkSize int64 ChunkSize int64
RootDirectory string RootDirectory string
StorageClass s3.StorageClass
UserAgent string UserAgent string
} }
@ -79,6 +80,7 @@ type driver struct {
ChunkSize int64 ChunkSize int64
Encrypt bool Encrypt bool
RootDirectory string RootDirectory string
StorageClass s3.StorageClass
pool sync.Pool // pool []byte buffers used for WriteStream pool sync.Pool // pool []byte buffers used for WriteStream
zeros []byte // shared, zero-valued buffer used for WriteStream zeros []byte // shared, zero-valued buffer used for WriteStream
@ -183,6 +185,21 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
rootDirectory = "" rootDirectory = ""
} }
storageClass := s3.StandardStorage
storageClassParam, ok := parameters["storageclass"]
if ok {
storageClassString, ok := storageClassParam.(string)
if !ok {
return nil, fmt.Errorf("The storageclass parameter must be one of %v, %v invalid", []s3.StorageClass{s3.StandardStorage, s3.ReducedRedundancy}, storageClassParam)
}
// All valid storage class parameters are UPPERCASE, so be a bit more flexible here
storageClassCasted := s3.StorageClass(strings.ToUpper(storageClassString))
if storageClassCasted != s3.StandardStorage && storageClassCasted != s3.ReducedRedundancy {
return nil, fmt.Errorf("The storageclass parameter must be one of %v, %v invalid", []s3.StorageClass{s3.StandardStorage, s3.ReducedRedundancy}, storageClassParam)
}
storageClass = storageClassCasted
}
userAgent, ok := parameters["useragent"] userAgent, ok := parameters["useragent"]
if !ok { if !ok {
userAgent = "" userAgent = ""
@ -198,6 +215,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
v4AuthBool, v4AuthBool,
chunkSize, chunkSize,
fmt.Sprint(rootDirectory), fmt.Sprint(rootDirectory),
storageClass,
fmt.Sprint(userAgent), fmt.Sprint(userAgent),
} }
@ -259,6 +277,7 @@ func New(params DriverParameters) (*Driver, error) {
ChunkSize: params.ChunkSize, ChunkSize: params.ChunkSize,
Encrypt: params.Encrypt, Encrypt: params.Encrypt,
RootDirectory: params.RootDirectory, RootDirectory: params.RootDirectory,
StorageClass: params.StorageClass,
zeros: make([]byte, params.ChunkSize), zeros: make([]byte, params.ChunkSize),
} }
@ -826,7 +845,10 @@ func hasCode(err error, code string) bool {
} }
func (d *driver) getOptions() s3.Options { func (d *driver) getOptions() s3.Options {
return s3.Options{SSE: d.Encrypt} return s3.Options{
SSE: d.Encrypt,
StorageClass: d.StorageClass,
}
} }
func getPermissions() s3.ACL { func getPermissions() s3.ACL {

View file

@ -10,6 +10,7 @@ import (
storagedriver "github.com/docker/distribution/registry/storage/driver" storagedriver "github.com/docker/distribution/registry/storage/driver"
"github.com/docker/distribution/registry/storage/driver/testsuites" "github.com/docker/distribution/registry/storage/driver/testsuites"
"github.com/docker/goamz/aws" "github.com/docker/goamz/aws"
"github.com/docker/goamz/s3"
"gopkg.in/check.v1" "gopkg.in/check.v1"
) )
@ -69,6 +70,7 @@ func init() {
v4AuthBool, v4AuthBool,
minChunkSize, minChunkSize,
rootDirectory, rootDirectory,
s3.StandardStorage,
"", "",
} }