From f1f43f2b957693393f2ecfe1bcaec3acfd93366c Mon Sep 17 00:00:00 2001 From: Xinlong-Chen Date: Fri, 28 Apr 2023 14:14:03 +0800 Subject: [PATCH] [feat] tools-v2: add do-snapshot Signed-off-by: Xinlong-Chen --- tools-v2/pkg/cli/command/curvebs/bs.go | 2 + .../cli/command/curvebs/snapshot/one/one.go | 176 ++++++++++++++++++ .../cli/command/curvebs/snapshot/snapshot.go | 51 +++++ 3 files changed, 229 insertions(+) create mode 100644 tools-v2/pkg/cli/command/curvebs/snapshot/one/one.go create mode 100644 tools-v2/pkg/cli/command/curvebs/snapshot/snapshot.go diff --git a/tools-v2/pkg/cli/command/curvebs/bs.go b/tools-v2/pkg/cli/command/curvebs/bs.go index 0c6f533260..35efb74ea4 100644 --- a/tools-v2/pkg/cli/command/curvebs/bs.go +++ b/tools-v2/pkg/cli/command/curvebs/bs.go @@ -31,6 +31,7 @@ import ( "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/delete" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/list" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/query" + "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/snapshot" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/status" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/update" ) @@ -50,6 +51,7 @@ func (bsCmd *CurveBsCommand) AddSubCommands() { create.NewCreateCmd(), update.NewUpdateCommand(), clean_recycle.NewCleanRecycleCommand(), + snapshot.NewSnapshotCommand(), ) } diff --git a/tools-v2/pkg/cli/command/curvebs/snapshot/one/one.go b/tools-v2/pkg/cli/command/curvebs/snapshot/one/one.go new file mode 100644 index 0000000000..aee90357d4 --- /dev/null +++ b/tools-v2/pkg/cli/command/curvebs/snapshot/one/one.go @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2023 NetEase Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Project: CurveCli + * Created Date: 2023-04-28 + * Author: Xinlong-Chen + */ + +package one + +import ( + "context" + "fmt" + "time" + + "github.com/spf13/cobra" + "google.golang.org/grpc" + + cmderror "github.com/opencurve/curve/tools-v2/internal/error" + cobrautil "github.com/opencurve/curve/tools-v2/internal/utils" + basecmd "github.com/opencurve/curve/tools-v2/pkg/cli/command" + "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/delete/peer" + "github.com/opencurve/curve/tools-v2/pkg/config" + "github.com/opencurve/curve/tools-v2/pkg/output" + "github.com/opencurve/curve/tools-v2/proto/proto/cli2" + "github.com/opencurve/curve/tools-v2/proto/proto/common" +) + +const ( + updateExample = `$ curve bs snapshot one 127.0.0.0:8200:0 --logicalpoolid=1 --copysetid=1` +) + +type SnapshotRpc struct { + Info *basecmd.Rpc + Request *cli2.SnapshotRequest2 + Client cli2.CliService2Client +} + +func (sRpc *SnapshotRpc) NewRpcClient(cc grpc.ClientConnInterface) { + sRpc.Client = cli2.NewCliService2Client(cc) +} + +func (sRpc *SnapshotRpc) Stub_Func(ctx context.Context) (interface{}, error) { + return sRpc.Client.Snapshot(ctx, sRpc.Request) +} + +// Options rpc request options. +type Options struct { + Timeout time.Duration + RetryTimes int32 +} + +type SnapshotOneCommand struct { + basecmd.FinalCurveCmd + + // request parameters + opts Options + logicalPoolID uint32 + copysetID uint32 + + snapshotPeer *common.Peer +} + +var _ basecmd.FinalCurveCmdFunc = (*SnapshotOneCommand)(nil) // check interface + +// NewCommand ... +func NewSnapshotOneCommand() *cobra.Command { + peerCmd := &SnapshotOneCommand{ + FinalCurveCmd: basecmd.FinalCurveCmd{ + Use: "one", + Short: "take a snapshot for one peer from the copyset", + Example: updateExample, + }, + } + basecmd.NewFinalCurveCli(&peerCmd.FinalCurveCmd, peerCmd) + return peerCmd.Cmd +} + +func (sCmd *SnapshotOneCommand) AddFlags() { + config.AddRpcRetryTimesFlag(sCmd.Cmd) + config.AddRpcTimeoutFlag(sCmd.Cmd) + + config.AddBSLogicalPoolIdRequiredFlag(sCmd.Cmd) + config.AddBSCopysetIdRequiredFlag(sCmd.Cmd) +} + +func (sCmd *SnapshotOneCommand) Init(cmd *cobra.Command, args []string) error { + sCmd.opts = Options{} + + sCmd.SetHeader([]string{cobrautil.ROW_PEER, cobrautil.ROW_COPYSET, cobrautil.ROW_RESULT, cobrautil.ROW_REASON}) + sCmd.TableNew.SetAutoMergeCellsByColumnIndex(cobrautil.GetIndexSlice( + sCmd.Header, []string{}, + )) + + var e *cmderror.CmdError + + sCmd.opts.Timeout = config.GetFlagDuration(sCmd.Cmd, config.RPCTIMEOUT) + sCmd.opts.RetryTimes = config.GetFlagInt32(sCmd.Cmd, config.RPCRETRYTIMES) + + sCmd.copysetID = config.GetBsFlagUint32(sCmd.Cmd, config.CURVEBS_COPYSET_ID) + + sCmd.logicalPoolID = config.GetBsFlagUint32(sCmd.Cmd, config.CURVEBS_LOGIC_POOL_ID) + + // parse peer conf + if len(args) < 1 { + pErr := cmderror.ErrGetPeer() + pErr.Format("should specified the peer address") + return pErr.ToError() + } + sCmd.snapshotPeer, e = peer.ParsePeer(args[0]) + if e != nil { + return e.ToError() + } + return nil +} + +func (sCmd *SnapshotOneCommand) Print(cmd *cobra.Command, args []string) error { + return output.FinalCmdOutput(&sCmd.FinalCurveCmd, sCmd) +} + +func (sCmd *SnapshotOneCommand) RunCommand(cmd *cobra.Command, args []string) error { + out := make(map[string]string) + out[cobrautil.ROW_PEER] = fmt.Sprintf("%s:%d", sCmd.snapshotPeer.GetAddress(), sCmd.snapshotPeer.GetId()) + out[cobrautil.ROW_COPYSET] = fmt.Sprintf("(%d:%d)", sCmd.logicalPoolID, sCmd.copysetID) + + var err *cmderror.CmdError + sCmd.Result, err = sCmd.execSnapshotPeer() + if err != nil { + out[cobrautil.ROW_RESULT] = cobrautil.ROW_VALUE_FAILED + out[cobrautil.ROW_REASON] = err.ToError().Error() + sCmd.Error = err + return nil + } + out[cobrautil.ROW_RESULT] = cobrautil.ROW_VALUE_SUCCESS + out[cobrautil.ROW_REASON] = cobrautil.ROW_VALUE_NULL + list := cobrautil.Map2List(out, sCmd.Header) + sCmd.TableNew.Append(list) + return nil +} + +func (sCmd *SnapshotOneCommand) ResultPlainOutput() error { + return output.FinalCmdOutputPlain(&sCmd.FinalCurveCmd) +} + +func (sCmd *SnapshotOneCommand) execSnapshotPeer() (interface{}, *cmderror.CmdError) { + rpcCli := &SnapshotRpc{ + Info: basecmd.NewRpc([]string{sCmd.snapshotPeer.GetAddress()}, sCmd.opts.Timeout, sCmd.opts.RetryTimes, "Snapshot"), + Request: &cli2.SnapshotRequest2{ + LogicPoolId: &sCmd.logicalPoolID, + CopysetId: &sCmd.copysetID, + Peer: sCmd.snapshotPeer, + }, + } + + response, errCmd := basecmd.GetRpcResponse(rpcCli.Info, rpcCli) + + if errCmd.TypeCode() != cmderror.CODE_SUCCESS { + return response, errCmd + } + + return response, nil +} diff --git a/tools-v2/pkg/cli/command/curvebs/snapshot/snapshot.go b/tools-v2/pkg/cli/command/curvebs/snapshot/snapshot.go new file mode 100644 index 0000000000..ddc58d25c9 --- /dev/null +++ b/tools-v2/pkg/cli/command/curvebs/snapshot/snapshot.go @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 NetEase Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Project: CurveCli + * Created Date: 2023-04-28 + * Author: Xinlong-Chen + */ + +package snapshot + +import ( + basecmd "github.com/opencurve/curve/tools-v2/pkg/cli/command" + "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/snapshot/one" + "github.com/spf13/cobra" +) + +type SnapshotCommand struct { + basecmd.MidCurveCmd +} + +var _ basecmd.MidCurveCmdFunc = (*SnapshotCommand)(nil) // check interface + +func (statusCmd *SnapshotCommand) AddSubCommands() { + statusCmd.Cmd.AddCommand( + one.NewSnapshotOneCommand(), + ) +} + +func NewSnapshotCommand() *cobra.Command { + statusCmd := &SnapshotCommand{ + basecmd.MidCurveCmd{ + Use: "snapshot", + Short: "take a snapshot for peer", + }, + } + return basecmd.NewMidCurveCli(&statusCmd.MidCurveCmd, statusCmd) +}