forked from TrueCloudLab/frostfs-s3-gw
[#413] Fix delete object without version
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
332de834ae
commit
7e8b57605a
2 changed files with 36 additions and 34 deletions
|
@ -9,8 +9,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
|
||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||||
|
@ -23,6 +21,7 @@ import (
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -252,8 +251,6 @@ type (
|
||||||
const (
|
const (
|
||||||
tagPrefix = "S3-Tag-"
|
tagPrefix = "S3-Tag-"
|
||||||
tagEmptyMark = "\\"
|
tagEmptyMark = "\\"
|
||||||
|
|
||||||
emptyOID = "11111111111111111111111111111111"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *VersionedObject) String() string {
|
func (t *VersionedObject) String() string {
|
||||||
|
@ -556,54 +553,39 @@ func getRandomOID() (*oid.ID, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteObject removes all objects with the passed nice name.
|
// DeleteObject removes all objects with the passed nice name.
|
||||||
func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, _ *data.BucketSettings, obj *VersionedObject) *VersionedObject {
|
func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, settings *data.BucketSettings, obj *VersionedObject) *VersionedObject {
|
||||||
if !isRegularVersion(obj.VersionID) { // version null or empty
|
if len(obj.VersionID) == 0 || obj.VersionID == unversionedObjectVersionID {
|
||||||
randOID, err := getRandomOID()
|
randOID, err := getRandomOID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
obj.Error = fmt.Errorf("couldn't get random oid: %w", err)
|
obj.Error = fmt.Errorf("couldn't get random oid: %w", err)
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
obj.DeleteMarkVersion = randOID.EncodeToString()
|
|
||||||
|
obj.DeleteMarkVersion = unversionedObjectVersionID
|
||||||
newVersion := &NodeVersion{
|
newVersion := &NodeVersion{
|
||||||
BaseNodeVersion: BaseNodeVersion{
|
BaseNodeVersion: BaseNodeVersion{
|
||||||
OID: *randOID,
|
OID: *randOID,
|
||||||
},
|
},
|
||||||
IsDeleteMarker: true,
|
IsDeleteMarker: true,
|
||||||
IsUnversioned: obj.VersionID == unversionedObjectVersionID,
|
IsUnversioned: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(obj.VersionID) == 0 && settings.VersioningEnabled {
|
||||||
|
newVersion.IsUnversioned = false
|
||||||
|
obj.DeleteMarkVersion = randOID.EncodeToString()
|
||||||
|
}
|
||||||
|
|
||||||
if obj.Error = n.treeService.AddVersion(ctx, &bkt.CID, obj.Name, newVersion); obj.Error != nil {
|
if obj.Error = n.treeService.AddVersion(ctx, &bkt.CID, obj.Name, newVersion); obj.Error != nil {
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if obj.VersionID == emptyOID {
|
|
||||||
obj.Error = errors.GetAPIError(errors.ErrInvalidVersion)
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
|
|
||||||
versions, err := n.treeService.GetVersions(ctx, &bkt.CID, obj.Name)
|
versions, err := n.treeService.GetVersions(ctx, &bkt.CID, obj.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
obj.Error = err
|
obj.Error = err
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
var found bool
|
if obj.DeleteMarkVersion, obj.Error = n.removeVersionIfFound(ctx, bkt, versions, obj); obj.Error != nil {
|
||||||
for _, version := range versions {
|
|
||||||
if version.OID.EncodeToString() == obj.VersionID {
|
|
||||||
if err = n.treeService.RemoveVersion(ctx, &bkt.CID, version.ID); err == nil {
|
|
||||||
if err = n.objectDelete(ctx, bkt, version.OID); err == nil {
|
|
||||||
if err = n.DeleteObjectTagging(ctx, bkt, &data.ObjectInfo{ID: version.OID, Bucket: bkt.Name, Name: obj.Name}); err == nil {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
obj.Error = err
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !found {
|
|
||||||
obj.Error = errors.GetAPIError(errors.ErrNoSuchVersion)
|
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -613,8 +595,28 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, _ *data.
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
func isRegularVersion(version string) bool {
|
func (n *layer) removeVersionIfFound(ctx context.Context, bkt *data.BucketInfo, versions []*NodeVersion, obj *VersionedObject) (string, error) {
|
||||||
return len(version) != 0 && version != unversionedObjectVersionID
|
for _, version := range versions {
|
||||||
|
if version.OID.EncodeToString() != obj.VersionID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteMarkVersion string
|
||||||
|
if version.IsDeleteMarker {
|
||||||
|
deleteMarkVersion = obj.VersionID
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := n.treeService.RemoveVersion(ctx, &bkt.CID, version.ID); err != nil {
|
||||||
|
return deleteMarkVersion, err
|
||||||
|
}
|
||||||
|
if err := n.objectDelete(ctx, bkt, version.OID); err != nil {
|
||||||
|
return deleteMarkVersion, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return deleteMarkVersion, n.DeleteObjectTagging(ctx, bkt, &data.ObjectInfo{ID: version.OID, Bucket: bkt.Name, Name: obj.Name})
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.GetAPIError(errors.ErrNoSuchVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteObjects from the storage.
|
// DeleteObjects from the storage.
|
||||||
|
|
|
@ -339,7 +339,7 @@ func (c *TreeClient) addVersion(ctx context.Context, cnrID *cid.ID, treeID, attr
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.moveNode(ctx, cnrID, treeID, version.ID, parentID, meta)
|
return c.moveNode(ctx, cnrID, treeID, node.ID, parentID, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !errors.Is(err, layer.ErrNodeNotFound) {
|
if !errors.Is(err, layer.ErrNodeNotFound) {
|
||||||
|
|
Loading…
Reference in a new issue