diff --git a/command/agent/agent.go b/command/agent/agent.go index 5b55a0bd2f..ca816ff27f 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -417,6 +417,11 @@ func (a *Agent) AddCheck(check *structs.HealthCheck, chkType *CheckType) error { if _, ok := a.checkMonitors[check.CheckID]; ok { return fmt.Errorf("CheckID is already registered") } + if chkType.Interval < MinInterval { + a.logger.Println(fmt.Sprintf("[WARN] agent: check '%s' has interval below minimum of %v", + check.CheckID, MinInterval)) + chkType.Interval = MinInterval + } monitor := &CheckMonitor{ Notify: &a.state, diff --git a/command/agent/agent_test.go b/command/agent/agent_test.go index 683b83b495..71d960039c 100644 --- a/command/agent/agent_test.go +++ b/command/agent/agent_test.go @@ -205,6 +205,39 @@ func TestAgent_AddCheck(t *testing.T) { } } +func TestAgent_AddCheck_MinInterval(t *testing.T) { + dir, agent := makeAgent(t, nextConfig()) + defer os.RemoveAll(dir) + defer agent.Shutdown() + + health := &structs.HealthCheck{ + Node: "foo", + CheckID: "mem", + Name: "memory util", + Status: structs.HealthUnknown, + } + chk := &CheckType{ + Script: "exit 0", + Interval: time.Microsecond, + } + err := agent.AddCheck(health, chk) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Ensure we have a check mapping + if _, ok := agent.state.Checks()["mem"]; !ok { + t.Fatalf("missing mem check") + } + + // Ensure a TTL is setup + if mon, ok := agent.checkMonitors["mem"]; !ok { + t.Fatalf("missing mem monitor") + } else if mon.Interval != MinInterval { + t.Fatalf("bad mem monitor interval") + } +} + func TestAgent_RemoveCheck(t *testing.T) { dir, agent := makeAgent(t, nextConfig()) defer os.RemoveAll(dir) diff --git a/command/agent/check.go b/command/agent/check.go index b358399a8d..f79aaff966 100644 --- a/command/agent/check.go +++ b/command/agent/check.go @@ -12,6 +12,12 @@ import ( "time" ) +const ( + // Do not allow for a interval below this value. + // Otherwise we risk fork bombing a system. + MinInterval = time.Second +) + // CheckType is used to create either the CheckMonitor // or the CheckTTL. Only one of TTL or Script/Interval // needs to be provided