c8d/list: Add test and combine size#47449
Conversation
4540ff4 to
e6d2ed7
Compare
e6d2ed7 to
0dea7d9
Compare
$ docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
c2bf9493c1bf: Download complete
Digest: sha256:6d9ac9237a84afe1516540f40a0fafdc86859b2141954b4d643af7066d598b74
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 6d9ac9237a84 5 weeks ago 6.09MB
$ docker pull --platform linux/amd64 busybox
Using default tag: latest
latest: Pulling from library/busybox
9ad63333ebc9: Download complete
Digest: sha256:6d9ac9237a84afe1516540f40a0fafdc86859b2141954b4d643af7066d598b74
Status: Image is up to date for busybox:latest
docker.io/library/busybox:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 6d9ac9237a84 5 weeks ago 12.7MB |
0dea7d9 to
f5ad7e8
Compare
daemon/containerd/image_list.go
Outdated
| // TODO(thaJeztah): do we need to take multiple snapshotters into account? See https://github.com/moby/moby/issues/45273 | ||
| snapshotter := i.client.SnapshotService(i.snapshotter) | ||
| snapshotter := i.snapshotterService |
There was a problem hiding this comment.
Hmm.. this means we won't be able to use multiple snapshotters (see the TODO comment above). If we do this, we should store it indexed by snapshotter.
There was a problem hiding this comment.
Hmmm fair enough, done.
| return nil, nil, errors.Wrapf(err, "failed to get rootfs of image %s", imageManifest.Name()) | ||
| } | ||
|
|
||
| func (i *ImageService) singlePlatformSize(ctx context.Context, imgMfst *ImageManifest) (totalSize int64, contentSize int64, _ error) { |
There was a problem hiding this comment.
This name is a bit confusing. I need to look into what exactly it returns; totalSize is the size for all platforms? what is contentSize in this context?
There was a problem hiding this comment.
Oh! This is for a single-arch image (so "total" for the image, in this case being the total for a single arch, correct?)
There was a problem hiding this comment.
Yes, total here means both content (distributed blobs) and "unpacked" size (snaphots).
a21249e to
ffef668
Compare
daemon/containerd/service.go
Outdated
| return s | ||
| } | ||
|
|
||
| return i.client.SnapshotService(snapshotter) |
There was a problem hiding this comment.
Should this be stored in the map, or was it intentional to only keep a reference to the default one?
daemon/containerd/image_list.go
Outdated
|
|
||
| if opts.ContainerCount { | ||
| i.containers.ApplyAll(func(c *container.Container) { | ||
| if c.ImageManifest != nil && c.ImageManifest.Digest == img.Target().Digest { |
There was a problem hiding this comment.
For a follow-up; we should really document the ImageManifest field in container; I went looking to see if this was the "platform-specific" manifest, or if this was the manifest-index ("root" of the image), but the field is currently not documented.
daemon/containerd/image_list.go
Outdated
| platform = dockerImage.Platform | ||
| } | ||
|
|
||
| if !platformMatcher.Match(platform) { |
There was a problem hiding this comment.
Perhaps would be worth adding your commit-message description as a comment here; this would not be obvious immediately when looking at the code.
Currently this won't have any real effect because the platform matcher matches all platform and is only used for sorting.
Curious if this would filter, wouldn't that mean that docker image ls would not include sizes for all images?
There was a problem hiding this comment.
I'd assume it would only include the size for matching-platform images. However, I think that makes sense: if the passes in a specific platform matcher, it's because they only want to know about those particular images.
There was a problem hiding this comment.
Not sure what's the correct behavior here when we're reducing multiple platforms into one list item.
Hmmm good one. I feel like technically the correct behavior would be to show the total size of all images, because the single entry represents the whole multi-platform image with all platforms.
This would mean, that if we now added the --platform switch, it wouldn't really affect anything in the output.. But perhaps that's actually what we want - it should only affect the platform specific subimages.
EDIT: Actually it would also hide the multiplatform images not supporting that platform, so I think it's actually the expected behavior.
There was a problem hiding this comment.
Yeah my train of thought here was that;
abcd ubuntu:latest 200MB
Is the compact view of;
abcd ubuntu:latest 200MB
|-- ubuntu:latest X64 100MB
|-- ubuntu:latest ARM64 100MB
So when "collapsed", it would show the summary of it all.
For sure, this is a bit of a limitation of the current means we have, and to some extent there's also something to be said for that to be showing "default" platform. But "hiding" the 100MB for the non-matching platform is also surprising (It says I have 200MB used for images, but I only see 100??)
There was a problem hiding this comment.
Yes, I think it makes more sense to show the total size. Fixed.
laurazard
left a comment
There was a problem hiding this comment.
LGTM!
Just noticed a little typo/duplicated word in c8d/list: Count containers by their manifest's text:
Move containers counting out out `singlePlatformImage` and count them
based on the `ImageManifest` property.
Use `image.Store` and `content.Store` stored in the ImageService struct instead of fetching it every time from containerd client. Signed-off-by: Paweł Gronowski <[email protected]>
Avoid fetching `SnapshotService` from client every time. Fetch it once and then store when creating the image service. This also allows to pass custom snapshotter implementation for unit testing. Signed-off-by: Paweł Gronowski <[email protected]>
To ease accessing image descriptors in tests. Signed-off-by: Paweł Gronowski <[email protected]>
Add unit test for `Images` implementation. Signed-off-by: Paweł Gronowski <[email protected]>
Multi-platform images are coalesced into one entry now. Signed-off-by: Paweł Gronowski <[email protected]>
Move containers counting out of `singlePlatformImage` and count them based on the `ImageManifest` property. (also remove ChainIDs calculation as they're no longer used) Signed-off-by: Paweł Gronowski <[email protected]>
Don't save all present images, inline the sorting into the loop instead. Signed-off-by: Paweł Gronowski <[email protected]>
Signed-off-by: Paweł Gronowski <[email protected]>
Signed-off-by: Paweł Gronowski <[email protected]>
Currently this won't have any real effect because the platform matcher matches all platform and is only used for sorting. Signed-off-by: Paweł Gronowski <[email protected]>
|
Thanks @laurazard! This one was meant to be |
thaJeztah
left a comment
There was a problem hiding this comment.
LGTM
I wonder if (with more complexity, and more iterating needed to collect all the data) if we should benchmark some of this. Do we need to consider caching at some point? Caching is hard though (and we should not optimise if not needed); more so because the list of present images / platforms will change at any moment, so cache invalidation would now be an issue.
| s, ok := i.snapshotterServices[snapshotter] | ||
| if !ok { | ||
| s = i.client.SnapshotService(snapshotter) | ||
| i.snapshotterServices[snapshotter] = s | ||
| } | ||
|
|
||
| return s |
There was a problem hiding this comment.
For posterity / future self; I think this is fine to do, but technically this map would be "unbounded", so would allow an "unlimited" number of snapshotters to be referenced here.
I don't think there's any realistic security here (unless someone would want to DOS themselves by having a gazillion snapshotters).
|
Looks like this one is flaky (I think I mentioned the same one on another PR); |
|
One easy thing to cache would be the Not sure how big of an performance improvement it would bring though, it would definitely be nice to have benchmarks! |
- What I did
Images(image list)ImageManifest- How I did it
See commits 🙈
- How to verify it
CI
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)