Do not create objects for directories
Signed-off-by: Sylvain Baubeau <sbaubeau@redhat.com>
This commit is contained in:
parent
ed08d8d4e0
commit
49582a6188
1 changed files with 29 additions and 36 deletions
|
@ -49,9 +49,6 @@ const defaultChunkSize = 20 * 1024 * 1024
|
||||||
// minChunkSize defines the minimum size of a segment
|
// minChunkSize defines the minimum size of a segment
|
||||||
const minChunkSize = 1 << 20
|
const minChunkSize = 1 << 20
|
||||||
|
|
||||||
// Vendor MIME type used for objects that act as directories
|
|
||||||
const directoryMimeType = "application/vnd.swift.directory"
|
|
||||||
|
|
||||||
// Parameters A struct that encapsulates all of the driver parameters after all values have been set
|
// Parameters A struct that encapsulates all of the driver parameters after all values have been set
|
||||||
type Parameters struct {
|
type Parameters struct {
|
||||||
Username string
|
Username string
|
||||||
|
@ -203,9 +200,6 @@ func (d *driver) GetContent(ctx context.Context, path string) ([]byte, error) {
|
||||||
|
|
||||||
// PutContent stores the []byte content at a location designated by "path".
|
// PutContent stores the []byte content at a location designated by "path".
|
||||||
func (d *driver) PutContent(ctx context.Context, path string, contents []byte) error {
|
func (d *driver) PutContent(ctx context.Context, path string, contents []byte) error {
|
||||||
if err := d.createParentFolders(path); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err := d.Conn.ObjectPutBytes(d.Container, d.swiftPath(path),
|
err := d.Conn.ObjectPutBytes(d.Container, d.swiftPath(path),
|
||||||
contents, d.getContentType())
|
contents, d.getContentType())
|
||||||
return parseError(path, err)
|
return parseError(path, err)
|
||||||
|
@ -265,9 +259,6 @@ func (d *driver) WriteStream(ctx context.Context, path string, offset int64, rea
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == swift.ContainerNotFound || err == swift.ObjectNotFound {
|
if err == swift.ContainerNotFound || err == swift.ObjectNotFound {
|
||||||
// Create a object manifest
|
// Create a object manifest
|
||||||
if err := d.createParentFolders(path); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
manifest, err := d.createManifest(path)
|
manifest, err := d.createManifest(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, parseError(path, err)
|
return 0, parseError(path, err)
|
||||||
|
@ -392,19 +383,40 @@ func (d *driver) WriteStream(ctx context.Context, path string, offset int64, rea
|
||||||
// Stat retrieves the FileInfo for the given path, including the current size
|
// Stat retrieves the FileInfo for the given path, including the current size
|
||||||
// in bytes and the creation time.
|
// in bytes and the creation time.
|
||||||
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
|
func (d *driver) Stat(ctx context.Context, path string) (storagedriver.FileInfo, error) {
|
||||||
info, _, err := d.Conn.Object(d.Container, d.swiftPath(path))
|
swiftPath := d.swiftPath(path)
|
||||||
|
opts := &swift.ObjectsOpts{
|
||||||
|
Prefix: swiftPath,
|
||||||
|
Delimiter: '/',
|
||||||
|
}
|
||||||
|
|
||||||
|
objects, err := d.Conn.ObjectsAll(d.Container, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, parseError(path, err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fi := storagedriver.FileInfoFields{
|
fi := storagedriver.FileInfoFields{
|
||||||
Path: path,
|
Path: strings.TrimPrefix(strings.TrimSuffix(swiftPath, "/"), d.swiftPath("/")),
|
||||||
IsDir: info.ContentType == directoryMimeType,
|
|
||||||
Size: info.Bytes,
|
|
||||||
ModTime: info.LastModified,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, obj := range objects {
|
||||||
|
if obj.PseudoDirectory && obj.Name == swiftPath+"/" {
|
||||||
|
fi.IsDir = true
|
||||||
return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
|
return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
|
||||||
|
} else if obj.Name == swiftPath {
|
||||||
|
// On Swift 1.12, the 'bytes' field is always 0
|
||||||
|
// so we need to do a second HEAD request
|
||||||
|
info, _, err := d.Conn.Object(d.Container, swiftPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, parseError(path, err)
|
||||||
|
}
|
||||||
|
fi.IsDir = false
|
||||||
|
fi.Size = info.Bytes
|
||||||
|
fi.ModTime = info.LastModified
|
||||||
|
return storagedriver.FileInfoInternal{FileInfoFields: fi}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, storagedriver.PathNotFoundError{Path: path}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a list of the objects that are direct descendants of the given path.
|
// List returns a list of the objects that are direct descendants of the given path.
|
||||||
|
@ -423,10 +435,8 @@ func (d *driver) List(ctx context.Context, path string) ([]string, error) {
|
||||||
|
|
||||||
objects, err := d.Conn.Objects(d.Container, opts)
|
objects, err := d.Conn.Objects(d.Container, opts)
|
||||||
for _, obj := range objects {
|
for _, obj := range objects {
|
||||||
if !obj.PseudoDirectory {
|
|
||||||
files = append(files, strings.TrimPrefix(strings.TrimSuffix(obj.Name, "/"), d.swiftPath("/")))
|
files = append(files, strings.TrimPrefix(strings.TrimSuffix(obj.Name, "/"), d.swiftPath("/")))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return files, parseError(path, err)
|
return files, parseError(path, err)
|
||||||
}
|
}
|
||||||
|
@ -516,23 +526,6 @@ func (d *driver) swiftSegmentPath(path string) string {
|
||||||
return strings.TrimLeft(strings.TrimRight(d.Prefix+"/segments"+path, "/"), "/")
|
return strings.TrimLeft(strings.TrimRight(d.Prefix+"/segments"+path, "/"), "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) createParentFolders(path string) error {
|
|
||||||
dir := gopath.Dir(path)
|
|
||||||
for dir != "/" {
|
|
||||||
_, _, err := d.Conn.Object(d.Container, d.swiftPath(dir))
|
|
||||||
if err == swift.ContainerNotFound || err == swift.ObjectNotFound {
|
|
||||||
_, err := d.Conn.ObjectPut(d.Container, d.swiftPath(dir), bytes.NewReader(make([]byte, 0)),
|
|
||||||
false, "", directoryMimeType, nil)
|
|
||||||
if err != nil {
|
|
||||||
return parseError(dir, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dir = gopath.Dir(dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *driver) getContentType() string {
|
func (d *driver) getContentType() string {
|
||||||
return "application/octet-stream"
|
return "application/octet-stream"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue