implement "images -tree"

This commit is contained in:
Nate Jones 2013-10-09 14:38:39 +00:00
parent 8f64759881
commit ec9a9a08b8
1 changed files with 88 additions and 0 deletions

View File

@ -1057,6 +1057,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
all := cmd.Bool("a", false, "show all images")
noTrunc := cmd.Bool("notrunc", false, "Don't truncate output")
flViz := cmd.Bool("viz", false, "output graph in graphviz format")
flTree := cmd.Bool("tree", false, "output graph in tree format")
if err := cmd.Parse(args); err != nil {
return nil
@ -1092,6 +1093,52 @@ func (cli *DockerCli) CmdImages(args ...string) error {
}
fmt.Fprintf(cli.out, " base [style=invisible]\n}\n")
} else if *flTree {
body, _, err := cli.call("GET", "/images/json?all=1", nil)
if err != nil {
return err
}
var outs []APIImages
err = json.Unmarshal(body, &outs)
if err != nil {
return err
}
var startImageArg = cmd.Arg(0)
var startImage APIImages
var roots []APIImages
var byParent = make(map[string][]APIImages)
for _, image := range outs {
if image.ParentId == "" {
roots = append(roots, image)
} else {
if children, exists := byParent[image.ParentId]; exists {
byParent[image.ParentId] = append(children, image)
} else {
byParent[image.ParentId] = []APIImages{image}
}
}
if startImageArg != "" {
if startImageArg == image.ID || startImageArg == utils.TruncateID(image.ID) {
startImage = image
}
for _, repotag := range image.RepoTags {
if repotag == startImageArg {
startImage = image
}
}
}
}
if startImageArg != "" {
WalkTree(cli, noTrunc, []APIImages{startImage}, byParent, "")
} else {
WalkTree(cli, noTrunc, roots, byParent, "")
}
} else {
v := url.Values{}
if cmd.NArg() == 1 {
@ -1150,6 +1197,47 @@ func (cli *DockerCli) CmdImages(args ...string) error {
return nil
}
func WalkTree(cli *DockerCli, noTrunc *bool, images []APIImages, byParent map[string][]APIImages, prefix string) {
if len(images) > 1 {
length := len(images)
for index, image := range images {
if index+1 == length {
PrintTreeNode(cli, noTrunc, image, prefix+"└─")
if subimages, exists := byParent[image.ID]; exists {
WalkTree(cli, noTrunc, subimages, byParent, prefix+" ")
}
} else {
PrintTreeNode(cli, noTrunc, image, prefix+"|─")
if subimages, exists := byParent[image.ID]; exists {
WalkTree(cli, noTrunc, subimages, byParent, prefix+"| ")
}
}
}
} else {
for _, image := range images {
PrintTreeNode(cli, noTrunc, image, prefix+"└─")
if subimages, exists := byParent[image.ID]; exists {
WalkTree(cli, noTrunc, subimages, byParent, prefix+" ")
}
}
}
}
func PrintTreeNode(cli *DockerCli, noTrunc *bool, image APIImages, prefix string) {
var imageID string
if *noTrunc {
imageID = image.ID
} else {
imageID = utils.TruncateID(image.ID)
}
if image.RepoTags[0] != "<none>:<none>" {
fmt.Fprintf(cli.out, "%s%s Tags: %s\n", prefix, imageID, strings.Join(image.RepoTags, ","))
} else {
fmt.Fprintf(cli.out, "%s%s\n", prefix, imageID)
}
}
func displayablePorts(ports []APIPort) string {
result := []string{}
for _, port := range ports {