c8d/list: Fix Repo(Digests|Tags) for untagged images#44840
c8d/list: Fix Repo(Digests|Tags) for untagged images#44840neersighted merged 2 commits intomoby:masterfrom
Conversation
f9ffa30 to
1293a3c
Compare
thaJeztah
left a comment
There was a problem hiding this comment.
Left a question (and a note); also curious if this addresses any of the TODO's on the function (haven't looked closely); https://github.com/moby/moby/blob/master/daemon/containerd/image_list.go#L24-L28
| ref, err := reference.ParseNamed(img.Name()) | ||
| if err == nil { |
There was a problem hiding this comment.
- Do we know in what case this could produce an error? (i.e., how we can end up with an image with an invalid name?)
- IIUC, previously, we would show
img.Name()(even if that could theoretically be an invalid name); in the new situation we replace that with<none>:<none>(discarding the name altogether). I'm curious in what situations that would happen (as it means we're loosing information about the image in the response).
There was a problem hiding this comment.
IMO, there are 2 scenarios:
- User fiddles with the
mobycontainerd namespace directly and creates an image with name that's not a valid reference. - We make some bug/error which creates image with bad name.
In both cases, I don't think we can guarantee that referencing these images by their name will succeed (as we do reference.ParseNormalizedName all over the place), so not presenting these names seems reasonable to me.
There was a problem hiding this comment.
User fiddles with the moby containerd namespace directly and creates an image with name that's not a valid reference.
- First of all, not sure if that's a scenario we must "ignore". Does containerd accept image names that we do not accept valid? (e.g. can I create an image in containerd that's named
🐳😄🐱?) - Second: if this happens, the current code would silently ignore this case
- And (finally): if this happens: how can I remove said image? (if none of our code is able to handle the invalid name, then A)
docker image rmwouldn't be able to delete it?, and B) this output does not allow me to "discover" the invalid name (because we hide it), which does not allow the user to correct their "fiddling" by removing it fromcontainerd(as they wouldn't know what<none>:<none>image this is).
I think currently it could even mean that an image ends up with multiple <none>:<none> tags (one for each invalid image name). Which, thinking of that scenario, could be problematic on other ways (it's not dangling, as we only consider dangling if there's a single <none>:<none> reference)
We make some bug/error which creates image with bad name.
This definitely sounds like something we should not silently ignore.
There was a problem hiding this comment.
- First of all, not sure if that's a scenario we must "ignore". Does containerd accept image names that we do not accept valid? (e.g. can I create an image in containerd that's named
🐳😄🐱?)
Yeah, it happily does.
$ ctr --address /run/docker/containerd/containerd.sock -n moby image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/alpine:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a 3.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
$ ctr --address /run/docker/containerd/containerd.sock -n moby image tag docker.io/library/alpine:latest 🐳😄🐱
🐳😄🐱
$ ctr --address /run/docker/containerd/containerd.sock -n moby image ls
REF TYPE DIGEST SIZE PLATFORMS LABELS
docker.io/library/alpine:latest application/vnd.docker.distribution.manifest.list.v2+json sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a 3.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
🐳😄🐱 application/vnd.docker.distribution.manifest.list.v2+json sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a 3.1 MiB linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest f271e74b17ce 44 seconds ago 3.26MB
<none> <none> f271e74b17ce 3 seconds ago 3.26MB
The image will still be shown, and can be referenced by the ID. In this case the ID will be ambiguous because we tagged it from alpine, so he won't be able to delete this 🐳😄🐱 image by using Docker.
We could use the isDanglingImage from #44781 here and only override the repo tags to <none>:<none> for our special "dangling" images and still persist the non-standard names.
This definitely sounds like something we should not silently ignore.
Good point; warning would be useful here
There was a problem hiding this comment.
Bumping this; I think this PR is ready to bring in once these concerns are addressed.
There was a problem hiding this comment.
I added some error logging and removed overriding the tag with <none> for non-dangling images.
ERRO[2023-01-30T14:20:45.364773471Z] failed to parse image name as reference digest="sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a" error="invalid reference format" name="🐳😄🐱"
There was a problem hiding this comment.
As for images with invalid name:
IIUC, previously, we would show img.Name() (even if that could theoretically be an invalid name); in the new situation we replace that with : (discarding the name altogether). I'm curious in what situations that would happen (as it means we're loosing information about the image in the response).
Previous code did set the repoTags={img.Name()} but doing that made the CLI not show them at all. This is because CLI attempts to parse the repoTags as a named reference (it needs to be able to show the REPO and TAG), and ignores the image if it fails to.
https://github.com/docker/cli/blob/4a500f690f2ef80707839d7b0bbbf38b46b36991/cli/command/formatter/image.go#L116-L119
So, keeping the previous approach (repoTags=invalid name) won't show them in the docker images output at all:
$ ctr --address /run/docker/containerd/containerd.sock -n moby image tag docker.io/library/alpine:l🐳😄🐱🐳😄🐱
🐳😄🐱
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest f271e74b17ce 23 seconds ago 3.26MB
$ curl -s --unix-socket /var/run/docker.sock http://localhost/images/json | jq
[
{
"Containers": -1,
"Created": 1675087679,
"Id": "sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a",
"Labels": null,
"ParentId": "",
"RepoDigests": [
"docker.io/library/alpine@sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a"
],
"RepoTags": [
"docker.io/library/alpine:latest"
],
"SharedSize": -1,
"Size": 3262892,
"VirtualSize": 8138752
},
{
"Containers": -1,
"Created": 1675087699,
"Id": "sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a",
"Labels": null,
"ParentId": "",
"RepoDigests": [
"<none>@<none>"
],
"RepoTags": [
"🐳😄🐱"
],
"SharedSize": -1,
"Size": 3262892,
"VirtualSize": 8138752
}
]But at least that looks somewhat better than overriding it (as the API still returns that information).
Possibly we could add some warning to the CLI that warns about a tag that's not a valid reference?
1293a3c to
223b60a
Compare
223b60a to
c12d8c1
Compare
neersighted
left a comment
There was a problem hiding this comment.
We discussed this extensively in the context of #44989 -- there were a couple takeaways:
These PRs both introduce isDanglingImage and <none>:<none> strings -- so we'd like to see the common parts factored out into a third PR that these two can then be re-stacked on.
In particular, centralizing the <none> string constants in the presentation layer and using a sentinel value (possibly the empty string) to represent untagged images in the plumbing layer makes a lot of sense. We should quarantine those values to the API, so that we can possibly deprecate them in favor of client-side presentation in a future API version.
Likewise, isDanglingImage should be factored into a common place for both these PRs (and then consumed by restacking on top of the common PR), as otherwise when both are merged the symbols will collide as they're in the same package.
Signed-off-by: Paweł Gronowski <[email protected]>
c12d8c1 to
93719be
Compare
|
I don't think there's a need for third PR - this is the first PR that makes the use of Extracted the |
| if len(img.RepoTags) == 0 && len(img.RepoDigests) == 0 { | ||
| img.RepoTags = append(img.RepoTags, "<none>:<none>") | ||
| img.RepoDigests = append(img.RepoDigests, "<none>@<none>") | ||
| } | ||
| } |
There was a problem hiding this comment.
I was thinking whether it would make sense to separate these, but original code did the same thing (except it checked if they're nil, not empty) and it doesn't seem like there's a reason why only one of them would be empty, so I just left the original logic.
neersighted
left a comment
There was a problem hiding this comment.
Fair point that we could make the second PR conditional on this one. Also I didn't mean that we needed a specific sentinel value, a zero-value is just fine as long as it doesn't violate assumptions made up the call stack. This LGTM now that we've isolated the presentation of <none> values to the API layer; let's merge this and rebase the second PR on top.
|
Also, can we ask that you look into deprecating the daemon-side |
|
|
||
| if err != nil { | ||
| if !isDanglingImage(rawImg) { | ||
| logger.WithError(err).Error("failed to parse image name as reference") |
There was a problem hiding this comment.
It's there to issue an error in case we encounter an image like "🐳😄🐱", see: #44840 (comment)
We don't want this error to be logged for dangling images - which have moby-dangling@sha256:... format, so they're not a valid Named reference (missing registry).
93719be to
09dd725
Compare
thaJeztah
left a comment
There was a problem hiding this comment.
LGTM
left one suggestion (let me know if you think that would be useful)
Show dangling images in `docker image ls` output. Signed-off-by: Paweł Gronowski <[email protected]>
09dd725 to
f8791db
Compare
Upstreams:
Make images without tag show correctly in the
docker image lsoutput.Before:
After:
Signed-off-by: Paweł Gronowski [email protected]
- What I did
- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)