From 90ec5de430a79ab6b145899a9842c1db968341cf Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 14 Jan 2014 16:51:59 -0800 Subject: [PATCH] move changes to a job Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) --- api.go | 27 ++++++++++++--- commands.go | 18 +++++++--- docs/sources/api/docker_remote_api_v1.9.rst | 14 ++++---- integration/api_test.go | 8 ++--- server.go | 37 ++++++++++++++++++--- 5 files changed, 78 insertions(+), 26 deletions(-) diff --git a/api.go b/api.go index 38871bcdfa..3d6b49f4a7 100644 --- a/api.go +++ b/api.go @@ -341,13 +341,30 @@ func getContainersChanges(srv *Server, version float64, w http.ResponseWriter, r if vars == nil { return fmt.Errorf("Missing parameter") } - name := vars["name"] - changesStr, err := srv.ContainerChanges(name) - if err != nil { + var ( + buffer *bytes.Buffer + job = srv.Eng.Job("changes", vars["name"]) + ) + + if version >= 1.9 { + job.Stdout.Add(w) + } else { + buffer = bytes.NewBuffer(nil) + job.Stdout.Add(buffer) + } + if err := job.Run(); err != nil { return err } - - return writeJSON(w, http.StatusOK, changesStr) + if version < 1.9 { // Send as a valid JSON array + outs := engine.NewTable("", 0) + if _, err := outs.ReadFrom(buffer); err != nil { + return err + } + if _, err := outs.WriteListTo(w); err != nil { + return err + } + } + return nil } func getContainersTop(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { diff --git a/commands.go b/commands.go index 4776a4312b..297fcdf786 100644 --- a/commands.go +++ b/commands.go @@ -1525,13 +1525,21 @@ func (cli *DockerCli) CmdDiff(args ...string) error { return err } - changes := []Change{} - err = json.Unmarshal(body, &changes) - if err != nil { + outs := engine.NewTable("", 0) + if _, err := outs.ReadFrom(bytes.NewReader(body)); err != nil { return err } - for _, change := range changes { - fmt.Fprintf(cli.out, "%s\n", change.String()) + for _, change := range outs.Data { + var kind string + switch change.GetInt("Kind") { + case archive.ChangeModify: + kind = "C" + case archive.ChangeAdd: + kind = "A" + case archive.ChangeDelete: + kind = "D" + } + fmt.Fprintf(cli.out, "%s %s\n", kind, change.Get("Path")) } return nil } diff --git a/docs/sources/api/docker_remote_api_v1.9.rst b/docs/sources/api/docker_remote_api_v1.9.rst index ba7f85031a..6546035a57 100644 --- a/docs/sources/api/docker_remote_api_v1.9.rst +++ b/docs/sources/api/docker_remote_api_v1.9.rst @@ -317,20 +317,18 @@ Inspect changes on a container's filesystem HTTP/1.1 200 OK Content-Type: application/json - [ - { + { "Path":"/dev", "Kind":0 - }, - { + } + { "Path":"/dev/kmsg", "Kind":1 - }, - { + } + { "Path":"/test", "Kind":1 - } - ] + } :statuscode 200: no error :statuscode 404: no such container diff --git a/integration/api_test.go b/integration/api_test.go index 3c807aecd7..30409c907b 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -408,15 +408,15 @@ func TestGetContainersChanges(t *testing.T) { t.Fatal(err) } assertHttpNotError(r, t) - changes := []docker.Change{} - if err := json.Unmarshal(r.Body.Bytes(), &changes); err != nil { + outs := engine.NewTable("", 0) + if _, err := outs.ReadFrom(r.Body); err != nil { t.Fatal(err) } // Check the changelog success := false - for _, elem := range changes { - if elem.Path == "/etc/passwd" && elem.Kind == 2 { + for _, elem := range outs.Data { + if elem.Get("Path") == "/etc/passwd" && elem.GetInt("Kind") == 2 { success = true } } diff --git a/server.go b/server.go index ebd10fd01c..dc05b4d0b5 100644 --- a/server.go +++ b/server.go @@ -155,6 +155,10 @@ func jobInitApi(job *engine.Job) engine.Status { job.Error(err) return engine.StatusErr } + if err := job.Eng.Register("changes", srv.ContainerChanges); err != nil { + job.Error(err) + return engine.StatusErr + } return engine.StatusOK } @@ -860,11 +864,36 @@ func (srv *Server) ContainerTop(name, psArgs string) (*APITop, error) { return nil, fmt.Errorf("No such container: %s", name) } -func (srv *Server) ContainerChanges(name string) ([]archive.Change, error) { - if container := srv.runtime.Get(name); container != nil { - return container.Changes() +func (srv *Server) ContainerChanges(job *engine.Job) engine.Status { + if n := len(job.Args); n != 1 { + job.Errorf("Usage: %s CONTAINER", job.Name) + return engine.StatusErr } - return nil, fmt.Errorf("No such container: %s", name) + name := job.Args[0] + if container := srv.runtime.Get(name); container != nil { + outs := engine.NewTable("", 0) + changes, err := container.Changes() + if err != nil { + job.Error(err) + return engine.StatusErr + } + for _, change := range changes { + out := &engine.Env{} + if err := out.Import(change); err != nil { + job.Error(err) + return engine.StatusErr + } + outs.Add(out) + } + if _, err := outs.WriteTo(job.Stdout); err != nil { + job.Error(err) + return engine.StatusErr + } + } else { + job.Errorf("No such container: %s", name) + return engine.StatusErr + } + return engine.StatusOK } func (srv *Server) Containers(all, size bool, n int, since, before string) []APIContainers {