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 <kunal.kushwaha@gmail.com>
This commit is contained in:
Kunal Kushwaha
2020-03-19 11:39:39 +09:00
parent c0e29b4a31
commit 9dc9f5cf4c
2 changed files with 38 additions and 8 deletions

View File

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

View File

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