Skip to content
This repository was archived by the owner on Apr 26, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
bin/
.admin-cli-history
pegasus.log
.idea
shell.log
43 changes: 43 additions & 0 deletions cmd/disk_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cmd

import (
"admin-cli/executor"
"admin-cli/shell"

"github.com/desertbit/grumble"
)

func init() {
shell.AddCommand(&grumble.Command{
Name: "disk-migrate",
Help: "migrate replica between the two disks within a specified ReplicaServer node",
Flags: func(f *grumble.Flags) {
/*define the flags*/
f.String("g", "gpid", "", "gpid, for example, '2.1'")
f.String("n", "node", "", "target node, for example, 127.0.0.1:34801")
f.String("f", "from", "", "origin disk tag, for example, ssd1")
f.String("t", "to", "", "target disk tag, for example, ssd2")
},
Run: func(c *grumble.Context) error {
return executor.DiskMigrate(
pegasusClient,
c.Flags.String("node"),
c.Flags.String("gpid"),
c.Flags.String("from"),
c.Flags.String("to"))
},
})

// TODO(jiashuo1) need generate migrate strategy(step) depends the disk-info result to run
shell.AddCommand(&grumble.Command{
Name: "disk-balance",
Help: "migrate replica automatically to let the disk capacity balance within a specified ReplicaServer node",
Flags: func(f *grumble.Flags) {
/*define the flags*/
},
Run: func(c *grumble.Context) error {
return executor.DiskBalance()
},
})

}
51 changes: 51 additions & 0 deletions cmd/disk_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package cmd

import (
"admin-cli/executor"
"admin-cli/shell"

"github.com/desertbit/grumble"
)

func init() {
shell.AddCommand(&grumble.Command{
Name: "disk-capacity",
Help: "query disk capacity info ",
Flags: func(f *grumble.Flags) {
/*define the flags*/
f.Bool("r", "resolve", false, "resolve input or output address, default false")
f.Bool("j", "json", false, "use JSON as the format of the output results. By default tabular format is used.")
f.String("n", "node", "", "node address(ip:port), for example, 127.0.0.1:34801")
f.String("d", "disk", "", "disk tag, for example, ssd1")
f.String("a", "app", "", "app name, for example, temp")
},
Run: func(c *grumble.Context) error {
return executor.QueryDiskInfo(
pegasusClient,
executor.CapacitySize,
c.Flags.String("node"),
c.Flags.String("app"),
c.Flags.String("disk"))
},
})

shell.AddCommand(&grumble.Command{
Name: "disk-replica",
Help: "query disk replica count info",
Flags: func(f *grumble.Flags) {
/*define the flags*/
f.Bool("r", "resolve", false, "resolve input or output address, default false")
f.Bool("j", "json", false, "use JSON as the format of the output results. By default tabular format is used.")
f.String("n", "node", "", "node address(ip:port), for example, 127.0.0.1:34801")
f.String("a", "app", "", "app name, for example, temp")
},
Run: func(c *grumble.Context) error {
return executor.QueryDiskInfo(
pegasusClient,
executor.ReplicaCount,
c.Flags.String("node"),
c.Flags.String("app"),
"")
},
})
}
25 changes: 0 additions & 25 deletions cmd/disk_migrate.go

This file was deleted.

24 changes: 24 additions & 0 deletions cmd/list_nodes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cmd

import (
"admin-cli/executor"
"admin-cli/shell"
"github.com/desertbit/grumble"
)

func init() {
shell.AddCommand(&grumble.Command{
Name: "list-nodes",
Aliases: []string{"nodes"},
Help: "list all nodes in the cluster",
Flags: func(f *grumble.Flags) {
f.Bool("d", "detail", false, "show detail replica count in all node")
},
Run: func(c *grumble.Context) error {
return executor.ListNodes(
pegasusClient,
c.Flags.Bool("detail"),
)
},
})
}
38 changes: 38 additions & 0 deletions cmd/remote_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cmd

import (
"admin-cli/executor"
"github.com/desertbit/grumble"
)

func init() {
rootCmd := &grumble.Command{
Name: "remote-command",
Help: "send remote command, for example, remote-command meta or replica",
}

rootCmd.AddCommand(&grumble.Command{
Name: "meta",
Help: "send remote command to meta server",
Flags: initFlag,
Run: func(c *grumble.Context) error {
return executor.RemoteCommand(pegasusClient, "meta", c.Flags.String("node"), c.Flags.String("command"), c.Flags.String("arguments"))
},
})

rootCmd.AddCommand(&grumble.Command{
Name: "replica",
Help: "send remote command to replica server",
Flags: initFlag,
Run: func(c *grumble.Context) error {
return executor.RemoteCommand(pegasusClient, "replica", c.Flags.String("node"), c.Flags.String("command"), c.Flags.String("arguments"))
},
})
}

