forked from TrueCloudLab/distribution
Use mitchellh/mapstructure library to parse Swift parameters
Signed-off-by: Sylvain Baubeau <sbaubeau@redhat.com>
This commit is contained in:
parent
ea81e208a4
commit
75ce67c469
1 changed files with 44 additions and 58 deletions
|
@ -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, ¶ms); 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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue