diff --git a/command/agent/agent.go b/command/agent/agent.go index 5ffc3e8b7e01..8ac791f61c19 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "sync" + "time" "github.com/hashicorp/nomad/client" "github.com/hashicorp/nomad/nomad" @@ -137,6 +138,14 @@ func (a *Agent) serverConfig() (*nomad.Config, error) { conf.SerfConfig.MemberlistConfig.BindPort = port } + if gcThreshold := a.config.Server.NodeGCThreshold; gcThreshold != "" { + dur, err := time.ParseDuration(gcThreshold) + if err != nil { + return nil, err + } + conf.NodeGCThreshold = dur + } + return conf, nil } diff --git a/command/agent/agent_test.go b/command/agent/agent_test.go index 28744853a99a..ec5cba95b5a4 100644 --- a/command/agent/agent_test.go +++ b/command/agent/agent_test.go @@ -148,6 +148,17 @@ func TestAgent_ServerConfig(t *testing.T) { t.Fatalf("expect 127.0.0.2, got: %s", addr) } + conf.Server.NodeGCThreshold = "42g" + out, err = a.serverConfig() + if err == nil || !strings.Contains(err.Error(), "unknown unit") { + t.Fatalf("expected unknown unit error, got: %#v", err) + } + conf.Server.NodeGCThreshold = "10s" + out, err = a.serverConfig() + if threshold := out.NodeGCThreshold; threshold != time.Second*10 { + t.Fatalf("expect 10s, got: %s", threshold) + } + // Defaults to the global bind addr conf.Addresses.RPC = "" conf.Addresses.Serf = "" diff --git a/command/agent/config.go b/command/agent/config.go index dc4a4b692d0f..45c3ea26ad0a 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -179,6 +179,9 @@ type ServerConfig struct { // enabled for this server to handle. This will restrict the evaluations // that the workers dequeue for processing. EnabledSchedulers []string `hcl:"enabled_schedulers"` + + // NodeGCThreshold contros how "old" a node must be to be collected by GC. + NodeGCThreshold string `hcl:"node_gc_threshold"` } // Telemetry is the telemetry configuration for the server @@ -378,6 +381,9 @@ func (a *ServerConfig) Merge(b *ServerConfig) *ServerConfig { if b.NumSchedulers != 0 { result.NumSchedulers = b.NumSchedulers } + if b.NodeGCThreshold != "" { + result.NodeGCThreshold = b.NodeGCThreshold + } // Add the schedulers result.EnabledSchedulers = append(result.EnabledSchedulers, b.EnabledSchedulers...) diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 530c4227dbcc..52def6d6acd0 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -47,6 +47,7 @@ func TestConfig_Merge(t *testing.T) { DataDir: "/tmp/data1", ProtocolVersion: 1, NumSchedulers: 1, + NodeGCThreshold: "1h", }, Ports: &Ports{ HTTP: 4646, @@ -106,6 +107,7 @@ func TestConfig_Merge(t *testing.T) { ProtocolVersion: 2, NumSchedulers: 2, EnabledSchedulers: []string{structs.JobTypeBatch}, + NodeGCThreshold: "12h", }, Ports: &Ports{ HTTP: 20000, @@ -369,6 +371,7 @@ func TestConfig_LoadConfigString(t *testing.T) { ProtocolVersion: 3, NumSchedulers: 2, EnabledSchedulers: []string{"test"}, + NodeGCThreshold: "12h", }, Telemetry: &Telemetry{ StatsiteAddr: "127.0.0.1:1234", @@ -441,6 +444,7 @@ server { protocol_version = 3 num_schedulers = 2 enabled_schedulers = ["test"] + node_gc_threshold = "12h" } telemetry { statsite_address = "127.0.0.1:1234" diff --git a/website/source/docs/agent/config.html.md b/website/source/docs/agent/config.html.md index 9fccd9ecb244..6f0b9b0dcb2d 100644 --- a/website/source/docs/agent/config.html.md +++ b/website/source/docs/agent/config.html.md @@ -173,6 +173,10 @@ configured on client nodes. sub-schedulers this server will handle. This can be used to restrict the evaluations that worker threads will dequeue for processing. This defaults to all available schedulers. + * `node_gc_threshold` This is a string with a unit suffix, such as "300ms", + "1.5h" or "25m". Valid time units are "ns", "us" (or "µs"), "ms", "s", + "m", "h". Controls how long a node must be in a terminal state before it is + garbage collected and purged from the system. ## Client-specific Options