From e8e7630d788d6ec1110b74c09080d8d58640cfad Mon Sep 17 00:00:00 2001 From: caoxianfei1 Date: Mon, 11 Dec 2023 10:01:44 +0800 Subject: [PATCH] Feat(space): support query usage of fs Signed-off-by: caoxianfei1 --- tools-v2/Makefile | 4 +- tools-v2/internal/utils/row.go | 3 + tools-v2/pkg/cli/command/curvefs/list/list.go | 2 + .../cli/command/curvefs/list/space/space.go | 207 ++++++++++++++++++ 4 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 tools-v2/pkg/cli/command/curvefs/list/space/space.go diff --git a/tools-v2/Makefile b/tools-v2/Makefile index b42c70de73..3d3389b949 100644 --- a/tools-v2/Makefile +++ b/tools-v2/Makefile @@ -8,7 +8,7 @@ PROTOC_GEN_GO_VERSION= "v1.28" PROTOC_GEN_GO_GRPC_VERSION= "v1.2" # go env -GOPROXY :=https://goproxy.cn,direct +GOPROXY := https://goproxy.cn,direct GOOS := $(if $(GOOS),$(GOOS),$(shell go env GOOS)) GOARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH)) CGO_LDFLAGS := "-static" @@ -38,7 +38,6 @@ CGO_BUILD_FLAG += -ldflags '$(CGO_BUILD_LDFLAGS) $(VERSION_FLAG)' BUILD_FLAGS := -a BUILD_FLAGS += -trimpath BUILD_FLAGS += $(CGO_BUILD_FLAG) -BUILD_FLAGS += $(EXTRA_FLAGS) # debug flags GCFLAGS := "all=-N -l" @@ -75,6 +74,7 @@ install_grpc_protobuf: # && rm protoc-${PROTOC_VERSION}-linux-x86_64.zip # enable Go Modules go env -w GO111MODULE=on + go mod vendor go install google.golang.org/protobuf/cmd/protoc-gen-go@${PROTOC_GEN_GO_VERSION} go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@${PROTOC_GEN_GO_GRPC_VERSION} diff --git a/tools-v2/internal/utils/row.go b/tools-v2/internal/utils/row.go index 6369aa3ed5..c5beebc5bd 100644 --- a/tools-v2/internal/utils/row.go +++ b/tools-v2/internal/utils/row.go @@ -122,6 +122,9 @@ const ( ROW_TOTAL = "total" ROW_TYPE = "type" ROW_USED = "used" + ROW_FREE = "free" + ROW_FILE_NUM = "fileNum" + ROW_INODE_NUM = "inodeNum" ROW_USER = "user" ROW_VERSION = "version" ROW_ZONE = "zone" diff --git a/tools-v2/pkg/cli/command/curvefs/list/list.go b/tools-v2/pkg/cli/command/curvefs/list/list.go index 93606b97d9..a5c2ee5f77 100644 --- a/tools-v2/pkg/cli/command/curvefs/list/list.go +++ b/tools-v2/pkg/cli/command/curvefs/list/list.go @@ -29,6 +29,7 @@ import ( "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/fs" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/mountpoint" "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/partition" + "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/space" topology "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/topology" "github.com/spf13/cobra" ) @@ -47,6 +48,7 @@ func (listCmd *ListCommand) AddSubCommands() { partition.NewPartitionCommand(), copyset.NewCopysetCommand(), cache.NewCacheCommand(), + space.NewSpaceCommand(), ) } diff --git a/tools-v2/pkg/cli/command/curvefs/list/space/space.go b/tools-v2/pkg/cli/command/curvefs/list/space/space.go new file mode 100644 index 0000000000..ab14d15a18 --- /dev/null +++ b/tools-v2/pkg/cli/command/curvefs/list/space/space.go @@ -0,0 +1,207 @@ +/* + * 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: 2023-12-07 + * Author: Cao Xianfei (caoxianfei1) + */ + +package space + +import ( + "context" + "fmt" + "strconv" + + 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/curvefs/proto/mds" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "google.golang.org/grpc" +) + +const ( + spaceExample = `$ curve fs list space --fs ` +) + +const ( + urlPrefix = "/vars/" + + KEY_USED = "used" + KEY_INODE_NUM = "inode_num" +) + +var ( + metrics = map[string]string{ + "used": "fs_usage_info_fs_" + "%s" + "_used", // used + "inode_num": "topology_fs_id_" + "%d" + "_inode_num", // inode_num + } +) + +type ListSpaceRpc struct { + Info *basecmd.Rpc + Request *mds.GetFsInfoRequest + mdsClient mds.MdsServiceClient +} + +var _ basecmd.RpcFunc = (*ListSpaceRpc)(nil) // check interface + +func (sRpc *ListSpaceRpc) NewRpcClient(cc grpc.ClientConnInterface) { + sRpc.mdsClient = mds.NewMdsServiceClient(cc) +} + +func (sRpc *ListSpaceRpc) Stub_Func(ctx context.Context) (interface{}, error) { + return sRpc.mdsClient.GetFsInfo(ctx, sRpc.Request) +} + +var _ basecmd.FinalCurveCmdFunc = (*SpaceCommand)(nil) // check interface + +type SpaceCommand struct { + basecmd.FinalCurveCmd + Rpc *ListSpaceRpc + metrics map[string]*basecmd.Metric + response *mds.GetFsInfoResponse + + addrs []string + fsName string +} + +func NewSpaceCommand() *cobra.Command { + return NewListSpaceCommand().Cmd +} + +func NewListSpaceCommand() *SpaceCommand { + spaceCmd := &SpaceCommand{ + FinalCurveCmd: basecmd.FinalCurveCmd{ + Use: "space", + Short: "list the space of specified fs", + Example: spaceExample, + }, + } + basecmd.NewFinalCurveCli(&spaceCmd.FinalCurveCmd, spaceCmd) + return spaceCmd +} + +func (sCmd *SpaceCommand) AddFlags() { + config.AddRpcRetryTimesFlag(sCmd.Cmd) + config.AddRpcTimeoutFlag(sCmd.Cmd) + config.AddFsMdsAddrFlag(sCmd.Cmd) + config.AddFsNameRequiredFlag(sCmd.Cmd) +} + +func (sCmd *SpaceCommand) Init(cmd *cobra.Command, args []string) error { + // build rpc + sCmd.Rpc = &ListSpaceRpc{} + addrs, addrErr := config.GetFsMdsAddrSlice(sCmd.Cmd) + if addrErr.TypeCode() != cmderror.CODE_SUCCESS { + return fmt.Errorf(addrErr.Message) + } + sCmd.addrs = addrs + timeout := viper.GetDuration(config.VIPER_GLOBALE_RPCTIMEOUT) + retrytimes := viper.GetInt32(config.VIPER_GLOBALE_RPCRETRYTIMES) + fsName, err := cmd.Flags().GetString(config.CURVEFS_FSNAME) + if err != nil { + return fmt.Errorf("get flag %s failed from cmd: %v", config.CURVEFS_FSNAME, err) + } + sCmd.fsName = fsName + sCmd.Rpc.Request = &mds.GetFsInfoRequest{FsName: &fsName} + sCmd.Rpc.Info = basecmd.NewRpc(addrs, timeout, retrytimes, "GetFsInfo") + + // build table header + header := []string{ + cobrautil.ROW_CAPACITY, + cobrautil.ROW_USED, + cobrautil.ROW_FREE, + cobrautil.ROW_FILE_NUM, + cobrautil.ROW_INODE_NUM, + } + sCmd.SetHeader(header) + + return nil +} + +func (sCmd *SpaceCommand) Print(cmd *cobra.Command, args []string) error { + return output.FinalCmdOutput(&sCmd.FinalCurveCmd, sCmd) +} + +func (sCmd *SpaceCommand) RunCommand(cmd *cobra.Command, args []string) error { + // rpc response + response, errCmd := basecmd.GetRpcResponse(sCmd.Rpc.Info, sCmd.Rpc) + if errCmd.TypeCode() != cmderror.CODE_SUCCESS { + return fmt.Errorf(errCmd.Message) + } + sCmd.response = response.(*mds.GetFsInfoResponse) + capacity := sCmd.response.GetFsInfo().GetCapacity() + fsId := sCmd.response.GetFsInfo().GetFsId() + fsName := sCmd.response.GetFsInfo().GetFsName() + + sCmd.Error = cmderror.ErrSuccess() + + rows := make([]map[string]string, 0) + row := make(map[string]string) + row[cobrautil.ROW_FS_NAME] = fsName + row[cobrautil.ROW_CAPACITY] = strconv.FormatUint(capacity, 10) + rows = append(rows, row) + + // metric response + for key, subUri := range metrics { + if key == KEY_USED { + subUri = fmt.Sprintf(subUri, sCmd.fsName) + } else if key == KEY_INODE_NUM { + subUri = fmt.Sprintf(subUri, fsId) + } + subUri = urlPrefix + subUri + m := basecmd.NewMetric(sCmd.addrs, subUri, viper.GetDuration(config.VIPER_GLOBALE_RPCTIMEOUT)) + sCmd.metrics[key] = m + } + + for key, metric := range sCmd.metrics { + kvValue, err := basecmd.QueryMetric(metric) + if err.TypeCode() != cmderror.CODE_SUCCESS { + return err.ToError() + } + value, err := basecmd.GetMetricValue(kvValue) + if err.TypeCode() != cmderror.CODE_SUCCESS { + return err.ToError() + } + + if key == KEY_USED { + row[cobrautil.ROW_USED] = value + } else if key == KEY_INODE_NUM { + row[cobrautil.ROW_INODE_NUM] = value + } + rows = append(rows, row) + } + + if len(rows) > 0 { + list := cobrautil.ListMap2ListSortByKeys(rows, sCmd.Header, []string{ + config.CURVEFS_FSID, + }) + sCmd.TableNew.AppendBulk(list) + sCmd.Result = rows + } + + return nil +} + +func (sCmd *SpaceCommand) ResultPlainOutput() error { + return output.FinalCmdOutputPlain(&sCmd.FinalCurveCmd) +}