From 423e3bbbd80f84fa96779731c503ec1402a14e5c Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Mon, 31 Aug 2015 17:05:35 -0700 Subject: [PATCH] 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. --- etcdctl/command/cluster_health.go | 9 +++- etcdctl/command/util.go | 78 +++++++++++++++++++------------ 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/etcdctl/command/cluster_health.go b/etcdctl/command/cluster_health.go index 549a70506..303e06f37 100644 --- a/etcdctl/command/cluster_health.go +++ b/etcdctl/command/cluster_health.go @@ -10,6 +10,7 @@ import ( "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/client" ) func NewClusterHealthCommand() cli.Command { @@ -44,7 +45,8 @@ func handleClusterHealth(c *cli.Context) { Transport: tr, } - mi := mustNewMembersAPI(c) + cln := mustNewClientNoSync(c) + mi := client.NewMembersAPI(cln) ms, err := mi.List(context.TODO()) if err != nil { fmt.Println("cluster may be unhealthy: failed to list members") @@ -54,6 +56,11 @@ func handleClusterHealth(c *cli.Context) { for { health := false 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 for _, url := range m.ClientURLs { resp, err := hc.Get(url + "/health") diff --git a/etcdctl/command/util.go b/etcdctl/command/util.go index ac6dbeda1..b8f329873 100644 --- a/etcdctl/command/util.go +++ b/etcdctl/command/util.go @@ -181,36 +181,7 @@ func mustNewMembersAPI(c *cli.Context) client.MembersAPI { } func mustNewClient(c *cli.Context) client.Client { - eps, err := getEndpoints(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) + hc, err := newClient(c) if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) @@ -223,7 +194,7 @@ func mustNewClient(c *cli.Context) client.Client { if err != nil { if err == client.ErrNoEndpoints { 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) os.Exit(1) @@ -237,3 +208,48 @@ func mustNewClient(c *cli.Context) client.Client { 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) +}