From 4715533743d8cd2e0660ebb6d9787cda1f323d68 Mon Sep 17 00:00:00 2001 From: Preetha Appan Date: Mon, 5 Mar 2018 16:56:36 -0600 Subject: [PATCH] Ignore left members when querying regions for leader in server-members command. --- command/server_members.go | 6 ++++ command/server_members_test.go | 60 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/command/server_members.go b/command/server_members.go index 247378b71..55a31d268 100644 --- a/command/server_members.go +++ b/command/server_members.go @@ -168,6 +168,12 @@ func regionLeaders(client *api.Client, mem []*api.AgentMember) (map[string]strin leaders := make(map[string]string) regions := make(map[string]struct{}) for _, m := range mem { + // Ignore left members + // This prevents querying for leader status on regions where all members have left + if m.Status == "left" { + continue + } + regions[m.Tags["region"]] = struct{}{} } diff --git a/command/server_members_test.go b/command/server_members_test.go index 7dd4e6232..e6ac296e6 100644 --- a/command/server_members_test.go +++ b/command/server_members_test.go @@ -1,9 +1,11 @@ package command import ( + "fmt" "strings" "testing" + "github.com/hashicorp/nomad/command/agent" "github.com/mitchellh/cli" ) @@ -66,3 +68,61 @@ func TestMembersCommand_Fails(t *testing.T) { t.Fatalf("expected failed query error, got: %s", out) } } + +// Tests that a single server region that left should still +// not return an error and list other members in other regions +func TestServerMembersCommand_MultiRegion_Leave(t *testing.T) { + t.Parallel() + + config1 := func(c *agent.Config) { + c.Region = "r1" + c.Datacenter = "d1" + } + + srv1, client1, url := testServer(t, false, config1) + defer srv1.Shutdown() + + config2 := func(c *agent.Config) { + c.Region = "r2" + c.Datacenter = "d2" + } + + srv2, _, _ := testServer(t, false, config2) + defer srv1.Shutdown() + + // Join with srv1 + addr := fmt.Sprintf("127.0.0.1:%d", + srv1.Agent.Server().GetConfig().SerfConfig.MemberlistConfig.BindPort) + + if _, err := srv2.Agent.Server().Join([]string{addr}); err != nil { + t.Fatalf("Join err: %v", err) + } + ui := new(cli.MockUi) + cmd := &ServerMembersCommand{Meta: Meta{Ui: ui}} + + // Get our own node name + name, err := client1.Agent().NodeName() + if err != nil { + t.Fatalf("err: %s", err) + } + + // Query the members + if code := cmd.Run([]string{"-address=" + url}); code != 0 { + t.Fatalf("expected exit 0, got: %d", code) + } + if out := ui.OutputWriter.String(); !strings.Contains(out, name) { + t.Fatalf("expected %q in output, got: %s", name, out) + } + ui.OutputWriter.Reset() + + // Make one of the servers leave + srv2.Agent.Leave() + + // Query again, should still contain expected output + if code := cmd.Run([]string{"-address=" + url}); code != 0 { + t.Fatalf("expected exit 0, got: %d", code) + } + if out := ui.OutputWriter.String(); !strings.Contains(out, name) { + t.Fatalf("expected %q in output, got: %s", name, out) + } +}