@@ -130,6 +130,7 @@ type Operator struct {
130130 clientFactory clients.Factory
131131 muInstallPlan sync.Mutex
132132 resolverSourceProvider * resolver.RegistrySourceProvider
133+ resolverMu sync.Mutex
133134}
134135
135136type CatalogSourceSyncFunc func (logger * logrus.Entry , in * v1alpha1.CatalogSource ) (out * v1alpha1.CatalogSource , continueSync bool , syncError error )
@@ -213,6 +214,7 @@ func NewOperator(ctx context.Context, kubeconfigPath string, clock utilclock.Clo
213214 installPlanTimeout : installPlanTimeout ,
214215 bundleUnpackTimeout : bundleUnpackTimeout ,
215216 clientFactory : clients .NewFactory (validatingConfig ),
217+ resolverMu : sync.Mutex {},
216218 }
217219 op .sources = grpc .NewSourceStore (logger , 10 * time .Second , 10 * time .Minute , op .syncSourceState )
218220 op .resolverSourceProvider = resolver .SourceProviderFromRegistryClientProvider (op .sources , lister .OperatorsV1alpha1 ().CatalogSourceLister (), logger )
@@ -1206,6 +1208,9 @@ func (o *Operator) syncCatalogSources(obj interface{}) (syncError error) {
12061208}
12071209
12081210func (o * Operator ) syncResolvingNamespace (obj interface {}) error {
1211+ o .resolverMu .Lock ()
1212+ defer o .resolverMu .Unlock ()
1213+
12091214 ns , ok := obj .(* corev1.Namespace )
12101215 if ! ok {
12111216 o .logger .Infof ("wrong type: %#v" , obj )
@@ -1472,27 +1477,31 @@ func (o *Operator) syncResolvingNamespace(obj interface{}) error {
14721477 // Remove resolutionfailed condition from subscriptions
14731478 o .removeSubsCond (subs , v1alpha1 .SubscriptionResolutionFailed )
14741479
1475- newSub := true
14761480 for _ , updatedSub := range updatedSubs {
1481+ isNewSub := true
14771482 updatedSub .Status .RemoveConditions (v1alpha1 .SubscriptionResolutionFailed )
14781483 for i , sub := range subs {
14791484 if sub .Name == updatedSub .Name && sub .Namespace == updatedSub .Namespace {
14801485 subs [i ] = updatedSub
1481- newSub = false
1486+ isNewSub = false
14821487 break
14831488 }
14841489 }
1485- if newSub {
1490+ if isNewSub {
14861491 subs = append (subs , updatedSub )
1487- continue
14881492 }
1489- newSub = true
14901493 }
14911494
1495+ // *********************************** WARNING *********************************** //
1496+ // if updateSubscriptionStatuses call fails and the IP reference was changed //
1497+ // in this run, we'll be screwed because the IP would have been created but the //
1498+ // subscription won't carry its reference. And, if the CSV gets created by the IP, //
1499+ // it won't be associated with the Subscription -> perma-failure on resolution //
1500+ // ******************************************************************************* //
14921501 // Update subscriptions with all changes so far
14931502 _ , updateErr := o .updateSubscriptionStatuses (subs )
14941503 if updateErr != nil {
1495- logger .WithError (updateErr ).Warn ("failed to update subscription conditions" )
1504+ logger .WithField ( "irreconcilable-resolution" , namespace ). WithError (updateErr ).Warn ("failed to patch subscription conditions" )
14961505 return updateErr
14971506 }
14981507
@@ -1672,7 +1681,7 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
16721681 return nil , nil
16731682 }
16741683
1675- csvNames := []string {}
1684+ var csvNames []string
16761685 catalogSourceMap := map [string ]struct {}{}
16771686 for _ , s := range steps {
16781687 if s .Resource .Kind == "ClusterServiceVersion" {
@@ -1681,7 +1690,7 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
16811690 catalogSourceMap [s .Resource .CatalogSource ] = struct {}{}
16821691 }
16831692
1684- catalogSources := []string {}
1693+ var catalogSources []string
16851694 for s := range catalogSourceMap {
16861695 catalogSources = append (catalogSources , s )
16871696 }
@@ -1717,12 +1726,18 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
17171726 CatalogSources : catalogSources ,
17181727 BundleLookups : bundleLookups ,
17191728 }
1720- res , err = o .client .OperatorsV1alpha1 ().InstallPlans (namespace ).UpdateStatus (context .TODO (), res , metav1.UpdateOptions {})
1729+
1730+ // *************************** WARNING *************************** //
1731+ // If this call fails, the IP will never do anything since it //
1732+ // requires the steps to exist in .status //
1733+ // *************************************************************** //
1734+ newRes , err := o .client .OperatorsV1alpha1 ().InstallPlans (namespace ).UpdateStatus (context .TODO (), res , metav1.UpdateOptions {})
17211735 if err != nil {
1736+ o .logger .WithField ("irreconcilable-ip" , res .GetName ()).WithError (err ).Warn ("error updating installplan status after creation" )
17221737 return nil , err
17231738 }
17241739
1725- return reference .GetReference (res )
1740+ return reference .GetReference (newRes )
17261741}
17271742
17281743// setSubsCond will set the condition to the subscription if it doesn't already
@@ -1746,7 +1761,7 @@ func (o *Operator) setSubsCond(subs []*v1alpha1.Subscription, cond v1alpha1.Subs
17461761 return subList
17471762}
17481763
1749- // removeSubsCond removes the given condition from all of the subscriptions in the input
1764+ // removeSubsCond removes the given condition from all the subscriptions in the input
17501765func (o * Operator ) removeSubsCond (subs []* v1alpha1.Subscription , condType v1alpha1.SubscriptionConditionType ) {
17511766 lastUpdated := o .now ()
17521767 for _ , sub := range subs {
0 commit comments