1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

add sizes in images and containers

This commit is contained in:
Victor Vieux 2013-05-13 15:10:26 +02:00
parent 908e4797a6
commit a91b710961
8 changed files with 105 additions and 11 deletions

View file

@ -11,6 +11,8 @@ type ApiImages struct {
Tag string `json:",omitempty"` Tag string `json:",omitempty"`
Id string Id string
Created int64 `json:",omitempty"` Created int64 `json:",omitempty"`
Size int64
ParentSize int64
} }
type ApiInfo struct { type ApiInfo struct {
@ -24,12 +26,14 @@ type ApiInfo struct {
} }
type ApiContainers struct { type ApiContainers struct {
Id string Id string
Image string `json:",omitempty"` Image string `json:",omitempty"`
Command string `json:",omitempty"` Command string `json:",omitempty"`
Created int64 `json:",omitempty"` Created int64 `json:",omitempty"`
Status string `json:",omitempty"` Status string `json:",omitempty"`
Ports string `json:",omitempty"` Ports string `json:",omitempty"`
SizeRw int64
SizeRootFs int64
} }
type ApiSearch struct { type ApiSearch struct {

View file

@ -1194,7 +1194,7 @@ func TestDeleteContainers(t *testing.T) {
func TestDeleteImages(t *testing.T) { func TestDeleteImages(t *testing.T) {
//FIXME: Implement this test //FIXME: Implement this test
t.Skip("Test not implemented") t.Log("Test not implemented")
} }
// Mocked types for tests // Mocked types for tests

View file

@ -728,12 +728,12 @@ func CmdImages(args ...string) error {
w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
if !*quiet { if !*quiet {
fmt.Fprintln(w, "REPOSITORY\tTAG\tID\tCREATED") fmt.Fprintln(w, "REPOSITORY\tTAG\tID\tCREATED\tSIZE")
} }
for _, out := range outs { for _, out := range outs {
if !*quiet { if !*quiet {
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\n", out.Repository, out.Tag, out.Id, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0)))) fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s (virtual %s)\n", out.Repository, out.Tag, out.Id, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), HumanSize(out.Size), HumanSize(out.ParentSize))
} else { } else {
fmt.Fprintln(w, out.Id) fmt.Fprintln(w, out.Id)
} }
@ -794,12 +794,17 @@ func CmdPs(args ...string) error {
} }
w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
if !*quiet { if !*quiet {
fmt.Fprintln(w, "ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS") fmt.Fprintln(w, "ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tSIZE")
} }
for _, out := range outs { for _, out := range outs {
if !*quiet { if !*quiet {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", out.Id, out.Image, out.Command, out.Status, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Ports) fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\t", out.Id, out.Image, out.Command, out.Status, HumanDuration(time.Now().Sub(time.Unix(out.Created, 0))), out.Ports)
if out.SizeRootFs > 0 {
fmt.Fprintf(w, "%s (virtual %s)\n", HumanSize(out.SizeRw), HumanSize(out.SizeRootFs))
} else {
fmt.Fprintf(w, "%s\n", HumanSize(out.SizeRw))
}
} else { } else {
fmt.Fprintln(w, out.Id) fmt.Fprintln(w, out.Id)
} }

View file

@ -11,6 +11,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"path/filepath"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -879,3 +880,26 @@ func validateId(id string) error {
} }
return nil return nil
} }
// GetSize, return real size, virtual size
func (container *Container) GetSize() (int64, int64) {
var sizeRw, sizeRootfs int64
filepath.Walk(container.rwPath(), func(path string, fileInfo os.FileInfo, err error) error {
if fileInfo != nil {
sizeRw += fileInfo.Size()
}
return nil
})
_, err := os.Stat(container.RootfsPath())
if err == nil {
filepath.Walk(container.RootfsPath(), func(path string, fileInfo os.FileInfo, err error) error {
if fileInfo != nil {
sizeRootfs += fileInfo.Size()
}
return nil
})
}
return sizeRw, sizeRootfs
}

View file

@ -89,6 +89,15 @@ func (graph *Graph) Get(name string) (*Image, error) {
if img.Id != id { if img.Id != id {
return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.Id) return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.Id)
} }
if img.Size == 0 {
root, err := img.root()
if err != nil {
return nil, err
}
if err := StoreSize(img, root); err != nil {
return nil, err
}
}
img.graph = graph img.graph = graph
graph.lockSumMap.Lock() graph.lockSumMap.Lock()
defer graph.lockSumMap.Unlock() defer graph.lockSumMap.Unlock()

View file

@ -12,6 +12,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"path/filepath"
"strings" "strings"
"time" "time"
) )
@ -27,6 +28,8 @@ type Image struct {
Author string `json:"author,omitempty"` Author string `json:"author,omitempty"`
Config *Config `json:"config,omitempty"` Config *Config `json:"config,omitempty"`
graph *Graph graph *Graph
Size int64
ParentSize int64
} }
func LoadImage(root string) (*Image, error) { func LoadImage(root string) (*Image, error) {
@ -93,6 +96,18 @@ func StoreImage(img *Image, layerData Archive, root string, store bool) error {
if err := Untar(layerData, layer); err != nil { if err := Untar(layerData, layer); err != nil {
return err return err
} }
return StoreSize(img, root)
}
func StoreSize(img *Image, root string) error {
layer := layerPath(root)
filepath.Walk(layer, func(path string, fileInfo os.FileInfo, err error) error {
img.Size += fileInfo.Size()
return nil
})
// Store the json ball // Store the json ball
jsonData, err := json.Marshal(img) jsonData, err := json.Marshal(img)
if err != nil { if err != nil {
@ -359,3 +374,12 @@ func (img *Image) Checksum() (string, error) {
return hash, nil return hash, nil
} }
func (img *Image) getVirtualSize(size int64) int64 {
parentImage, err := img.GetParent()
if err != nil || parentImage == nil {
return size
}
size += parentImage.Size
return parentImage.getVirtualSize(size)
}

View file

@ -164,6 +164,8 @@ func (srv *Server) Images(all, only_ids bool, filter string) ([]ApiImages, error
out.Tag = tag out.Tag = tag
out.Id = TruncateId(id) out.Id = TruncateId(id)
out.Created = image.Created.Unix() out.Created = image.Created.Unix()
out.Size = image.Size
out.ParentSize = image.getVirtualSize(0)
} else { } else {
out.Id = image.ShortId() out.Id = image.ShortId()
} }
@ -179,6 +181,8 @@ func (srv *Server) Images(all, only_ids bool, filter string) ([]ApiImages, error
out.Tag = "<none>" out.Tag = "<none>"
out.Id = TruncateId(id) out.Id = TruncateId(id)
out.Created = image.Created.Unix() out.Created = image.Created.Unix()
out.Size = image.Size
out.ParentSize = image.getVirtualSize(0)
} else { } else {
out.Id = image.ShortId() out.Id = image.ShortId()
} }
@ -280,6 +284,7 @@ func (srv *Server) Containers(all, trunc_cmd, only_ids bool, n int, since, befor
c.Created = container.Created.Unix() c.Created = container.Created.Unix()
c.Status = container.State.String() c.Status = container.State.String()
c.Ports = container.NetworkSettings.PortMappingHuman() c.Ports = container.NetworkSettings.PortMappingHuman()
c.SizeRw, c.SizeRootFs = container.GetSize()
} }
retContainers = append(retContainers, c) retContainers = append(retContainers, c)
} }

View file

@ -16,6 +16,7 @@ import (
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"runtime" "runtime"
_ "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -133,6 +134,28 @@ func HumanDuration(d time.Duration) string {
return fmt.Sprintf("%d years", d.Hours()/24/365) return fmt.Sprintf("%d years", d.Hours()/24/365)
} }
// HumanSize returns a human-readabla approximation of a size
// (eg. "44K", "17M")
func HumanSize(size int64) string {
i := 0
var sizef float64
sizef = float64(size)
units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
for sizef > 1024.0 {
sizef = sizef / 1024.0
i++
}
return fmt.Sprintf("%.*f %s", i, sizef, units[i])
// sprintf(buf, "%.*f %s", i, size, units[i]);
// if size/1024/1024 > 1000 {
// return strconv.FormatFloat((float64)(size/1024/1024), 'f', 2, 32) + "G"
// }
// if size/1024 > 1024 {
// return strconv.FormatInt(size/1024/1024, 10) + "M"
// }
// return strconv.FormatInt(size/1024, 10) + "K"
}
func Trunc(s string, maxlen int) string { func Trunc(s string, maxlen int) string {
if len(s) <= maxlen { if len(s) <= maxlen {
return s return s