diff --git a/components/engine/api.go b/components/engine/api.go index 095095954e..61252ab9af 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -203,6 +203,18 @@ func getImagesJSON(srv *Server, version float64, w http.ResponseWriter, r *http. } } +func getImagesViz(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + if version > 1.6 { + w.WriteHeader(http.StatusNotFound) + return fmt.Errorf("This is now implemented in the client.") + } + + if err := srv.ImagesViz(w); err != nil { + return err + } + return nil +} + func getInfo(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error { return writeJSON(w, http.StatusOK, srv.DockerInfo()) } @@ -1039,6 +1051,7 @@ func createRouter(srv *Server, logging bool) (*mux.Router, error) { "/info": getInfo, "/version": getVersion, "/images/json": getImagesJSON, + "/images/viz": getImagesViz, "/images/search": getImagesSearch, "/images/{name:.*}/history": getImagesHistory, "/images/{name:.*}/json": getImagesByName, diff --git a/components/engine/server.go b/components/engine/server.go index 644a433eeb..3441029027 100644 --- a/components/engine/server.go +++ b/components/engine/server.go @@ -233,6 +233,44 @@ func (srv *Server) ImageInsert(name, url, path string, out io.Writer, sf *utils. return img.ShortID(), nil } +func (srv *Server) ImagesViz(out io.Writer) error { + images, _ := srv.runtime.graph.Map() + if images == nil { + return nil + } + out.Write([]byte("digraph docker {\n")) + + var ( + parentImage *Image + err error + ) + for _, image := range images { + parentImage, err = image.GetParent() + if err != nil { + return fmt.Errorf("Error while getting parent image: %v", err) + } + if parentImage != nil { + out.Write([]byte(" \"" + parentImage.ShortID() + "\" -> \"" + image.ShortID() + "\"\n")) + } else { + out.Write([]byte(" base -> \"" + image.ShortID() + "\" [style=invis]\n")) + } + } + + reporefs := make(map[string][]string) + + for name, repository := range srv.runtime.repositories.Repositories { + for tag, id := range repository { + reporefs[utils.TruncateID(id)] = append(reporefs[utils.TruncateID(id)], fmt.Sprintf("%s:%s", name, tag)) + } + } + + for id, repos := range reporefs { + out.Write([]byte(" \"" + id + "\" [label=\"" + id + "\\n" + strings.Join(repos, "\\n") + "\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n")) + } + out.Write([]byte(" base [style=invisible]\n}\n")) + return nil +} + func (srv *Server) Images(all bool, filter string) ([]APIImages, error) { var ( allImages map[string]*Image