From 2dc83288871cc6009001a85d618061854ff6e88c Mon Sep 17 00:00:00 2001 From: Djordje Lukic Date: Mon, 12 Sep 2022 10:48:52 +0200 Subject: [PATCH] Refactor resolving/getting images There were a lot of useless duplicated code Signed-off-by: Djordje Lukic --- daemon/containerd/image.go | 112 +++++---------------------------- daemon/containerd/image_tag.go | 4 +- 2 files changed, 19 insertions(+), 97 deletions(-) diff --git a/daemon/containerd/image.go b/daemon/containerd/image.go index 170bbb01bbd55..aecb48bac7c16 100644 --- a/daemon/containerd/image.go +++ b/daemon/containerd/image.go @@ -26,8 +26,8 @@ var shortID = regexp.MustCompile(`^([a-f0-9]{4,64})$`) // GetContainerdImage returns the containerd image corresponding to the image referred to by refOrID. // The platform parameter is currently ignored -func (i *ImageService) GetContainerdImage(ctx context.Context, refOrID string, platform *ocispec.Platform) (containerdimages.Image, error) { - return i.resolveImageName2(ctx, refOrID) +func (i *ImageService) GetContainerdImage(ctx context.Context, refOrID string, platform *ocispec.Platform) (img containerdimages.Image, err error) { + return i.resolveImage(ctx, refOrID) } // GetImage returns an image corresponding to the image referred to by refOrID. @@ -68,12 +68,13 @@ func (i *ImageService) GetImage(ctx context.Context, refOrID string, options ima } func (i *ImageService) getImage(ctx context.Context, refOrID string) (containerd.Image, *image.Image, error) { - desc, err := i.ResolveImage(ctx, refOrID) + img, err := i.resolveImage(ctx, refOrID) if err != nil { return nil, nil, err } - ctrdimg, err := i.resolveImageName2(ctx, refOrID) + // TODO(rumpl): pass the platform + ctrdimg, err := i.GetContainerdImage(ctx, refOrID, nil) if err != nil { return nil, nil, err } @@ -108,7 +109,7 @@ func (i *ImageService) getImage(ctx context.Context, refOrID string) (containerd } return ii, &image.Image{ V1Image: image.V1Image{ - ID: string(desc.Digest), + ID: string(img.Target.Digest), OS: ociimage.OS, Architecture: ociimage.Architecture, Config: &containertypes.Config{ @@ -125,18 +126,13 @@ func (i *ImageService) getImage(ctx context.Context, refOrID string) (containerd }, nil } -// ResolveImage searches for an image based on the given +// resolveImage searches for an image based on the given // reference or identifier. Returns the descriptor of // the image, could be manifest list, manifest, or config. -func (i *ImageService) ResolveImage(ctx context.Context, refOrID string) (d ocispec.Descriptor, err error) { - d, _, err = i.resolveImageName(ctx, refOrID) - return -} - -func (i *ImageService) resolveImageName2(ctx context.Context, refOrID string) (img containerdimages.Image, err error) { +func (i *ImageService) resolveImage(ctx context.Context, refOrID string) (img containerdimages.Image, err error) { parsed, err := reference.ParseAnyReference(refOrID) if err != nil { - return img, errdefs.InvalidParameter(err) + return containerdimages.Image{}, errdefs.InvalidParameter(err) } is := i.client.ImageService() @@ -145,15 +141,15 @@ func (i *ImageService) resolveImageName2(ctx context.Context, refOrID string) (i if !ok { digested, ok := parsed.(reference.Digested) if !ok { - return img, errdefs.InvalidParameter(errors.New("bad reference")) + return containerdimages.Image{}, errdefs.InvalidParameter(errors.New("bad reference")) } imgs, err := is.List(ctx, fmt.Sprintf("target.digest==%s", digested.Digest())) if err != nil { - return img, errors.Wrap(err, "failed to lookup digest") + return containerdimages.Image{}, errors.Wrap(err, "failed to lookup digest") } if len(imgs) == 0 { - return img, errdefs.NotFound(errors.New("image not found with digest")) + return containerdimages.Image{}, errdefs.NotFound(errors.New("image not found with digest")) } return imgs[0], nil @@ -170,11 +166,11 @@ func (i *ImageService) resolveImageName2(ctx context.Context, refOrID string) (i } imgs, err := is.List(ctx, filters...) if err != nil { - return img, err + return containerdimages.Image{}, err } if len(imgs) == 0 { - return img, errdefs.NotFound(errors.New("list returned no images")) + return containerdimages.Image{}, errdefs.NotFound(errors.New("list returned no images")) } if len(imgs) > 1 { digests := map[digest.Digest]struct{}{} @@ -186,7 +182,7 @@ func (i *ImageService) resolveImageName2(ctx context.Context, refOrID string) (i } if len(digests) > 1 { - return img, errdefs.NotFound(errors.New("ambiguous reference")) + return containerdimages.Image{}, errdefs.NotFound(errors.New("ambiguous reference")) } } @@ -199,88 +195,14 @@ func (i *ImageService) resolveImageName2(ctx context.Context, refOrID string) (i if err != nil { // TODO(containerd): error translation can use common function if !cerrdefs.IsNotFound(err) { - return img, err + return containerdimages.Image{}, err } - return img, errdefs.NotFound(errors.New("id not found")) + return containerdimages.Image{}, errdefs.NotFound(errors.New("id not found")) } return img, nil } -func (i *ImageService) resolveImageName(ctx context.Context, refOrID string) (ocispec.Descriptor, reference.Named, error) { - parsed, err := reference.ParseAnyReference(refOrID) - if err != nil { - return ocispec.Descriptor{}, nil, errdefs.InvalidParameter(err) - } - - is := i.client.ImageService() - - namedRef, ok := parsed.(reference.Named) - if !ok { - digested, ok := parsed.(reference.Digested) - if !ok { - return ocispec.Descriptor{}, nil, errdefs.InvalidParameter(errors.New("bad reference")) - } - - imgs, err := is.List(ctx, fmt.Sprintf("target.digest==%s", digested.Digest())) - if err != nil { - return ocispec.Descriptor{}, nil, errors.Wrap(err, "failed to lookup digest") - } - if len(imgs) == 0 { - return ocispec.Descriptor{}, nil, errdefs.NotFound(errors.New("image not found with digest")) - } - - return imgs[0].Target, nil, nil - } - - namedRef = reference.TagNameOnly(namedRef) - - // If the identifier could be a short ID, attempt to match - if shortID.MatchString(refOrID) { - ref := namedRef.String() - filters := []string{ - fmt.Sprintf("name==%q", ref), - fmt.Sprintf(`target.digest~=/sha256:%s[0-9a-fA-F]{%d}/`, refOrID, 64-len(refOrID)), - } - imgs, err := is.List(ctx, filters...) - if err != nil { - return ocispec.Descriptor{}, nil, err - } - - if len(imgs) == 0 { - return ocispec.Descriptor{}, nil, errdefs.NotFound(errors.New("list returned no images")) - } - if len(imgs) > 1 { - digests := map[digest.Digest]struct{}{} - for _, img := range imgs { - if img.Name == ref { - return img.Target, namedRef, nil - } - digests[img.Target.Digest] = struct{}{} - } - - if len(digests) > 1 { - return ocispec.Descriptor{}, nil, errdefs.NotFound(errors.New("ambiguous reference")) - } - } - - if imgs[0].Name != ref { - namedRef = nil - } - return imgs[0].Target, namedRef, nil - } - img, err := is.Get(ctx, namedRef.String()) - if err != nil { - // TODO(containerd): error translation can use common function - if !cerrdefs.IsNotFound(err) { - return ocispec.Descriptor{}, nil, err - } - return ocispec.Descriptor{}, nil, errdefs.NotFound(errors.New("id not found")) - } - - return img.Target, namedRef, nil -} - // PresentChildrenHandler traverses recursively all children descriptors that are present in the store. func (i *ImageService) presentChildrenHandler() containerdimages.HandlerFunc { store := i.client.ContentStore() diff --git a/daemon/containerd/image_tag.go b/daemon/containerd/image_tag.go index 5bcf46a3a8576..a007490cd36e3 100644 --- a/daemon/containerd/image_tag.go +++ b/daemon/containerd/image_tag.go @@ -12,7 +12,7 @@ import ( // TagImage creates the tag specified by newTag, pointing to the image named // imageName (alternatively, imageName can also be an image ID). func (i *ImageService) TagImage(ctx context.Context, imageName, repository, tag string) (string, error) { - desc, err := i.ResolveImage(ctx, imageName) + img, err := i.resolveImage(ctx, imageName) if err != nil { return "", err } @@ -27,7 +27,7 @@ func (i *ImageService) TagImage(ctx context.Context, imageName, repository, tag } } - err = i.TagImageWithReference(ctx, image.ID(desc.Digest), newTag) + err = i.TagImageWithReference(ctx, image.ID(img.Target.Digest), newTag) return reference.FamiliarString(newTag), err }