diff --git a/api.go b/api.go index 1435762cd8..1e0e12e8bf 100644 --- a/api.go +++ b/api.go @@ -192,40 +192,35 @@ func getImagesJSON(srv *Server, version float64, w http.ResponseWriter, r *http. job.Setenv("filter", r.Form.Get("filter")) job.Setenv("all", r.Form.Get("all")) - if version >= 1.9 { + if version > 1.8 { job.Stdout.Add(w) - } else if outs, err = job.Stdout.AddTable(); err != nil { + } else if outs, err = job.Stdout.AddListTable(); err != nil { return err } - if err = job.Run(); err != nil { + if err := job.Run(); err != nil { return err } - if version < 1.9 { // Send as a valid JSON array - if version < 1.8 { // Convert to legacy format - outsLegacy := engine.NewTable("Created", 0) - for _, out := range outs.Data { - for _, repoTag := range out.GetList("RepoTags") { - parts := strings.Split(repoTag, ":") - outLegacy := &engine.Env{} - outLegacy.Set("Repository", parts[0]) - outLegacy.Set("Tag", parts[1]) - outLegacy.Set("ID", out.Get("ID")) - outLegacy.SetInt64("Created", out.GetInt64("Created")) - outLegacy.SetInt64("Size", out.GetInt64("Size")) - outLegacy.SetInt64("VirtualSize", out.GetInt64("VirtualSize")) - outsLegacy.Add(outLegacy) - } + if version < 1.8 && outs != nil { // Convert to legacy format + outsLegacy := engine.NewTable("Created", 0) + for _, out := range outs.Data { + for _, repoTag := range out.GetList("RepoTags") { + parts := strings.Split(repoTag, ":") + outLegacy := &engine.Env{} + outLegacy.Set("Repository", parts[0]) + outLegacy.Set("Tag", parts[1]) + outLegacy.Set("ID", out.Get("ID")) + outLegacy.SetInt64("Created", out.GetInt64("Created")) + outLegacy.SetInt64("Size", out.GetInt64("Size")) + outLegacy.SetInt64("VirtualSize", out.GetInt64("VirtualSize")) + outsLegacy.Add(outLegacy) } - if _, err = outsLegacy.WriteListTo(w); err != nil { - return err - } - } else if _, err = outs.WriteListTo(w); err != nil { + } + if _, err := outsLegacy.WriteListTo(w); err != nil { return err } } - return nil } @@ -307,25 +302,12 @@ func getImagesHistory(srv *Server, version float64, w http.ResponseWriter, r *ht return fmt.Errorf("Missing parameter") } - var ( - err error - outs *engine.Table - job = srv.Eng.Job("history", vars["name"]) - ) + var job = srv.Eng.Job("history", vars["name"]) + job.Stdout.Add(w) - if version >= 1.9 { - job.Stdout.Add(w) - } else if outs, err = job.Stdout.AddTable(); err != nil { + if err := job.Run(); err != nil { return err } - if err = job.Run(); err != nil { - return err - } - if version < 1.9 { // Send as a valid JSON array - if _, err = outs.WriteListTo(w); err != nil { - return err - } - } return nil } @@ -333,26 +315,10 @@ func getContainersChanges(srv *Server, version float64, w http.ResponseWriter, r if vars == nil { return fmt.Errorf("Missing parameter") } - var ( - err error - outs *engine.Table - job = srv.Eng.Job("changes", vars["name"]) - ) + var job = srv.Eng.Job("changes", vars["name"]) + job.Stdout.Add(w) - if version >= 1.9 { - job.Stdout.Add(w) - } else if outs, err = job.Stdout.AddTable(); err != nil { - return err - } - if err = job.Run(); err != nil { - return err - } - if version < 1.9 { // Send as a valid JSON array - if _, err = outs.WriteListTo(w); err != nil { - return err - } - } - return nil + return job.Run() } func getContainersTop(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { @@ -501,25 +467,10 @@ func getImagesSearch(srv *Server, version float64, w http.ResponseWriter, r *htt return err } - var ( - err error - outs *engine.Table - job = srv.Eng.Job("search", r.Form.Get("term")) - ) - if version >= 1.9 { - job.Stdout.Add(w) - } else if outs, err = job.Stdout.AddTable(); err != nil { - return err - } - if err = job.Run(); err != nil { - return err - } - if version < 1.9 { // Send as a valid JSON array - if _, err = outs.WriteListTo(w); err != nil { - return err - } - } - return nil + var job = srv.Eng.Job("search", r.Form.Get("term")) + job.Stdout.Add(w) + + return job.Run() } func postImagesInsert(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { diff --git a/commands.go b/commands.go index a5d7c9100a..2267774fb5 100644 --- a/commands.go +++ b/commands.go @@ -869,7 +869,7 @@ func (cli *DockerCli) CmdHistory(args ...string) error { } outs := engine.NewTable("Created", 0) - if _, err := outs.ReadFrom(stream); err != nil { + if _, err := outs.ReadListFrom(stream); err != nil { return err } @@ -1147,7 +1147,7 @@ func (cli *DockerCli) CmdImages(args ...string) error { } outs := engine.NewTable("Created", 0) - if _, err := outs.ReadFrom(stream); err != nil { + if _, err := outs.ReadListFrom(stream); err != nil { return err } @@ -1219,7 +1219,7 @@ func (cli *DockerCli) CmdImages(args ...string) error { } outs := engine.NewTable("Created", 0) - if _, err := outs.ReadFrom(stream); err != nil { + if _, err := outs.ReadListFrom(stream); err != nil { return err } @@ -1540,7 +1540,7 @@ func (cli *DockerCli) CmdDiff(args ...string) error { } outs := engine.NewTable("", 0) - if _, err := outs.ReadFrom(stream); err != nil { + if _, err := outs.ReadListFrom(stream); err != nil { return err } for _, change := range outs.Data { @@ -1681,7 +1681,7 @@ func (cli *DockerCli) CmdSearch(args ...string) error { return err } outs := engine.NewTable("star_count", 0) - if _, err := outs.ReadFrom(stream); err != nil { + if _, err := outs.ReadListFrom(stream); err != nil { return err } w := tabwriter.NewWriter(cli.out, 10, 1, 3, ' ', 0) diff --git a/docs/sources/reference/api/docker_remote_api.rst b/docs/sources/reference/api/docker_remote_api.rst index b616e10a8f..f7cd7faf4f 100644 --- a/docs/sources/reference/api/docker_remote_api.rst +++ b/docs/sources/reference/api/docker_remote_api.rst @@ -46,14 +46,6 @@ Full Documentation What's new ---------- -.. http:get:: /images/json - - **New!** This endpoint now returns a list of json message, like the events endpoint - -.. http:get:: /images/(name)/history - - **New!** This endpoint now returns a list of json message, like the events endpoint - .. http:post:: /build **New!** This endpoint now takes a serialized ConfigFile which it uses to diff --git a/docs/sources/reference/api/docker_remote_api_v1.9.rst b/docs/sources/reference/api/docker_remote_api_v1.9.rst index 65e501234f..cb406da82b 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.9.rst +++ b/docs/sources/reference/api/docker_remote_api_v1.9.rst @@ -317,18 +317,20 @@ 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 @@ -654,7 +656,8 @@ List Images HTTP/1.1 200 OK Content-Type: application/json - { + [ + { "RepoTags": [ "ubuntu:12.04", "ubuntu:precise", @@ -664,8 +667,8 @@ List Images "Created": 1365714795, "Size": 131506275, "VirtualSize": 131506275 - } - { + }, + { "RepoTags": [ "ubuntu:12.10", "ubuntu:quantal" @@ -675,7 +678,8 @@ List Images "Created": 1364102658, "Size": 24653, "VirtualSize": 180116135 - } + } + ] Create an image @@ -821,16 +825,18 @@ Get the history of an image HTTP/1.1 200 OK Content-Type: application/json - { + [ + { "Id":"b750fe79269d", "Created":1364102658, "CreatedBy":"/bin/bash" - } - { + }, + { "Id":"27cf78414709", "Created":1364068391, "CreatedBy":"" - } + } + ] :statuscode 200: no error :statuscode 404: no such image @@ -954,28 +960,30 @@ Search images HTTP/1.1 200 OK Content-Type: application/json - { + [ + { "description": "", "is_official": false, "is_trusted": false, "name": "wma55/u1210sshd", "star_count": 0 - } - { + }, + { "description": "", "is_official": false, "is_trusted": false, "name": "jdswinbank/sshd", "star_count": 0 - } - { + }, + { "description": "", "is_official": false, "is_trusted": false, "name": "vgauthier/sshd", "star_count": 0 - } + } ... + ] :query term: term to search :statuscode 200: no error diff --git a/engine/env.go b/engine/env.go index 0593bfa012..37ba2ddb4c 100644 --- a/engine/env.go +++ b/engine/env.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io" + "io/ioutil" "sort" "strconv" "strings" @@ -324,6 +325,31 @@ func (t *Table) WriteTo(dst io.Writer) (n int64, err error) { return n, nil } +func (t *Table) ReadListFrom(src io.Reader) (n int64, err error) { + var array []interface{} + + content, err := ioutil.ReadAll(src) + if err != nil { + return -1, err + } + + if err := json.Unmarshal(content, &array); err != nil { + return -1, err + } + + for _, item := range array { + if m, ok := item.(map[string]interface{}); ok { + env := &Env{} + for key, value := range m { + env.SetAuto(key, value) + } + t.Add(env) + } + } + + return int64(len(content)), nil +} + func (t *Table) ReadFrom(src io.Reader) (n int64, err error) { decoder := NewDecoder(src) for { diff --git a/engine/streams.go b/engine/streams.go index 75b3c768b2..703a56256d 100644 --- a/engine/streams.go +++ b/engine/streams.go @@ -211,6 +211,22 @@ func (o *Output) AddEnv() (dst *Env, err error) { return dst, nil } +func (o *Output) AddListTable() (dst *Table, err error) { + src, err := o.AddPipe() + if err != nil { + return nil, err + } + dst = NewTable("", 0) + o.tasks.Add(1) + go func() { + defer o.tasks.Done() + if _, err := dst.ReadListFrom(src); err != nil { + return + } + }() + return dst, nil +} + func (o *Output) AddTable() (dst *Table, err error) { src, err := o.AddPipe() if err != nil { diff --git a/integration/api_test.go b/integration/api_test.go index 30409c907b..8a9d64684f 100644 --- a/integration/api_test.go +++ b/integration/api_test.go @@ -61,7 +61,7 @@ func TestGetInfo(t *testing.T) { srv := mkServerFromEngine(eng, t) job := eng.Job("images") - initialImages, err := job.Stdout.AddTable() + initialImages, err := job.Stdout.AddListTable() if err != nil { t.Fatal(err) } @@ -149,7 +149,7 @@ func TestGetImagesJSON(t *testing.T) { srv := mkServerFromEngine(eng, t) job := eng.Job("images") - initialImages, err := job.Stdout.AddTable() + initialImages, err := job.Stdout.AddListTable() if err != nil { t.Fatal(err) } @@ -170,7 +170,7 @@ func TestGetImagesJSON(t *testing.T) { assertHttpNotError(r, t) images := engine.NewTable("Created", 0) - if _, err := images.ReadFrom(r.Body); err != nil { + if _, err := images.ReadListFrom(r.Body); err != nil { t.Fatal(err) } @@ -205,7 +205,7 @@ func TestGetImagesJSON(t *testing.T) { assertHttpNotError(r2, t) images2 := engine.NewTable("ID", 0) - if _, err := images2.ReadFrom(r2.Body); err != nil { + if _, err := images2.ReadListFrom(r2.Body); err != nil { t.Fatal(err) } @@ -238,7 +238,7 @@ func TestGetImagesJSON(t *testing.T) { assertHttpNotError(r3, t) images3 := engine.NewTable("ID", 0) - if _, err := images3.ReadFrom(r3.Body); err != nil { + if _, err := images3.ReadListFrom(r3.Body); err != nil { t.Fatal(err) } @@ -264,7 +264,7 @@ func TestGetImagesHistory(t *testing.T) { assertHttpNotError(r, t) outs := engine.NewTable("Created", 0) - if _, err := outs.ReadFrom(r.Body); err != nil { + if _, err := outs.ReadListFrom(r.Body); err != nil { t.Fatal(err) } if len(outs.Data) != 1 { @@ -409,7 +409,7 @@ func TestGetContainersChanges(t *testing.T) { } assertHttpNotError(r, t) outs := engine.NewTable("", 0) - if _, err := outs.ReadFrom(r.Body); err != nil { + if _, err := outs.ReadListFrom(r.Body); err != nil { t.Fatal(err) } diff --git a/integration/utils_test.go b/integration/utils_test.go index 63ac3a44b9..a7734fb257 100644 --- a/integration/utils_test.go +++ b/integration/utils_test.go @@ -335,7 +335,7 @@ func getImages(eng *engine.Engine, t *testing.T, all bool, filter string) *engin job := eng.Job("images") job.SetenvBool("all", all) job.Setenv("filter", filter) - images, err := job.Stdout.AddTable() + images, err := job.Stdout.AddListTable() if err != nil { t.Fatal(err) } diff --git a/server.go b/server.go index e0ba2cca08..331c596411 100644 --- a/server.go +++ b/server.go @@ -493,7 +493,7 @@ func (srv *Server) ImagesSearch(job *engine.Job) engine.Status { outs.Add(out) } outs.ReverseSort() - if _, err := outs.WriteTo(job.Stdout); err != nil { + if _, err := outs.WriteListTo(job.Stdout); err != nil { job.Error(err) return engine.StatusErr } @@ -658,7 +658,7 @@ func (srv *Server) Images(job *engine.Job) engine.Status { } outs.ReverseSort() - if _, err := outs.WriteTo(job.Stdout); err != nil { + if _, err := outs.WriteListTo(job.Stdout); err != nil { job.Error(err) return engine.StatusErr } @@ -744,7 +744,7 @@ func (srv *Server) ImageHistory(job *engine.Job) engine.Status { return nil }) outs.ReverseSort() - if _, err := outs.WriteTo(job.Stdout); err != nil { + if _, err := outs.WriteListTo(job.Stdout); err != nil { job.Error(err) return engine.StatusErr } @@ -849,7 +849,7 @@ func (srv *Server) ContainerChanges(job *engine.Job) engine.Status { } outs.Add(out) } - if _, err := outs.WriteTo(job.Stdout); err != nil { + if _, err := outs.WriteListTo(job.Stdout); err != nil { job.Error(err) return engine.StatusErr }