mirror of https://github.com/status-im/consul.git
Merge pull request #1539 from hashicorp/f-reap
Adds child process reaping when Consul is running as PID 1.
This commit is contained in:
commit
14922b58ae
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/armon/go-metrics/datadog"
|
||||
"github.com/hashicorp/consul/watch"
|
||||
"github.com/hashicorp/go-checkpoint"
|
||||
"github.com/hashicorp/go-reap"
|
||||
"github.com/hashicorp/go-syslog"
|
||||
"github.com/hashicorp/logutils"
|
||||
scada "github.com/hashicorp/scada-client"
|
||||
|
@ -641,6 +642,33 @@ func (c *Command) Run(args []string) int {
|
|||
defer server.Shutdown()
|
||||
}
|
||||
|
||||
// Enable child process reaping
|
||||
if (config.Reap != nil && *config.Reap) || (config.Reap == nil && os.Getpid() == 1) {
|
||||
if !reap.IsSupported() {
|
||||
c.Ui.Error("Child process reaping is not supported on this platform (set reap=false)")
|
||||
return 1
|
||||
} else {
|
||||
logger := c.agent.logger
|
||||
logger.Printf("[DEBUG] Automatically reaping child processes")
|
||||
|
||||
pids := make(reap.PidCh, 1)
|
||||
errors := make(reap.ErrorCh, 1)
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case pid := <-pids:
|
||||
logger.Printf("[DEBUG] Reaped child process %d", pid)
|
||||
case err := <-errors:
|
||||
logger.Printf("[ERR] Error reaping child process: %v", err)
|
||||
case <-c.agent.shutdownCh:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
go reap.ReapChildren(pids, errors, c.agent.shutdownCh)
|
||||
}
|
||||
}
|
||||
|
||||
// Check and shut down the SCADA listeners at the end
|
||||
defer func() {
|
||||
if c.scadaHttp != nil {
|
||||
|
|
|
@ -422,6 +422,17 @@ type Config struct {
|
|||
// Minimum Session TTL
|
||||
SessionTTLMin time.Duration `mapstructure:"-"`
|
||||
SessionTTLMinRaw string `mapstructure:"session_ttl_min"`
|
||||
|
||||
// Reap controls automatic reaping of child processes, useful if running
|
||||
// as PID 1 in a Docker container. This defaults to nil which will make
|
||||
// Consul reap only if it detects it's running as PID 1. If non-nil,
|
||||
// then this will be used to decide if reaping is enabled.
|
||||
Reap *bool `mapstructure:"reap"`
|
||||
}
|
||||
|
||||
// Bool is used to initialize bool pointers in struct literals.
|
||||
func Bool(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
// UnixSocketPermissions contains information about a unix socket, and
|
||||
|
@ -1140,6 +1151,10 @@ func MergeConfig(a, b *Config) *Config {
|
|||
result.RetryJoinWan = append(result.RetryJoinWan, a.RetryJoinWan...)
|
||||
result.RetryJoinWan = append(result.RetryJoinWan, b.RetryJoinWan...)
|
||||
|
||||
if b.Reap != nil {
|
||||
result.Reap = b.Reap
|
||||
}
|
||||
|
||||
return &result
|
||||
}
|
||||
|
||||
|
|
|
@ -777,6 +777,27 @@ func TestDecodeConfig(t *testing.T) {
|
|||
if config.SessionTTLMin != 5*time.Second {
|
||||
t.Fatalf("bad: %s %#v", config.SessionTTLMin.String(), config)
|
||||
}
|
||||
|
||||
// Reap
|
||||
input = `{"reap": true}`
|
||||
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if config.Reap == nil || *config.Reap != true {
|
||||
t.Fatalf("bad: reap not enabled: %#v", config)
|
||||
}
|
||||
|
||||
input = `{}`
|
||||
config, err = DecodeConfig(bytes.NewReader([]byte(input)))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if config.Reap != nil {
|
||||
t.Fatalf("bad: reap not tri-stated: %#v", config)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeConfig_invalidKeys(t *testing.T) {
|
||||
|
@ -1266,6 +1287,7 @@ func TestMergeConfig(t *testing.T) {
|
|||
RPC: &net.TCPAddr{},
|
||||
RPCRaw: "127.0.0.5:1233",
|
||||
},
|
||||
Reap: Bool(true),
|
||||
}
|
||||
|
||||
c := MergeConfig(a, b)
|
||||
|
|
|
@ -504,6 +504,11 @@ definitions support being updated during a reload.
|
|||
* <a name="protocol"></a><a href="#protocol">`protocol`</a> Equivalent to the
|
||||
[`-protocol` command-line flag](#_protocol).
|
||||
|
||||
* <a name="reap"></a><a href="#reap">`reap`</a> controls Consul's automatic reaping of child processes, which
|
||||
is useful if Consul is running as PID 1 in a Docker container. If this isn't specified, then Consul will
|
||||
automatically reap child processes if it detects it is running as PID 1. If this is specified, then it
|
||||
controls reaping regardless of Consul's PID.
|
||||
|
||||
* <a name="recursor"></a><a href="#recursor">`recursor`</a> Provides a single recursor address.
|
||||
This has been deprecated, and the value is appended to the [`recursors`](#recursors) list for
|
||||
backwards compatibility.
|
||||
|
|
Loading…
Reference in New Issue