Skip to content

Commit b184f47

Browse files
committed
Feat(space): support query space usage of specified fs
Signed-off-by: caoxianfei1 <caoxianfei@corp.netease.com>
1 parent 0c24f4f commit b184f47

File tree

6 files changed

+267
-2
lines changed

6 files changed

+267
-2
lines changed

tools-v2/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ PROTOC_GEN_GO_VERSION= "v1.28"
88
PROTOC_GEN_GO_GRPC_VERSION= "v1.2"
99

1010
# go env
11-
GOPROXY :=https://goproxy.cn,direct
11+
GOPROXY := https://goproxy.cn,direct
1212
GOOS := $(if $(GOOS),$(GOOS),$(shell go env GOOS))
1313
GOARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH))
1414
CGO_LDFLAGS := "-static"
@@ -38,7 +38,6 @@ CGO_BUILD_FLAG += -ldflags '$(CGO_BUILD_LDFLAGS) $(VERSION_FLAG)'
3838
BUILD_FLAGS := -a
3939
BUILD_FLAGS += -trimpath
4040
BUILD_FLAGS += $(CGO_BUILD_FLAG)
41-
BUILD_FLAGS += $(EXTRA_FLAGS)
4241

4342
# debug flags
4443
GCFLAGS := "all=-N -l"

