parent
80970dcee2
commit
e936558a78
3 changed files with 77 additions and 16 deletions
38
README.md
38
README.md
|
@ -91,6 +91,9 @@ $ dockviz images -t
|
|||
└─cb12405ee8fa Virtual Size: 98.5 MB
|
||||
└─316b678ddf48 Virtual Size: 169.4 MB Tags: ubuntu:13.04, ubuntu:raring
|
||||
```
|
||||
|
||||
Only showing labelled images:
|
||||
|
||||
```
|
||||
$ dockviz images -t -l
|
||||
└─511136ea3c5a Virtual Size: 0.0 B
|
||||
|
@ -104,6 +107,41 @@ $ dockviz images -t -l
|
|||
└─316b678ddf48 Virtual Size: 169.4 MB Tags: ubuntu:13.04, ubuntu:raring
|
||||
```
|
||||
|
||||
Showing incremental size rather than cumulative:
|
||||
|
||||
```
|
||||
$ dockviz images -t -i
|
||||
└─511136ea3c5a Virtual Size: 0.0 B
|
||||
├─f10ebce2c0e1 Virtual Size: 103.7 MB
|
||||
│ └─82cdea7ab5b5 Virtual Size: 255.5 KB
|
||||
│ └─5dbd9cb5a02f Virtual Size: 1.9 KB
|
||||
│ └─74fe38d11401 Virtual Size: 105.7 MB Tags: ubuntu:12.04, ubuntu:precise
|
||||
├─ef519c9ee91a Virtual Size: 100.9 MB
|
||||
│ └─07302703becc Virtual Size: 251.0 KB
|
||||
│ └─cf8dc907452c Virtual Size: 1.9 KB
|
||||
│ └─a7cf8ae4e998 Virtual Size: 70.1 MB Tags: ubuntu:12.10, ubuntu:quantal
|
||||
│ ├─e18d8001204e Virtual Size: 29.4 KB
|
||||
│ │ └─d0525208a46c Virtual Size: 71.0 B
|
||||
│ │ └─59dac4bae93b Virtual Size: 71.2 MB
|
||||
│ │ └─89541b3b35f2 Virtual Size: 269.3 MB
|
||||
│ │ └─7dac4e98548e Virtual Size: 0.0 B
|
||||
│ │ └─341d0cc3fac8 Virtual Size: 0.0 B
|
||||
│ │ └─2f96171d2098 Virtual Size: 0.0 B
|
||||
│ │ └─67b8b7262a67 Virtual Size: 1.9 MB
|
||||
│ │ └─0fe9a2bc50fe Virtual Size: 656.0 B
|
||||
│ │ └─8c32832f07ba Virtual Size: 383.0 B
|
||||
│ │ └─cc4e1358bc80 Virtual Size: 0.0 B
|
||||
│ │ └─5c0d04fba9df Virtual Size: 0.0 B Tags: nate/mongodb:latest
|
||||
│ └─398d592f2009 Virtual Size: 70.9 MB
|
||||
│ └─0cd8e7f50270 Virtual Size: 1.4 MB
|
||||
│ └─594b6f8e6f92 Virtual Size: 0.0 B
|
||||
│ └─f832a63e87a4 Virtual Size: 0.0 B Tags: redis:latest
|
||||
└─02dae1c13f51 Virtual Size: 98.3 MB
|
||||
└─e7206bfc66aa Virtual Size: 190.0 KB
|
||||
└─cb12405ee8fa Virtual Size: 1.9 KB
|
||||
└─316b678ddf48 Virtual Size: 70.8 MB Tags: ubuntu:13.04, ubuntu:raring
|
||||
```
|
||||
|
||||
# Running
|
||||
|
||||
Dockviz supports connecting to the Docker daemon directly. It defaults to `unix:///var/run/docker.sock`, but respects the following as well:
|
||||
|
|
30
images.go
30
images.go
|
@ -25,6 +25,7 @@ type ImagesCommand struct {
|
|||
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)."`
|
||||
NoTruncate bool `short:"n" long:"no-trunc" description:"Don't truncate the image IDs."`
|
||||
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."`
|
||||
}
|
||||
|
||||
|
@ -110,7 +111,7 @@ func (x *ImagesCommand) Execute(args []string) error {
|
|||
}
|
||||
|
||||
if imagesCommand.Tree {
|
||||
fmt.Print(jsonToTree(roots, imagesByParent, imagesCommand.NoTruncate))
|
||||
fmt.Print(jsonToTree(roots, imagesByParent, imagesCommand.NoTruncate, imagesCommand.Incremental))
|
||||
}
|
||||
if imagesCommand.Dot {
|
||||
fmt.Print(jsonToDot(roots, imagesByParent))
|
||||
|
@ -163,10 +164,10 @@ IMAGES:
|
|||
return startImage, nil
|
||||
}
|
||||
|
||||
func jsonToTree(images []Image, byParent map[string][]Image, noTrunc bool) string {
|
||||
func jsonToTree(images []Image, byParent map[string][]Image, noTrunc bool, incremental bool) string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
jsonToText(&buffer, images, byParent, noTrunc, "")
|
||||
jsonToText(&buffer, images, byParent, noTrunc, incremental, "")
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
@ -235,33 +236,33 @@ func filterImages(images *[]Image, byParent *map[string][]Image) (filteredImages
|
|||
return filteredImages, filteredChildren
|
||||
}
|
||||
|
||||
func jsonToText(buffer *bytes.Buffer, images []Image, byParent map[string][]Image, noTrunc bool, prefix string) {
|
||||
func jsonToText(buffer *bytes.Buffer, images []Image, byParent map[string][]Image, noTrunc bool, incremental bool, prefix string) {
|
||||
var length = len(images)
|
||||
if length > 1 {
|
||||
for index, image := range images {
|
||||
var nextPrefix string = ""
|
||||
if index+1 == length {
|
||||
PrintTreeNode(buffer, image, noTrunc, prefix+"└─")
|
||||
PrintTreeNode(buffer, image, noTrunc, incremental, prefix+"└─")
|
||||
nextPrefix = " "
|
||||
} else {
|
||||
PrintTreeNode(buffer, image, noTrunc, prefix+"├─")
|
||||
PrintTreeNode(buffer, image, noTrunc, incremental, prefix+"├─")
|
||||
nextPrefix = "│ "
|
||||
}
|
||||
if subimages, exists := byParent[image.Id]; exists {
|
||||
jsonToText(buffer, subimages, byParent, noTrunc, prefix+nextPrefix)
|
||||
jsonToText(buffer, subimages, byParent, noTrunc, incremental, prefix+nextPrefix)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, image := range images {
|
||||
PrintTreeNode(buffer, image, noTrunc, prefix+"└─")
|
||||
PrintTreeNode(buffer, image, noTrunc, incremental, prefix+"└─")
|
||||
if subimages, exists := byParent[image.Id]; exists {
|
||||
jsonToText(buffer, subimages, byParent, noTrunc, prefix+" ")
|
||||
jsonToText(buffer, subimages, byParent, noTrunc, incremental, prefix+" ")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func PrintTreeNode(buffer *bytes.Buffer, image Image, noTrunc bool, prefix string) {
|
||||
func PrintTreeNode(buffer *bytes.Buffer, image Image, noTrunc bool, incremental bool, prefix string) {
|
||||
var imageID string
|
||||
if noTrunc {
|
||||
imageID = image.Id
|
||||
|
@ -269,7 +270,14 @@ func PrintTreeNode(buffer *bytes.Buffer, image Image, noTrunc bool, prefix strin
|
|||
imageID = truncate(image.Id)
|
||||
}
|
||||
|
||||
buffer.WriteString(fmt.Sprintf("%s%s Virtual Size: %s", prefix, imageID, humanSize(image.VirtualSize)))
|
||||
var size int64
|
||||
if incremental {
|
||||
size = image.Size
|
||||
} else {
|
||||
size = image.VirtualSize
|
||||
}
|
||||
|
||||
buffer.WriteString(fmt.Sprintf("%s%s Virtual Size: %s", prefix, imageID, humanSize(size)))
|
||||
if image.RepoTags[0] != "<none>:<none>" {
|
||||
buffer.WriteString(fmt.Sprintf(" Tags: %s\n", strings.Join(image.RepoTags, ", ")))
|
||||
} else {
|
||||
|
|
|
@ -19,6 +19,7 @@ type TreeTest struct {
|
|||
json string
|
||||
startImage string
|
||||
noTrunc bool
|
||||
incr bool
|
||||
regexps []string
|
||||
}
|
||||
|
||||
|
@ -78,23 +79,36 @@ func Test_Dot(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_Tree(t *testing.T) {
|
||||
treeJSON := `[ { "VirtualSize": 662553464, "Size": 0, "RepoTags": [ "foo:latest" ], "ParentId": "735f5db5626147582d2ae3f2c87be8e5e697c088574c5faaf8d4d1bccab99470", "Id": "c87be8e5e697c735f5db5626147582d2ae3f2088574c5faaf8d4d1bccab99470", "Created": 1386142123 }, { "VirtualSize": 682553464, "Size": 0, "RepoTags": [ "<none>:<none>" ], "ParentId": "4c1208b690c68af3476b437e7bc2bcc460f062bda2094d2d8f21a7e70368d358", "Id": "626147582d2ae3735f5db5f2c87be8e5e697c088574c5faaf8d4d1bccab99470", "Created": 1386142123 }, { "VirtualSize": 712553464, "Size": 0, "RepoTags": [ "base:latest" ], "ParentId": "626147582d2ae3735f5db5f2c87be8e5e697c088574c5faaf8d4d1bccab99470", "Id": "574c5faaf8d4d1bccab994626147582d2ae3735f5db5f2c87be8e5e697c08870", "Created": 1386142123 }, { "VirtualSize": 752553464, "Size": 0, "RepoTags": [ "<none>:<none>" ], "ParentId": "574c5faaf8d4d1bccab994626147582d2ae3735f5db5f2c87be8e5e697c08870", "Id": "aaf8d4d1bccab994574c5f626147582d2ae3735f5db5f2c87be8e5e697c08870", "Created": 1386142123 }, { "VirtualSize": 662553464, "Size": 0, "RepoTags": [ "<none>:<none>" ], "ParentId": "4c1208b690c68af3476b437e7bc2bcc460f062bda2094d2d8f21a7e70368d358", "Id": "735f5db5626147582d2ae3f2c87be8e5e697c088574c5faaf8d4d1bccab99470", "Created": 1386142123 }, { "VirtualSize": 662553464, "Size": 662553464, "RepoTags": [ "<none>:<none>" ], "ParentId": "", "Id": "4c1208b690c68af3476b437e7bc2bcc460f062bda2094d2d8f21a7e70368d358", "Created": 1386114144 } ]`
|
||||
treeJSON := `[{"VirtualSize":674553464,"Size":2000000,"RepoTags":["foo:latest"],"ParentId":"735f5db5626147582d2ae3f2c87be8e5e697c088574c5faaf8d4d1bccab99470","Id":"c87be8e5e697c735f5db5626147582d2ae3f2088574c5faaf8d4d1bccab99470","Created":1386142123},{"VirtualSize":682553464,"Size":20000000,"RepoTags":["<none>:<none>"],"ParentId":"4c1208b690c68af3476b437e7bc2bcc460f062bda2094d2d8f21a7e70368d358","Id":"626147582d2ae3735f5db5f2c87be8e5e697c088574c5faaf8d4d1bccab99470","Created":1386142123},{"VirtualSize":712553464,"Size":30000000,"RepoTags":["base:latest"],"ParentId":"626147582d2ae3735f5db5f2c87be8e5e697c088574c5faaf8d4d1bccab99470","Id":"574c5faaf8d4d1bccab994626147582d2ae3735f5db5f2c87be8e5e697c08870","Created":1386142123},{"VirtualSize":752553464,"Size":40000000,"RepoTags":["<none>:<none>"],"ParentId":"574c5faaf8d4d1bccab994626147582d2ae3735f5db5f2c87be8e5e697c08870","Id":"aaf8d4d1bccab994574c5f626147582d2ae3735f5db5f2c87be8e5e697c08870","Created":1386142123},{"VirtualSize":672553464,"Size":10000000,"RepoTags":["<none>:<none>"],"ParentId":"4c1208b690c68af3476b437e7bc2bcc460f062bda2094d2d8f21a7e70368d358","Id":"735f5db5626147582d2ae3f2c87be8e5e697c088574c5faaf8d4d1bccab99470","Created":1386142123},{"VirtualSize":662553464,"Size":662553464,"RepoTags":["<none>:<none>"],"ParentId":"","Id":"4c1208b690c68af3476b437e7bc2bcc460f062bda2094d2d8f21a7e70368d358","Created":1386114144}]`
|
||||
|
||||
treeTests := []TreeTest{
|
||||
TreeTest{
|
||||
json: treeJSON,
|
||||
startImage: "",
|
||||
noTrunc: false,
|
||||
incr: false,
|
||||
regexps: []string{
|
||||
`(?m)└─4c1208b690c6`,
|
||||
`(?m) └─735f5db56261`,
|
||||
`(?m) └─c87be8e5e697`,
|
||||
`(?m)└─4c1208b690c6 Virtual Size: 662.6 MB`,
|
||||
`(?m) └─735f5db56261 Virtual Size: 672.6 MB`,
|
||||
`(?m) └─c87be8e5e697 Virtual Size: 674.6 MB Tags: foo:latest`,
|
||||
},
|
||||
},
|
||||
TreeTest{
|
||||
json: treeJSON,
|
||||
startImage: "",
|
||||
noTrunc: false,
|
||||
incr: true,
|
||||
regexps: []string{
|
||||
`(?m)└─4c1208b690c6 Virtual Size: 662.6 MB`,
|
||||
`(?m) └─735f5db56261 Virtual Size: 10.0 MB`,
|
||||
`(?m) └─c87be8e5e697 Virtual Size: 2.0 MB Tags: foo:latest`,
|
||||
},
|
||||
},
|
||||
TreeTest{
|
||||
json: treeJSON,
|
||||
startImage: "626147582d2a",
|
||||
noTrunc: false,
|
||||
incr: false,
|
||||
regexps: []string{
|
||||
`(?m)└─626147582d2a`,
|
||||
`(?m) └─574c5faaf8d4`,
|
||||
|
@ -105,6 +119,7 @@ func Test_Tree(t *testing.T) {
|
|||
json: treeJSON,
|
||||
startImage: "base:latest",
|
||||
noTrunc: true,
|
||||
incr: false,
|
||||
regexps: []string{
|
||||
`(?m)└─574c5faaf8d4d1bccab994626147582d2ae3735f5db5f2c87be8e5e697c08870`,
|
||||
`(?m) └─aaf8d4d1bccab994574c5f626147582d2ae3735f5db5f2c87be8e5e697c08870`,
|
||||
|
@ -123,7 +138,7 @@ func Test_Tree(t *testing.T) {
|
|||
} else {
|
||||
roots = collectRoots(im)
|
||||
}
|
||||
result := jsonToTree(roots, byParent, treeTest.noTrunc)
|
||||
result := jsonToTree(roots, byParent, treeTest.noTrunc, treeTest.incr)
|
||||
|
||||
for _, regexp := range compileRegexps(t, treeTest.regexps) {
|
||||
if !regexp.MatchString(result) {
|
||||
|
|
Loading…
Reference in a new issue