From 25449e5f695d02ee6aae559cc7f97cc4265174af Mon Sep 17 00:00:00 2001 From: montaguelhz <1443171175@qq.com> Date: Sun, 25 Jun 2023 12:19:05 +0800 Subject: [PATCH] [feat] tools-v2: add update leader-schedule Signed-off-by: montaguelhz <1443171175@qq.com> --- tools-v2/README.md | 23 ++- .../proto/curvebs/schedule/statuscode.proto | 30 ++++ tools-v2/internal/utils/row.go | 2 +- tools-v2/mk-proto.sh | 2 + .../update/leader_schedule/leader_schedule.go | 164 ++++++++++++++++++ .../pkg/cli/command/curvebs/update/update.go | 2 + tools-v2/pkg/config/bs.go | 31 ++++ 7 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 tools-v2/internal/proto/curvebs/schedule/statuscode.proto create mode 100644 tools-v2/pkg/cli/command/curvebs/update/leader_schedule/leader_schedule.go diff --git a/tools-v2/README.md b/tools-v2/README.md index 11bfaaceec..6b2c0b25cd 100644 --- a/tools-v2/README.md +++ b/tools-v2/README.md @@ -73,6 +73,7 @@ A tool for CurveFS & CurveBs. - [update throttle](#update-throttle) - [update scan-state](#update-scan-state) - [update copyset availflag](#update-copyset-availflag) + - [update leader-schedule](#update-leader-schedule) - [create](#create-1) - [create file](#create-file) - [create dir](#create-dir) @@ -1579,6 +1580,25 @@ Output: +--------+-----------+---------------+--------+ ``` +#### update leader-schedule + +"rapidly transfer leader + +Usage: +```bash +curve bs update leader-schedule --logicalpoolid 1 +curve bs update leader-schedule --all +``` + +Output: +``` ++---------+--------+ +| RESULT | REASON | ++---------+--------+ +| success | null | ++---------+--------+ +``` + ### create #### create file @@ -1720,9 +1740,10 @@ Output: | curve_ops_tool clean-recycle | curve bs clean-recycle | | curve_ops_tool copysets-status | curve bs status copyset | | curve_ops_tool list-may-broken-vol | curve bs list may-broken-vol | +| curve_ops_tool rapid-leader-schedule | curve bs update leader-schedule | | | curve_ops_tool status | | | curve_ops_tool check-consistency | | | curve_ops_tool do-snapshot-all | | | curve_ops_tool check-chunkserver | | | curve_ops_tool check-server | | -| curve_ops_tool rapid-leader-schedule | | + diff --git a/tools-v2/internal/proto/curvebs/schedule/statuscode.proto b/tools-v2/internal/proto/curvebs/schedule/statuscode.proto new file mode 100644 index 0000000000..dd442a4ccf --- /dev/null +++ b/tools-v2/internal/proto/curvebs/schedule/statuscode.proto @@ -0,0 +1,30 @@ +/* + * 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-06-14 +* Author: montaguelhz + */ + +syntax="proto2"; +option go_package = "proto/schedule/statuscode"; + +enum ScheduleStatusCode { + ScheduleSuccess = 0; + InvalidLogicalPool = -1; + InvalidQueryChunkserverID = -2; +} \ No newline at end of file diff --git a/tools-v2/internal/utils/row.go b/tools-v2/internal/utils/row.go index d10a3213ad..affb4e1097 100644 --- a/tools-v2/internal/utils/row.go +++ b/tools-v2/internal/utils/row.go @@ -130,7 +130,7 @@ const ( ROW_S3CHUNKINFO_OFFSET = "s3Offset" ROW_S3CHUNKINFO_SIZE = "s3Size" - // vale + // value ROW_VALUE_ADD = "add" ROW_VALUE_DEL = "del" ROW_VALUE_DNE = "DNE" diff --git a/tools-v2/mk-proto.sh b/tools-v2/mk-proto.sh index c5201d4ac0..0659d0b923 100644 --- a/tools-v2/mk-proto.sh +++ b/tools-v2/mk-proto.sh @@ -3,6 +3,8 @@ mkdir -p proto # proto protoc --go_out=proto --proto_path=internal/proto \ internal/proto/curvebs/topology/statuscode.proto +protoc --go_out=proto --proto_path=internal/proto \ + internal/proto/curvebs/schedule/statuscode.proto ## curvebs ### proto/chunk.proto protoc --go_out=proto --proto_path=.. \ diff --git a/tools-v2/pkg/cli/command/curvebs/update/leader_schedule/leader_schedule.go b/tools-v2/pkg/cli/command/curvebs/update/leader_schedule/leader_schedule.go new file mode 100644 index 0000000000..e5af63531b --- /dev/null +++ b/tools-v2/pkg/cli/command/curvebs/update/leader_schedule/leader_schedule.go @@ -0,0 +1,164 @@ +/* + * 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-06-14 +* Author: montaguelhz + */ + +package leader_schedule + +import ( + "context" + "fmt" + + 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/config" + "github.com/opencurve/curve/tools-v2/pkg/output" + "github.com/opencurve/curve/tools-v2/proto/proto/schedule" + "github.com/opencurve/curve/tools-v2/proto/proto/schedule/statuscode" + "github.com/spf13/cobra" + "google.golang.org/grpc" +) + +type UpdateLeaderScheduleRpc struct { + Info *basecmd.Rpc + Request *schedule.RapidLeaderScheduleRequst + Client schedule.ScheduleServiceClient +} + +var _ basecmd.RpcFunc = (*UpdateLeaderScheduleRpc)(nil) // check interface + +func (uRpc *UpdateLeaderScheduleRpc) NewRpcClient(cc grpc.ClientConnInterface) { + uRpc.Client = schedule.NewScheduleServiceClient(cc) +} + +func (uRpc *UpdateLeaderScheduleRpc) Stub_Func(ctx context.Context) (interface{}, error) { + return uRpc.Client.RapidLeaderSchedule(ctx, uRpc.Request) +} + +type LeaderScheduleCommand struct { + basecmd.FinalCurveCmd + + Rpc *UpdateLeaderScheduleRpc +} + +var _ basecmd.FinalCurveCmdFunc = (*LeaderScheduleCommand)(nil) // check interface + +const ( + leaderScheduleExample = `$ curve bs update leader-schedule --logicalpoolid 1 +$ curve bs update leader-schedule --all` +) + +func NewLeaderScheduleCommand() *cobra.Command { + return NewUpdateLeaderScheduleCommand().Cmd +} + +func (lCmd *LeaderScheduleCommand) AddFlags() { + config.AddBsMdsFlagOption(lCmd.Cmd) + config.AddRpcRetryTimesFlag(lCmd.Cmd) + config.AddRpcTimeoutFlag(lCmd.Cmd) + + config.AddBsLogicalPoolIdOptionFlag(lCmd.Cmd) + config.AddBsAllOptionFlag(lCmd.Cmd) +} + +func NewUpdateLeaderScheduleCommand() *LeaderScheduleCommand { + sCmd := &LeaderScheduleCommand{ + FinalCurveCmd: basecmd.FinalCurveCmd{ + Use: "leader-schedule", + Short: "rapidly transfer leader", + Example: leaderScheduleExample, + }, + } + + basecmd.NewFinalCurveCli(&sCmd.FinalCurveCmd, sCmd) + return sCmd +} + +func (lCmd *LeaderScheduleCommand) Init(cmd *cobra.Command, args []string) error { + mdsAddrs, err := config.GetBsMdsAddrSlice(lCmd.Cmd) + if err.TypeCode() != cmderror.CODE_SUCCESS { + return err.ToError() + } + + header := []string{cobrautil.ROW_RESULT, cobrautil.ROW_REASON} + lCmd.SetHeader(header) + + timeout := config.GetFlagDuration(lCmd.Cmd, config.RPCTIMEOUT) + retryTimes := config.GetFlagInt32(lCmd.Cmd, config.RPCRETRYTIMES) + + // if flag all not changed, it must be false + all := config.GetBsFlagBool(lCmd.Cmd, config.CURVEBS_ALL) + islogicalPoolIDChanged := config.GetBsFlagChanged(lCmd.Cmd, config.CURVEBS_LOGIC_POOL_ID) + if !all && !islogicalPoolIDChanged { + return fmt.Errorf("all or logicalpoolid is required") + } + + var logicalPoolID uint32 + if all { + logicalPoolID = 0 + } else { + logicalPoolID = config.GetBsFlagUint32(lCmd.Cmd, config.CURVEBS_LOGIC_POOL_ID) + if logicalPoolID == 0 { + return fmt.Errorf("please set flag all true instead of setting flag logicalpoolid 0") + } + } + + lCmd.Rpc = &UpdateLeaderScheduleRpc{ + Request: &schedule.RapidLeaderScheduleRequst{ + LogicalPoolID: &logicalPoolID, + }, + Info: basecmd.NewRpc(mdsAddrs, timeout, retryTimes, "RapidLeaderSchedule"), + } + + return nil +} + +func (lCmd *LeaderScheduleCommand) Print(cmd *cobra.Command, args []string) error { + return output.FinalCmdOutput(&lCmd.FinalCurveCmd, lCmd) +} + +func (lCmd *LeaderScheduleCommand) RunCommand(cmd *cobra.Command, args []string) error { + result, err := basecmd.GetRpcResponse(lCmd.Rpc.Info, lCmd.Rpc) + if err.TypeCode() != cmderror.CODE_SUCCESS { + return err.ToError() + } + out := make(map[string]string) + if response, ok := result.(*schedule.RapidLeaderScheduleResponse); ok { + if response.GetStatusCode() != 0 { + out[cobrautil.ROW_RESULT] = cobrautil.ROW_VALUE_FAILED + out[cobrautil.ROW_REASON] = statuscode.ScheduleStatusCode_name[*response.StatusCode] + } else { + out[cobrautil.ROW_RESULT] = cobrautil.ROW_VALUE_SUCCESS + out[cobrautil.ROW_REASON] = cobrautil.ROW_VALUE_NULL + } + } + + res := cobrautil.Map2List(out, lCmd.Header) + lCmd.TableNew.Append(res) + + lCmd.Result = out + lCmd.Error = cmderror.ErrSuccess() + return nil +} + +func (lCmd *LeaderScheduleCommand) ResultPlainOutput() error { + return output.FinalCmdOutputPlain(&lCmd.FinalCurveCmd) +} diff --git a/tools-v2/pkg/cli/command/curvebs/update/update.go b/tools-v2/pkg/cli/command/curvebs/update/update.go index b21407623d..efc5707bd3 100644 --- a/tools-v2/pkg/cli/command/curvebs/update/update.go +++ b/tools-v2/pkg/cli/command/curvebs/update/update.go @@ -29,6 +29,7 @@ import ( basecmd "github.com/opencurve/curve/tools-v2/pkg/cli/command" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/update/file" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/update/leader" + "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/update/leader_schedule" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/update/peer" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/update/scan_state" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/update/throttle" @@ -48,6 +49,7 @@ func (updateCmd *UpdateCommand) AddSubCommands() { leader.NewleaderCommand(), scan_state.NewScanStateCommand(), copyset.NewCopysetCommand(), + leader_schedule.NewLeaderScheduleCommand(), ) } diff --git a/tools-v2/pkg/config/bs.go b/tools-v2/pkg/config/bs.go index 0fae3d141b..61b1b1bc22 100644 --- a/tools-v2/pkg/config/bs.go +++ b/tools-v2/pkg/config/bs.go @@ -125,6 +125,9 @@ const ( CURVEBS_FIlTER = "filter" VIPER_CURVEBS_FILTER = "curvebs.filter" CURVEBS_DEFAULT_FILTER = false + CURVEBS_ALL = "all" + VIPER_CURVEBS_ALL = "curvebs.all" + CURVEBS_DEFAULT_ALL = false ) var ( @@ -171,6 +174,7 @@ var ( CURVEBS_CHUNK_ID: VIPER_CURVEBS_CHUNK_ID, CURVEBS_CHUNKSERVER_ADDRESS: VIPER_CURVEBS_CHUNKSERVER_ADDRESS, CURVEBS_FIlTER: VIPER_CURVEBS_FILTER, + CURVEBS_ALL: VIPER_CURVEBS_ALL, } BSFLAG2DEFAULT = map[string]interface{}{ @@ -191,6 +195,7 @@ var ( CURVEBS_CHUNKSERVER_ID: CURVEBS_DEFAULT_CHUNKSERVER_ID, CURVEBS_DRYRUN: CURVEBS_DEFAULT_DRYRUN, CURVEBS_FIlTER: CURVEBS_DEFAULT_FILTER, + CURVEBS_ALL: CURVEBS_DEFAULT_ALL, } ) @@ -304,6 +309,18 @@ func AddBsDurationOptionFlag(cmd *cobra.Command, name string, usage string) { } } +func AddBsUint32OptionFlag(cmd *cobra.Command, name string, usage string) { + defaultValue := BSFLAG2DEFAULT[name] + if defaultValue == nil { + defaultValue = uint32(0) + } + cmd.Flags().Uint32(name, defaultValue.(uint32), usage) + err := viper.BindPFlag(BSFLAG2VIPER[name], cmd.Flags().Lookup(name)) + if err != nil { + cobra.CheckErr(err) + } +} + func AddBsUint32SliceOptionFlag(cmd *cobra.Command, name string, usage string) { defaultValue := BSFLAG2DEFAULT[name] if defaultValue == nil { @@ -462,6 +479,15 @@ func AddBsScanOptionFlag(cmd *cobra.Command) { AddBsBoolOptionFlag(cmd, CURVEBS_SCAN, "enable/disable scan for logical pool") } +// leader-schedule +func AddBsLogicalPoolIdOptionFlag(cmd *cobra.Command) { + AddBsUint32OptionFlag(cmd, CURVEBS_LOGIC_POOL_ID, "logical pool id") +} + +func AddBsAllOptionFlag(cmd *cobra.Command) { + AddBsBoolOptionFlag(cmd, CURVEBS_ALL, "all") +} + // add flag required // add path[required] func AddBsPathRequiredFlag(cmd *cobra.Command) { @@ -607,6 +633,11 @@ func GetBsFlagInt64(cmd *cobra.Command, flagName string) int64 { return value } +// determine whether the flag is changed +func GetBsFlagChanged(cmd *cobra.Command, flagName string) bool { + return cmd.Flag(flagName).Changed +} + // get mdsaddr func GetBsAddrSlice(cmd *cobra.Command, addrType string) ([]string, *cmderror.CmdError) { var addrsStr string