agent: persist service/check data using hashed service/check IDs (fixes #573)

pull/586/head
Ryan Uber 2015-01-07 19:11:21 -08:00
parent cb1b722813
commit 0b9f2b0954
4 changed files with 25 additions and 10 deletions

View File

@ -491,7 +491,7 @@ func (a *Agent) ResumeSync() {
// persistService saves a service definition to a JSON file in the data dir // persistService saves a service definition to a JSON file in the data dir
func (a *Agent) persistService(service *structs.NodeService) error { func (a *Agent) persistService(service *structs.NodeService) error {
svcPath := filepath.Join(a.config.DataDir, servicesDir, service.ID) svcPath := filepath.Join(a.config.DataDir, servicesDir, stringHash(service.ID))
if _, err := os.Stat(svcPath); os.IsNotExist(err) { if _, err := os.Stat(svcPath); os.IsNotExist(err) {
encoded, err := json.Marshal(service) encoded, err := json.Marshal(service)
if err != nil { if err != nil {
@ -514,7 +514,7 @@ func (a *Agent) persistService(service *structs.NodeService) error {
// purgeService removes a persisted service definition file from the data dir // purgeService removes a persisted service definition file from the data dir
func (a *Agent) purgeService(serviceID string) error { func (a *Agent) purgeService(serviceID string) error {
svcPath := filepath.Join(a.config.DataDir, servicesDir, serviceID) svcPath := filepath.Join(a.config.DataDir, servicesDir, stringHash(serviceID))
if _, err := os.Stat(svcPath); err == nil { if _, err := os.Stat(svcPath); err == nil {
return os.Remove(svcPath) return os.Remove(svcPath)
} }
@ -565,7 +565,7 @@ 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, chkType *CheckType) 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, stringHash(check.CheckID))
if _, err := os.Stat(checkPath); !os.IsNotExist(err) { if _, err := os.Stat(checkPath); !os.IsNotExist(err) {
return err return err
} }
@ -593,7 +593,7 @@ func (a *Agent) persistCheck(check *structs.HealthCheck, chkType *CheckType) err
// purgeCheck removes a persisted check definition file from the data dir // purgeCheck removes a persisted check definition file from the data dir
func (a *Agent) purgeCheck(checkID string) error { func (a *Agent) purgeCheck(checkID string) error {
checkPath := filepath.Join(a.config.DataDir, checksDir, checkID) checkPath := filepath.Join(a.config.DataDir, checksDir, stringHash(checkID))
if _, err := os.Stat(checkPath); err == nil { if _, err := os.Stat(checkPath); err == nil {
return os.Remove(checkPath) return os.Remove(checkPath)
} }

View File

@ -398,7 +398,7 @@ func TestAgent_PersistService(t *testing.T) {
Port: 8000, Port: 8000,
} }
file := filepath.Join(agent.config.DataDir, servicesDir, svc.ID) file := filepath.Join(agent.config.DataDir, servicesDir, stringHash(svc.ID))
// Check is not persisted unless requested // Check is not persisted unless requested
if err := agent.AddService(svc, nil, false); err != nil { if err := agent.AddService(svc, nil, false); err != nil {
@ -455,7 +455,7 @@ func TestAgent_PurgeService(t *testing.T) {
Port: 8000, Port: 8000,
} }
file := filepath.Join(agent.config.DataDir, servicesDir, svc.ID) file := filepath.Join(agent.config.DataDir, servicesDir, stringHash(svc.ID))
if err := agent.AddService(svc, nil, true); err != nil { if err := agent.AddService(svc, nil, true); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -513,7 +513,7 @@ func TestAgent_PurgeServiceOnDuplicate(t *testing.T) {
} }
defer agent2.Shutdown() defer agent2.Shutdown()
file := filepath.Join(agent.config.DataDir, servicesDir, svc1.ID) file := filepath.Join(agent.config.DataDir, servicesDir, stringHash(svc1.ID))
if _, err := os.Stat(file); err == nil { if _, err := os.Stat(file); err == nil {
t.Fatalf("should have removed persisted service") t.Fatalf("should have removed persisted service")
} }
@ -546,7 +546,7 @@ func TestAgent_PersistCheck(t *testing.T) {
Interval: 10 * time.Second, Interval: 10 * time.Second,
} }
file := filepath.Join(agent.config.DataDir, checksDir, check.CheckID) file := filepath.Join(agent.config.DataDir, checksDir, stringHash(check.CheckID))
// Not persisted if not requested // Not persisted if not requested
if err := agent.AddCheck(check, chkType, false); err != nil { if err := agent.AddCheck(check, chkType, false); err != nil {
@ -615,7 +615,7 @@ func TestAgent_PurgeCheck(t *testing.T) {
ServiceName: "redis", ServiceName: "redis",
} }
file := filepath.Join(agent.config.DataDir, checksDir, check.CheckID) file := filepath.Join(agent.config.DataDir, checksDir, stringHash(check.CheckID))
if err := agent.AddCheck(check, nil, true); err != nil { if err := agent.AddCheck(check, nil, true); err != nil {
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
@ -677,7 +677,7 @@ func TestAgent_PurgeCheckOnDuplicate(t *testing.T) {
} }
defer agent2.Shutdown() defer agent2.Shutdown()
file := filepath.Join(agent.config.DataDir, checksDir, check1.CheckID) file := filepath.Join(agent.config.DataDir, checksDir, stringHash(check1.CheckID))
if _, err := os.Stat(file); err == nil { if _, err := os.Stat(file); err == nil {
t.Fatalf("should have removed persisted check") t.Fatalf("should have removed persisted check")
} }

View File

@ -2,6 +2,7 @@ package agent
import ( import (
"bytes" "bytes"
"crypto/md5"
crand "crypto/rand" crand "crypto/rand"
"fmt" "fmt"
"math" "math"
@ -91,3 +92,8 @@ func encodeMsgPack(msg interface{}) ([]byte, error) {
err := codec.NewEncoder(&buf, msgpackHandle).Encode(msg) err := codec.NewEncoder(&buf, msgpackHandle).Encode(msg)
return buf.Bytes(), err return buf.Bytes(), err
} }
// stringHash returns a simple md5sum for a string.
func stringHash(s string) string {
return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}

View File

@ -30,3 +30,12 @@ func TestRandomStagger(t *testing.T) {
} }
} }
} }
func TestStringHash(t *testing.T) {
in := "hello world"
expected := "5eb63bbbe01eeed093cb22bb8f5acdc3"
if out := stringHash(in); out != expected {
t.Fatalf("bad: %s", out)
}
}