agent: persist CheckType with health checks
This commit is contained in:
parent
4f14ba6326
commit
9e52588cec
|
@ -564,10 +564,16 @@ func (a *Agent) restoreServices() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// persistCheck saves a check definition to the local agent's state directory
|
// persistCheck saves a check definition to the local agent's state directory
|
||||||
func (a *Agent) persistCheck(check *structs.HealthCheck) error {
|
func (a *Agent) persistCheck(check *structs.HealthCheck, chkType *CheckType) error {
|
||||||
checkPath := filepath.Join(a.config.DataDir, checksDir, check.CheckID)
|
checkPath := filepath.Join(a.config.DataDir, checksDir, check.CheckID)
|
||||||
if _, err := os.Stat(checkPath); os.IsNotExist(err) {
|
if _, err := os.Stat(checkPath); !os.IsNotExist(err) {
|
||||||
encoded, err := json.Marshal(check)
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the persisted check
|
||||||
|
p := persistedCheck{check, chkType}
|
||||||
|
|
||||||
|
encoded, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -582,7 +588,6 @@ func (a *Agent) persistCheck(check *structs.HealthCheck) error {
|
||||||
if _, err := fh.Write(encoded); err != nil {
|
if _, err := fh.Write(encoded); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,23 +624,23 @@ func (a *Agent) restoreChecks() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var check *structs.HealthCheck
|
var p persistedCheck
|
||||||
if err := json.Unmarshal(content, &check); err != nil {
|
if err := json.Unmarshal(content, &p); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := a.state.checks[check.CheckID]; ok {
|
if _, ok := a.state.checks[p.Check.CheckID]; ok {
|
||||||
// Purge previously persisted check. This allows config to be
|
// Purge previously persisted check. This allows config to be
|
||||||
// preferred over persisted checks from the API.
|
// preferred over persisted checks from the API.
|
||||||
a.logger.Printf("[DEBUG] Check %s exists, not restoring", check.CheckID)
|
a.logger.Printf("[DEBUG] Check %s exists, not restoring", p.Check.CheckID)
|
||||||
return a.purgeCheck(check.CheckID)
|
return a.purgeCheck(p.Check.CheckID)
|
||||||
} else {
|
} else {
|
||||||
// Default check to critical to avoid placing potentially unhealthy
|
// Default check to critical to avoid placing potentially unhealthy
|
||||||
// services into the active pool
|
// services into the active pool
|
||||||
check.Status = structs.HealthCritical
|
p.Check.Status = structs.HealthCritical
|
||||||
|
|
||||||
a.logger.Printf("[DEBUG] Restored health check: %s", check.CheckID)
|
a.logger.Printf("[DEBUG] Restored health check: %s", p.Check.CheckID)
|
||||||
return a.AddCheck(check, nil, false)
|
return a.AddCheck(p.Check, p.ChkType, false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
|
@ -766,7 +771,7 @@ func (a *Agent) AddCheck(check *structs.HealthCheck, chkType *CheckType, persist
|
||||||
|
|
||||||
// Persist the check
|
// Persist the check
|
||||||
if persist {
|
if persist {
|
||||||
return a.persistCheck(check)
|
return a.persistCheck(check, chkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -534,11 +534,15 @@ func TestAgent_PersistCheck(t *testing.T) {
|
||||||
ServiceID: "redis",
|
ServiceID: "redis",
|
||||||
ServiceName: "redis",
|
ServiceName: "redis",
|
||||||
}
|
}
|
||||||
|
chkType := &CheckType{
|
||||||
|
Script: "/bin/true",
|
||||||
|
Interval: 10 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
file := filepath.Join(agent.config.DataDir, checksDir, check.CheckID)
|
file := filepath.Join(agent.config.DataDir, checksDir, check.CheckID)
|
||||||
|
|
||||||
// Not persisted if not requested
|
// Not persisted if not requested
|
||||||
if err := agent.AddCheck(check, nil, false); err != nil {
|
if err := agent.AddCheck(check, chkType, false); err != nil {
|
||||||
t.Fatalf("err: %v", err)
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(file); err == nil {
|
if _, err := os.Stat(file); err == nil {
|
||||||
|
@ -546,7 +550,7 @@ func TestAgent_PersistCheck(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should persist if requested
|
// Should persist if requested
|
||||||
if err := agent.AddCheck(check, nil, true); err != nil {
|
if err := agent.AddCheck(check, chkType, true); err != nil {
|
||||||
t.Fatalf("err: %v", err)
|
t.Fatalf("err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +558,8 @@ func TestAgent_PersistCheck(t *testing.T) {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := json.Marshal(check)
|
p := persistedCheck{check, chkType}
|
||||||
|
expected, err := json.Marshal(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -574,13 +579,18 @@ func TestAgent_PersistCheck(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer agent2.Shutdown()
|
defer agent2.Shutdown()
|
||||||
|
|
||||||
result, ok := agent2.state.checks[check.CheckID]
|
result, ok := agent2.state.checks[p.Check.CheckID]
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatalf("bad: %#v", agent2.state.checks)
|
t.Fatalf("bad: %#v", agent2.state.checks)
|
||||||
}
|
}
|
||||||
if result.Status != structs.HealthCritical {
|
if result.Status != structs.HealthCritical {
|
||||||
t.Fatalf("bad: %#v", result)
|
t.Fatalf("bad: %#v", result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should have restored the monitor
|
||||||
|
if _, ok := agent2.checkMonitors[p.Check.CheckID]; !ok {
|
||||||
|
t.Fatalf("bad: %#v", agent2.checkMonitors)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAgent_PurgeCheck(t *testing.T) {
|
func TestAgent_PurgeCheck(t *testing.T) {
|
||||||
|
|
|
@ -234,3 +234,10 @@ func (c *CheckTTL) SetStatus(status, output string) {
|
||||||
c.Notify.UpdateCheck(c.CheckID, status, output)
|
c.Notify.UpdateCheck(c.CheckID, status, output)
|
||||||
c.timer.Reset(c.TTL)
|
c.timer.Reset(c.TTL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// persistedCheck is used to serialize a check and write it to disk
|
||||||
|
// so that it may be restored later on.
|
||||||
|
type persistedCheck struct {
|
||||||
|
Check *structs.HealthCheck
|
||||||
|
ChkType *CheckType
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue