@@ -57,7 +57,7 @@ const (
57
57
// pruneAlgorithm contains the various settings to use when evaluating images
58
58
// and layers for pruning.
59
59
type pruneAlgorithm struct {
60
- keepYoungerThan time.Duration
60
+ keepYoungerThan time.Time
61
61
keepTagRevisions int
62
62
pruneOverSizeLimit bool
63
63
namespace string
@@ -217,7 +217,7 @@ func NewPruner(options PrunerOptions) (Pruner, error) {
217
217
218
218
algorithm := pruneAlgorithm {}
219
219
if options .KeepYoungerThan != nil {
220
- algorithm .keepYoungerThan = * options .KeepYoungerThan
220
+ algorithm .keepYoungerThan = metav1 . Now (). Add ( - * options .KeepYoungerThan )
221
221
}
222
222
if options .KeepTagRevisions != nil {
223
223
algorithm .keepTagRevisions = * options .KeepTagRevisions
@@ -307,8 +307,7 @@ func addImageStreamsToGraph(g graph.Graph, streams *imageapi.ImageStreamList, li
307
307
// use a weak reference for old image revisions by default
308
308
oldImageRevisionReferenceKind := WeakReferencedImageEdgeKind
309
309
310
- age := metav1 .Now ().Sub (stream .CreationTimestamp .Time )
311
- if ! algorithm .pruneOverSizeLimit && age < algorithm .keepYoungerThan {
310
+ if ! algorithm .pruneOverSizeLimit && stream .CreationTimestamp .Time .After (algorithm .keepYoungerThan ) {
312
311
// stream's age is below threshold - use a strong reference for old image revisions instead
313
312
oldImageRevisionReferenceKind = ReferencedImageEdgeKind
314
313
}
@@ -415,9 +414,8 @@ func addPodsToGraph(g graph.Graph, pods *kapi.PodList, algorithm pruneAlgorithm)
415
414
// pending or running. Additionally, it has to be at least as old as the minimum
416
415
// age threshold defined by the algorithm.
417
416
if pod .Status .Phase != kapi .PodRunning && pod .Status .Phase != kapi .PodPending {
418
- age := metav1 .Now ().Sub (pod .CreationTimestamp .Time )
419
- if age >= algorithm .keepYoungerThan {
420
- glog .V (4 ).Infof ("Pod %s is not running nor pending and age exceeds keepYoungerThan (%v) - skipping" , getName (pod ), age )
417
+ if ! pod .CreationTimestamp .Time .After (algorithm .keepYoungerThan ) {
418
+ glog .V (4 ).Infof ("Pod %s is neither running nor pending and is too old" , getName (pod ))
421
419
continue
422
420
}
423
421
}
@@ -598,9 +596,8 @@ func imageIsPrunable(g graph.Graph, imageNode *imagegraph.ImageNode, algorithm p
598
596
}
599
597
}
600
598
601
- age := metav1 .Now ().Sub (imageNode .Image .CreationTimestamp .Time )
602
- if ! algorithm .pruneOverSizeLimit && age < algorithm .keepYoungerThan {
603
- glog .V (4 ).Infof ("Image %q is younger than minimum pruning age, skipping (age=%v)" , imageNode .Image .Name , age )
599
+ if ! algorithm .pruneOverSizeLimit && imageNode .Image .CreationTimestamp .Time .After (algorithm .keepYoungerThan ) {
600
+ glog .V (4 ).Infof ("Image %q is younger than minimum pruning age" , imageNode .Image .Name )
604
601
return false
605
602
}
606
603
@@ -690,23 +687,15 @@ func pruneStreams(
690
687
g graph.Graph ,
691
688
prunableImageNodes map [string ]* imagegraph.ImageNode ,
692
689
streamPruner ImageStreamDeleter ,
690
+ keepYoungerThan time.Time ,
693
691
) error {
694
- prunableStreams := make (map [string ]* imagegraph.ImageStreamNode )
695
-
696
692
glog .V (4 ).Infof ("Removing pruned image references from streams" )
697
- for _ , imageNode := range prunableImageNodes {
698
- for _ , n := range g .To (imageNode ) {
699
- streamNode , ok := n .(* imagegraph.ImageStreamNode )
700
- if ! ok {
701
- continue
702
- }
703
-
704
- streamName := getName (streamNode .ImageStream )
705
- prunableStreams [streamName ] = streamNode
693
+ for _ , node := range g .Nodes () {
694
+ streamNode , ok := node .(* imagegraph.ImageStreamNode )
695
+ if ! ok {
696
+ continue
706
697
}
707
- }
708
-
709
- for streamName , streamNode := range prunableStreams {
698
+ streamName := getName (streamNode .ImageStream )
710
699
err := retry .RetryOnConflict (retry .DefaultRetry , func () error {
711
700
stream , err := streamPruner .GetImageStream (streamNode .ImageStream )
712
701
if err != nil {
@@ -720,26 +709,11 @@ func pruneStreams(
720
709
updatedTags := sets .NewString ()
721
710
deletedTags := sets .NewString ()
722
711
723
- for tag , history := range stream .Status .Tags {
724
- newHistory := imageapi.TagEventList {}
725
- for i , tagEvent := range history .Items {
726
- glog .V (4 ).Infof ("Checking tag event %d with image %q" , i , tagEvent .Image )
727
-
728
- if _ , ok := prunableImageNodes [tagEvent .Image ]; ok {
729
- glog .V (4 ).Infof ("Image stream tag %s:%s revision %d - removing because image %q matches deleted image" , streamName , tag , i , tagEvent .Image )
730
- updatedTags .Insert (tag )
731
- } else {
732
- glog .V (4 ).Infof ("Image stream tag %s:%s revision %d - keeping because image %q is not deleted" , streamName , tag , i , tagEvent .Image )
733
- newHistory .Items = append (newHistory .Items , tagEvent )
734
- }
735
- }
736
-
737
- if len (newHistory .Items ) == 0 {
738
- glog .V (4 ).Infof ("Image stream tag %s:%s - removing empty tag" , streamName , tag )
739
- delete (stream .Status .Tags , tag )
712
+ for tag := range stream .Status .Tags {
713
+ if updated , deleted := pruneISTagHistory (g , prunableImageNodes , keepYoungerThan , streamName , stream , tag ); deleted {
740
714
deletedTags .Insert (tag )
741
- } else {
742
- stream . Status . Tags [ tag ] = newHistory
715
+ } else if updated {
716
+ updatedTags . Insert ( tag )
743
717
}
744
718
}
745
719
@@ -770,6 +744,65 @@ func pruneStreams(
770
744
return nil
771
745
}
772
746
747
+ // pruneISTagHistory processes tag event list of the given image stream tag. It removes references to images
748
+ // that are going to be removed or are missing in the graph.
749
+ func pruneISTagHistory (
750
+ g graph.Graph ,
751
+ prunableImageNodes map [string ]* imagegraph.ImageNode ,
752
+ keepYoungerThan time.Time ,
753
+ streamName string ,
754
+ imageStream * imageapi.ImageStream ,
755
+ tag string ,
756
+ ) (tagUpdated , tagDeleted bool ) {
757
+ history := imageStream .Status .Tags [tag ]
758
+ newHistory := imageapi.TagEventList {}
759
+
760
+ for i , tagEvent := range history .Items {
761
+ glog .V (4 ).Infof ("Checking tag event %d with image %q" , i , tagEvent .Image )
762
+
763
+ if ok , reason := tagEventIsPrunable (tagEvent , g , prunableImageNodes , keepYoungerThan ); ok {
764
+ glog .V (4 ).Infof ("Image stream tag %s:%s revision %d - removing because %s" , streamName , tag , i , reason )
765
+ tagUpdated = true
766
+ } else {
767
+ glog .V (4 ).Infof ("Image stream tag %s:%s revision %d - keeping because %s" , streamName , tag , i , reason )
768
+ newHistory .Items = append (newHistory .Items , tagEvent )
769
+ }
770
+ }
771
+
772
+ if len (newHistory .Items ) == 0 {
773
+ glog .V (4 ).Infof ("Image stream tag %s:%s - removing empty tag" , streamName , tag )
774
+ delete (imageStream .Status .Tags , tag )
775
+ tagDeleted = true
776
+ tagUpdated = false
777
+ } else if tagUpdated {
778
+ imageStream .Status .Tags [tag ] = newHistory
779
+ }
780
+
781
+ return
782
+ }
783
+
784
+ func tagEventIsPrunable (
785
+ tagEvent imageapi.TagEvent ,
786
+ g graph.Graph ,
787
+ prunableImageNodes map [string ]* imagegraph.ImageNode ,
788
+ keepYoungerThan time.Time ,
789
+ ) (ok bool , reason string ) {
790
+ if _ , ok := prunableImageNodes [tagEvent .Image ]; ok {
791
+ return true , fmt .Sprintf ("image %q matches deleted image" , tagEvent .Image )
792
+ }
793
+
794
+ n := imagegraph .FindImage (g , tagEvent .Image )
795
+ if n != nil {
796
+ return false , fmt .Sprintf ("image %q is not deleted" , tagEvent .Image )
797
+ }
798
+
799
+ if n == nil && ! tagEvent .Created .After (keepYoungerThan ) {
800
+ return true , fmt .Sprintf ("image %q is absent" , tagEvent .Image )
801
+ }
802
+
803
+ return false , "the tag event is younger than threshold"
804
+ }
805
+
773
806
// pruneImages invokes imagePruner.DeleteImage with each image that is prunable.
774
807
func pruneImages (g graph.Graph , imageNodes map [string ]* imagegraph.ImageNode , imagePruner ImageDeleter ) []error {
775
808
errs := []error {}
@@ -802,7 +835,7 @@ func (p *pruner) Prune(
802
835
803
836
prunableImageNodes , prunableImageIDs := calculatePrunableImages (p .g , imageNodes , p .algorithm )
804
837
805
- err := pruneStreams (p .g , prunableImageNodes , streamPruner )
838
+ err := pruneStreams (p .g , prunableImageNodes , streamPruner , p . algorithm . keepYoungerThan )
806
839
// if namespace is specified prune only ImageStreams and nothing more
807
840
// if we have any errors after ImageStreams pruning this may mean that
808
841
// we still have references to images.
0 commit comments