diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d458513f2..cf48d2788f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ IMPROVEMENTS: * Enable logging to syslog. [GH-105] * Allow raw key value lookup [GH-150] * Log encryption enabled [GH-151] + * Support `-rejoin` to rejoin a cluster after a previous leave. [GH-110] ## 0.2.1 (May 20, 2014) diff --git a/command/agent/command.go b/command/agent/command.go index 2e516176cf..148f26bfa9 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -64,6 +64,8 @@ func (c *Command) readConfig() *Config { cmdFlags.BoolVar(&cmdConfig.EnableSyslog, "syslog", false, "enable logging to syslog facility") + cmdFlags.BoolVar(&cmdConfig.RejoinAfterLeave, "rejoin", false, + "enable re-joining after a previous leave") cmdFlags.Var((*AppendSliceValue)(&cmdConfig.StartJoin), "join", "address of agent to join on startup") @@ -507,6 +509,7 @@ Options: -log-level=info Log level of the agent. -node=hostname Name of this node. Must be unique in the cluster -protocol=N Sets the protocol version. Defaults to latest. + -rejoin Ignores a previous leave and attempts to rejoin the cluster. -server Switches agent to server mode. -syslog Enables logging to syslog -ui-dir=path Path to directory containing the Web UI resources diff --git a/command/agent/config.go b/command/agent/config.go index eacfcc43e0..b3130a3680 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -135,6 +135,12 @@ type Config struct { // on linux and OSX. Other platforms will generate an error. EnableSyslog bool `mapstructure:"enable_syslog"` + // RejoinAfterLeave controls our interaction with the cluster after leave. + // When set to false (default), a leave causes Consul to not rejoin + // the cluster until an explicit join is received. If this is set to + // true, we ignore the leave, and rejoin the cluster on start. + RejoinAfterLeave bool `mapstructure:"rejoin_after_leave"` + // AEInterval controls the anti-entropy interval. This is how often // the agent attempts to reconcile it's local state with the server' // representation of our state. Defaults to every 60s. @@ -436,6 +442,9 @@ func MergeConfig(a, b *Config) *Config { if b.EnableSyslog { result.EnableSyslog = true } + if b.RejoinAfterLeave { + result.RejoinAfterLeave = true + } // Copy the start join addresses result.StartJoin = make([]string, 0, len(a.StartJoin)+len(b.StartJoin)) diff --git a/command/agent/config_test.go b/command/agent/config_test.go index e71b5e8e20..288e6fd196 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -279,6 +279,17 @@ func TestDecodeConfig(t *testing.T) { if !config.EnableSyslog { t.Fatalf("bad: %#v", config) } + + // Rejoin + input = `{"rejoin_after_leave": true}` + config, err = DecodeConfig(bytes.NewReader([]byte(input))) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !config.RejoinAfterLeave { + t.Fatalf("bad: %#v", config) + } } func TestDecodeConfig_Service(t *testing.T) { @@ -398,20 +409,21 @@ func TestMergeConfig(t *testing.T) { SerfWan: 5, Server: 6, }, - Server: true, - LeaveOnTerm: true, - SkipLeaveOnInt: true, - EnableDebug: true, - VerifyIncoming: true, - VerifyOutgoing: true, - CAFile: "test/ca.pem", - CertFile: "test/cert.pem", - KeyFile: "test/key.pem", - Checks: []*CheckDefinition{nil}, - Services: []*ServiceDefinition{nil}, - StartJoin: []string{"1.1.1.1"}, - UiDir: "/opt/consul-ui", - EnableSyslog: true, + Server: true, + LeaveOnTerm: true, + SkipLeaveOnInt: true, + EnableDebug: true, + VerifyIncoming: true, + VerifyOutgoing: true, + CAFile: "test/ca.pem", + CertFile: "test/cert.pem", + KeyFile: "test/key.pem", + Checks: []*CheckDefinition{nil}, + Services: []*ServiceDefinition{nil}, + StartJoin: []string{"1.1.1.1"}, + UiDir: "/opt/consul-ui", + EnableSyslog: true, + RejoinAfterLeave: true, } c := MergeConfig(a, b) diff --git a/consul/client.go b/consul/client.go index abd1f500e3..90b01f636b 100644 --- a/consul/client.go +++ b/consul/client.go @@ -127,6 +127,7 @@ func (c *Client) setupSerf(conf *serf.Config, ch chan serf.Event, path string) ( conf.EventCh = ch conf.SnapshotPath = filepath.Join(c.config.DataDir, path) conf.ProtocolVersion = protocolVersionMap[c.config.ProtocolVersion] + conf.RejoinAfterLeave = c.config.RejoinAfterLeave if err := ensurePath(conf.SnapshotPath, false); err != nil { return nil, err } diff --git a/consul/config.go b/consul/config.go index d74cbaa071..e848c3b011 100644 --- a/consul/config.go +++ b/consul/config.go @@ -108,6 +108,12 @@ type Config struct { // Must be provided to serve TLS connections. KeyFile string + // RejoinAfterLeave controls our interaction with Serf. + // When set to false (default), a leave causes a Consul to not rejoin + // the cluster until an explicit join is received. If this is set to + // true, we ignore the leave, and rejoin the cluster on start. + RejoinAfterLeave bool + // ServerUp callback can be used to trigger a notification that // a Consul server is now up and known about. ServerUp func() diff --git a/consul/server.go b/consul/server.go index 598e6bde3e..e8fcd4655c 100644 --- a/consul/server.go +++ b/consul/server.go @@ -220,6 +220,7 @@ func (s *Server) setupSerf(conf *serf.Config, ch chan serf.Event, path string, w conf.EventCh = ch conf.SnapshotPath = filepath.Join(s.config.DataDir, path) conf.ProtocolVersion = protocolVersionMap[s.config.ProtocolVersion] + conf.RejoinAfterLeave = s.config.RejoinAfterLeave // Until Consul supports this fully, we disable automatic resolution. // When enabled, the Serf gossip may just turn off if we are the minority diff --git a/website/source/docs/agent/options.html.markdown b/website/source/docs/agent/options.html.markdown index ece80457e3..b185a1f458 100644 --- a/website/source/docs/agent/options.html.markdown +++ b/website/source/docs/agent/options.html.markdown @@ -92,6 +92,11 @@ The options below are all specified on the command-line. version. This should be set only when [upgrading](/docs/upgrading.html). You can view the protocol versions supported by Consul by running `consul -v`. +* `-rejoin` - When provided Consul will ignore a previous leave and attempt to + rejoin the cluster when starting. By default, Consul treats leave as a permanent + intent, and does not attempt to join the cluster again when starting. This flag + allows the previous state to be used to rejoin the cluster. + * `-server` - This flag is used to control if an agent is in server or client mode. When provided, an agent will act as a Consul server. Each Consul cluster must have at least one server, and ideally no more than 5 *per* datacenter. All servers participate in the Raft consensus algorithm, to ensure that @@ -164,6 +169,8 @@ definitions support being updated during a reload. * `enable_syslog` - Equivalent to the `-syslog` command-line flag. +* `rejoin_after_leave` - Equivalent to the `-rejoin` command-line flag. + * `ca_file` - This provides a the file path to a PEM encoded certificate authority. The certificate authority is used to check the authenticity of client and server connections with the appropriate `verify_incoming` or `verify_outgoing` flags.