consul: Update for serf 0.4

This commit is contained in:
Armon Dadgar 2014-01-30 13:13:29 -08:00
parent c4f516d034
commit fe0efdfa75
6 changed files with 39 additions and 31 deletions

View File

@ -90,8 +90,10 @@ func NewClient(config *Config) (*Client, error) {
// setupSerf is used to setup and initialize a Serf // setupSerf is used to setup and initialize a Serf
func (c *Client) setupSerf(conf *serf.Config, ch chan serf.Event, path string) (*serf.Serf, error) { func (c *Client) setupSerf(conf *serf.Config, ch chan serf.Event, path string) (*serf.Serf, error) {
conf.Init()
conf.NodeName = c.config.NodeName conf.NodeName = c.config.NodeName
conf.Role = fmt.Sprintf("node:%s", c.config.Datacenter) conf.Tags["role"] = "node"
conf.Tags["dc"] = c.config.Datacenter
conf.MemberlistConfig.LogOutput = c.config.LogOutput conf.MemberlistConfig.LogOutput = c.config.LogOutput
conf.LogOutput = c.config.LogOutput conf.LogOutput = c.config.LogOutput
conf.EventCh = ch conf.EventCh = ch

View File

@ -270,11 +270,11 @@ func (s *Server) joinConsulServer(m serf.Member, parts *serverParts) error {
} }
// Check for possibility of multiple bootstrap nodes // Check for possibility of multiple bootstrap nodes
if parts.HasFlag(bootstrapFlag) { if parts.Bootstrap {
members := s.serfLAN.Members() members := s.serfLAN.Members()
for _, member := range members { for _, member := range members {
valid, p := isConsulServer(member) valid, p := isConsulServer(member)
if valid && member.Name != m.Name && p.HasFlag(bootstrapFlag) { if valid && member.Name != m.Name && p.Bootstrap {
s.logger.Printf("[ERR] consul: '%v' and '%v' are both in bootstrap mode. Only one node should be in bootstrap mode, not adding Raft peer.", m.Name, member.Name) s.logger.Printf("[ERR] consul: '%v' and '%v' are both in bootstrap mode. Only one node should be in bootstrap mode, not adding Raft peer.", m.Name, member.Name)
return nil return nil
} }

View File

@ -162,12 +162,14 @@ func NewServer(config *Config) (*Server, error) {
// setupSerf is used to setup and initialize a Serf // setupSerf is used to setup and initialize a Serf
func (s *Server) setupSerf(conf *serf.Config, ch chan serf.Event, path string) (*serf.Serf, error) { func (s *Server) setupSerf(conf *serf.Config, ch chan serf.Event, path string) (*serf.Serf, error) {
addr := s.rpcListener.Addr().(*net.TCPAddr) addr := s.rpcListener.Addr().(*net.TCPAddr)
flags := "" conf.Init()
if s.config.Bootstrap {
flags = bootstrapFlag
}
conf.NodeName = s.config.NodeName conf.NodeName = s.config.NodeName
conf.Role = fmt.Sprintf("consul:%s:%d:%s", s.config.Datacenter, addr.Port, flags) conf.Tags["role"] = "consul"
conf.Tags["dc"] = s.config.Datacenter
conf.Tags["port"] = fmt.Sprintf("%d", addr.Port)
if s.config.Bootstrap {
conf.Tags["bootstrap"] = "1"
}
conf.MemberlistConfig.LogOutput = s.config.LogOutput conf.MemberlistConfig.LogOutput = s.config.LogOutput
conf.LogOutput = s.config.LogOutput conf.LogOutput = s.config.LogOutput
conf.EventCh = ch conf.EventCh = ch

View File

@ -173,7 +173,8 @@ func TestServer_Leave(t *testing.T) {
defer os.RemoveAll(dir1) defer os.RemoveAll(dir1)
defer s1.Shutdown() defer s1.Shutdown()
dir2, s2 := testServer(t) // Second server not in bootstrap mode
dir2, s2 := testServerDCBootstrap(t, "dc1", false)
defer os.RemoveAll(dir2) defer os.RemoveAll(dir2)
defer s2.Shutdown() defer s2.Shutdown()

View File

@ -8,7 +8,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings"
) )
/* /*
@ -23,12 +22,7 @@ var privateBlocks []*net.IPNet
type serverParts struct { type serverParts struct {
Datacenter string Datacenter string
Port int Port int
Flags string Bootstrap bool
}
// HasFlag is used to check if a flag is present
func (s *serverParts) HasFlag(flag string) bool {
return strings.Contains(s.Flags, flag)
} }
func init() { func init() {
@ -74,34 +68,28 @@ func ensurePath(path string, dir bool) error {
// Returns if a member is a consul server. Returns a bool, // Returns if a member is a consul server. Returns a bool,
// the data center, and the rpc port // the data center, and the rpc port
func isConsulServer(m serf.Member) (bool, *serverParts) { func isConsulServer(m serf.Member) (bool, *serverParts) {
role := m.Role if m.Tags["role"] != "consul" {
if !strings.HasPrefix(role, "consul:") {
return false, nil return false, nil
} }
parts := strings.SplitN(role, ":", 4) datacenter := m.Tags["dc"]
datacenter := parts[1] port_str := m.Tags["port"]
port_str := parts[2] _, bootstrap := m.Tags["bootstrap"]
flags := parts[3]
port, err := strconv.Atoi(port_str) port, err := strconv.Atoi(port_str)
if err != nil { if err != nil {
return false, nil return false, nil
} }
return true, &serverParts{datacenter, port, flags} return true, &serverParts{datacenter, port, bootstrap}
} }
// Returns if a member is a consul node. Returns a boo, // Returns if a member is a consul node. Returns a boo,
// and the data center. // and the data center.
func isConsulNode(m serf.Member) (bool, string) { func isConsulNode(m serf.Member) (bool, string) {
role := m.Role if m.Tags["role"] != "node" {
if !strings.HasPrefix(role, "node:") {
return false, "" return false, ""
} }
return true, m.Tags["dc"]
parts := strings.SplitN(role, ":", 2)
datacenter := parts[1]
return true, datacenter
} }
// Returns if the given IP is in a private block // Returns if the given IP is in a private block

View File

@ -35,17 +35,32 @@ func TestIsPrivateIP(t *testing.T) {
func TestIsConsulServer(t *testing.T) { func TestIsConsulServer(t *testing.T) {
m := serf.Member{ m := serf.Member{
Role: "consul:east-aws:10000", Tags: map[string]string{
"role": "consul",
"dc": "east-aws",
"port": "10000",
},
} }
valid, parts := isConsulServer(m) valid, parts := isConsulServer(m)
if !valid || parts.Datacenter != "east-aws" || parts.Port != 10000 { if !valid || parts.Datacenter != "east-aws" || parts.Port != 10000 {
t.Fatalf("bad: %v %v", valid, parts) t.Fatalf("bad: %v %v", valid, parts)
} }
if parts.Bootstrap {
t.Fatalf("unexpected bootstrap")
}
m.Tags["bootstrap"] = "1"
valid, parts = isConsulServer(m)
if !valid || !parts.Bootstrap {
t.Fatalf("expected bootstrap")
}
} }
func TestIsConsulNode(t *testing.T) { func TestIsConsulNode(t *testing.T) {
m := serf.Member{ m := serf.Member{
Role: "node:east-aws", Tags: map[string]string{
"role": "node",
"dc": "east-aws",
},
} }
valid, dc := isConsulNode(m) valid, dc := isConsulNode(m)
if !valid || dc != "east-aws" { if !valid || dc != "east-aws" {