Do not create objects for directories

Signed-off-by: Sylvain Baubeau <sbaubeau@redhat.com>
This commit is contained in:
Sylvain Baubeau 2015-07-02 18:25:27 +02:00
parent ed08d8d4e0
commit 49582a6188

View file

@ -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"
} }