diff --git a/consul/autopilot.go b/consul/autopilot.go index ed0f500abf..34d28f457d 100644 --- a/consul/autopilot.go +++ b/consul/autopilot.go @@ -49,7 +49,7 @@ func (s *Server) autopilotLoop() { case <-s.autopilotShutdownCh: return case <-ticker.C: - autopilotConfig, ok := s.getAutopilotConfig() + autopilotConfig, ok := s.getOrCreateAutopilotConfig() if !ok { continue } @@ -62,7 +62,7 @@ func (s *Server) autopilotLoop() { s.logger.Printf("[ERR] autopilot: error checking for dead servers to remove: %s", err) } case <-s.autopilotRemoveDeadCh: - autopilotConfig, ok := s.getAutopilotConfig() + autopilotConfig, ok := s.getOrCreateAutopilotConfig() if !ok { continue } diff --git a/consul/leader.go b/consul/leader.go index 19667b87ba..95e5a7da94 100644 --- a/consul/leader.go +++ b/consul/leader.go @@ -154,7 +154,7 @@ func (s *Server) establishLeadership() error { } // Setup autopilot config if we need to - s.getAutopilotConfig() + s.getOrCreateAutopilotConfig() s.startAutopilot() @@ -246,12 +246,12 @@ func (s *Server) initializeACL() error { return nil } -// getAutopilotConfig is used to get the autopilot config, initializing it if necessary -func (s *Server) getAutopilotConfig() (*structs.AutopilotConfig, bool) { +// getOrCreateAutopilotConfig is used to get the autopilot config, initializing it if necessary +func (s *Server) getOrCreateAutopilotConfig() (*structs.AutopilotConfig, bool) { state := s.fsm.State() _, config, err := state.AutopilotConfig() if err != nil { - s.logger.Printf("failed to get autopilot config: %v", err) + s.logger.Printf("[ERR] autopilot: failed to get config: %v", err) return nil, false } if config != nil { @@ -259,14 +259,14 @@ func (s *Server) getAutopilotConfig() (*structs.AutopilotConfig, bool) { } if !ServersMeetMinimumVersion(s.LANMembers(), minAutopilotVersion) { - s.logger.Printf("can't initialize autopilot until all servers are >= %s", minAutopilotVersion.String()) + s.logger.Printf("[ERR] autopilot: can't initialize until all servers are >= %s", minAutopilotVersion.String()) return nil, false } config = s.config.AutopilotConfig req := structs.AutopilotSetConfigRequest{Config: *config} if _, err = s.raftApply(structs.AutopilotRequestType, req); err != nil { - s.logger.Printf("failed to initialize autopilot config") + s.logger.Printf("[ERR] autopilot: failed to initialize config: %v", err) return nil, false } diff --git a/consul/util.go b/consul/util.go index 044dd3d118..dd04a340b6 100644 --- a/consul/util.go +++ b/consul/util.go @@ -310,4 +310,4 @@ func ServersMeetMinimumVersion(members []serf.Member, minVersion *version.Versio } return true -} \ No newline at end of file +} diff --git a/consul/util_test.go b/consul/util_test.go index 042a4f6779..567e77c7ed 100644 --- a/consul/util_test.go +++ b/consul/util_test.go @@ -7,6 +7,7 @@ import ( "regexp" "testing" + "github.com/hashicorp/go-version" "github.com/hashicorp/serf/serf" ) @@ -325,3 +326,72 @@ func TestGetPublicIPv6(t *testing.T) { } } } + +func TestServersMeetMinimumVersion(t *testing.T) { + makeMember := func(version string) serf.Member { + return serf.Member{ + Name: "foo", + Addr: net.IP([]byte{127, 0, 0, 1}), + Tags: map[string]string{ + "role": "consul", + "id": "asdf", + "dc": "east-aws", + "port": "10000", + "build": version, + "wan_join_port": "1234", + "vsn": "1", + "expect": "3", + "raft_vsn": "3", + }, + Status: serf.StatusAlive, + } + } + + cases := []struct { + members []serf.Member + ver *version.Version + expected bool + }{ + // One server, meets reqs + { + members: []serf.Member{ + makeMember("0.7.5"), + }, + ver: version.Must(version.NewVersion("0.7.5")), + expected: true, + }, + // One server, doesn't meet reqs + { + members: []serf.Member{ + makeMember("0.7.5"), + }, + ver: version.Must(version.NewVersion("0.8.0")), + expected: false, + }, + // Multiple servers, meets req version + { + members: []serf.Member{ + makeMember("0.7.5"), + makeMember("0.8.0"), + }, + ver: version.Must(version.NewVersion("0.7.5")), + expected: true, + }, + // Multiple servers, doesn't meet req version + { + members: []serf.Member{ + makeMember("0.7.5"), + makeMember("0.8.0"), + }, + ver: version.Must(version.NewVersion("0.8.0")), + expected: false, + }, + } + + for _, tc := range cases { + result := ServersMeetMinimumVersion(tc.members, tc.ver) + if result != tc.expected { + t.Fatalf("bad: %v, %v, %v", result, tc.ver.String(), tc) + } + } +}