diff --git a/tools-v2/README.md b/tools-v2/README.md index bfa24de658..408e470c0c 100644 --- a/tools-v2/README.md +++ b/tools-v2/README.md @@ -45,6 +45,7 @@ A tool for CurveFS & CurveBs. - [list](#list-1) - [list logical-pool](#list-logical-pool) - [list server](#list-server) + - [list client](#list-client) - [query](#query-1) - [query file](#query-file) - [status](#status-1) @@ -842,6 +843,24 @@ Output: +----+---------------------+------+---------+-------------------+-------------------+ ``` +##### list client + +list all client information in curvebs + +```bash +curve bs list client +``` + +Output: + +```bash ++------------+------+ +| IP | PORT | ++------------+------+ +| 172.17.0.2 | 9000 | ++------------+------+ +``` + ### query ##### query file @@ -958,7 +977,7 @@ Output: | status | | | chunkserver-status | | | client-status | | -| client-list | | +| client-list | curve bs list client | | snapshot-clone-status | | | copysets-status | | | chunkserver-list | | diff --git a/tools-v2/internal/utils/row.go b/tools-v2/internal/utils/row.go index bf2f4167c2..bd5d1944e1 100644 --- a/tools-v2/internal/utils/row.go +++ b/tools-v2/internal/utils/row.go @@ -91,6 +91,8 @@ const ( ROW_USED = "used" ROW_VERSION = "version" ROW_ZONE = "zone" + ROW_IP = "ip" + ROW_PORT = "port" // s3 ROW_S3CHUNKINFO_CHUNKID = "s3ChunkId" diff --git a/tools-v2/pkg/cli/command/curvebs/list/client/client.go b/tools-v2/pkg/cli/command/curvebs/list/client/client.go new file mode 100644 index 0000000000..1fb6a9da68 --- /dev/null +++ b/tools-v2/pkg/cli/command/curvebs/list/client/client.go @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2022 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: 2022-11-10 + * Author: Tsonglew + */ + +package client + +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/nameserver2" + "github.com/spf13/cobra" + "google.golang.org/grpc" +) + +const ( + clientExample = `$ curve bs list client` +) + +type ListClientRpc struct { + Info *basecmd.Rpc + Request *nameserver2.ListClientRequest + curveFSClient nameserver2.CurveFSServiceClient +} + +var _ basecmd.RpcFunc = (*ListClientRpc)(nil) // check interface + +type ClientCommand struct { + basecmd.FinalCurveCmd + Rpc []*ListClientRpc +} + +var _ basecmd.FinalCurveCmdFunc = (*ClientCommand)(nil) // check interface + +func (lRpc *ListClientRpc) NewRpcClient(cc grpc.ClientConnInterface) { + lRpc.curveFSClient = nameserver2.NewCurveFSServiceClient(cc) +} + +func (lRpc *ListClientRpc) Stub_Func(ctx context.Context) (interface{}, error) { + return lRpc.curveFSClient.ListClient(ctx, lRpc.Request) +} + +func NewClientCommand() *cobra.Command { + return NewListCLientCommand().Cmd +} + +func NewListCLientCommand() *ClientCommand { + lsCmd := &ClientCommand{ + FinalCurveCmd: basecmd.FinalCurveCmd{ + Use: "client", + Short: "list all client information in curvebs", + Example: clientExample, + }, + } + + basecmd.NewFinalCurveCli(&lsCmd.FinalCurveCmd, lsCmd) + return lsCmd +} + +// AddFlags implements basecmd.FinalCurveCmdFunc +func (pCmd *ClientCommand) AddFlags() { + config.AddBsMdsFlagOption(pCmd.Cmd) + config.AddRpcRetryTimesFlag(pCmd.Cmd) + config.AddRpcTimeoutFlag(pCmd.Cmd) +} + +// Init implements basecmd.FinalCurveCmdFunc +func (pCmd *ClientCommand) Init(cmd *cobra.Command, args []string) error { + mdsAddrs, err := config.GetBsMdsAddrSlice(pCmd.Cmd) + if err.TypeCode() != cmderror.CODE_SUCCESS { + return err.ToError() + } + + timeout := config.GetFlagDuration(pCmd.Cmd, config.RPCTIMEOUT) + retrytimes := config.GetFlagInt32(pCmd.Cmd, config.RPCRETRYTIMES) + + rpc := &ListClientRpc{ + Request: &nameserver2.ListClientRequest{}, + Info: basecmd.NewRpc(mdsAddrs, timeout, retrytimes, "ListClient"), + } + pCmd.Rpc = append(pCmd.Rpc, rpc) + + header := []string{cobrautil.ROW_IP, cobrautil.ROW_PORT} + pCmd.SetHeader(header) + pCmd.TableNew.SetAutoMergeCellsByColumnIndex(cobrautil.GetIndexSlice( + pCmd.Header, header, + )) + return nil +} + +// Print implements basecmd.FinalCurveCmdFunc +func (pCmd *ClientCommand) Print(cmd *cobra.Command, args []string) error { + return output.FinalCmdOutput(&pCmd.FinalCurveCmd, pCmd) +} + +// RunCommand implements basecmd.FinalCurveCmdFunc +func (pCmd *ClientCommand) RunCommand(cmd *cobra.Command, args []string) error { + var infos []*basecmd.Rpc + var funcs []basecmd.RpcFunc + for _, rpc := range pCmd.Rpc { + infos = append(infos, rpc.Info) + funcs = append(funcs, rpc) + } + results, errs := basecmd.GetRpcListResponse(infos, funcs) + if len(errs) == len(infos) { + mergeErr := cmderror.MergeCmdErrorExceptSuccess(errs) + return mergeErr.ToError() + } + var errors []*cmderror.CmdError + rows := make([]map[string]string, 0) + for _, res := range results { + infos := res.(*nameserver2.ListClientResponse).GetClientInfos() + for _, info := range infos { + row := make(map[string]string) + row[cobrautil.ROW_IP] = info.GetIp() + row[cobrautil.ROW_PORT] = fmt.Sprintf("%d", info.GetPort()) + rows = append(rows, row) + } + } + list := cobrautil.ListMap2ListSortByKeys(rows, pCmd.Header, []string{ + cobrautil.ROW_IP, + }) + pCmd.TableNew.AppendBulk(list) + errRet := cmderror.MergeCmdError(errors) + pCmd.Error = &errRet + pCmd.Result = results + return nil +} + +// ResultPlainOutput implements basecmd.FinalCurveCmdFunc +func (pCmd *ClientCommand) ResultPlainOutput() error { + return output.FinalCmdOutputPlain(&pCmd.FinalCurveCmd) +} diff --git a/tools-v2/pkg/cli/command/curvebs/list/list.go b/tools-v2/pkg/cli/command/curvebs/list/list.go index b49e8c8f0f..be741ee281 100644 --- a/tools-v2/pkg/cli/command/curvebs/list/list.go +++ b/tools-v2/pkg/cli/command/curvebs/list/list.go @@ -24,6 +24,7 @@ package list import ( basecmd "github.com/opencurve/curve/tools-v2/pkg/cli/command" + "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/list/client" logicalpool "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/list/logicalPool" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvebs/list/server" "github.com/spf13/cobra" @@ -39,6 +40,7 @@ func (listCmd *ListCommand) AddSubCommands() { listCmd.Cmd.AddCommand( logicalpool.NewLogicalPoolCommand(), server.NewServerCommand(), + client.NewClientCommand(), ) } diff --git a/tools-v2/pkg/config/bs.go b/tools-v2/pkg/config/bs.go index 6822d95021..972a6c1b1c 100644 --- a/tools-v2/pkg/config/bs.go +++ b/tools-v2/pkg/config/bs.go @@ -110,10 +110,10 @@ func AddBsStringRequiredFlag(cmd *cobra.Command, name string, usage string) { // add flag option // bs mds[option] func AddBsMdsFlagOption(cmd *cobra.Command) { - AddBsStringSliceOptionFlag(cmd, CURVEBS_MDSADDR, "mds address, should be like 127.0.0.1:6700,127.0.0.1:6701,127.0.0.1:6702") + AddBsStringOptionFlag(cmd, CURVEBS_MDSADDR, "mds address, should be like 127.0.0.1:6700,127.0.0.1:6701,127.0.0.1:6702") } func AddBsMdsDummyFlagOption(cmd *cobra.Command) { - AddBsStringSliceOptionFlag(cmd, CURVEBS_MDSDUMMYADDR, "mds dummy address, should be like 127.0.0.1:6700,127.0.0.1:6701,127.0.0.1:6702") + AddBsStringOptionFlag(cmd, CURVEBS_MDSDUMMYADDR, "mds dummy address, should be like 127.0.0.1:6700,127.0.0.1:6701,127.0.0.1:6702") } // user