Add Store.ContainerSize()
Add a ContainerSize() method, which knows how to compute the sizes of container, so that our callers don't need to all be updated when we make changes to how we store them. Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
parent
ce1b85933f
commit
92105b61a8
|
@ -43,6 +43,12 @@ func container(flags *mflag.FlagSet, action string, m storage.Store, args []stri
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
size, err := m.ContainerSize(container.ID)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Size unknown: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Size: %d\n", size)
|
||||||
|
}
|
||||||
fmt.Printf("Layer: %s\n", container.LayerID)
|
fmt.Printf("Layer: %s\n", container.LayerID)
|
||||||
for _, name := range container.BigDataNames {
|
for _, name := range container.BigDataNames {
|
||||||
fmt.Printf("Data: %s\n", name)
|
fmt.Printf("Data: %s\n", name)
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
drivers "github.com/containers/storage/drivers"
|
drivers "github.com/containers/storage/drivers"
|
||||||
"github.com/containers/storage/pkg/archive"
|
"github.com/containers/storage/pkg/archive"
|
||||||
|
"github.com/containers/storage/pkg/directory"
|
||||||
"github.com/containers/storage/pkg/idtools"
|
"github.com/containers/storage/pkg/idtools"
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
|
@ -371,6 +372,10 @@ type Store interface {
|
||||||
// associated with a container.
|
// associated with a container.
|
||||||
SetContainerBigData(id, key string, data []byte) error
|
SetContainerBigData(id, key string, data []byte) error
|
||||||
|
|
||||||
|
// ContainerSize computes the size of the container's layer and ancillary
|
||||||
|
// data. Warning: this is a potentially expensive operation.
|
||||||
|
ContainerSize(id string) (int64, error)
|
||||||
|
|
||||||
// Layer returns a specific layer.
|
// Layer returns a specific layer.
|
||||||
Layer(id string) (*Layer, error)
|
Layer(id string) (*Layer, error)
|
||||||
|
|
||||||
|
@ -1479,6 +1484,94 @@ func (s *store) ImageSize(id string) (int64, error) {
|
||||||
return size, nil
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *store) ContainerSize(id string) (int64, error) {
|
||||||
|
lstore, err := s.LayerStore()
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
lstores, err := s.ROLayerStores()
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
for _, store := range append([]ROLayerStore{lstore}, lstores...) {
|
||||||
|
store.Lock()
|
||||||
|
defer store.Unlock()
|
||||||
|
if modified, err := store.Modified(); modified || err != nil {
|
||||||
|
store.Load()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the location of the container directory and container run directory.
|
||||||
|
// Do it before we lock the container store because they do, too.
|
||||||
|
cdir, err := s.ContainerDirectory(id)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
rdir, err := s.ContainerRunDirectory(id)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rcstore, err := s.ContainerStore()
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
rcstore.Lock()
|
||||||
|
defer rcstore.Unlock()
|
||||||
|
if modified, err := rcstore.Modified(); modified || err != nil {
|
||||||
|
rcstore.Load()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the container record.
|
||||||
|
container, err := rcstore.Get(id)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the container's layer's size.
|
||||||
|
var layer *Layer
|
||||||
|
var size int64
|
||||||
|
for _, store := range append([]ROLayerStore{lstore}, lstores...) {
|
||||||
|
if layer, err = store.Get(container.LayerID); err == nil {
|
||||||
|
size, err = store.DiffSize("", layer.ID)
|
||||||
|
if err != nil {
|
||||||
|
return -1, errors.Wrapf(err, "error determining size of layer with ID %q", layer.ID)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if layer == nil {
|
||||||
|
return -1, errors.Wrapf(ErrLayerUnknown, "error locating layer with ID %q", container.LayerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count big data items.
|
||||||
|
names, err := rcstore.BigDataNames(id)
|
||||||
|
if err != nil {
|
||||||
|
return -1, errors.Wrapf(err, "error reading list of big data items for container %q", container.ID)
|
||||||
|
}
|
||||||
|
for _, name := range names {
|
||||||
|
n, err := rcstore.BigDataSize(id, name)
|
||||||
|
if err != nil {
|
||||||
|
return -1, errors.Wrapf(err, "error reading size of big data item %q for container %q", name, id)
|
||||||
|
}
|
||||||
|
size += n
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the size of our container directory and container run directory.
|
||||||
|
n, err := directory.Size(cdir)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
size += n
|
||||||
|
n, err = directory.Size(rdir)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
size += n
|
||||||
|
|
||||||
|
return size, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *store) ListContainerBigData(id string) ([]string, error) {
|
func (s *store) ListContainerBigData(id string) ([]string, error) {
|
||||||
rcstore, err := s.ContainerStore()
|
rcstore, err := s.ContainerStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue