Use mitchellh/mapstructure library to parse Swift parameters

Signed-off-by: Sylvain Baubeau <sbaubeau@redhat.com>
pull/493/head
Sylvain Baubeau 2015-05-29 16:12:58 +02:00
parent 2632fd9dc8
commit 4497d6c973
2 changed files with 48 additions and 58 deletions

4
Godeps/Godeps.json generated
View File

@ -82,6 +82,10 @@
"ImportPath": "github.com/stevvooe/resumable", "ImportPath": "github.com/stevvooe/resumable",
"Rev": "51ad44105773cafcbe91927f70ac68e1bf78f8b4" "Rev": "51ad44105773cafcbe91927f70ac68e1bf78f8b4"
}, },
"ImportPath": "github.com/mitchellh/mapstructure",
"Rev": "482a9fd5fa83e8c4e7817413b80f3eb8feec03ef"
},
{
"ImportPath": "github.com/ncw/swift", "ImportPath": "github.com/ncw/swift",
"Rev": "021f1ecdb0940ce5c64ce0e27928d9680f85f291" "Rev": "021f1ecdb0940ce5c64ce0e27928d9680f85f291"
}, },

View File

@ -21,6 +21,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/mitchellh/mapstructure"
"github.com/ncw/swift" "github.com/ncw/swift"
"github.com/docker/distribution/context" "github.com/docker/distribution/context"
@ -33,6 +34,10 @@ const driverName = "swift"
const defaultChunkSize = 5 * 1024 * 1024 const defaultChunkSize = 5 * 1024 * 1024
const minChunkSize = 1 << 20
const directoryMimeType = "application/directory"
//DriverParameters A struct that encapsulates all of the driver parameters after all values have been set //DriverParameters A struct that encapsulates all of the driver parameters after all values have been set
type DriverParameters struct { type DriverParameters struct {
Username string Username string
@ -42,7 +47,7 @@ type DriverParameters struct {
Region string Region string
Container string Container string
Prefix string Prefix string
ChunkSize int64 ChunkSize int
} }
type swiftInfo map[string]interface{} type swiftInfo map[string]interface{}
@ -63,7 +68,7 @@ type driver struct {
Container string Container string
Prefix string Prefix string
BulkDeleteSupport bool BulkDeleteSupport bool
ChunkSize int64 ChunkSize int
} }
type baseEmbed struct { type baseEmbed struct {
@ -83,52 +88,32 @@ type Driver struct {
// - authurl // - authurl
// - container // - container
func FromParameters(parameters map[string]interface{}) (*Driver, error) { func FromParameters(parameters map[string]interface{}) (*Driver, error) {
username, ok := parameters["username"] params := DriverParameters{
if !ok || fmt.Sprint(username) == "" { ChunkSize: defaultChunkSize,
return nil, fmt.Errorf("No username parameter provided")
}
password, ok := parameters["password"]
if !ok || fmt.Sprint(password) == "" {
return nil, fmt.Errorf("No password parameter provided")
}
authURL, ok := parameters["authurl"]
if !ok || fmt.Sprint(authURL) == "" {
return nil, fmt.Errorf("No container parameter provided")
}
container, ok := parameters["container"]
if !ok || fmt.Sprint(container) == "" {
return nil, fmt.Errorf("No container parameter provided")
}
tenant, ok := parameters["tenant"]
if !ok {
tenant = ""
}
region, ok := parameters["region"]
if !ok {
region = ""
}
rootDirectory, ok := parameters["rootdirectory"]
if !ok {
rootDirectory = ""
}
chunkSize := int64(defaultChunkSize)
chunkSizeParam, ok := parameters["chunksize"]
if ok {
chunkSize, ok = chunkSizeParam.(int64)
if !ok {
return nil, fmt.Errorf("The chunksize parameter should be a number")
}
} }
params := DriverParameters{ if err := mapstructure.Decode(parameters, &params); err != nil {
fmt.Sprint(username), return nil, err
fmt.Sprint(password), }
fmt.Sprint(authURL),
fmt.Sprint(tenant), if params.Username == "" {
fmt.Sprint(region), return nil, fmt.Errorf("No username parameter provided")
fmt.Sprint(container), }
fmt.Sprint(rootDirectory),
chunkSize, if params.Password == "" {
return nil, fmt.Errorf("No password parameter provided")
}
if params.AuthURL == "" {
return nil, fmt.Errorf("No authurl parameter provided")
}
if params.Container == "" {
return nil, fmt.Errorf("No container parameter provided")
}
if params.ChunkSize < minChunkSize {
return nil, fmt.Errorf("The chunksize %#v parameter should be a number that is larger than or equal to %d", params.ChunkSize, minChunkSize)
} }
return New(params) return New(params)
@ -231,13 +216,14 @@ func (d *driver) WriteStream(ctx context.Context, path string, offset int64, rea
var ( var (
segments []swift.Object segments []swift.Object
paddingReader io.Reader paddingReader io.Reader
bytesRead int64
currentLength int64
cursor int64
) )
partNumber := int64(1) partNumber := 1
bytesRead := int64(0) chunkSize := int64(d.ChunkSize)
currentLength := int64(0)
zeroBuf := make([]byte, d.ChunkSize) zeroBuf := make([]byte, d.ChunkSize)
cursor := int64(0)
segmentsContainer := d.getSegmentsContainer() segmentsContainer := d.getSegmentsContainer()
getSegment := func() string { getSegment := func() string {
@ -287,12 +273,12 @@ func (d *driver) WriteStream(ctx context.Context, path string, offset int64, rea
// We reached the end of the file but we haven't reached 'offset' yet // We reached the end of the file but we haven't reached 'offset' yet
// Therefore we add blocks of zeros // Therefore we add blocks of zeros
if offset >= currentLength { if offset >= currentLength {
for offset-currentLength >= d.ChunkSize { for offset-currentLength >= chunkSize {
// Insert a block a zero // Insert a block a zero
d.Conn.ObjectPut(segmentsContainer, getSegment(), d.Conn.ObjectPut(segmentsContainer, getSegment(),
bytes.NewReader(zeroBuf), false, "", bytes.NewReader(zeroBuf), false, "",
d.getContentType(), nil) d.getContentType(), nil)
currentLength += d.ChunkSize currentLength += chunkSize
partNumber++ partNumber++
} }
@ -309,7 +295,7 @@ func (d *driver) WriteStream(ctx context.Context, path string, offset int64, rea
multi := io.MultiReader( multi := io.MultiReader(
io.LimitReader(paddingReader, offset-cursor), io.LimitReader(paddingReader, offset-cursor),
io.LimitReader(reader, d.ChunkSize-(offset-cursor)), io.LimitReader(reader, chunkSize-(offset-cursor)),
) )
for { for {
@ -323,12 +309,12 @@ func (d *driver) WriteStream(ctx context.Context, path string, offset int64, rea
return bytesRead, parseError(path, err) return bytesRead, parseError(path, err)
} }
if n < d.ChunkSize { if n < chunkSize {
// We wrote all the data // We wrote all the data
if cursor+n < currentLength { if cursor+n < currentLength {
// Copy the end of the chunk // Copy the end of the chunk
headers := make(swift.Headers) headers := make(swift.Headers)
headers["Range"] = "bytes=" + strconv.FormatInt(cursor+n, 10) + "-" + strconv.FormatInt(cursor+d.ChunkSize, 10) headers["Range"] = "bytes=" + strconv.FormatInt(cursor+n, 10) + "-" + strconv.FormatInt(cursor+chunkSize, 10)
file, _, err := d.Conn.ObjectOpen(d.Container, d.swiftPath(path), false, headers) file, _, err := d.Conn.ObjectOpen(d.Container, d.swiftPath(path), false, headers)
if err != nil { if err != nil {
return bytesRead, parseError(path, err) return bytesRead, parseError(path, err)
@ -347,8 +333,8 @@ func (d *driver) WriteStream(ctx context.Context, path string, offset int64, rea
currentSegment.Close() currentSegment.Close()
bytesRead += n - max(0, offset-cursor) bytesRead += n - max(0, offset-cursor)
multi = io.MultiReader(io.LimitReader(reader, d.ChunkSize)) multi = io.MultiReader(io.LimitReader(reader, chunkSize))
cursor += d.ChunkSize cursor += chunkSize
partNumber++ partNumber++
} }
@ -365,7 +351,7 @@ func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo,
fi := storagedriver.FileInfoFields{ fi := storagedriver.FileInfoFields{
Path: path, Path: path,
IsDir: info.ContentType == "application/directory", IsDir: info.ContentType == directoryMimeType,
Size: info.Bytes, Size: info.Bytes,
ModTime: info.LastModified, ModTime: info.LastModified,
} }