diff --git a/consul/client.go b/consul/client.go index e01e4943d..9412e1e20 100644 --- a/consul/client.go +++ b/consul/client.go @@ -63,6 +63,11 @@ type Client struct { // NewClient is used to construct a new Consul client from the // configuration, potentially returning an error func NewClient(config *Config) (*Client, error) { + // Check the protocol version + if err := config.CheckVersion(); err != nil { + return nil, err + } + // Check for a data directory! if config.DataDir == "" { return nil, fmt.Errorf("Config must provide a DataDir") @@ -109,7 +114,7 @@ func (c *Client) setupSerf(conf *serf.Config, ch chan serf.Event, path string) ( conf.LogOutput = c.config.LogOutput conf.EventCh = ch conf.SnapshotPath = filepath.Join(c.config.DataDir, path) - conf.ProtocolVersion = 3 // TODO: Support version 4 + conf.ProtocolVersion = protocolVersionMap[c.config.ProtocolVersion] if err := ensurePath(conf.SnapshotPath, false); err != nil { return nil, err } diff --git a/consul/config.go b/consul/config.go index 35de3789c..fef1b0058 100644 --- a/consul/config.go +++ b/consul/config.go @@ -1,6 +1,7 @@ package consul import ( + "fmt" "github.com/hashicorp/memberlist" "github.com/hashicorp/raft" "github.com/hashicorp/serf/serf" @@ -20,6 +21,17 @@ var ( DefaultRPCAddr = &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 8300} ) +// ProtocolVersionMap is the mapping of Consul protocol versions +// to Serf protocol versions. We mask the Serf protocols using +// our own protocol version. +var protocolVersionMap map[uint8]uint8 + +func init() { + protocolVersionMap = map[uint8]uint8{ + 1: 4, + } +} + // Config is used to configure the server type Config struct { // Bootstrap mode is used to bring up the first Consul server. @@ -65,11 +77,27 @@ type Config struct { // logs will go to stderr. LogOutput io.Writer + // ProtocolVersion is the protocol version to speak. This must be between + // ProtocolVersionMin and ProtocolVersionMax. + ProtocolVersion uint8 + // ServerUp callback can be used to trigger a notification that // a Consul server is now up and known about. ServerUp func() } +// CheckVersion is used to check if the ProtocolVersion is valid +func (c *Config) CheckVersion() error { + if c.ProtocolVersion < ProtocolVersionMin { + return fmt.Errorf("Protocol version '%d' too low. Must be in range: [%d, %d]", + c.ProtocolVersion, ProtocolVersionMin, ProtocolVersionMax) + } else if c.ProtocolVersion > ProtocolVersionMax { + return fmt.Errorf("Protocol version '%d' too high. Must be in range: [%d, %d]", + c.ProtocolVersion, ProtocolVersionMin, ProtocolVersionMax) + } + return nil +} + // DefaultConfig is used to return a sane default configuration func DefaultConfig() *Config { hostname, err := os.Hostname() @@ -85,6 +113,7 @@ func DefaultConfig() *Config { SerfLANConfig: serf.DefaultConfig(), SerfWANConfig: serf.DefaultConfig(), ReconcileInterval: 60 * time.Second, + ProtocolVersion: ProtocolVersionMax, } // WAN Serf should use the WAN timing, since we are using it diff --git a/consul/server.go b/consul/server.go index 2b1b64a2f..654a319fc 100644 --- a/consul/server.go +++ b/consul/server.go @@ -14,6 +14,14 @@ import ( "time" ) +// These are the protocol versions that Consul can _understand_. These are +// Consul-level protocol versions, that are used to configure the Serf +// protocol versions. +const ( + ProtocolVersionMin uint8 = 1 + ProtocolVersionMax = 1 +) + const ( serfLANSnapshot = "serf/local.snapshot" serfWANSnapshot = "serf/remote.snapshot" @@ -97,6 +105,11 @@ type endpoints struct { // NewServer is used to construct a new Consul server from the // configuration, potentially returning an error func NewServer(config *Config) (*Server, error) { + // Check the protocol version + if err := config.CheckVersion(); err != nil { + return nil, err + } + // Check for a data directory! if config.DataDir == "" { return nil, fmt.Errorf("Config must provide a DataDir") @@ -175,7 +188,7 @@ func (s *Server) setupSerf(conf *serf.Config, ch chan serf.Event, path string) ( conf.LogOutput = s.config.LogOutput conf.EventCh = ch conf.SnapshotPath = filepath.Join(s.config.DataDir, path) - conf.ProtocolVersion = 3 // TODO: Support version 4 + conf.ProtocolVersion = protocolVersionMap[s.config.ProtocolVersion] if err := ensurePath(conf.SnapshotPath, false); err != nil { return nil, err }