conditionalize createdby display, make display options consistent
This commit is contained in:
parent
4c4b3c154a
commit
85dd6df8b2
1 changed files with 53 additions and 29 deletions
82
images.go
82
images.go
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/dustin/go-humanize"
|
|
||||||
"github.com/fsouza/go-dockerclient"
|
"github.com/fsouza/go-dockerclient"
|
||||||
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -27,19 +26,21 @@ type Image struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImagesCommand struct {
|
type ImagesCommand struct {
|
||||||
Dot bool `short:"d" long:"dot" description:"Show image information as Graphviz dot. You can add a start image id or name -d/--dot [id/name]"`
|
Dot bool `short:"d" long:"dot" description:"Show image information as Graphviz dot. You can add a start image id or name -d/--dot [id/name]"`
|
||||||
Tree bool `short:"t" long:"tree" description:"Show image information as tree. You can add a start image id or name -t/--tree [id/name]"`
|
Tree bool `short:"t" long:"tree" description:"Show image information as tree. You can add a start image id or name -t/--tree [id/name]"`
|
||||||
Short bool `short:"s" long:"short" description:"Show short summary of images (repo name and list of tags)."`
|
Short bool `short:"s" long:"short" description:"Show short summary of images (repo name and list of tags)."`
|
||||||
NoTruncate bool `short:"n" long:"no-trunc" description:"Don't truncate the image IDs (only works with tree mode)."`
|
NoTruncate bool `short:"n" long:"no-trunc" description:"Don't truncate the image IDs (only works with tree mode)."`
|
||||||
Incremental bool `short:"i" long:"incremental" description:"Display image size as incremental rather than cumulative."`
|
Incremental bool `short:"i" long:"incremental" description:"Display image size as incremental rather than cumulative."`
|
||||||
OnlyLabelled bool `short:"l" long:"only-labelled" description:"Print only labelled images/containers."`
|
OnlyLabelled bool `short:"l" long:"only-labelled" description:"Print only labelled images/containers."`
|
||||||
NoHuman bool `short:"c" long:"no-human" description:"Don't humanize the sizes."`
|
ShowCreatedBy bool `long:"show-created-by" description:"Show the image 'CreatedBy' to help identify layers."`
|
||||||
|
NoHuman bool `short:"c" long:"no-human" description:"Don't humanize the sizes."`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DisplayOpts struct {
|
type DisplayOpts struct {
|
||||||
NoTruncate bool
|
NoTruncate bool
|
||||||
Incremental bool
|
Incremental bool
|
||||||
NoHuman bool
|
NoHuman bool
|
||||||
|
ShowCreatedBy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var imagesCommand ImagesCommand
|
var imagesCommand ImagesCommand
|
||||||
|
@ -157,16 +158,17 @@ func (x *ImagesCommand) Execute(args []string) error {
|
||||||
*images, imagesByParent = filterImages(images, &imagesByParent)
|
*images, imagesByParent = filterImages(images, &imagesByParent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispOpts := DisplayOpts{
|
||||||
|
imagesCommand.NoTruncate,
|
||||||
|
imagesCommand.Incremental,
|
||||||
|
imagesCommand.NoHuman,
|
||||||
|
imagesCommand.ShowCreatedBy,
|
||||||
|
}
|
||||||
if imagesCommand.Tree {
|
if imagesCommand.Tree {
|
||||||
dispOpts := DisplayOpts{
|
|
||||||
imagesCommand.NoTruncate,
|
|
||||||
imagesCommand.Incremental,
|
|
||||||
imagesCommand.NoHuman,
|
|
||||||
}
|
|
||||||
fmt.Print(jsonToTree(roots, imagesByParent, dispOpts))
|
fmt.Print(jsonToTree(roots, imagesByParent, dispOpts))
|
||||||
}
|
}
|
||||||
if imagesCommand.Dot {
|
if imagesCommand.Dot {
|
||||||
fmt.Print(jsonToDot(roots, imagesByParent))
|
fmt.Print(jsonToDot(roots, imagesByParent, dispOpts))
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if imagesCommand.Short {
|
} else if imagesCommand.Short {
|
||||||
|
@ -283,11 +285,11 @@ func jsonToTree(images []Image, byParent map[string][]Image, dispOpts DisplayOpt
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonToDot(roots []Image, byParent map[string][]Image) string {
|
func jsonToDot(roots []Image, byParent map[string][]Image, dispOpts DisplayOpts) string {
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
buffer.WriteString("digraph docker {\n")
|
buffer.WriteString("digraph docker {\n")
|
||||||
imagesToDot(&buffer, roots, byParent)
|
imagesToDot(&buffer, roots, byParent, dispOpts)
|
||||||
buffer.WriteString(" base [style=invisible]\n}\n")
|
buffer.WriteString(" base [style=invisible]\n}\n")
|
||||||
|
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
|
@ -400,10 +402,12 @@ func PrintTreeNode(buffer *bytes.Buffer, image Image, dispOpts DisplayOpts, pref
|
||||||
|
|
||||||
buffer.WriteString(fmt.Sprintf("%s%s %s: %s", prefix, imageID, sizeLabel, sizeStr))
|
buffer.WriteString(fmt.Sprintf("%s%s %s: %s", prefix, imageID, sizeLabel, sizeStr))
|
||||||
if image.RepoTags[0] != "<none>:<none>" {
|
if image.RepoTags[0] != "<none>:<none>" {
|
||||||
buffer.WriteString(fmt.Sprintf(" Tags: %s\n", strings.Join(image.RepoTags, ", ")))
|
buffer.WriteString(fmt.Sprintf(" Tags: %s", strings.Join(image.RepoTags, ", ")))
|
||||||
} else {
|
|
||||||
buffer.WriteString(fmt.Sprintf("\n"))
|
|
||||||
}
|
}
|
||||||
|
if dispOpts.ShowCreatedBy {
|
||||||
|
buffer.WriteString(fmt.Sprintf(" (%s)", SanitizeCommand(image.CreatedBy, 100)))
|
||||||
|
}
|
||||||
|
buffer.WriteString(fmt.Sprintf("\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func humanSize(raw int64) string {
|
func humanSize(raw int64) string {
|
||||||
|
@ -454,7 +458,7 @@ func parseImagesJSON(rawJSON []byte) (*[]Image, error) {
|
||||||
return &images, nil
|
return &images, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func imagesToDot(buffer *bytes.Buffer, images []Image, byParent map[string][]Image) {
|
func imagesToDot(buffer *bytes.Buffer, images []Image, byParent map[string][]Image, dispOpts DisplayOpts) {
|
||||||
for _, image := range images {
|
for _, image := range images {
|
||||||
|
|
||||||
if image.ParentId == "" {
|
if image.ParentId == "" {
|
||||||
|
@ -462,17 +466,37 @@ func imagesToDot(buffer *bytes.Buffer, images []Image, byParent map[string][]Ima
|
||||||
} else {
|
} else {
|
||||||
buffer.WriteString(fmt.Sprintf(" \"%s\" -> \"%s\"\n", truncate(image.ParentId, 12), truncate(image.Id, 12)))
|
buffer.WriteString(fmt.Sprintf(" \"%s\" -> \"%s\"\n", truncate(image.ParentId, 12), truncate(image.Id, 12)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if image.RepoTags[0] != "<none>:<none>" {
|
if image.RepoTags[0] != "<none>:<none>" {
|
||||||
buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12), strings.Join(image.RepoTags, "\\n")))
|
buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12), strings.Join(image.RepoTags, "\\n")))
|
||||||
} else {
|
} else {
|
||||||
// show partial command and size to make up for
|
labelParts := []string{truncate(stripPrefix(image.OrigId), 12)}
|
||||||
// the fact that since Docker 1.10 content addressing
|
if dispOpts.ShowCreatedBy {
|
||||||
// image ids are usually empty and report as <missing>
|
labelParts = append(labelParts, SanitizeCommand(image.CreatedBy, 30))
|
||||||
SanitizedCommand := SanitizeCommand(image.CreatedBy, 30)
|
}
|
||||||
buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\"]\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12)+"\n"+SanitizedCommand+"\n"+humanize.Bytes(uint64(image.Size))))
|
|
||||||
|
var size int64
|
||||||
|
var sizeLabel string
|
||||||
|
if dispOpts.Incremental {
|
||||||
|
sizeLabel = "Size"
|
||||||
|
size = image.Size
|
||||||
|
} else {
|
||||||
|
sizeLabel = "Virtual Size"
|
||||||
|
size = image.VirtualSize
|
||||||
|
}
|
||||||
|
|
||||||
|
var sizeStr string
|
||||||
|
if dispOpts.NoHuman {
|
||||||
|
sizeStr = strconv.FormatInt(size, 10)
|
||||||
|
} else {
|
||||||
|
sizeStr = humanSize(size)
|
||||||
|
}
|
||||||
|
labelParts = append(labelParts, fmt.Sprintf("%s: %s", sizeLabel, sizeStr))
|
||||||
|
|
||||||
|
buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\"]\n", truncate(image.Id, 12), strings.Join(labelParts, "\n")))
|
||||||
}
|
}
|
||||||
if subimages, exists := byParent[image.Id]; exists {
|
if subimages, exists := byParent[image.Id]; exists {
|
||||||
imagesToDot(buffer, subimages, byParent)
|
imagesToDot(buffer, subimages, byParent, dispOpts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue