etcdctl: cluster-health supports forever flag

cluster-health command supports checking the cluster health
forever.
This commit is contained in:
Xiang Li 2015-07-30 10:01:47 +08:00
parent 219ed1695b
commit f7f00b0af6

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
"os/signal"
"sort" "sort"
"time" "time"
@ -17,33 +18,52 @@ func NewClusterHealthCommand() cli.Command {
return cli.Command{ return cli.Command{
Name: "cluster-health", Name: "cluster-health",
Usage: "check the health of the etcd cluster", Usage: "check the health of the etcd cluster",
Flags: []cli.Flag{}, Flags: []cli.Flag{
cli.BoolFlag{Name: "forever", Usage: "forever check the health every 10 second until CTRL+C"},
},
Action: handleClusterHealth, Action: handleClusterHealth,
} }
} }
func handleClusterHealth(c *cli.Context) { func handleClusterHealth(c *cli.Context) {
forever := c.Bool("forever")
if forever {
sigch := make(chan os.Signal, 1)
signal.Notify(sigch, os.Interrupt)
go func() {
<-sigch
os.Exit(0)
}()
}
tr, err := getTransport(c) tr, err := getTransport(c)
if err != nil { if err != nil {
handleError(ExitServerError, err) handleError(ExitServerError, err)
} }
// TODO: update members when forever is set.
mi := mustNewMembersAPI(c) mi := mustNewMembersAPI(c)
ms, err := mi.List(context.TODO()) ms, err := mi.List(context.TODO())
if err != nil { if err != nil {
fmt.Println("cluster may be unhealthy: failed to list members")
handleError(ExitServerError, err) handleError(ExitServerError, err)
} }
cl := make([]string, 0) cl := make([]string, 0)
for _, m := range ms { for _, m := range ms {
cl = append(cl, m.ClientURLs...) cl = append(cl, m.ClientURLs...)
} }
for {
// check the /health endpoint of all members first // check the /health endpoint of all members first
ep, rs0, err := getLeaderStatus(tr, cl) ep, rs0, err := getLeaderStatus(tr, cl)
if err != nil { if err != nil {
fmt.Println("cluster may be unhealthy: failed to connect", cl) fmt.Println("cluster may be unhealthy: failed to connect", cl)
if forever {
time.Sleep(10 * time.Second)
continue
}
os.Exit(1) os.Exit(1)
} }
@ -53,6 +73,10 @@ func handleClusterHealth(c *cli.Context) {
_, rs1, err := getLeaderStatus(tr, []string{ep}) _, rs1, err := getLeaderStatus(tr, []string{ep})
if err != nil { if err != nil {
fmt.Println("cluster is unhealthy") fmt.Println("cluster is unhealthy")
if forever {
time.Sleep(10 * time.Second)
continue
}
os.Exit(1) os.Exit(1)
} }
@ -68,6 +92,7 @@ func handleClusterHealth(c *cli.Context) {
for id, pr0 := range rs0.Progress { for id, pr0 := range rs0.Progress {
pr1, ok := rs1.Progress[id] pr1, ok := rs1.Progress[id]
if !ok { if !ok {
// TODO: forever should handle configuration change.
fmt.Println("Cluster configuration changed during health checking. Please retry.") fmt.Println("Cluster configuration changed during health checking. Please retry.")
os.Exit(1) os.Exit(1)
} }
@ -82,7 +107,13 @@ func handleClusterHealth(c *cli.Context) {
for _, p := range prints { for _, p := range prints {
fmt.Print(p) fmt.Print(p)
} }
os.Exit(0)
if !forever {
return
}
time.Sleep(10 * time.Second)
}
} }
type raftStatus struct { type raftStatus struct {