Explorar el Código

Merge pull request #43820 from thaJeztah/image_delete

containerd integration: Implement ImageDelete for containerd
Brian Goff hace 2 años
padre
commit
7e8df0e2c9

+ 1 - 1
api/server/router/image/backend.go

@@ -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)

+ 1 - 1
api/server/router/image/image_routes.go

@@ -184,7 +184,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
 	}

+ 25 - 3
daemon/containerd/image_delete.go

@@ -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
 }

+ 1 - 1
daemon/image_service.go

@@ -28,7 +28,7 @@ type ImageService interface {
 	PullImage(ctx context.Context, image, tag string, platform *v1.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
 	PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.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)

+ 2 - 1
daemon/images/image_delete.go

@@ -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{}
 

+ 3 - 3
daemon/images/image_prune.go

@@ -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)