1
// Copyright 2018 The CubeFS Authors.
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
21
"github.com/cubefs/cubefs/proto"
22
"github.com/cubefs/cubefs/sdk/master"
23
"github.com/spf13/cobra"
27
cmdMetaNodeUse = "metanode [COMMAND]"
28
cmdMetaNodeShort = "Manage meta nodes"
32
func newMetaNodeCmd(client *master.MasterClient) *cobra.Command {
33
cmd := &cobra.Command{
35
Short: cmdMetaNodeShort,
38
newMetaNodeListCmd(client),
39
newMetaNodeInfoCmd(client),
40
newMetaNodeDecommissionCmd(client),
41
newMetaNodeMigrateCmd(client),
47
cmdMetaNodeListShort = "List information of meta nodes"
48
cmdMetaNodeInfoShort = "Show information of meta nodes"
49
cmdMetaNodeDecommissionInfoShort = "Decommission partitions in a meta node to other nodes"
50
cmdMetaNodeMigrateInfoShort = "Migrate partitions from a meta node to the other node"
53
func newMetaNodeListCmd(client *master.MasterClient) *cobra.Command {
54
var optFilterStatus string
55
var optFilterWritable string
56
cmd := &cobra.Command{
58
Short: cmdMetaNodeListShort,
59
Aliases: []string{"ls"},
60
Run: func(cmd *cobra.Command, args []string) {
65
var view *proto.ClusterView
66
if view, err = client.AdminAPI().GetCluster(); err != nil {
69
sort.SliceStable(view.MetaNodes, func(i, j int) bool {
70
return view.MetaNodes[i].ID < view.MetaNodes[j].ID
72
stdout("[Meta nodes]\n")
73
stdout("%v\n", formatNodeViewTableHeader())
74
for _, node := range view.MetaNodes {
75
if optFilterStatus != "" &&
76
!strings.Contains(formatNodeStatus(node.IsActive), optFilterStatus) {
79
if optFilterWritable != "" &&
80
!strings.Contains(formatYesNo(node.IsWritable), optFilterWritable) {
83
stdout("%v\n", formatNodeView(&node, true))
87
cmd.Flags().StringVar(&optFilterWritable, "filter-writable", "", "Filter node writable status")
88
cmd.Flags().StringVar(&optFilterStatus, "filter-status", "", "Filter status [Active, Inactive")
92
func newMetaNodeInfoCmd(client *master.MasterClient) *cobra.Command {
93
cmd := &cobra.Command{
94
Use: CliOpInfo + " [{HOST}:{PORT}]",
95
Short: cmdMetaNodeInfoShort,
96
Args: cobra.MinimumNArgs(1),
97
Run: func(cmd *cobra.Command, args []string) {
100
var metanodeInfo *proto.MetaNodeInfo
105
if metanodeInfo, err = client.NodeAPI().GetMetaNode(nodeAddr); err != nil {
108
stdout("[Meta node info]\n")
109
stdout("%v", formatMetaNodeDetail(metanodeInfo, false))
111
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
113
return nil, cobra.ShellCompDirectiveNoFileComp
115
return validMetaNodes(client, toComplete), cobra.ShellCompDirectiveNoFileComp
121
func newMetaNodeDecommissionCmd(client *master.MasterClient) *cobra.Command {
126
cmd := &cobra.Command{
127
Use: CliOpDecommission + " [{HOST}:{PORT}]",
128
Short: cmdMetaNodeDecommissionInfoShort,
129
Args: cobra.MinimumNArgs(1),
130
Run: func(cmd *cobra.Command, args []string) {
138
stdout("Migrate mp count should >= 0\n")
141
if err = client.NodeAPI().MetaNodeDecommission(nodeAddr, optCount, clientIDKey); err != nil {
144
stdout("Decommission meta node successfully\n")
146
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
148
return nil, cobra.ShellCompDirectiveNoFileComp
150
return validMetaNodes(client, toComplete), cobra.ShellCompDirectiveNoFileComp
153
cmd.Flags().IntVar(&optCount, CliFlagCount, 0, "MetaNode delete mp count")
154
cmd.Flags().StringVar(&clientIDKey, CliFlagClientIDKey, client.ClientIDKey(), CliUsageClientIDKey)
158
func newMetaNodeMigrateCmd(client *master.MasterClient) *cobra.Command {
163
cmd := &cobra.Command{
164
Use: CliOpMigrate + " src[{HOST}:{PORT}] dst[{HOST}:{PORT}]",
165
Short: cmdMetaNodeMigrateInfoShort,
166
Args: cobra.MinimumNArgs(2),
167
Run: func(cmd *cobra.Command, args []string) {
175
if optCount > mpMigrateMax || optCount <= 0 {
176
stdout("Migrate mp count should between [1-15]\n")
179
if err = client.NodeAPI().MetaNodeMigrate(src, dst, optCount, clientIDKey); err != nil {
182
stdout("Migrate meta node successfully\n")
184
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
186
return nil, cobra.ShellCompDirectiveNoFileComp
188
return validMetaNodes(client, toComplete), cobra.ShellCompDirectiveNoFileComp
191
cmd.Flags().IntVar(&optCount, CliFlagCount, mpMigrateMax, "Migrate mp count")
192
cmd.Flags().StringVar(&clientIDKey, CliFlagClientIDKey, client.ClientIDKey(), CliUsageClientIDKey)