Implement ImageDelete for containerd

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Djordje Lukic 2022-07-08 14:26:17 +02:00 committed by Sebastiaan van Stijn
parent 71cb54cec4
commit 26c65447df
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
6 changed files with 33 additions and 10 deletions

View File

@ -21,7 +21,7 @@ type Backend interface {
}
type imageBackend interface {
ImageDelete(imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
ImageHistory(imageName string) ([]*image.HistoryResponseItem, error)
Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error)
GetImage(refOrID string, platform *specs.Platform) (retImg *dockerimage.Image, retErr error)

View File

@ -195,7 +195,7 @@ func (s *imageRouter) deleteImages(ctx context.Context, w http.ResponseWriter, r
force := httputils.BoolValue(r, "force")
prune := !httputils.BoolValue(r, "noprune")
list, err := s.backend.ImageDelete(name, force, prune)
list, err := s.backend.ImageDelete(ctx, name, force, prune)
if err != nil {
return err
}

View File

@ -1,6 +1,12 @@
package containerd
import "github.com/docker/docker/api/types"
import (
"context"
"github.com/containerd/containerd/images"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
)
// ImageDelete deletes the image referenced by the given imageRef from this
// daemon. The given imageRef can be an image ID, ID prefix, or a repository
@ -35,6 +41,22 @@ import "github.com/docker/docker/api/types"
// If prune is true, ancestor images will each attempt to be deleted quietly,
// meaning any delete conflicts will cause the image to not be deleted and the
// conflict will not be reported.
func (i *ImageService) ImageDelete(imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) {
panic("not implemented")
//
// TODO(thaJeztah): implement ImageDelete "force" options; see https://github.com/moby/moby/issues/43850
// TODO(thaJeztah): implement ImageDelete "prune" options; see https://github.com/moby/moby/issues/43849
// TODO(thaJeztah): add support for image delete using image (short)ID; see https://github.com/moby/moby/issues/43854
// TODO(thaJeztah): mage delete should send image "untag" events and prometheus counters; see https://github.com/moby/moby/issues/43855
func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) {
parsedRef, err := reference.ParseNormalizedNamed(imageRef)
if err != nil {
return nil, err
}
ref := reference.TagNameOnly(parsedRef)
err = i.client.ImageService().Delete(ctx, ref.String(), images.SynchronousDelete())
if err != nil {
return nil, err
}
return []types.ImageDeleteResponseItem{{Untagged: reference.FamiliarString(parsedRef)}}, nil
}

View File

@ -28,7 +28,7 @@ type ImageService interface {
PullImage(ctx context.Context, image, tag string, platform *v1.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error
CreateImage(config []byte, parent string) (builder.Image, error)
ImageDelete(imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
ExportImage(names []string, outStream io.Writer) error
LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error
Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error)

View File

@ -1,6 +1,7 @@
package images // import "github.com/docker/docker/daemon/images"
import (
"context"
"fmt"
"strings"
"time"
@ -58,7 +59,7 @@ const (
// If prune is true, ancestor images will each attempt to be deleted quietly,
// meaning any delete conflicts will cause the image to not be deleted and the
// conflict will not be reported.
func (i *ImageService) ImageDelete(imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) {
func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) {
start := time.Now()
records := []types.ImageDeleteResponseItem{}

View File

@ -119,7 +119,7 @@ deleteImagesLoop:
if shouldDelete {
for _, ref := range refs {
imgDel, err := i.ImageDelete(ref.String(), false, true)
imgDel, err := i.ImageDelete(ctx, ref.String(), false, true)
if imageDeleteFailed(ref.String(), err) {
continue
}
@ -128,7 +128,7 @@ deleteImagesLoop:
}
} else {
hex := id.Digest().Hex()
imgDel, err := i.ImageDelete(hex, false, true)
imgDel, err := i.ImageDelete(ctx, hex, false, true)
if imageDeleteFailed(hex, err) {
continue
}
@ -163,7 +163,7 @@ func imageDeleteFailed(ref string, err error) bool {
switch {
case err == nil:
return false
case errdefs.IsConflict(err):
case errdefs.IsConflict(err), errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
return true
default:
logrus.Warnf("failed to prune image %s: %v", ref, err)