diff --git a/pkg/core/container/storage.go b/pkg/core/container/storage.go index c79b7c04..bdff45cc 100644 --- a/pkg/core/container/storage.go +++ b/pkg/core/container/storage.go @@ -20,6 +20,15 @@ type Container struct { Session *session.Container } +// DelInfo contains info about removed container. +type DelInfo struct { + // Container owner. + Owner []byte + + // Epoch indicates when the container was removed. + Epoch int +} + // Source is an interface that wraps // basic container receiving method. type Source interface { diff --git a/pkg/morph/client/container/client.go b/pkg/morph/client/container/client.go index 2b5996cd..c8702b1c 100644 --- a/pkg/morph/client/container/client.go +++ b/pkg/morph/client/container/client.go @@ -29,6 +29,7 @@ const ( containersOfMethod = "containersOf" eaclMethod = "eACL" setEACLMethod = "setEACL" + deletionInfoMethod = "deletionInfo" startEstimationMethod = "startContainerEstimation" stopEstimationMethod = "stopContainerEstimation" diff --git a/pkg/morph/client/container/deletion_info.go b/pkg/morph/client/container/deletion_info.go new file mode 100644 index 00000000..094d4e11 --- /dev/null +++ b/pkg/morph/client/container/deletion_info.go @@ -0,0 +1,52 @@ +package container + +import ( + "fmt" + "strings" + + containerContract "git.frostfs.info/TrueCloudLab/frostfs-contract/container" + containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" + apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status" + cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" +) + +func (c *Client) DeletionInfo(cid cid.ID) (*containercore.DelInfo, error) { + prm := client.TestInvokePrm{} + prm.SetMethod(deletionInfoMethod) + prm.SetArgs(cid) + + res, err := c.client.TestInvoke(prm) + if err != nil { + if strings.Contains(err.Error(), containerContract.NotFoundError) { + return nil, new(apistatus.ContainerNotFound) + } + return nil, fmt.Errorf("could not perform test invocation (%s): %w", deletionInfoMethod, err) + } else if ln := len(res); ln != 1 { + return nil, fmt.Errorf("unexpected stack item count (%s): %d", deletionInfoMethod, ln) + } + + arr, err := client.ArrayFromStackItem(res[0]) + if err != nil { + return nil, fmt.Errorf("could not get item array of container (%s): %w", deletionInfoMethod, err) + } + + if len(arr) != 2 { + return nil, fmt.Errorf("unexpected container stack item count (%s): %d", deletionInfoMethod, len(arr)) + } + + owner, err := client.BytesFromStackItem(arr[0]) + if err != nil { + return nil, fmt.Errorf("could not get byte array of container (%s): %w", deletionInfoMethod, err) + } + + epoch, err := client.IntFromStackItem(arr[1]) + if err != nil { + return nil, fmt.Errorf("could not get byte array of container signature (%s): %w", deletionInfoMethod, err) + } + + return &containercore.DelInfo{ + Owner: owner, + Epoch: int(epoch), + }, nil +}