package tree import ( "crypto/sha256" "errors" "io" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/tree" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" "github.com/spf13/cobra" ) var moveCmd = &cobra.Command{ Use: "move", Short: "Move node", Run: move, PersistentPreRun: func(cmd *cobra.Command, _ []string) { commonflags.Bind(cmd) }, } func initMoveCmd() { commonflags.Init(moveCmd) initCTID(moveCmd) ff := moveCmd.Flags() ff.Uint64(nodeIDFlagKey, 0, "Node ID.") ff.Uint64(parentIDFlagKey, 0, "Parent ID.") _ = getSubtreeCmd.MarkFlagRequired(nodeIDFlagKey) _ = getSubtreeCmd.MarkFlagRequired(parentIDFlagKey) _ = cobra.MarkFlagRequired(ff, commonflags.RPC) } func move(cmd *cobra.Command, _ []string) { pk := key.GetOrGenerate(cmd) cidString, _ := cmd.Flags().GetString(commonflags.CIDFlag) var cnr cid.ID err := cnr.DecodeString(cidString) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) ctx := cmd.Context() cli, err := _client(ctx) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) rawCID := make([]byte, sha256.Size) cnr.Encode(rawCID) tid, _ := cmd.Flags().GetString(treeIDFlagKey) pid, _ := cmd.Flags().GetUint64(parentIDFlagKey) nid, _ := cmd.Flags().GetUint64(nodeIDFlagKey) var bt []byte if t := common.ReadBearerToken(cmd, bearerFlagKey); t != nil { bt = t.Marshal() } subTreeReq := &tree.GetSubTreeRequest{ Body: &tree.GetSubTreeRequest_Body{ ContainerId: rawCID, TreeId: tid, RootId: []uint64{nid}, Depth: 1, BearerToken: bt, }, } commonCmd.ExitOnErr(cmd, "signing message: %w", tree.SignMessage(subTreeReq, pk)) resp, err := cli.GetSubTree(ctx, subTreeReq) commonCmd.ExitOnErr(cmd, "rpc call: %w", err) var meta []tree.KeyValue subtreeResp, err := resp.Recv() for ; err == nil; subtreeResp, err = resp.Recv() { meta = subtreeResp.GetBody().GetMeta() } if !errors.Is(err, io.EOF) { commonCmd.ExitOnErr(cmd, "failed to read getSubTree response stream: %w", err) } var metaErr error if len(meta) == 0 { metaErr = errors.New("no meta for given node ID") } commonCmd.ExitOnErr(cmd, "unexpected rpc call result: %w", metaErr) req := &tree.MoveRequest{ Body: &tree.MoveRequest_Body{ ContainerId: rawCID, TreeId: tid, ParentId: pid, NodeId: nid, Meta: meta, }, } commonCmd.ExitOnErr(cmd, "signing message: %w", tree.SignMessage(req, pk)) _, err = cli.Move(ctx, req) commonCmd.ExitOnErr(cmd, "failed to call move: %w", err) common.PrintVerbose(cmd, "Successful move invocation.") }