diff --git a/client/alloc_runner.go b/client/alloc_runner.go index 8ca6f671e..1bb6d1a65 100644 --- a/client/alloc_runner.go +++ b/client/alloc_runner.go @@ -279,8 +279,17 @@ func copyTaskStates(states map[string]*structs.TaskState) map[string]*structs.Ta // Alloc returns the associated allocation func (r *AllocRunner) Alloc() *structs.Allocation { r.allocLock.Lock() + + // Clear the job before copying + job := r.alloc.Job + r.alloc.Job = nil + alloc := r.alloc.Copy() + // Restore + r.alloc.Job = job + alloc.Job = job + // The status has explicitly been set. if r.allocClientStatus != "" || r.allocClientDescription != "" { alloc.ClientStatus = r.allocClientStatus diff --git a/client/util.go b/client/util.go index 3f7cef981..ee78ebac2 100644 --- a/client/util.go +++ b/client/util.go @@ -1,6 +1,7 @@ package client import ( + "bytes" "encoding/json" "fmt" "io/ioutil" @@ -9,6 +10,7 @@ import ( "path/filepath" "github.com/hashicorp/nomad/nomad/structs" + "github.com/ugorji/go/codec" ) type allocTuple struct { @@ -78,15 +80,17 @@ func shuffleStrings(list []string) { // persistState is used to help with saving state func persistState(path string, data interface{}) error { - buf, err := json.Marshal(data) - if err != nil { - return fmt.Errorf("failed to encode state: %v", err) + var buf bytes.Buffer + enc := codec.NewEncoder(&buf, structs.JsonHandlePretty) + if err := enc.Encode(data); err != nil { + return err } + if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { return fmt.Errorf("failed to make dirs for %s: %v", path, err) } tmpPath := path + ".tmp" - if err := ioutil.WriteFile(tmpPath, buf, 0600); err != nil { + if err := ioutil.WriteFile(tmpPath, buf.Bytes(), 0600); err != nil { return fmt.Errorf("failed to save state to tmp: %v", err) } if err := os.Rename(tmpPath, path); err != nil { diff --git a/command/agent/fs_endpoint.go b/command/agent/fs_endpoint.go index 7658e6628..ad6847c4e 100644 --- a/command/agent/fs_endpoint.go +++ b/command/agent/fs_endpoint.go @@ -21,6 +21,7 @@ import ( "github.com/docker/docker/pkg/ioutils" "github.com/hashicorp/nomad/client/allocdir" + "github.com/hashicorp/nomad/nomad/structs" "github.com/hpcloud/tail/watch" "github.com/ugorji/go/codec" ) @@ -290,7 +291,7 @@ func NewStreamFramer(out io.WriteCloser, plainTxt bool, heartbeatRate, batchWindow time.Duration, frameSize int) *StreamFramer { // Create a JSON encoder - enc := codec.NewEncoder(out, jsonHandle) + enc := codec.NewEncoder(out, structs.JsonHandle) // Create the heartbeat and flush ticker heartbeat := time.NewTicker(heartbeatRate) diff --git a/command/agent/http.go b/command/agent/http.go index 8dbfca78e..147a9df08 100644 --- a/command/agent/http.go +++ b/command/agent/http.go @@ -29,18 +29,6 @@ const ( scadaHTTPAddr = "SCADA" ) -var ( - // jsonHandle and jsonHandlePretty are the codec handles to JSON encode - // structs. The pretty handle will add indents for easier human consumption. - jsonHandle = &codec.JsonHandle{ - HTMLCharsAsIs: true, - } - jsonHandlePretty = &codec.JsonHandle{ - HTMLCharsAsIs: true, - Indent: 4, - } -) - // HTTPServer is used to wrap an Agent and expose it over an HTTP interface type HTTPServer struct { agent *Agent @@ -248,13 +236,13 @@ func (s *HTTPServer) wrap(handler func(resp http.ResponseWriter, req *http.Reque if obj != nil { var buf bytes.Buffer if prettyPrint { - enc := codec.NewEncoder(&buf, jsonHandlePretty) + enc := codec.NewEncoder(&buf, structs.JsonHandlePretty) err = enc.Encode(obj) if err == nil { buf.Write([]byte("\n")) } } else { - enc := codec.NewEncoder(&buf, jsonHandle) + enc := codec.NewEncoder(&buf, structs.JsonHandle) err = enc.Encode(obj) } if err != nil { diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 924c39009..3826ed784 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -4231,6 +4231,18 @@ var MsgpackHandle = func() *codec.MsgpackHandle { return h }() +var ( + // JsonHandle and JsonHandlePretty are the codec handles to JSON encode + // structs. The pretty handle will add indents for easier human consumption. + JsonHandle = &codec.JsonHandle{ + HTMLCharsAsIs: true, + } + JsonHandlePretty = &codec.JsonHandle{ + HTMLCharsAsIs: true, + Indent: 4, + } +) + var HashiMsgpackHandle = func() *hcodec.MsgpackHandle { h := &hcodec.MsgpackHandle{RawToString: true}