Do not create objects for directories
Signed-off-by: Sylvain Baubeau <sbaubeau@redhat.com>master
							parent
							
								
									ed08d8d4e0
								
							
						
					
					
						commit
						49582a6188
					
				| 
						 | 
					@ -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 New Issue