Skip to content

Commit b9adeba

Browse files
Merge pull request #16656 from dmage/bz1487408
Automatic merge from submit-queue (batch tested with PRs 16644, 16649, 16656, 16651, 16663). Pruning should keep layers referenced by other images Fixes #14863 [BZ 1487408](https://bugzilla.redhat.com/show_bug.cgi?id=1487408)
2 parents 2696919 + 917bfe7 commit b9adeba

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

pkg/image/prune/prune.go

+19-20
Original file line numberDiff line numberDiff line change
@@ -260,21 +260,6 @@ func addImagesToGraph(g graph.Graph, images *imageapi.ImageList, algorithm prune
260260
for i := range images.Items {
261261
image := &images.Items[i]
262262

263-
glog.V(4).Infof("Examining image %q", image.Name)
264-
265-
if !algorithm.allImages {
266-
if image.Annotations[imageapi.ManagedByOpenShiftAnnotation] != "true" {
267-
glog.V(4).Infof("Image %q with DockerImageReference %q belongs to an external registry - skipping", image.Name, image.DockerImageReference)
268-
continue
269-
}
270-
}
271-
272-
age := metav1.Now().Sub(image.CreationTimestamp.Time)
273-
if !algorithm.pruneOverSizeLimit && age < algorithm.keepYoungerThan {
274-
glog.V(4).Infof("Image %q is younger than minimum pruning age, skipping (age=%v)", image.Name, age)
275-
continue
276-
}
277-
278263
glog.V(4).Infof("Adding image %q to graph", image.Name)
279264
imageNode := imagegraph.EnsureImageNode(g, image)
280265

@@ -596,12 +581,26 @@ func edgeKind(g graph.Graph, from, to gonum.Node, desiredKind string) bool {
596581
return kinds.Has(desiredKind)
597582
}
598583

599-
// imageIsPrunable returns true iff the image node only has weak references
584+
// imageIsPrunable returns true if the image node only has weak references
600585
// from its predecessors to it. A weak reference to an image is a reference
601586
// from an image stream to an image where the image is not the current image
602587
// for a tag and the image stream is at least as old as the minimum pruning
603588
// age.
604-
func imageIsPrunable(g graph.Graph, imageNode *imagegraph.ImageNode) bool {
589+
func imageIsPrunable(g graph.Graph, imageNode *imagegraph.ImageNode, algorithm pruneAlgorithm) bool {
590+
if !algorithm.allImages {
591+
if imageNode.Image.Annotations[imageapi.ManagedByOpenShiftAnnotation] != "true" {
592+
glog.V(4).Infof("Image %q with DockerImageReference %q belongs to an external registry - skipping",
593+
imageNode.Image.Name, imageNode.Image.DockerImageReference)
594+
return false
595+
}
596+
}
597+
598+
age := metav1.Now().Sub(imageNode.Image.CreationTimestamp.Time)
599+
if !algorithm.pruneOverSizeLimit && age < algorithm.keepYoungerThan {
600+
glog.V(4).Infof("Image %q is younger than minimum pruning age, skipping (age=%v)", imageNode.Image.Name, age)
601+
return false
602+
}
603+
605604
for _, n := range g.To(imageNode) {
606605
glog.V(4).Infof("Examining predecessor %#v", n)
607606
if edgeKind(g, n, imageNode, ReferencedImageEdgeKind) {
@@ -615,14 +614,14 @@ func imageIsPrunable(g graph.Graph, imageNode *imagegraph.ImageNode) bool {
615614

616615
// calculatePrunableImages returns the list of prunable images and a
617616
// graph.NodeSet containing the image node IDs.
618-
func calculatePrunableImages(g graph.Graph, imageNodes []*imagegraph.ImageNode) ([]*imagegraph.ImageNode, graph.NodeSet) {
617+
func calculatePrunableImages(g graph.Graph, imageNodes []*imagegraph.ImageNode, algorithm pruneAlgorithm) ([]*imagegraph.ImageNode, graph.NodeSet) {
619618
prunable := []*imagegraph.ImageNode{}
620619
ids := make(graph.NodeSet)
621620

622621
for _, imageNode := range imageNodes {
623622
glog.V(4).Infof("Examining image %q", imageNode.Image.Name)
624623

625-
if imageIsPrunable(g, imageNode) {
624+
if imageIsPrunable(g, imageNode, algorithm) {
626625
glog.V(4).Infof("Image %q is prunable", imageNode.Image.Name)
627626
prunable = append(prunable, imageNode)
628627
ids.Add(imageNode.ID())
@@ -765,7 +764,7 @@ func (p *pruner) Prune(
765764
return nil
766765
}
767766

768-
prunableImageNodes, prunableImageIDs := calculatePrunableImages(p.g, imageNodes)
767+
prunableImageNodes, prunableImageIDs := calculatePrunableImages(p.g, imageNodes, p.algorithm)
769768

770769
errs := []error{}
771770
errs = append(errs, pruneStreams(p.g, prunableImageNodes, streamPruner)...)

pkg/image/prune/prune_test.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,14 @@ func TestImagePruning(t *testing.T) {
914914
},
915915
},
916916

917+
"layers shared with young images are not pruned": {
918+
images: imageList(
919+
agedImage("sha256:0000000000000000000000000000000000000000000000000000000000000001", registryHost+"/foo/bar@sha256:0000000000000000000000000000000000000000000000000000000000000001", 43200),
920+
agedImage("sha256:0000000000000000000000000000000000000000000000000000000000000002", registryHost+"/foo/bar@sha256:0000000000000000000000000000000000000000000000000000000000000002", 5),
921+
),
922+
expectedImageDeletions: []string{"sha256:0000000000000000000000000000000000000000000000000000000000000001"},
923+
},
924+
917925
"image exceeding limits": {
918926
pruneOverSizeLimit: newBool(true),
919927
images: imageList(
@@ -1378,7 +1386,7 @@ func TestImageIsPrunable(t *testing.T) {
13781386
g.AddEdge(streamNode, imageNode, ReferencedImageEdgeKind)
13791387
g.AddEdge(streamNode, imageNode, WeakReferencedImageEdgeKind)
13801388

1381-
if imageIsPrunable(g, imageNode.(*imagegraph.ImageNode)) {
1389+
if imageIsPrunable(g, imageNode.(*imagegraph.ImageNode), pruneAlgorithm{}) {
13821390
t.Fatalf("Image is prunable although it should not")
13831391
}
13841392
}

0 commit comments

Comments
 (0)