From ad0b3cfdab859c2d29c2605443c9820f44d34ae5 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Thu, 8 Jun 2017 16:06:11 -0700 Subject: [PATCH 1/2] ctlv2: report unhealthy in cluster-health if any node is unavailable Fixes #8061 and #7032 --- etcdctl/ctlv2/command/cluster_health.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/etcdctl/ctlv2/command/cluster_health.go b/etcdctl/ctlv2/command/cluster_health.go index 95101785d..d1429649a 100644 --- a/etcdctl/ctlv2/command/cluster_health.go +++ b/etcdctl/ctlv2/command/cluster_health.go @@ -70,7 +70,7 @@ func handleClusterHealth(c *cli.Context) error { } for { - health := false + healthyMembers := 0 for _, m := range ms { if len(m.ClientURLs) == 0 { fmt.Printf("member %s is unreachable: no available published client urls\n", m.ID) @@ -105,8 +105,8 @@ func handleClusterHealth(c *cli.Context) error { checked = true if result.Health == "true" || nresult.Health { - health = true fmt.Printf("member %s is healthy: got healthy result from %s\n", m.ID, url) + healthyMembers++ } else { fmt.Printf("member %s is unhealthy: got unhealthy result from %s\n", m.ID, url) } @@ -116,19 +116,20 @@ func handleClusterHealth(c *cli.Context) error { fmt.Printf("member %s is unreachable: %v are all unreachable\n", m.ID, m.ClientURLs) } } - if health { + switch healthyMembers { + case len(ms): fmt.Println("cluster is healthy") - } else { - fmt.Println("cluster is unhealthy") + case 0: + fmt.Println("cluster is unavailable") + default: + fmt.Println("cluster is degraded") } if !forever { - if health { + if healthyMembers == len(ms) { os.Exit(ExitSuccess) - return nil } os.Exit(ExitClusterNotHealthy) - return nil } fmt.Printf("\nnext check after 10 second...\n\n") From 3fcb8336aa8da058b3f1f3eb6e3b4c4e75bd5644 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Fri, 9 Jun 2017 12:55:23 -0700 Subject: [PATCH 2/2] e2e: update cluster-health test for new etcdctl output --- e2e/ctl_v2_test.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/e2e/ctl_v2_test.go b/e2e/ctl_v2_test.go index 8f877c256..c1635887d 100644 --- a/e2e/ctl_v2_test.go +++ b/e2e/ctl_v2_test.go @@ -321,17 +321,31 @@ func TestCtlV2ClusterHealth(t *testing.T) { } }() - // has quorum + // all members available if err := etcdctlClusterHealth(epc, "cluster is healthy"); err != nil { t.Fatalf("cluster-health expected to be healthy (%v)", err) } - // cut quorum + // missing members, has quorum epc.procs[0].Stop() - epc.procs[1].Stop() - if err := etcdctlClusterHealth(epc, "cluster is unhealthy"); err != nil { - t.Fatalf("cluster-health expected to be unhealthy (%v)", err) + + for i := 0; i < 3; i++ { + err := etcdctlClusterHealth(epc, "cluster is degraded") + if err == nil { + break + } else if i == 2 { + t.Fatalf("cluster-health expected to be degraded (%v)", err) + } + // possibly no leader yet; retry + time.Sleep(time.Second) } + + // no quorum + epc.procs[1].Stop() + if err := etcdctlClusterHealth(epc, "cluster is unavailable"); err != nil { + t.Fatalf("cluster-health expected to be unavailable (%v)", err) + } + epc.procs[0], epc.procs[1] = nil, nil }