Tree generates a tree for the specified image and its layers. Use `traverseChildren` to traverse the layers of all children. By default, only layers of the image are printed.
(traverseChildren bool)
| 12 | // `traverseChildren` to traverse the layers of all children. By default, only |
| 13 | // layers of the image are printed. |
| 14 | func (i *Image) Tree(traverseChildren bool) (string, error) { |
| 15 | // NOTE: a string builder prevents us from copying to much data around |
| 16 | // and compile the string when and where needed. |
| 17 | sb := &strings.Builder{} |
| 18 | |
| 19 | // First print the pretty header for the target image. |
| 20 | size, err := i.Size() |
| 21 | if err != nil { |
| 22 | return "", err |
| 23 | } |
| 24 | repoTags, err := i.RepoTags() |
| 25 | if err != nil { |
| 26 | return "", err |
| 27 | } |
| 28 | |
| 29 | fmt.Fprintf(sb, "Image ID: %s\n", i.ID()[:12]) |
| 30 | fmt.Fprintf(sb, "Tags: %s\n", repoTags) |
| 31 | fmt.Fprintf(sb, "Size: %v\n", units.HumanSizeWithPrecision(float64(size), 4)) |
| 32 | if i.TopLayer() != "" { |
| 33 | fmt.Fprintf(sb, "Image Layers") |
| 34 | } else { |
| 35 | fmt.Fprintf(sb, "No Image Layers") |
| 36 | } |
| 37 | |
| 38 | layerTree, err := i.runtime.layerTree() |
| 39 | if err != nil { |
| 40 | return "", err |
| 41 | } |
| 42 | imageNode := layerTree.node(i.TopLayer()) |
| 43 | |
| 44 | // Traverse the entire tree down to all children. |
| 45 | if traverseChildren { |
| 46 | tree := gotree.New(sb.String()) |
| 47 | if err := imageTreeTraverseChildren(imageNode, tree); err != nil { |
| 48 | return "", err |
| 49 | } |
| 50 | return tree.Print(), nil |
| 51 | } |
| 52 | |
| 53 | // Walk all layers of the image and assemlbe their data. Note that the |
| 54 | // tree is constructed in reverse order to remain backwards compatible |
| 55 | // with Podman. |
| 56 | contents := []string{} |
| 57 | for parentNode := imageNode; parentNode != nil; parentNode = parentNode.parent { |
| 58 | if parentNode.layer == nil { |
| 59 | break // we're done |
| 60 | } |
| 61 | var tags string |
| 62 | repoTags, err := parentNode.repoTags() |
| 63 | if err != nil { |
| 64 | return "", err |
| 65 | } |
| 66 | if len(repoTags) > 0 { |
| 67 | tags = fmt.Sprintf(" Top Layer of: %s", repoTags) |
| 68 | } |
| 69 | content := fmt.Sprintf("ID: %s Size: %7v%s", parentNode.layer.ID[:12], units.HumanSizeWithPrecision(float64(parentNode.layer.UncompressedSize), 4), tags) |
| 70 | contents = append(contents, content) |
| 71 | } |