c8d: align "Size" and "VirtualSize" for images

In versions of Docker before v1.10, this field was calculated from
the image itself and all of its parent images. Images are now stored
self-contained, and no longer use a parent-chain, making this field
an equivalent of the Size field.

For the containerd integration, the Size should be the sum of the
image's compressed / packaged and unpacked (snapshots) layers.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-04-17 13:53:21 +02:00
parent 5bf405b2af
commit e7980275c0
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
2 changed files with 17 additions and 10 deletions

View file

@ -203,11 +203,15 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
sizeCache[d] = usage.Size
return usage.Size, nil
}
virtualSize, err := computeVirtualSize(chainIDs, snapshotSizeFn)
snapshotSize, err := computeSnapshotSize(chainIDs, snapshotSizeFn)
if err != nil {
return nil, nil, err
}
// totalSize is the size of the image's packed layers and snapshots
// (unpacked layers) combined.
totalSize := size + snapshotSize
var repoTags, repoDigests []string
rawImg := image.Metadata()
target := rawImg.Target.Digest
@ -245,8 +249,8 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
Created: rawImg.CreatedAt.Unix(),
RepoDigests: repoDigests,
RepoTags: repoTags,
Size: size,
VirtualSize: virtualSize,
Size: totalSize,
VirtualSize: totalSize,
// -1 indicates that the value has not been set (avoids ambiguity
// between 0 (default) and "not set". We cannot use a pointer (nil)
// for this, as the JSON representation uses "omitempty", which would
@ -476,16 +480,18 @@ func setupLabelFilter(store content.Store, fltrs filters.Args) (func(image image
}, nil
}
func computeVirtualSize(chainIDs []digest.Digest, sizeFn func(d digest.Digest) (int64, error)) (int64, error) {
var virtualSize int64
// computeSnapshotSize calculates the total size consumed by the snapshots
// for the given chainIDs.
func computeSnapshotSize(chainIDs []digest.Digest, sizeFn func(d digest.Digest) (int64, error)) (int64, error) {
var totalSize int64
for _, chainID := range chainIDs {
size, err := sizeFn(chainID)
if err != nil {
return virtualSize, err
return totalSize, err
}
virtualSize += size
totalSize += size
}
return virtualSize, nil
return totalSize, nil
}
func computeSharedSize(chainIDs []digest.Digest, layers map[digest.Digest]int, sizeFn func(d digest.Digest) (int64, error)) (int64, error) {

View file

@ -195,10 +195,11 @@ func (i *ImageService) GetContainerLayerSize(ctx context.Context, containerID st
}
chainIDs := identity.ChainIDs(img.RootFS.DiffIDs)
virtualSize, err := computeVirtualSize(chainIDs, snapshotSizeFn)
snapShotSize, err := computeSnapshotSize(chainIDs, snapshotSizeFn)
if err != nil {
return 0, 0, err
}
return usage.Size, usage.Size + virtualSize, nil
// TODO(thaJeztah): include content-store size for the image (similar to "GET /images/json")
return usage.Size, usage.Size + snapShotSize, nil
}