diff --git a/api/client/images.go b/api/client/images.go index 32440d48d1..e39c473749 100644 --- a/api/client/images.go +++ b/api/client/images.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "net/url" - "strings" "text/tabwriter" "time" @@ -18,74 +17,6 @@ import ( "github.com/docker/docker/utils" ) -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) walkTree(noTrunc bool, images []*types.Image, byParent map[string][]*types.Image, prefix string, printNode func(cli *DockerCli, noTrunc bool, image *types.Image, prefix string)) { - length := len(images) - if length > 1 { - for index, image := range images { - if index+1 == length { - printNode(cli, noTrunc, image, prefix+"└─") - if subimages, exists := byParent[image.ID]; exists { - cli.walkTree(noTrunc, subimages, byParent, prefix+" ", printNode) - } - } else { - printNode(cli, noTrunc, image, prefix+"\u251C─") - if subimages, exists := byParent[image.ID]; exists { - cli.walkTree(noTrunc, subimages, byParent, prefix+"\u2502 ", printNode) - } - } - } - } else { - for _, image := range images { - printNode(cli, noTrunc, image, prefix+"└─") - if subimages, exists := byParent[image.ID]; exists { - cli.walkTree(noTrunc, subimages, byParent, prefix+" ", printNode) - } - } - } -} - -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) printVizNode(noTrunc bool, image *types.Image, prefix string) { - var ( - imageID string - parentID string - ) - if noTrunc { - imageID = image.ID - parentID = image.ParentId - } else { - imageID = stringid.TruncateID(image.ID) - parentID = stringid.TruncateID(image.ParentId) - } - if parentID == "" { - fmt.Fprintf(cli.out, " base -> \"%s\" [style=invis]\n", imageID) - } else { - fmt.Fprintf(cli.out, " \"%s\" -> \"%s\"\n", parentID, imageID) - } - if image.RepoTags[0] != ":" { - fmt.Fprintf(cli.out, " \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", - imageID, imageID, strings.Join(image.RepoTags, "\\n")) - } -} - -// FIXME: --viz and --tree are deprecated. Remove them in a future version. -func (cli *DockerCli) printTreeNode(noTrunc bool, image *types.Image, prefix string) { - var imageID string - if noTrunc { - imageID = image.ID - } else { - imageID = stringid.TruncateID(image.ID) - } - - fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(float64(image.VirtualSize))) - if image.RepoTags[0] != ":" { - fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.RepoTags, ", ")) - } else { - fmt.Fprint(cli.out, "\n") - } -} - // CmdImages lists the images in a specified repository, or all top-level images if no repository is specified. // // Usage: docker images [OPTIONS] [REPOSITORY] @@ -95,9 +26,6 @@ func (cli *DockerCli) CmdImages(args ...string) error { all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)") noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output") showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests") - // FIXME: --viz and --tree are deprecated. Remove them in a future version. - flViz := cmd.Bool([]string{"#v", "#viz", "#-viz"}, false, "Output graph in graphviz format") - flTree := cmd.Bool([]string{"#t", "#tree", "#-tree"}, false, "Output graph in tree format") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") @@ -116,158 +44,83 @@ func (cli *DockerCli) CmdImages(args ...string) error { } matchName := cmd.Arg(0) - // FIXME: --viz and --tree are deprecated. Remove them in a future version. - if *flViz || *flTree { - v := url.Values{ - "all": []string{"1"}, - } - if len(imageFilterArgs) > 0 { - filterJSON, err := filters.ToParam(imageFilterArgs) - if err != nil { - return err - } - v.Set("filters", filterJSON) - } - - rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil) + v := url.Values{} + if len(imageFilterArgs) > 0 { + filterJSON, err := filters.ToParam(imageFilterArgs) if err != nil { return err } + v.Set("filters", filterJSON) + } - images := []types.Image{} - err = json.NewDecoder(rdr).Decode(&images) - if err != nil { - return err - } + if cmd.NArg() == 1 { + // FIXME rename this parameter, to not be confused with the filters flag + v.Set("filter", matchName) + } + if *all { + v.Set("all", "1") + } - var ( - printNode func(cli *DockerCli, noTrunc bool, image *types.Image, prefix string) - startImage *types.Image + rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil) + if err != nil { + return err + } - roots = []*types.Image{} - byParent = make(map[string][]*types.Image) - ) + images := []types.Image{} + if err := json.NewDecoder(rdr).Decode(&images); err != nil { + return err + } - for _, image := range images { - if image.ParentId == "" { - roots = append(roots, &image) - } else { - if children, exists := byParent[image.ParentId]; exists { - children = append(children, &image) - } else { - byParent[image.ParentId] = []*types.Image{&image} - } - } - - if matchName != "" { - if matchName == image.ID || matchName == stringid.TruncateID(image.ID) { - startImage = &image - } - - for _, repotag := range image.RepoTags { - if repotag == matchName { - startImage = &image - } - } - } - } - - if *flViz { - fmt.Fprintf(cli.out, "digraph docker {\n") - printNode = (*DockerCli).printVizNode + w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) + if !*quiet { + if *showDigests { + fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tVIRTUAL SIZE") } else { - printNode = (*DockerCli).printTreeNode + fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE") + } + } + + for _, image := range images { + ID := image.ID + if !*noTrunc { + ID = stringid.TruncateID(ID) } - if startImage != nil { - root := []*types.Image{startImage} - cli.walkTree(*noTrunc, root, byParent, "", printNode) - } else if matchName == "" { - cli.walkTree(*noTrunc, roots, byParent, "", printNode) - } - if *flViz { - fmt.Fprintf(cli.out, " base [style=invisible]\n}\n") - } - } else { - v := url.Values{} - if len(imageFilterArgs) > 0 { - filterJSON, err := filters.ToParam(imageFilterArgs) - if err != nil { - return err - } - v.Set("filters", filterJSON) + repoTags := image.RepoTags + repoDigests := image.RepoDigests + + if len(repoTags) == 1 && repoTags[0] == ":" && len(repoDigests) == 1 && repoDigests[0] == "@" { + // dangling image - clear out either repoTags or repoDigsts so we only show it once below + repoDigests = []string{} } - if cmd.NArg() == 1 { - // FIXME rename this parameter, to not be confused with the filters flag - v.Set("filter", matchName) - } - if *all { - v.Set("all", "1") - } - - rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil) - if err != nil { - return err - } - - images := []types.Image{} - err = json.NewDecoder(rdr).Decode(&images) - if err != nil { - return err - } - - w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) - if !*quiet { - if *showDigests { - fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tVIRTUAL SIZE") + // combine the tags and digests lists + tagsAndDigests := append(repoTags, repoDigests...) + for _, repoAndRef := range tagsAndDigests { + repo, ref := parsers.ParseRepositoryTag(repoAndRef) + // default tag and digest to none - if there's a value, it'll be set below + tag := "" + digest := "" + if utils.DigestReference(ref) { + digest = ref } else { - fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE") - } - } - - for _, image := range images { - ID := image.ID - if !*noTrunc { - ID = stringid.TruncateID(ID) + tag = ref } - repoTags := image.RepoTags - repoDigests := image.RepoDigests - - if len(repoTags) == 1 && repoTags[0] == ":" && len(repoDigests) == 1 && repoDigests[0] == "@" { - // dangling image - clear out either repoTags or repoDigsts so we only show it once below - repoDigests = []string{} - } - - // combine the tags and digests lists - tagsAndDigests := append(repoTags, repoDigests...) - for _, repoAndRef := range tagsAndDigests { - repo, ref := parsers.ParseRepositoryTag(repoAndRef) - // default tag and digest to none - if there's a value, it'll be set below - tag := "" - digest := "" - if utils.DigestReference(ref) { - digest = ref + if !*quiet { + if *showDigests { + fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) } else { - tag = ref - } - - if !*quiet { - if *showDigests { - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) - } else { - fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) - } - } else { - fmt.Fprintln(w, ID) + fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.VirtualSize))) } + } else { + fmt.Fprintln(w, ID) } } + } - if !*quiet { - w.Flush() - } + if !*quiet { + w.Flush() } return nil } diff --git a/api/server/server.go b/api/server/server.go index 830e731a7e..b5f978e844 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -406,15 +406,6 @@ func (s *Server) getImagesJSON(eng *engine.Engine, version version.Version, w ht return writeJSON(w, http.StatusOK, legacyImages) } -func (s *Server) getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - if version.GreaterThan("1.6") { - w.WriteHeader(http.StatusNotFound) - return fmt.Errorf("This is now implemented in the client.") - } - eng.ServeHTTP(w, r) - return nil -} - func (s *Server) getInfo(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { w.Header().Set("Content-Type", "application/json") @@ -1588,7 +1579,6 @@ func createRouter(s *Server, eng *engine.Engine) *mux.Router { "/info": s.getInfo, "/version": s.getVersion, "/images/json": s.getImagesJSON, - "/images/viz": s.getImagesViz, "/images/search": s.getImagesSearch, "/images/get": s.getImagesGet, "/images/{name:.*}/get": s.getImagesGet,