mirror of https://github.com/status-im/consul.git
Wait to initialize autopilot until all servers are >= 0.8.0
This commit is contained in:
parent
56c3f4576e
commit
7d36403291
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
"github.com/hashicorp/consul/consul/agent"
|
"github.com/hashicorp/consul/consul/agent"
|
||||||
"github.com/hashicorp/consul/consul/structs"
|
"github.com/hashicorp/consul/consul/structs"
|
||||||
|
"github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/raft"
|
"github.com/hashicorp/raft"
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
)
|
)
|
||||||
|
@ -33,6 +34,8 @@ func (s *Server) stopAutopilot() {
|
||||||
s.autopilotWaitGroup.Wait()
|
s.autopilotWaitGroup.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var minAutopilotVersion, _ = version.NewVersion("0.8.0")
|
||||||
|
|
||||||
// autopilotLoop periodically looks for nonvoting servers to promote and dead servers to remove.
|
// autopilotLoop periodically looks for nonvoting servers to promote and dead servers to remove.
|
||||||
func (s *Server) autopilotLoop() {
|
func (s *Server) autopilotLoop() {
|
||||||
defer s.autopilotWaitGroup.Done()
|
defer s.autopilotWaitGroup.Done()
|
||||||
|
@ -53,6 +56,15 @@ func (s *Server) autopilotLoop() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup autopilot config if we need to
|
||||||
|
if autopilotConf == nil {
|
||||||
|
if err := s.initializeAutopilot(); err != nil {
|
||||||
|
s.logger.Printf("[ERR] autopilot: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.autopilotPolicy.PromoteNonVoters(autopilotConf); err != nil {
|
if err := s.autopilotPolicy.PromoteNonVoters(autopilotConf); err != nil {
|
||||||
s.logger.Printf("[ERR] autopilot: error checking for non-voters to promote: %s", err)
|
s.logger.Printf("[ERR] autopilot: error checking for non-voters to promote: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -68,11 +80,26 @@ func (s *Server) autopilotLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lowestServerVersion returns the lowest version among the alive servers
|
||||||
|
func (s *Server) lowestServerVersion() *version.Version {
|
||||||
|
lowest := minAutopilotVersion
|
||||||
|
|
||||||
|
for _, member := range s.LANMembers() {
|
||||||
|
if valid, parts := agent.IsConsulServer(member); valid && parts.Status == serf.StatusAlive {
|
||||||
|
if parts.Build.LessThan(lowest) {
|
||||||
|
lowest = &parts.Build
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lowest
|
||||||
|
}
|
||||||
|
|
||||||
// pruneDeadServers removes up to numPeers/2 failed servers
|
// pruneDeadServers removes up to numPeers/2 failed servers
|
||||||
func (s *Server) pruneDeadServers() error {
|
func (s *Server) pruneDeadServers() error {
|
||||||
state := s.fsm.State()
|
state := s.fsm.State()
|
||||||
_, autopilotConf, err := state.AutopilotConfig()
|
_, autopilotConf, err := state.AutopilotConfig()
|
||||||
if err != nil {
|
if err != nil || autopilotConf == nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,8 @@ func TestAutopilot_CleanupStaleRaftServer(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testutil.WaitForLeader(t, s1.RPC, "dc1")
|
||||||
|
|
||||||
// Add s4 to peers directly
|
// Add s4 to peers directly
|
||||||
s4addr := fmt.Sprintf("127.0.0.1:%d",
|
s4addr := fmt.Sprintf("127.0.0.1:%d",
|
||||||
s4.config.SerfLANConfig.MemberlistConfig.BindPort)
|
s4.config.SerfLANConfig.MemberlistConfig.BindPort)
|
||||||
|
|
|
@ -153,10 +153,9 @@ func (s *Server) establishLeadership() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup autopilot config if we are the leader and need to
|
// Setup autopilot config if we need to
|
||||||
if err := s.initializeAutopilot(); err != nil {
|
if err := s.initializeAutopilot(); err != nil {
|
||||||
s.logger.Printf("[ERR] consul: Autopilot initialization failed: %v", err)
|
s.logger.Printf("[ERR] autopilot: %v", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.startAutopilot()
|
s.startAutopilot()
|
||||||
|
@ -252,6 +251,12 @@ func (s *Server) initializeACL() error {
|
||||||
// initializeAutopilot is used to setup the autopilot config if we are
|
// initializeAutopilot is used to setup the autopilot config if we are
|
||||||
// the leader and need to do this
|
// the leader and need to do this
|
||||||
func (s *Server) initializeAutopilot() error {
|
func (s *Server) initializeAutopilot() error {
|
||||||
|
lowestVersion := s.lowestServerVersion()
|
||||||
|
|
||||||
|
if !lowestVersion.Equal(minAutopilotVersion) && !lowestVersion.GreaterThan(minAutopilotVersion) {
|
||||||
|
return fmt.Errorf("can't initialize autopilot until all servers are >= %s", minAutopilotVersion.String())
|
||||||
|
}
|
||||||
|
|
||||||
// Bail if the config has already been initialized
|
// Bail if the config has already been initialized
|
||||||
state := s.fsm.State()
|
state := s.fsm.State()
|
||||||
_, config, err := state.AutopilotConfig()
|
_, config, err := state.AutopilotConfig()
|
||||||
|
|
Loading…
Reference in New Issue