From 15867ff4308c5c1330a400be56410d404336100f Mon Sep 17 00:00:00 2001 From: Nate Jones Date: Sun, 6 Oct 2013 05:44:04 +0000 Subject: [PATCH] rework images JSON --- api_params.go | 6 +++--- commands.go | 36 +++++++++++++++++++----------------- server.go | 39 ++++++++++++++++++++++++++++----------- sorter.go | 2 +- 4 files changed, 51 insertions(+), 32 deletions(-) diff --git a/api_params.go b/api_params.go index f666ac2393..d796b96542 100644 --- a/api_params.go +++ b/api_params.go @@ -9,12 +9,12 @@ type APIHistory struct { } type APIImages struct { - Repository string `json:",omitempty"` - Tag string `json:",omitempty"` - ID string `json:"Id"` + ID string `json:"Id"` + RepoTags []string `json:",omitempty"` Created int64 Size int64 VirtualSize int64 + ParentId string `json:",omitempty"` } type APIInfo struct { diff --git a/commands.go b/commands.go index d52114553f..7fc3dceb43 100644 --- a/commands.go +++ b/commands.go @@ -1097,27 +1097,29 @@ func (cli *DockerCli) CmdImages(args ...string) error { fmt.Fprintln(w, "REPOSITORY\tTAG\tID\tCREATED\tSIZE") } + var repo string + var tag string for _, out := range outs { - if out.Repository == "" { - out.Repository = "" - } - if out.Tag == "" { - out.Tag = "" - } + for _, repotag := range out.RepoTags { - if !*noTrunc { - out.ID = utils.TruncateID(out.ID) - } + components := strings.SplitN(repotag, ":", 2) + repo = components[0] + tag = components[1] - if !*quiet { - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t", out.Repository, out.Tag, out.ID, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0)))) - if out.VirtualSize > 0 { - fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.Size), utils.HumanSize(out.VirtualSize)) - } else { - fmt.Fprintf(w, "%s\n", utils.HumanSize(out.Size)) + if !*noTrunc { + out.ID = utils.TruncateID(out.ID) + } + + if !*quiet { + fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t", repo, tag, out.ID, utils.HumanDuration(time.Now().Sub(time.Unix(out.Created, 0)))) + if out.VirtualSize > 0 { + fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.Size), utils.HumanSize(out.VirtualSize)) + } else { + fmt.Fprintf(w, "%s\n", utils.HumanSize(out.Size)) + } + } else { + fmt.Fprintln(w, out.ID) } - } else { - fmt.Fprintln(w, out.ID) } } diff --git a/server.go b/server.go index cbe7c6435c..2492c88683 100644 --- a/server.go +++ b/server.go @@ -284,7 +284,7 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { if err != nil { return nil, err } - outs := []APIImages{} //produce [] when empty instead of 'null' + lookup := make(map[string]APIImages) for name, repository := range srv.runtime.repositories.Repositories { if filter != "" { if match, _ := path.Match(filter, name); !match { @@ -292,23 +292,40 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { } } for tag, id := range repository { - var out APIImages image, err := srv.runtime.graph.Get(id) if err != nil { log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err) continue } - delete(allImages, id) - out.Repository = name - out.Tag = tag - out.ID = image.ID - out.Created = image.Created.Unix() - out.Size = image.Size - out.VirtualSize = image.getParentsSize(0) + image.Size - outs = append(outs, out) + + if out, exists := lookup[id]; exists { + out.RepoTags = append(out.RepoTags, fmt.Sprintf("%s:%s", name, tag)) + + lookup[id] = out + } else { + var out APIImages + + delete(allImages, id) + + out.ParentId = image.Parent + out.RepoTags = []string{fmt.Sprintf("%s:%s", name, tag)} + out.ID = image.ID + out.Created = image.Created.Unix() + out.Size = image.Size + out.VirtualSize = image.getParentsSize(0) + image.Size + + lookup[id] = out + } + } } - // Display images which aren't part of a + + outs := make([]APIImages, 0, len(lookup)) + for _, value := range lookup { + outs = append(outs, value) + } + + // Display images which aren't part of a repository/tag if filter == "" { for _, image := range allImages { var out APIImages diff --git a/sorter.go b/sorter.go index d4331eaf1f..c9a86b45c0 100644 --- a/sorter.go +++ b/sorter.go @@ -25,7 +25,7 @@ func (s *imageSorter) Less(i, j int) bool { // Sort []ApiImages by most recent creation date and tag name. func sortImagesByCreationAndTag(images []APIImages) { creationAndTag := func(i1, i2 *APIImages) bool { - return i1.Created > i2.Created || (i1.Created == i2.Created && i2.Tag > i1.Tag) + return i1.Created > i2.Created } sorter := &imageSorter{