From 9dc9f5cf4cc5d0c688263d5532ece0d3079c6d4a Mon Sep 17 00:00:00 2001 From: Kunal Kushwaha Date: Thu, 19 Mar 2020 11:39:39 +0900 Subject: image prune skips images with child images. While image build process, intermediate images are created. These images are also used as cache images, used in rebuilding same images. This fix the deletion of cache images. Signed-off-by: Kunal Kushwaha --- libpod/image/image.go | 24 ++++++++++++++++++++++-- libpod/image/prune.go | 22 ++++++++++++++++------ 2 files changed, 38 insertions(+), 8 deletions(-) (limited to 'libpod') diff --git a/libpod/image/image.go b/libpod/image/image.go index 80cc6f15a..7198a42a3 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -32,10 +32,10 @@ import ( "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" - "github.com/opencontainers/go-digest" + digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/opentracing/opentracing-go" + opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -847,6 +847,26 @@ func (i *Image) Dangling() bool { return len(i.Names()) == 0 } +// Intermediate returns true if the image is cache or intermediate image. +// Cache image has parent and child. +func (i *Image) Intermediate(ctx context.Context) (bool, error) { + parent, err := i.IsParent(ctx) + if err != nil { + return false, err + } + if !parent { + return false, nil + } + img, err := i.GetParent(ctx) + if err != nil { + return false, err + } + if img != nil { + return true, nil + } + return false, nil +} + // Labels returns the image's labels func (i *Image) Labels(ctx context.Context) (map[string]string, error) { imgInspect, err := i.imageInspectInfo(ctx) diff --git a/libpod/image/prune.go b/libpod/image/prune.go index 3afff22af..3b4ea74c4 100644 --- a/libpod/image/prune.go +++ b/libpod/image/prune.go @@ -57,7 +57,7 @@ func generatePruneFilterFuncs(filter, filterValue string) (ImageFilter, error) { } // GetPruneImages returns a slice of images that have no names/unused -func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image, error) { +func (ir *Runtime) GetPruneImages(ctx context.Context, all bool, filterFuncs []ImageFilter) ([]*Image, error) { var ( pruneImages []*Image ) @@ -74,10 +74,6 @@ func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image } } - if len(i.Names()) == 0 { - pruneImages = append(pruneImages, i) - continue - } if all { containers, err := i.Containers() if err != nil { @@ -85,8 +81,22 @@ func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image } if len(containers) < 1 { pruneImages = append(pruneImages, i) + continue } } + + //skip the cache or intermediate images + intermediate, err := i.Intermediate(ctx) + if err != nil { + return nil, err + } + if intermediate { + continue + } + + if i.Dangling() { + pruneImages = append(pruneImages, i) + } } return pruneImages, nil } @@ -111,7 +121,7 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ( filterFuncs = append(filterFuncs, generatedFunc) } - pruneImages, err := ir.GetPruneImages(all, filterFuncs) + pruneImages, err := ir.GetPruneImages(ctx, all, filterFuncs) if err != nil { return nil, errors.Wrap(err, "unable to get images to prune") } -- cgit v1.2.3-54-g00ecf