@@ -58,6 +58,7 @@ type Operator struct {
5858 lister operatorlister.OperatorLister
5959 recorder record.EventRecorder
6060 copyQueueIndexer * queueinformer.QueueIndexer
61+ gcQueueIndexer * queueinformer.QueueIndexer
6162}
6263
6364func NewOperator (logger * logrus.Logger , crClient versioned.Interface , opClient operatorclient.ClientInterface , strategyResolver install.StrategyResolverInterface , wakeupInterval time.Duration , namespaces []string ) (* Operator , error ) {
@@ -261,6 +262,12 @@ func NewOperator(logger *logrus.Logger, crClient versioned.Interface, opClient o
261262 op .RegisterQueueIndexer (csvQueueIndexer )
262263 op .copyQueueIndexer = csvQueueIndexer
263264
265+ // Register separate queue for copying csvs
266+ csvGCQueue := workqueue .NewNamedRateLimitingQueue (workqueue .DefaultControllerRateLimiter (), "csvGC" )
267+ csvGCQueueIndexer := queueinformer .NewQueueIndexer (csvGCQueue , csvIndexes , op .syncGcCsv , "csvGC" , logger , metrics .NewMetricsNil ())
268+ op .RegisterQueueIndexer (csvGCQueueIndexer )
269+ op .gcQueueIndexer = csvGCQueueIndexer
270+
264271 // Set up watch on deployments
265272 depHandlers := & cache.ResourceEventHandlerFuncs {
266273 // TODO: pass closure that forgets queue item after calling custom deletion handler.
@@ -435,7 +442,7 @@ func (a *Operator) handleClusterServiceVersionDeletion(obj interface{}) {
435442 for _ , namespace := range namespaces {
436443 if namespace != operatorNamespace {
437444 logger .WithField ("targetNamespace" , namespace ).Debug ("requeueing child csv for deletion" )
438- a .csvQueueSet . Requeue ( clusterServiceVersion . GetName () , namespace )
445+ a .gcQueueIndexer . Add ( fmt . Sprintf ( "%s/%s" , namespace , clusterServiceVersion . GetName ()) )
439446 }
440447 }
441448
@@ -478,33 +485,34 @@ func (a *Operator) removeDanglingChildCSVs(csv *v1alpha1.ClusterServiceVersion)
478485 operatorNamespace , ok := csv .Annotations [v1alpha2 .OperatorGroupNamespaceAnnotationKey ]
479486 if ! ok {
480487 logger .Debug ("missing operator namespace annotation on copied CSV" )
481- return a .deleteChild (csv )
488+ return a .deleteChild (csv , logger )
482489 }
483490
484491 logger = logger .WithField ("parentNamespace" , operatorNamespace )
485492 parent , err := a .lister .OperatorsV1alpha1 ().ClusterServiceVersionLister ().ClusterServiceVersions (operatorNamespace ).Get (csv .GetName ())
486493 if k8serrors .IsNotFound (err ) || k8serrors .IsGone (err ) || parent == nil {
487494 logger .Debug ("deleting copied CSV since parent is missing" )
488- return a .deleteChild (csv )
495+ return a .deleteChild (csv , logger )
489496 }
490497
491498 if parent .Status .Phase == v1alpha1 .CSVPhaseFailed && parent .Status .Reason == v1alpha1 .CSVReasonInterOperatorGroupOwnerConflict {
492499 logger .Debug ("deleting copied CSV since parent has intersecting operatorgroup conflict" )
493- return a .deleteChild (csv )
500+ return a .deleteChild (csv , logger )
494501 }
495502
496503 if annotations := parent .GetAnnotations (); annotations != nil {
497504 if ! resolver .NewNamespaceSetFromString (annotations [v1alpha2 .OperatorGroupTargetsAnnotationKey ]).Contains (csv .GetNamespace ()) {
498505 logger .WithField ("parentTargets" , annotations [v1alpha2 .OperatorGroupTargetsAnnotationKey ]).
499506 Debug ("deleting copied CSV since parent no longer lists this as a target namespace" )
500- return a .deleteChild (csv )
507+ return a .deleteChild (csv , logger )
501508 }
502509 }
503510
504511 return nil
505512}
506513
507- func (a * Operator ) deleteChild (csv * v1alpha1.ClusterServiceVersion ) error {
514+ func (a * Operator ) deleteChild (csv * v1alpha1.ClusterServiceVersion , logger * logrus.Entry ) error {
515+ logger .Debug ("gcing csv" )
508516 return a .client .OperatorsV1alpha1 ().ClusterServiceVersions (csv .GetNamespace ()).Delete (csv .GetName (), & metav1.DeleteOptions {})
509517}
510518
@@ -609,6 +617,19 @@ func (a *Operator) syncCopyCSV(obj interface{}) (syncError error) {
609617 return
610618}
611619
620+ func (a * Operator ) syncGcCsv (obj interface {}) (syncError error ) {
621+ clusterServiceVersion , ok := obj .(* v1alpha1.ClusterServiceVersion )
622+ if ! ok {
623+ a .Log .Debugf ("wrong type: %#v" , obj )
624+ return fmt .Errorf ("casting ClusterServiceVersion failed" )
625+ }
626+ if clusterServiceVersion .IsCopied () {
627+ syncError = a .removeDanglingChildCSVs (clusterServiceVersion )
628+ return
629+ }
630+ return
631+ }
632+
612633// operatorGroupFromAnnotations returns the OperatorGroup for the CSV only if the CSV is active one in the group
613634func (a * Operator ) operatorGroupFromAnnotations (logger * logrus.Entry , csv * v1alpha1.ClusterServiceVersion ) * v1alpha2.OperatorGroup {
614635 annotations := csv .GetAnnotations ()
@@ -712,8 +733,8 @@ func (a *Operator) transitionCSVState(in v1alpha1.ClusterServiceVersion) (out *v
712733 now := timeNow ()
713734
714735 if out .IsCopied () {
715- logger .Debug ("skipping copied csv transition" )
716- syncError = a . removeDanglingChildCSVs (out )
736+ logger .Debug ("skipping copied csv transition, schedule for gc check " )
737+ a . gcQueueIndexer . Enqueue (out )
717738 return
718739 }
719740
0 commit comments