From f5a9735e1c7121ec0962cad200c191eda51b1fb9 Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Mon, 20 Dec 2021 13:03:29 +0300 Subject: [PATCH] [#1048] cli: Add `shard list` operation Signed-off-by: Pavel Karpy --- cmd/neofs-cli/modules/control.go | 85 ++++++++++++++++++++++++++++++++ pkg/services/control/types.go | 6 +-- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/cmd/neofs-cli/modules/control.go b/cmd/neofs-cli/modules/control.go index c11b05cc2..94d90ac07 100644 --- a/cmd/neofs-cli/modules/control.go +++ b/cmd/neofs-cli/modules/control.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "fmt" + "github.com/mr-tron/base58" "github.com/nspcc-dev/neofs-node/pkg/services/control" ircontrol "github.com/nspcc-dev/neofs-node/pkg/services/control/ir" ircontrolsrv "github.com/nspcc-dev/neofs-node/pkg/services/control/ir/server" @@ -47,6 +48,19 @@ var setNetmapStatusCmd = &cobra.Command{ Run: setNetmapStatus, } +var listShardsCmd = &cobra.Command{ + Use: "list", + Short: "List shards of the storage node", + Long: "List shards of the storage node", + Run: listShards, +} + +var shardsCmd = &cobra.Command{ + Use: "shards", + Short: "Operations with storage node's shards", + Long: "Operations with storage node's shards", +} + const ( netmapStatusFlag = "status" @@ -82,6 +96,14 @@ func initControlHealthCheckCmd() { flags.BoolVar(&healthCheckIRVar, healthcheckIRFlag, false, "Communicate with IR node") } +func initControlShardsListCmd() { + initCommonFlagsWithoutRPC(listShardsCmd) + + flags := listShardsCmd.Flags() + + flags.String(controlRPC, controlRPCDefault, controlRPCUsage) +} + func initControlSetNetmapStatusCmd() { initCommonFlagsWithoutRPC(setNetmapStatusCmd) @@ -124,17 +146,21 @@ func initControlSnapshotCmd() { func init() { rootCmd.AddCommand(controlCmd) + shardsCmd.AddCommand(listShardsCmd) + controlCmd.AddCommand( healthCheckCmd, setNetmapStatusCmd, dropObjectsCmd, snapshotCmd, + shardsCmd, ) initControlHealthCheckCmd() initControlSetNetmapStatusCmd() initControlDropObjectsCmd() initControlSnapshotCmd() + initControlShardsListCmd() } func healthCheck(cmd *cobra.Command, _ []string) { @@ -335,6 +361,34 @@ var snapshotCmd = &cobra.Command{ }, } +func listShards(cmd *cobra.Command, _ []string) { + key, err := getKey() + exitOnErr(cmd, err) + + req := new(control.ListShardsRequest) + req.SetBody(new(control.ListShardsRequest_Body)) + + err = controlSvc.SignMessage(key, req) + exitOnErr(cmd, errf("could not sign request: %w", err)) + + cli, err := getControlSDKClient(key) + exitOnErr(cmd, err) + + resp, err := control.ListShards(cli.Raw(), req) + exitOnErr(cmd, errf("rpc error: %w", err)) + + sign := resp.GetSignature() + err = signature.VerifyDataWithSource( + resp, + func() ([]byte, []byte) { + return sign.GetKey(), sign.GetSign() + }, + ) + exitOnErr(cmd, errf("invalid response signature: %w", err)) + + prettyPrintShards(cmd, resp.GetBody().GetShards()) +} + // getControlSDKClient is the same getSDKClient but with // another RPC endpoint flag. func getControlSDKClient(key *ecdsa.PrivateKey) (client.Client, error) { @@ -359,3 +413,34 @@ func getControlSDKClient(key *ecdsa.PrivateKey) (client.Client, error) { return c, err } + +func prettyPrintShards(cmd *cobra.Command, ii []*control.ShardInfo) { + for _, i := range ii { + var mode string + + switch i.GetMode() { + case control.ShardMode_READ_WRITE: + mode = "read-write" + case control.ShardMode_READ_ONLY: + mode = "read-only" + default: + mode = "unknown" + } + + pathPrinter := func(name, path string) string { + if path == "" { + return "" + } + + return fmt.Sprintf("%s: %s\n", name, path) + } + + cmd.Printf("Shard %s:\nMode: %s\n"+ + pathPrinter("Metabase", i.GetMetabasePath())+ + pathPrinter("Blobstor", i.GetBlobstorPath())+ + pathPrinter("Write-cache", i.GetWritecachePath())+"\n", + base58.Encode(i.Shard_ID), + mode, + ) + } +} diff --git a/pkg/services/control/types.go b/pkg/services/control/types.go index 08f7a4c60..b21a1cd43 100644 --- a/pkg/services/control/types.go +++ b/pkg/services/control/types.go @@ -329,7 +329,7 @@ func (x *ShardInfo) SetMetabasePath(v string) { // SetBlobstorePath sets path to shard's blobstore. func (x *ShardInfo) SetBlobstorePath(v string) { - x.BlobstorePath = v + x.BlobstorPath = v } // SetWriteCachePath sets path to shard's write-cache. @@ -364,7 +364,7 @@ func (x *ShardInfo) StableSize() int { size += proto.BytesSize(shardInfoIDFNum, x.Shard_ID) size += proto.StringSize(shardInfoMetabaseFNum, x.MetabasePath) - size += proto.StringSize(shardInfoBlobstoreFNum, x.BlobstorePath) + size += proto.StringSize(shardInfoBlobstoreFNum, x.BlobstorPath) size += proto.StringSize(shardInfoWriteCacheFNum, x.WritecachePath) size += proto.EnumSize(shardInfoModeFNum, int32(x.Mode)) @@ -408,7 +408,7 @@ func (x *ShardInfo) StableMarshal(buf []byte) ([]byte, error) { offset += n - n, err = proto.StringMarshal(shardInfoBlobstoreFNum, buf[offset:], x.BlobstorePath) + n, err = proto.StringMarshal(shardInfoBlobstoreFNum, buf[offset:], x.BlobstorPath) if err != nil { return nil, err }