func initFlag(f *grumble.Flags) {
/*define the flags*/
f.String("n", "node", "", "specify server node address, such as 127.0.0.1:34801, empty mean all node")
f.String("c", "command", "help", "remote command name, you can -c help to see support command")
f.String("a", "arguments", "", "if empty means query the command argument value, otherwise mean set update value")
}
19 changes: 19 additions & 0 deletions cmd/server_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cmd

import (
"admin-cli/executor"
"admin-cli/shell"

"github.com/desertbit/grumble"
)

func init() {
shell.AddCommand(&grumble.Command{
Name: "server-info",
Help: "displays the overall server information",
Run: func(c *grumble.Context) error {
return executor.ServerInfo(pegasusClient)
},
})

}
86 changes: 82 additions & 4 deletions executor/client.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package executor

import (
"context"
"fmt"
"io"
"time"

adminClient "github.com/XiaoMi/pegasus-go-client/admin"
"github.com/XiaoMi/pegasus-go-client/idl/admin"
"github.com/XiaoMi/pegasus-go-client/session"
"github.com/pegasus-kv/collector/aggregate"
)

// Client can access both Pegasus ReplicaServer and MetaServer.
Expand All @@ -15,14 +21,86 @@ type Client struct {
ReplicaPool *session.ReplicaManager

MetaAddresses []string

ReplicaAddresses []string
}

// NewClient creates a client for accessing Pegasus cluster for use of admin-cli.
func NewClient(writer io.Writer, metaAddrs []string) *Client {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

meta := session.NewMetaManager(metaAddrs, session.NewNodeSession)
replicaPool := session.NewReplicaManager(session.NewNodeSession)

resp, err := meta.ListNodes(ctx, &admin.ListNodesRequest{
Status: admin.NodeStatus_NS_INVALID,
})
if err != nil {
return nil
}

var nodes []string
for _, node := range resp.Infos {
nodes = append(nodes, node.Address.GetAddress())
}

return &Client{
Writer: writer,
Meta: session.NewMetaManager(metaAddrs, session.NewNodeSession),
ReplicaPool: session.NewReplicaManager(session.NewNodeSession),
MetaAddresses: metaAddrs,
Writer: writer,
Meta: meta,
ReplicaPool: replicaPool,
MetaAddresses: metaAddrs,
ReplicaAddresses: nodes,
}
}

func (client *Client) GetReplicaClient(addr string) (*session.ReplicaSession, error) {
err := client.validateReplicaAddress(addr)
if err != nil {
return nil, err
}
return client.ReplicaPool.GetReplica(addr), nil
}

func (client *Client) GetRemoteCommandClient(addr string, nodeType session.NodeType) (*adminClient.RemoteCmdClient, error) {
switch nodeType {
case session.NodeTypeMeta:
err := client.validateMetaAddress(addr)
if err != nil {
return nil, err
}
case session.NodeTypeReplica:
err := client.validateReplicaAddress(addr)
if err != nil {
return nil, err
}
}
return adminClient.NewRemoteCmdClient(addr, nodeType), nil
}

func (client *Client) GetPerfCounterClient(addr string) (*aggregate.PerfSession, error) {
err := client.validateReplicaAddress(addr)
if err != nil {
return nil, err
}
return aggregate.NewPerfSession(addr), nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use PerfClient instead, PerfSession is low level primitive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know PerfClient, I only use one node session to query counter, but query all node and then filter one of them

}

func (client *Client) validateReplicaAddress(addr string) error {
for _, node := range client.ReplicaAddresses {
if node == addr {
return nil
}
}
return fmt.Errorf("The cluster doesn't exist the replica server node [%s]", addr)
}

// used for remote_command -t meta
func (client *Client) validateMetaAddress(addr string) error {
for _, meta := range client.MetaAddresses {
if addr == meta {
return nil
}
}
return fmt.Errorf("The cluster doesn't exist the meta server node [%s]", addr)
}
51 changes: 51 additions & 0 deletions executor/disk_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package executor

import (
"admin-cli/helper"
"context"
"fmt"
"time"

"github.com/XiaoMi/pegasus-go-client/idl/radmin"
)

func DiskMigrate(client *Client, replicaServer string, pidStr string, from string, to string) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

var addr, err = helper.Resolve(replicaServer, helper.Host2Addr)
if err == nil {
replicaServer = addr
}

pid, err := helper.Str2Gpid(pidStr)
if err != nil {
return err
}

replicaClient, err := client.GetReplicaClient(replicaServer)
if err != nil {
return err
}

resp, err := replicaClient.DiskMigrate(ctx, &radmin.ReplicaDiskMigrateRequest{
Pid: pid,
OriginDisk: from,
TargetDisk: to,
})

if err != nil {
if resp != nil && resp.Hint != nil {
return fmt.Errorf("Internal server error [%s:%s]", err, *resp.Hint)
}
return err
}

return nil
}

// TODO(jiashuo1) need generate migrate strategy(step) depends the disk-info result to run
func DiskBalance() error {
fmt.Println("Wait support")
return nil
}
Loading