tools-v2/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ A tool for CurveFS & CurveBs.
2424
- [list mountpoint](#list-mountpoint)
2525
- [list partition](#list-partition)
2626
- [list topology](#list-topology)
27+
- [list space usage](#list-space-usage)
2728
- [query](#query)
2829
- [query copyset](#query-copyset)
2930
- [query fs](#query-fs)
@@ -542,6 +543,26 @@ Output:
542543
+----+------------+--------------------+------------+-----------------------+
543544
```
544545

546+
##### list space usage
547+
548+
list the space usage of the curvefs
549+
550+
Usage:
551+
552+
```shell
553+
curve fs list space --fs test
554+
```
555+
556+
Output:
557+
558+
```shell
559+
+--------+----------+---------+----------+
560+
| FSNAME | CAPACITY | USED | INODENUM |
561+
+--------+----------+---------+----------+
562+
| test | 10PB | 6.71GiB | 7313 |
563+
+--------+----------+---------+----------+
564+
```
565+
545566
#### query
546567

547568
##### query copyset

tools-v2/internal/utils/row.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ const (
122122
ROW_TOTAL = "total"
123123
ROW_TYPE = "type"
124124
ROW_USED = "used"
125+
ROW_INODE_NUM = "inodeNum"
125126
ROW_USER = "user"
126127
ROW_VERSION = "version"
127128
ROW_ZONE = "zone"

tools-v2/pkg/cli/command/curvefs/list/list.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/fs"
3030
"github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/mountpoint"
3131
"github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/partition"
32+
"github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/space"
3233
topology "github.com/opencurve/curve/tools-v2/pkg/cli/command/curvefs/list/topology"
3334
"github.com/spf13/cobra"
3435
)
@@ -47,6 +48,7 @@ func (listCmd *ListCommand) AddSubCommands() {
4748
partition.NewPartitionCommand(),
4849
copyset.NewCopysetCommand(),
4950
cache.NewCacheCommand(),
51+
space.NewSpaceCommand(),
5052
)
5153
}
5254

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/*
2+
* Copyright (c) 2022 NetEase Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* Project: CurveCli
19+
* Created Date: 2023-12-07
20+
* Author: Cao Xianfei (caoxianfei1)
21+
*/
22+
23+
package space
24+
25+
import (
26+
"context"
27+
"fmt"
28+
"strconv"
29+
30+
cmderror "github.com/opencurve/curve/tools-v2/internal/error"
31+
cobrautil "github.com/opencurve/curve/tools-v2/internal/utils"
32+
basecmd "github.com/opencurve/curve/tools-v2/pkg/cli/command"
33+
"github.com/opencurve/curve/tools-v2/pkg/config"
34+
"github.com/opencurve/curve/tools-v2/pkg/output"
35+
"github.com/opencurve/curve/tools-v2/proto/curvefs/proto/mds"
36+
"github.com/spf13/cobra"
37+
"github.com/spf13/viper"
38+
"google.golang.org/grpc"
39+
)
40+
41+
const (
42+
spaceExample = `$ curve fs list space --fs <fsname>`
43+
)
44+
45+
const (
46+
urlPrefix = "/vars/"
47+
48+
KEY_USED = "used"
49+
KEY_INODE_NUM = "inode_num"
50+
51+
unit = 1024
52+
MiB = 1048576
53+
GiB = 1073741824
54+
DefaultCapacity = "10PB"
55+
)
56+
57+
var (
58+
metrics = map[string]string{
59+
"used": "fs_usage_info_fs_" + "%s" + "_used", // used
60+
"inode_num": "topology_fs_id_" + "%d" + "_inode_num", // inode_num
61+
}
62+
)
63+
64+
type ListSpaceRpc struct {
65+
Info *basecmd.Rpc
66+
Request *mds.GetFsInfoRequest
67+
mdsClient mds.MdsServiceClient
68+
}
69+
70+
var _ basecmd.RpcFunc = (*ListSpaceRpc)(nil) // check interface
71+
72+
func (sRpc *ListSpaceRpc) NewRpcClient(cc grpc.ClientConnInterface) {
73+
sRpc.mdsClient = mds.NewMdsServiceClient(cc)
74+
}
75+
76+
func (sRpc *ListSpaceRpc) Stub_Func(ctx context.Context) (interface{}, error) {
77+
return sRpc.mdsClient.GetFsInfo(ctx, sRpc.Request)
78+
}
79+
80+
var _ basecmd.FinalCurveCmdFunc = (*SpaceCommand)(nil) // check interface
81+
82+
type SpaceCommand struct {
83+
basecmd.FinalCurveCmd
84+
Rpc *ListSpaceRpc
85+
metrics map[string]*basecmd.Metric
86+
response *mds.GetFsInfoResponse
87+
88+
addrs []string
89+
fsName string
90+
}
91+
92+
func NewSpaceCommand() *cobra.Command {
93+
return NewListSpaceCommand().Cmd
94+
}
95+
96+
func NewListSpaceCommand() *SpaceCommand {
97+
spaceCmd := &SpaceCommand{
98+
FinalCurveCmd: basecmd.FinalCurveCmd{
99+
Use: "space",
100+
Short: "list the space of specified fs",
101+
Example: spaceExample,
102+
},
103+
}
104+
basecmd.NewFinalCurveCli(&spaceCmd.FinalCurveCmd, spaceCmd)
105+
return spaceCmd
106+
}
107+
108+
func (sCmd *SpaceCommand) AddFlags() {
109+
config.AddRpcRetryTimesFlag(sCmd.Cmd)
110+
config.AddRpcTimeoutFlag(sCmd.Cmd)
111+
config.AddFsMdsAddrFlag(sCmd.Cmd)
112+
config.AddFsRequiredFlag(sCmd.Cmd)
113+
}
114+
115+
func (sCmd *SpaceCommand) Init(cmd *cobra.Command, args []string) error {
116+
// build rpc
117+
sCmd.Rpc = &ListSpaceRpc{}
118+
addrs, addrErr := config.GetFsMdsAddrSlice(sCmd.Cmd)
119+
if addrErr.TypeCode() != cmderror.CODE_SUCCESS {
120+
return fmt.Errorf(addrErr.Message)
121+
}
122+
sCmd.metrics = make(map[string]*basecmd.Metric)
123+
sCmd.addrs = []string{}
124+
sCmd.addrs = addrs
125+
timeout := viper.GetDuration(config.VIPER_GLOBALE_RPCTIMEOUT)
126+
retrytimes := viper.GetInt32(config.VIPER_GLOBALE_RPCRETRYTIMES)
127+
fsName, err := cmd.Flags().GetString(config.CURVEFS)
128+
if err != nil {
129+
return fmt.Errorf("get flag %s failed from cmd: %v", config.CURVEFS, err)
130+
}
131+
sCmd.fsName = fsName
132+
sCmd.Rpc.Request = &mds.GetFsInfoRequest{FsName: &fsName}
133+
sCmd.Rpc.Info = basecmd.NewRpc(addrs, timeout, retrytimes, "GetFsInfo")
134+
135+
// build table header
136+
header := []string{
137+
cobrautil.ROW_FS_NAME,
138+
cobrautil.ROW_CAPACITY,
139+
cobrautil.ROW_USED,
140+
cobrautil.ROW_INODE_NUM,
141+
}
142+
sCmd.SetHeader(header)
143+
144+
return nil
145+
}
146+
147+
func (sCmd *SpaceCommand) Print(cmd *cobra.Command, args []string) error {
148+
return output.FinalCmdOutput(&sCmd.FinalCurveCmd, sCmd)
149+
}
150+
151+
func (sCmd *SpaceCommand) RunCommand(cmd *cobra.Command, args []string) error {
152+
// rpc response
153+
response, errCmd := basecmd.GetRpcResponse(sCmd.Rpc.Info, sCmd.Rpc)
154+
if errCmd.TypeCode() != cmderror.CODE_SUCCESS {
155+
return fmt.Errorf(errCmd.Message)
156+
}
157+
sCmd.response = response.(*mds.GetFsInfoResponse)
158+
capacity := sCmd.response.GetFsInfo().GetCapacity()
159+
fsId := sCmd.response.GetFsInfo().GetFsId()
160+
fsName := sCmd.response.GetFsInfo().GetFsName()
161+
162+
sCmd.Error = cmderror.ErrSuccess()
163+
164+
rows := make([]map[string]string, 0)
165+
row := make(map[string]string)
166+
row[cobrautil.ROW_FS_NAME] = fsName
167+
row[cobrautil.ROW_CAPACITY] = strconv.FormatUint(capacity, 10)
168+
capStr := convertStr(capacity)
169+
row[cobrautil.ROW_CAPACITY] = capStr
170+
if row[cobrautil.ROW_CAPACITY] == "0" {
171+
row[cobrautil.ROW_CAPACITY] = DefaultCapacity
172+
}
173+
174+
// metric response
175+
for key, subUri := range metrics {
176+
if key == KEY_USED {
177+
subUri = fmt.Sprintf(subUri, sCmd.fsName)
178+
} else if key == KEY_INODE_NUM {
179+
subUri = fmt.Sprintf(subUri, fsId)
180+
}
181+
subUri = urlPrefix + subUri
182+
m := basecmd.NewMetric(sCmd.addrs, subUri, viper.GetDuration(config.VIPER_GLOBALE_RPCTIMEOUT))
183+
sCmd.metrics[key] = m
184+
}
185+
186+
for key, metric := range sCmd.metrics {
187+
kvValue, err := basecmd.QueryMetric(metric)
188+
if err.TypeCode() != cmderror.CODE_SUCCESS {
189+
return err.ToError()
190+
}
191+
used, err := basecmd.GetMetricValue(kvValue)
192+
if err.TypeCode() != cmderror.CODE_SUCCESS {
193+
return err.ToError()
194+
}
195+
196+
if key == KEY_USED {
197+
row[cobrautil.ROW_USED] = used
198+
value, _ := strconv.ParseUint(used, 10, 64)
199+
valueStr := convertStr(value)
200+
row[cobrautil.ROW_USED] = valueStr
201+
} else if key == KEY_INODE_NUM {
202+
row[cobrautil.ROW_INODE_NUM] = used
203+
}
204+
}
205+
rows = append(rows, row)
206+
207+
if len(rows) > 0 {
208+
list := cobrautil.ListMap2ListSortByKeys(rows, sCmd.Header, []string{
209+
config.CURVEFS_FSID,
210+
})
211+
sCmd.TableNew.AppendBulk(list)
212+
sCmd.Result = rows
213+
}
214+
215+
return nil
216+
}
217+
218+
func (sCmd *SpaceCommand) ResultPlainOutput() error {
219+
return output.FinalCmdOutputPlain(&sCmd.FinalCurveCmd)
220+
}
221+
222+
func convertStr(capacity uint64) string {
223+
var transRes float64
224+
var transResStr string
225+
if capacity < MiB {
226+
transResStr = strconv.FormatUint(capacity, 10)
227+
} else if capacity >= MiB && capacity < GiB {
228+
transRes, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", float64(capacity)/float64(unit)/float64(unit)), 64)
229+
transResStr = strconv.FormatFloat(transRes, 'f', -1, 64) + "MiB"
230+
} else if capacity >= GiB {
231+
transRes, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", float64(capacity)/float64(unit)/float64(unit)/float64(unit)), 64)
232+
transResStr = strconv.FormatFloat(transRes, 'f', -1, 64) + "GiB"
233+
}
234+
return transResStr
235+
}

tools-v2/pkg/config/fs.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const (
4545
VIPER_CURVEFS_METASERVERID = "curvefs.metaserverId"
4646
CURVEFS_FSID = "fsid"
4747
VIPER_CURVEFS_FSID = "curvefs.fsId"
48+
CURVEFS = "fs"
4849
CURVEFS_FSNAME = "fsname"
4950
VIPER_CURVEFS_FSNAME = "curvefs.fsName"
5051
CURVEFS_MOUNTPOINT = "mountpoint"
@@ -563,6 +564,12 @@ func AddFsNameRequiredFlag(cmd *cobra.Command) {
563564
}
564565
}
565566

567+
// fs
568+
func AddFsRequiredFlag(cmd *cobra.Command) {
569+
cmd.Flags().String(CURVEFS, "", "fs"+color.Red.Sprint("[required]"))
570+
cmd.MarkFlagRequired(CURVEFS)
571+
}
572+
566573
// fs name
567574
func AddFsNameSliceOptionFlag(cmd *cobra.Command) {
568575
cmd.Flags().StringSlice(CURVEFS_FSNAME, nil, "fs name")

0 commit comments

Comments
 (0)