Skip to content

Commit edbf83e

Browse files
author
Per Goncalves da Silva
committed
another go
Signed-off-by: Per Goncalves da Silva <[email protected]>
1 parent 1efb9bf commit edbf83e

File tree

2 files changed

+48
-24
lines changed

2 files changed

+48
-24
lines changed

pkg/controller/operators/catalog/operator.go

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"k8s.io/client-go/util/retry"
89
"reflect"
910
"sort"
1011
"strings"
@@ -1477,25 +1478,30 @@ func (o *Operator) syncResolvingNamespace(obj interface{}) error {
14771478
o.removeSubsCond(subs, v1alpha1.SubscriptionResolutionFailed)
14781479

14791480
for _, updatedSub := range updatedSubs {
1480-
newSub := true
1481+
isNewSub := true
14811482
updatedSub.Status.RemoveConditions(v1alpha1.SubscriptionResolutionFailed)
14821483
for i, sub := range subs {
14831484
if sub.Name == updatedSub.Name && sub.Namespace == updatedSub.Namespace {
14841485
subs[i] = updatedSub
1485-
newSub = false
1486+
isNewSub = false
14861487
break
14871488
}
14881489
}
1489-
if newSub {
1490+
if isNewSub {
14901491
subs = append(subs, updatedSub)
1491-
continue
14921492
}
14931493
}
14941494

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+
// ******************************************************************************* //
14951501
// Update subscriptions with all changes so far
14961502
_, updateErr := o.updateSubscriptionStatuses(subs)
14971503
if updateErr != nil {
1498-
logger.WithError(updateErr).Warn("failed to update subscription conditions")
1504+
logger.WithField("irreconcilable-resolution", namespace).WithError(updateErr).Warn("failed to patch subscription conditions")
14991505
return updateErr
15001506
}
15011507

@@ -1675,7 +1681,7 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
16751681
return nil, nil
16761682
}
16771683

1678-
csvNames := []string{}
1684+
var csvNames []string
16791685
catalogSourceMap := map[string]struct{}{}
16801686
for _, s := range steps {
16811687
if s.Resource.Kind == "ClusterServiceVersion" {
@@ -1684,7 +1690,7 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
16841690
catalogSourceMap[s.Resource.CatalogSource] = struct{}{}
16851691
}
16861692

1687-
catalogSources := []string{}
1693+
var catalogSources []string
16881694
for s := range catalogSourceMap {
16891695
catalogSources = append(catalogSources, s)
16901696
}
@@ -1720,12 +1726,18 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
17201726
CatalogSources: catalogSources,
17211727
BundleLookups: bundleLookups,
17221728
}
1723-
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{})
17241735
if err != nil {
1736+
o.logger.WithField("irreconcilable-ip", res.GetName()).WithError(err).Warn("error updating installplan status after creation")
17251737
return nil, err
17261738
}
17271739

1728-
return reference.GetReference(res)
1740+
return reference.GetReference(newRes)
17291741
}
17301742

17311743
// setSubsCond will set the condition to the subscription if it doesn't already
@@ -1749,7 +1761,7 @@ func (o *Operator) setSubsCond(subs []*v1alpha1.Subscription, cond v1alpha1.Subs
17491761
return subList
17501762
}
17511763

1752-
// 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
17531765
func (o *Operator) removeSubsCond(subs []*v1alpha1.Subscription, condType v1alpha1.SubscriptionConditionType) {
17541766
lastUpdated := o.now()
17551767
for _, sub := range subs {
@@ -1775,7 +1787,19 @@ func (o *Operator) updateSubscriptionStatuses(subs []*v1alpha1.Subscription) ([]
17751787
wg.Add(1)
17761788
go func(sub *v1alpha1.Subscription) {
17771789
defer wg.Done()
1778-
if _, err := o.client.OperatorsV1alpha1().Subscriptions(sub.Namespace).UpdateStatus(context.TODO(), sub, updateOpts); err != nil {
1790+
1791+
update := func() error {
1792+
// Update the status of the latest revision
1793+
latest, err := o.client.OperatorsV1alpha1().Subscriptions(sub.GetNamespace()).Get(context.TODO(), sub.GetName(), getOpts)
1794+
if err != nil {
1795+
return err
1796+
}
1797+
latest.Status = sub.Status
1798+
*sub = *latest
1799+
_, err = o.client.OperatorsV1alpha1().Subscriptions(sub.Namespace).UpdateStatus(context.TODO(), latest, updateOpts)
1800+
return err
1801+
}
1802+
if err := retry.RetryOnConflict(retry.DefaultRetry, update); err != nil {
17791803
mu.Lock()
17801804
defer mu.Unlock()
17811805
errs = append(errs, err)

pkg/controller/registry/resolver/source_csvs.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,19 @@ func (s *csvSource) Snapshot(ctx context.Context) (*cache.Snapshot, error) {
9393
continue
9494
}
9595

96-
//if cachedSubscription, ok := csvSubscriptions[csv]; !ok || cachedSubscription == nil {
97-
// // we might be in an incoherent state, so let's check with live clients to make sure
98-
// realSubscriptions, err := s.listSubscriptions(ctx)
99-
// if err != nil {
100-
// return nil, fmt.Errorf("failed to list subscriptions: %w", err)
101-
// }
102-
// for _, realSubscription := range realSubscriptions.Items {
103-
// if realSubscription.Status.InstalledCSV == csv.Name {
104-
// // oops, live cluster state is coherent
105-
// return nil, fmt.Errorf("lister caches incoherent for CSV %s/%s - found owning Subscription %s/%s", csv.Namespace, csv.Name, realSubscription.Namespace, realSubscription.Name)
106-
// }
107-
// }
108-
//}
96+
if cachedSubscription, ok := csvSubscriptions[csv]; !ok || cachedSubscription == nil {
97+
// we might be in an incoherent state, so let's check with live clients to make sure
98+
realSubscriptions, err := s.listSubscriptions(ctx)
99+
if err != nil {
100+
return nil, fmt.Errorf("failed to list subscriptions: %w", err)
101+
}
102+
for _, realSubscription := range realSubscriptions.Items {
103+
if realSubscription.Status.InstalledCSV == csv.Name {
104+
// oops, live cluster state is coherent
105+
return nil, fmt.Errorf("lister caches incoherent for CSV %s/%s - found owning Subscription %s/%s", csv.Namespace, csv.Name, realSubscription.Namespace, realSubscription.Name)
106+
}
107+
}
108+
}
109109

110110
if failForwardEnabled {
111111
replacementChainEndsInFailure, err := isReplacementChainThatEndsInFailure(csv, ReplacementMapping(csvs))

0 commit comments

Comments
 (0)