Protect against deletion of objects with the same prefix
Signed-off-by: Sylvain Baubeau <sbaubeau@redhat.com>
This commit is contained in:
parent
61e3bce794
commit
78d722e708
1 changed files with 22 additions and 12 deletions
|
@ -447,32 +447,36 @@ func (d *driver) Move(ctx context.Context, sourcePath string, destPath string) e
|
||||||
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
||||||
func (d *driver) Delete(ctx context.Context, path string) error {
|
func (d *driver) Delete(ctx context.Context, path string) error {
|
||||||
opts := swift.ObjectsOpts{
|
opts := swift.ObjectsOpts{
|
||||||
Prefix: d.swiftPath(path),
|
Prefix: d.swiftPath(path) + "/",
|
||||||
}
|
}
|
||||||
|
|
||||||
objects, err := d.Conn.ObjectNamesAll(d.Container, &opts)
|
objects, err := d.Conn.Objects(d.Container, &opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return parseError(path, err)
|
return parseError(path, err)
|
||||||
}
|
}
|
||||||
if len(objects) == 0 {
|
|
||||||
return storagedriver.PathNotFoundError{Path: path}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.BulkDeleteSupport {
|
if d.BulkDeleteSupport {
|
||||||
if _, err := d.Conn.BulkDelete(d.Container, objects); err != swift.Forbidden {
|
filenames := make([]string, len(objects))
|
||||||
|
for i, obj := range objects {
|
||||||
|
filenames[i] = obj.Name
|
||||||
|
}
|
||||||
|
if _, err := d.Conn.BulkDelete(d.Container, filenames); err != swift.Forbidden {
|
||||||
return parseError(path, err)
|
return parseError(path, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range objects {
|
for _, obj := range objects {
|
||||||
if _, headers, err := d.Conn.Object(d.Container, name); err == nil {
|
if obj.PseudoDirectory {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, headers, err := d.Conn.Object(d.Container, obj.Name); err == nil {
|
||||||
manifest, ok := headers["X-Object-Manifest"]
|
manifest, ok := headers["X-Object-Manifest"]
|
||||||
if ok {
|
if ok {
|
||||||
components := strings.SplitN(manifest, "/", 2)
|
components := strings.SplitN(manifest, "/", 2)
|
||||||
segContainer := components[0]
|
segContainer := components[0]
|
||||||
segments, err := d.getAllSegments(components[1])
|
segments, err := d.getAllSegments(components[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return parseError(name, err)
|
return parseError(obj.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range segments {
|
for _, s := range segments {
|
||||||
|
@ -482,14 +486,20 @@ func (d *driver) Delete(ctx context.Context, path string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return parseError(name, err)
|
return parseError(obj.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d.Conn.ObjectDelete(d.Container, name); err != nil {
|
if err := d.Conn.ObjectDelete(d.Container, obj.Name); err != nil {
|
||||||
return parseError(name, err)
|
return parseError(obj.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := d.Stat(ctx, path); err == nil {
|
||||||
|
return parseError(path, d.Conn.ObjectDelete(d.Container, d.swiftPath(path)))
|
||||||
|
} else if len(objects) == 0 {
|
||||||
|
return storagedriver.PathNotFoundError{Path: path}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue