Skip to content

daemon/c8d: Implement docker tag#44781

Merged
neersighted merged 6 commits intomoby:masterfrom
vvoland:c8d-tag-upstream
Feb 7, 2023
Merged

daemon/c8d: Implement docker tag#44781
neersighted merged 6 commits intomoby:masterfrom
vvoland:c8d-tag-upstream

Conversation

@vvoland
Copy link
Copy Markdown
Contributor

@vvoland vvoland commented Jan 10, 2023

- What I did
Implement docker tag for containerd image store.

- How I did it
See individual commits.

- How to verify it

$ docker pull ubuntu
$ docker tag ubuntu test
$ docker pull alpine
$ docker tag alpine test
Tag replace
$ docker pull alpine
Using default tag: latest
f271e74b17ce: Download complete
41d876d4e443: Download complete
04eeaa5f8c35: Download complete
a9eaa45ef418: Download complete
docker.io/library/alpine:latest
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED                  SIZE
alpine       latest    f271e74b17ce   Less than a second ago   3.26MB
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
alpine       latest    f271e74b17ce   6 seconds ago   3.26MB
$ docker pull busybox
Using default tag: latest
7b3ccabffc97: Download complete
5e42fbc46b17: Download complete
abaa813f94fd: Download complete
f78e6840ded1: Download complete
docker.io/library/busybox:latest
$ docker tag busybox myimage
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
alpine       latest    f271e74b17ce   8 seconds ago   3.26MB
busybox      latest    7b3ccabffc97   5 seconds ago   2.01MB
myimage      latest    7b3ccabffc97   1 second ago    2.01MB
$ docker rmi busybox
Untagged: busybox
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
alpine       latest    f271e74b17ce   13 seconds ago   3.26MB
myimage      latest    7b3ccabffc97   6 seconds ago    2.01MB
$ docker tag alpine myimage
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
<none>       <none>    7b3ccabffc97   2 seconds ago    2.01MB
alpine       latest    f271e74b17ce   24 seconds ago   3.26MB
myimage      latest    f271e74b17ce   2 seconds ago    3.26MB
$ docker tag 7b3ccabffc97 busybox # this needs https://github.com/moby/moby/pull/44842
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
alpine       latest    f271e74b17ce   About a minute ago   3.26MB
busybox      latest    7b3ccabffc97   2 seconds ago        2.01MB
myimage      latest    f271e74b17ce   52 seconds ago       3.26MB

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)
image

@vvoland vvoland added area/api API area/images Image Service area/daemon Core Engine containerd-integration Issues and PRs related to containerd integration labels Jan 10, 2023
Comment thread daemon/containerd/image_tag.go Outdated
err := is.Delete(ctx, img.Name)

if err != nil {
logger.WithError(err).Error("failed to delete old image")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other logs are Debug these could be too no?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reasoning was that the first one can be Debug, because it mostly should be just an user error (non existing id) and it's kind of expected to happen normally.

But if the image couldn't be created and it's not an "already exists" error, then probably it's something that's not expected to happen under normal circumstances s and it's worth having logging without debug enabled.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if the image couldn't be created and it's not an "already exists" error, then probably it's something that's not expected to happen under normal circumstances s and it's worth having logging without debug enabled.

That one should probably be an Error(), as it's an unexpected error (and we currently return a errdefs.System() (internal server error).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really we shouldn't need to log and return an error.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log has additional information about the context (imageID, tag) - which might be useful when debugging failures. The only caveat is that these will only appear in the daemon log.
Should we drop the logging and just include these in the returned error?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to include it in the error.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the extra logrus logs and included details directly in returned errors.

@vvoland
Copy link
Copy Markdown
Contributor Author

vvoland commented Jan 10, 2023

CI failures are related, will fix those.

@vvoland vvoland force-pushed the c8d-tag-upstream branch 2 times, most recently from 0bfe16f to 070f6a0 Compare January 10, 2023 14:55
Comment thread daemon/containerd/image_tag.go Outdated
Comment thread daemon/containerd/image_tag.go Outdated
if err != nil {
if !cerrdefs.IsAlreadyExists(err) {
logger.WithError(err).Debug("failed to create image")
return errdefs.System(err)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know what errors this can return, and if they should always be considered an internal server error? (does is.Create() return typed errors from containerd, and can any of those be a "user error" (4xx)?

(Perhaps a 5xx is okay in all cases, but might be worth checking and/or a comment to outline that irregardless of the error type, we consider it an internal server error).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah definitely there are some errors which shouldn't be considered a server error, like: missing name, labels too big. Those are the minority of all errors that could be returned though. The rest look system related (grpc, internal storage failures).
I think we should keep this as System, but validate the image ourselves before calling is.Create() and return an user error.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, in this case already have a valid reference which is a valid image name. So it's not possible for this one to fail with user user. Will change the Debug to Error log then.

Comment thread daemon/containerd/image_tag.go Outdated
Comment thread daemon/containerd/soft_delete.go Outdated
Comment thread daemon/containerd/image_tag.go Outdated
Comment thread api/server/router/image/backend.go Outdated
Comment thread daemon/containerd/soft_delete.go Outdated
Comment thread daemon/containerd/image_tag.go Outdated
Comment thread daemon/containerd/image_tag.go Outdated
Comment thread daemon/containerd/image_tag.go Outdated
Comment thread daemon/containerd/image_tag.go Outdated
Comment thread api/server/router/image/image_routes.go Outdated
Comment thread daemon/containerd/soft_delete.go Outdated
@vvoland vvoland force-pushed the c8d-tag-upstream branch 2 times, most recently from d29316b to 0e41b77 Compare January 25, 2023 10:20
Comment thread daemon/containerd/soft_delete.go Outdated
// Error out in case we couldn't persist the old image.
// If it already exists, then just continue.
if err != nil && !cerrdefs.IsAlreadyExists(err) {
logger.WithError(err).Error("failed to create a dangling image for the image being replaced")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, we shouldn't need to log and return an error.

Copy link
Copy Markdown
Member

@neersighted neersighted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like to see the following changes:

  • Amending commits squashed, TODOs between commits minimized
  • Don't override ctx
  • TagImage instead of TagImageWithReference would be nice

I feel like you may have preferred TagImageWithReference over TagImage as it makes the need to create the correct reference first clear. It looks like there's common that does this shared between the tag API and the commit code.

Can we consider DRYing that up? It seems possible we could preserve TagImage as a fully encapsulated version, though on the other hand, the need for TagImageWithReference would be decreased. In any case, I'd like the logic of creating the reference to be de-duplicated and contained in the tagging code, if possible.

Comment thread daemon/containerd/image_tag.go
Comment thread daemon/containerd/image_tag.go Outdated
Copy link
Copy Markdown
Contributor Author

@vvoland vvoland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Squashed, removed the ctx overriding and changed TagImageWithReference into TagImage.

I still kept the reference parsing logic outside of tagging code - I don't see how it belongs here, many operations should make sure the reference is valid, before attempting the tag, so they already have a parsed reference. Also it feel weird to make ImageService responsible for parsing that.
I moved the reference parsing from commit to the caller code and made it accept a NamedParsed reference instead. The parsing logic is extracted to httputils as for now only http handlers parse the reference, but ideally this should probably belong to the reference package,

Comment thread daemon/containerd/image_tag.go Outdated
err := is.Delete(ctx, img.Name)

if err != nil {
logger.WithError(err).Error("failed to delete old image")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log has additional information about the context (imageID, tag) - which might be useful when debugging failures. The only caveat is that these will only appear in the daemon log.
Should we drop the logging and just include these in the returned error?

Comment thread daemon/containerd/image_tag.go
Comment thread daemon/containerd/image_tag.go Outdated
@vvoland vvoland force-pushed the c8d-tag-upstream branch 2 times, most recently from 1eb14ec to b2d47f2 Compare January 31, 2023 14:59
Copy link
Copy Markdown
Member

@neersighted neersighted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating my review: LGTM with the exception of dropping the unused method causing a linter error.

@neersighted
Copy link
Copy Markdown
Member

I'd like to see @cpuguy83's logging concerns addressed (looks like he didn't mark them as changes requested). Looks ready to merge once he gives his sign-off.

@vvoland vvoland force-pushed the c8d-tag-upstream branch 2 times, most recently from b8f4126 to 12efc2d Compare February 6, 2023 15:25
@neersighted
Copy link
Copy Markdown
Member

Let's :shipit:

Copy link
Copy Markdown
Member

@rumpl rumpl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍👍

Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@thaJeztah
Copy link
Copy Markdown
Member

arf.. running into the "dubious permissions" issue; @vvoland can you try rebasing?

ndeloof and others added 6 commits February 7, 2023 15:43
Signed-off-by: Nicolas De Loof <[email protected]>
Signed-off-by: Paweł Gronowski <[email protected]>
TagImage is just a wrapper for TagImageWithReference which parses the
repo and tag into a reference. Change TagImageWithReference into
TagImage and move the responsibility of reference parsing to caller.

Signed-off-by: Paweł Gronowski <[email protected]>
Implements image tagging under containerd image store.

If an image with this tag already exists, and there's no other image
with the same target, change its name. The name will have a special
format `moby-dangling@<digest>` which isn't a valid canonical reference
and doesn't resolve to any repository.

Signed-off-by: Paweł Gronowski <[email protected]>
@vvoland
Copy link
Copy Markdown
Contributor Author

vvoland commented Feb 7, 2023

@thaJeztah Rebased

@thaJeztah
Copy link
Copy Markdown
Member

Thanks!

@neersighted neersighted merged commit 5f369ff into moby:master Feb 7, 2023
@thaJeztah thaJeztah added this to the v-next milestone Feb 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api API area/daemon Core Engine area/images Image Service containerd-integration Issues and PRs related to containerd integration status/4-merge

Projects

Development

Successfully merging this pull request may close these issues.

7 participants