Skip to content

Commit

Permalink
neofs-cli/control: add object revive control command
Browse files Browse the repository at this point in the history
Support command that revive object by purging all removal marks from all
metabases.

```
$ neofs-cli control object status --endpoint s04.neofs.devenv:8081 -w
services/storage/wallet04.json --object 4yYJV2AyHaJ3fpVimEihAj6NTkwmanbwE7YatJUWBPyM/CYUeRyjfiNXhBMW9XZmdSBJNVLXYBH3gSNQASWTGZX8t
Enter password >
Shard ID: 2wEzFvWsao9yBiDWKjSBfF
	metabase: AVAILABLE
	peapod: path: "/storage/peapod1.db"
$ neofs-cli object delete -r s04.neofs.devenv:8080 -w services/storage/wallet04
.json --cid 4yYJV2AyHaJ3fpVimEihAj6NTkwmanbwE7YatJUWBPyM --oid CYUeRyjfiNXhBMW9XZmdSBJNVLXYBH3gSNQASWTGZX8t
Enter password >
Object CYUeRyjfiNXhBMW9XZmdSBJNVLXYBH3gSNQASWTGZX8t removed successfully.
  ID: C2LrMExCF3FTfQaFYYZfoDGLpsUVLUy156pUpWh72YeN
  CID: 4yYJV2AyHaJ3fpVimEihAj6NTkwmanbwE7YatJUWBPyM
$ neofs-cli control object status --endpoint s04.neofs.devenv:8081 -w
services/storage/wallet04.json --object 4yYJV2AyHaJ3fpVimEihAj6NTkwmanbwE7YatJUWBPyM/CYUeRyjfiNXhBMW9XZmdSBJNVLXYBH3gSNQASWTGZX8t
Enter password >
Shard ID: 2wEzFvWsao9yBiDWKjSBfF
	metabase: AVAILABLE,IN GRAVEYARD
	peapod: path: "/storage/peapod1.db"
$ neofs-cli control object revive --endpoint s04.neofs.devenv:8081 -w
services/storage/wallet04.json --object 4yYJV2AyHaJ3fpVimEihAj6NTkwmanbwE7YatJUWBPyM/CYUeRyjfiNXhBMW9XZmdSBJNVLXYBH3gSNQASWTGZX8t
Enter password >
Shard ID: Vuy2Q8QaPZSuUxDycPxSBC
Revival status: don't revive, err: logical error: object neither in the graveyard nor was marked with GC mark
Shard ID: 2wEzFvWsao9yBiDWKjSBfF
Revival status: successful revival from graveyard, tomb: 4yYJV2AyHaJ3fpVimEihAj6NTkwmanbwE7YatJUWBPyM/C2LrMExCF3FTfQaFYYZfoDGLpsUVLUy156pUpWh72YeN
$ neofs-cli control object status --endpoint s04.neofs.devenv:8081 -w
services/storage/wallet04.json --object 4yYJV2AyHaJ3fpVimEihAj6NTkwmanbwE7YatJUWBPyM/CYUeRyjfiNXhBMW9XZmdSBJNVLXYBH3gSNQASWTGZX8t
Enter password >
Shard ID: 2wEzFvWsao9yBiDWKjSBfF
	metabase: AVAILABLE
	peapod: path: "/storage/peapod1.db"
```

Closes #1450.

Signed-off-by: Andrey Butusov <[email protected]>
  • Loading branch information
End-rey committed Oct 17, 2024
1 parent 66fdf01 commit 7399fa6
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Changelog for NeoFS Node
- `node` config option `storage.ignore_uninited_shards` (#2953)
- For `neofs-cli container create`, add `--global-name` flag, that sets name attribute as the value of `__NEOFS__NAME`
attribute, which is used for container domain name in NNS contracts (#2954)
- `neofs-cli control object revive` command (#2968)

### Fixed
- Do not search for tombstones when handling their expiration, use local indexes instead (#2929)
Expand Down
4 changes: 4 additions & 0 deletions cmd/neofs-cli/modules/control/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"github.com/spf13/cobra"
)

const objectFlag = "object"

var objectCmd = &cobra.Command{
Use: "object",
Short: "Direct object operations with storage engine",
Expand All @@ -12,7 +14,9 @@ var objectCmd = &cobra.Command{
func initControlObjectsCmd() {
objectCmd.AddCommand(listObjectsCmd)
objectCmd.AddCommand(objectStatusCmd)
objectCmd.AddCommand(reviveObjectCmd)

initControlObjectReviveCmd()
initControlObjectsListCmd()
initObjectStatusFlags()
}
89 changes: 89 additions & 0 deletions cmd/neofs-cli/modules/control/object_revive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package control

import (
"fmt"

rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
"github.com/nspcc-dev/neofs-node/pkg/services/control"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/spf13/cobra"
)

var reviveObjectCmd = &cobra.Command{
Use: "revive",
Short: "Forcefully revive object",
Long: "Purge removal marks from metabases",
Args: cobra.NoArgs,
RunE: reviveObject,
}

func initControlObjectReviveCmd() {
initControlFlags(reviveObjectCmd)

flags := reviveObjectCmd.Flags()
flags.String(objectFlag, "", "Object address")
}

func reviveObject(cmd *cobra.Command, _ []string) error {
ctx, cancel := commonflags.GetCommandContext(cmd)
defer cancel()

pk, err := key.Get(cmd)
if err != nil {
return err
}
addressRaw, err := cmd.Flags().GetString(objectFlag)
if err != nil {
return fmt.Errorf("reading %s flag: %w", objectFlag, err)
}

var sdkAddr oid.Address
err = sdkAddr.DecodeString(addressRaw)
if err != nil {
return fmt.Errorf("validating address (%s): %w", addressRaw, err)
}

var resp *control.ReviveObjectResponse
req := &control.ReviveObjectRequest{
Body: &control.ReviveObjectRequest_Body{
ObjectAddress: addressRaw,
},
}
err = signRequest(pk, req)
if err != nil {
return err
}

cli, err := getClient(ctx)
if err != nil {
return err
}

err = cli.ExecRaw(func(client *rawclient.Client) error {
resp, err = control.ReviveObject(client, req)
return err
})
if err != nil {
return fmt.Errorf("rpc error: %w", err)
}

err = verifyResponse(resp.GetSignature(), resp.GetBody())
if err != nil {
return err
}

shards := resp.GetBody().GetShards()
if len(shards) == 0 {
cmd.Println("<empty response>")
return nil
}

for _, shard := range shards {
cmd.Printf("Shard ID: %s\n", shard.ShardId)
cmd.Printf("Revival status: %s\n", shard.Status)
}

return nil
}
2 changes: 0 additions & 2 deletions cmd/neofs-cli/modules/control/object_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"github.com/spf13/cobra"
)

const objectFlag = "object"

var objectStatusCmd = &cobra.Command{
Use: "status",
Short: "Check current object status",
Expand Down

0 comments on commit 7399fa6

Please sign in to comment.