etcdctl/cluster_health: provide better message for empty client urls

It skips sync when init client, and prints out unreachable messagen and
points to notice when checking health of etcd members one by one.
This commit is contained in:
Yicheng Qin
2015-08-31 17:05:35 -07:00
parent c2caa4ae3b
commit 423e3bbbd8
2 changed files with 55 additions and 32 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/codegangsta/cli" "github.com/coreos/etcd/Godeps/_workspace/src/github.com/codegangsta/cli"
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
"github.com/coreos/etcd/client"
) )
func NewClusterHealthCommand() cli.Command { func NewClusterHealthCommand() cli.Command {
@ -44,7 +45,8 @@ func handleClusterHealth(c *cli.Context) {
Transport: tr, Transport: tr,
} }
mi := mustNewMembersAPI(c) cln := mustNewClientNoSync(c)
mi := client.NewMembersAPI(cln)
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") fmt.Println("cluster may be unhealthy: failed to list members")
@ -54,6 +56,11 @@ func handleClusterHealth(c *cli.Context) {
for { for {
health := false health := false
for _, m := range ms { for _, m := range ms {
if len(m.ClientURLs) == 0 {
fmt.Printf("member %s is unreachable: no available published client urls\n", m.ID)
continue
}
checked := false checked := false
for _, url := range m.ClientURLs { for _, url := range m.ClientURLs {
resp, err := hc.Get(url + "/health") resp, err := hc.Get(url + "/health")

View File

@ -181,36 +181,7 @@ func mustNewMembersAPI(c *cli.Context) client.MembersAPI {
} }
func mustNewClient(c *cli.Context) client.Client { func mustNewClient(c *cli.Context) client.Client {
eps, err := getEndpoints(c) hc, err := newClient(c)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
tr, err := getTransport(c)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
cfg := client.Config{
Transport: tr,
Endpoints: eps,
HeaderTimeoutPerRequest: c.GlobalDuration("timeout"),
}
uFlag := c.GlobalString("username")
if uFlag != "" {
username, password, err := getUsernamePasswordFromFlag(uFlag)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
cfg.Username = username
cfg.Password = password
}
hc, err := client.New(cfg)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err.Error()) fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1) os.Exit(1)
@ -223,7 +194,7 @@ func mustNewClient(c *cli.Context) client.Client {
if err != nil { if err != nil {
if err == client.ErrNoEndpoints { if err == client.ErrNoEndpoints {
fmt.Fprintf(os.Stderr, "etcd cluster has no published client endpoints.\n") fmt.Fprintf(os.Stderr, "etcd cluster has no published client endpoints.\n")
fmt.Fprintf(os.Stderr, "Try '--no-sync' if you want to access non-published client endpoints(%s).\n", strings.Join(eps, ",")) fmt.Fprintf(os.Stderr, "Try '--no-sync' if you want to access non-published client endpoints(%s).\n", strings.Join(hc.Endpoints(), ","))
} }
handleError(ExitServerError, err) handleError(ExitServerError, err)
os.Exit(1) os.Exit(1)
@ -237,3 +208,48 @@ func mustNewClient(c *cli.Context) client.Client {
return hc return hc
} }
func mustNewClientNoSync(c *cli.Context) client.Client {
hc, err := newClient(c)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
if c.GlobalBool("debug") {
fmt.Fprintf(os.Stderr, "Cluster-Endpoints: %s\n", strings.Join(hc.Endpoints(), ", "))
client.EnablecURLDebug()
}
return hc
}
func newClient(c *cli.Context) (client.Client, error) {
eps, err := getEndpoints(c)
if err != nil {
return nil, err
}
tr, err := getTransport(c)
if err != nil {
return nil, err
}
cfg := client.Config{
Transport: tr,
Endpoints: eps,
HeaderTimeoutPerRequest: c.GlobalDuration("timeout"),
}
uFlag := c.GlobalString("username")
if uFlag != "" {
username, password, err := getUsernamePasswordFromFlag(uFlag)
if err != nil {
return nil, err
}
cfg.Username = username
cfg.Password = password
}
return client.New(cfg)
}