skip_leave_on_int's default changes based on agent mode

`skip_leave_on_int`'s behavior now changes based on whether or not the agent is acting as a client or server.

Fixes: 1687
This commit is contained in:
Sean Chittenden 2016-03-31 17:45:14 -07:00
parent cbe0910dc8
commit 5994c9efbf
5 changed files with 90 additions and 24 deletions

View File

@ -175,6 +175,17 @@ func (c *Command) readConfig() *Config {
return nil
}
// Make sure SkipLeaveOnInt is set to the right default based on the
// agent's mode (client or server)
if config.SkipLeaveOnInt == nil {
config.SkipLeaveOnInt = new(bool)
if config.Server {
*config.SkipLeaveOnInt = true
} else {
*config.SkipLeaveOnInt = false
}
}
// Ensure we have a data directory
if config.DataDir == "" && !dev {
c.Ui.Error("Must specify data directory using -data-dir")
@ -810,7 +821,7 @@ WAIT:
// Check if we should do a graceful leave
graceful := false
if sig == os.Interrupt && !config.SkipLeaveOnInt {
if sig == os.Interrupt && !(*config.SkipLeaveOnInt) {
graceful = true
} else if sig == syscall.SIGTERM && config.LeaveOnTerm {
graceful = true

View File

@ -110,17 +110,17 @@ func TestRetryJoin(t *testing.T) {
}
func TestReadCliConfig(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
defer os.RemoveAll(tmpDir)
shutdownCh := make(chan struct{})
defer close(shutdownCh)
// Test config parse
{
tmpDir, err := ioutil.TempDir("", "consul")
if err != nil {
t.Fatalf("err: %s", err)
}
cmd := &Command{
args: []string{
"-data-dir", tmpDir,
@ -137,12 +137,59 @@ func TestReadCliConfig(t *testing.T) {
}
}
// Test SkipLeaveOnInt default for server mode
{
ui := new(cli.MockUi)
cmd := &Command{
args: []string{
"-node", `"server1"`,
"-server",
"-data-dir", tmpDir,
},
ShutdownCh: shutdownCh,
Ui: ui,
}
config := cmd.readConfig()
if config == nil {
t.Fatalf(`Expected non-nil config object: %s`, ui.ErrorWriter.String())
}
if config.Server != true {
t.Errorf(`Expected -server to be true`)
}
if (*config.SkipLeaveOnInt) != true {
t.Errorf(`Expected SkipLeaveOnInt to be true in server mode`)
}
}
// Test SkipLeaveOnInt default for client mode
{
ui := new(cli.MockUi)
cmd := &Command{
args: []string{
"-data-dir", tmpDir,
"-node", `"client"`,
},
ShutdownCh: shutdownCh,
Ui: ui,
}
config := cmd.readConfig()
if config == nil {
t.Fatalf(`Expected non-nil config object: %s`, ui.ErrorWriter.String())
}
if config.Server != false {
t.Errorf(`Expected server to be false`)
}
if *config.SkipLeaveOnInt != false {
t.Errorf(`Expected SkipLeaveOnInt to be false in client mode`)
}
}
// Test empty node name
{
cmd := &Command{
args: []string{
"-node", `""`,
},
args: []string{"-node", `""`},
ShutdownCh: shutdownCh,
Ui: new(cli.MockUi),
}

View File

@ -227,9 +227,10 @@ type Config struct {
// the TERM signal. Defaults false. This can be changed on reload.
LeaveOnTerm bool `mapstructure:"leave_on_terminate"`
// SkipLeaveOnInt controls if Serf skips a graceful leave when receiving
// the INT signal. Defaults false. This can be changed on reload.
SkipLeaveOnInt bool `mapstructure:"skip_leave_on_interrupt"`
// SkipLeaveOnInt controls if Serf skips a graceful leave when
// receiving the INT signal. Defaults false on clients, true on
// servers. This can be changed on reload.
SkipLeaveOnInt *bool `mapstructure:"skip_leave_on_interrupt"`
Telemetry Telemetry `mapstructure:"telemetry"`
@ -1018,8 +1019,8 @@ func MergeConfig(a, b *Config) *Config {
if b.LeaveOnTerm == true {
result.LeaveOnTerm = true
}
if b.SkipLeaveOnInt == true {
result.SkipLeaveOnInt = true
if b.SkipLeaveOnInt != nil {
result.SkipLeaveOnInt = b.SkipLeaveOnInt
}
if b.Telemetry.DisableHostname == true {
result.Telemetry.DisableHostname = true

View File

@ -74,8 +74,8 @@ func TestDecodeConfig(t *testing.T) {
t.Fatalf("bad: %#v", config)
}
if config.SkipLeaveOnInt != DefaultConfig().SkipLeaveOnInt {
t.Fatalf("bad: %#v", config)
if config.SkipLeaveOnInt != nil {
t.Fatalf("bad: expected nil SkipLeaveOnInt")
}
if config.LeaveOnTerm != DefaultConfig().LeaveOnTerm {
@ -290,7 +290,7 @@ func TestDecodeConfig(t *testing.T) {
t.Fatalf("err: %s", err)
}
if config.SkipLeaveOnInt != true {
if *config.SkipLeaveOnInt != true {
t.Fatalf("bad: %#v", config)
}
@ -1239,7 +1239,7 @@ func TestMergeConfig(t *testing.T) {
AdvertiseAddr: "127.0.0.1",
Server: false,
LeaveOnTerm: false,
SkipLeaveOnInt: false,
SkipLeaveOnInt: new(bool),
EnableDebug: false,
CheckUpdateIntervalRaw: "8m",
RetryIntervalRaw: "10s",
@ -1294,7 +1294,7 @@ func TestMergeConfig(t *testing.T) {
},
Server: true,
LeaveOnTerm: true,
SkipLeaveOnInt: true,
SkipLeaveOnInt: new(bool),
EnableDebug: true,
VerifyIncoming: true,
VerifyOutgoing: true,
@ -1368,6 +1368,7 @@ func TestMergeConfig(t *testing.T) {
},
Reap: Bool(true),
}
*b.SkipLeaveOnInt = true
c := MergeConfig(a, b)

View File

@ -621,11 +621,17 @@ Consul will not enable TLS for the HTTP API unless the `https` port has been ass
at or above the default to encourage clients to send infrequent heartbeats.
Defaults to 10s.
* <a name="skip_leave_on_interrupt"></a><a href="#skip_leave_on_interrupt">`skip_leave_on_interrupt`</a>
This is similar to [`leave_on_terminate`](#leave_on_terminate) but
only affects interrupt handling. By default, an interrupt (such as hitting
Control-C in a shell) causes Consul to gracefully leave. Setting this to true
disables that. Defaults to false.
* <a name="skip_leave_on_interrupt"></a><a
href="#skip_leave_on_interrupt">`skip_leave_on_interrupt`</a> This is
similar to [`leave_on_terminate`](#leave_on_terminate) but only affects
interrupt handling. When Consul receives an interrupt signal (such as
hitting Control-C in a terminal), Consul will gracefully leave the cluster.
Setting this to `true` disables that behavior. The default behavior for
this feature varies based on whether or not the agent is running as a
client or a server. On agents in client-mode, this defaults to `false` and
for agents in server-mode, this defaults to `true` (i.e. Ctrl-C on a server
will keep the server in the cluster and therefore quorum, and Ctrl-C on a
client will gracefully leave).
* <a name="start_join"></a><a href="#start_join">`start_join`</a> An array of strings specifying addresses
of nodes to [`-join`](#_join) upon startup.