Skip to content

Commit 125ebce

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

File tree

1 file changed

+71
-5
lines changed

1 file changed

+71
-5
lines changed

pkg/controller/operators/catalog/operator.go

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"k8s.io/apimachinery/pkg/types"
89
"reflect"
910
"sort"
1011
"strings"
@@ -1492,10 +1493,16 @@ func (o *Operator) syncResolvingNamespace(obj interface{}) error {
14921493
}
14931494
}
14941495

1496+
// ************************************************ WARNING ************************************************* //
1497+
// if updateSubscriptionStatuses call fails and the IP reference was changed in this run, //
1498+
// we'll be screwed because the IP would have been created but the subscription won't carry its reference. //
1499+
// And if the CSV gets created by the IP, it won't be associated with the Subscription //
1500+
// -> perma-failure on resolution //
1501+
// ********************************************************************************************************** //
14951502
// Update subscriptions with all changes so far
1496-
_, updateErr := o.updateSubscriptionStatuses(subs)
1503+
_, updateErr := o.patchSubscriptionStatuses(subs)
14971504
if updateErr != nil {
1498-
logger.WithError(updateErr).Warn("failed to update subscription conditions")
1505+
logger.WithError(updateErr).Warn("failed to patch subscription conditions")
14991506
return updateErr
15001507
}
15011508

@@ -1667,15 +1674,23 @@ func (o *Operator) ensureInstallPlan(logger *logrus.Entry, namespace string, gen
16671674
}
16681675
logger.Warn("no installplan found with matching generation, creating new one")
16691676

1670-
return o.createInstallPlan(namespace, gen, subs, installPlanApproval, steps, bundleLookups)
1677+
// **************************** WARNING **************************** //
1678+
// If this call fails, after the IP is created, the IP will never
1679+
// do anything since it requires the steps to exist in .status
1680+
// ***************************************************************** //
1681+
ip, err := o.createInstallPlan(namespace, gen, subs, installPlanApproval, steps, bundleLookups)
1682+
if err != nil {
1683+
return nil, err
1684+
}
1685+
return reference.GetReference(ip)
16711686
}
16721687

16731688
func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1.Subscription, installPlanApproval v1alpha1.Approval, steps []*v1alpha1.Step, bundleLookups []v1alpha1.BundleLookup) (*corev1.ObjectReference, error) {
16741689
if len(steps) == 0 && len(bundleLookups) == 0 {
16751690
return nil, nil
16761691
}
16771692

1678-
csvNames := []string{}
1693+
var csvNames []string
16791694
catalogSourceMap := map[string]struct{}{}
16801695
for _, s := range steps {
16811696
if s.Resource.Kind == "ClusterServiceVersion" {
@@ -1684,7 +1699,7 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
16841699
catalogSourceMap[s.Resource.CatalogSource] = struct{}{}
16851700
}
16861701

1687-
catalogSources := []string{}
1702+
var catalogSources []string
16881703
for s := range catalogSourceMap {
16891704
catalogSources = append(catalogSources, s)
16901705
}
@@ -1720,6 +1735,7 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
17201735
CatalogSources: catalogSources,
17211736
BundleLookups: bundleLookups,
17221737
}
1738+
17231739
res, err = o.client.OperatorsV1alpha1().InstallPlans(namespace).UpdateStatus(context.TODO(), res, metav1.UpdateOptions{})
17241740
if err != nil {
17251741
return nil, err
@@ -1763,6 +1779,56 @@ func (o *Operator) removeSubsCond(subs []*v1alpha1.Subscription, condType v1alph
17631779
}
17641780
}
17651781

1782+
func (o *Operator) patchSubscriptionStatuses(subs []*v1alpha1.Subscription) ([]*v1alpha1.Subscription, error) {
1783+
var (
1784+
errs []error
1785+
mu sync.Mutex
1786+
wg sync.WaitGroup
1787+
patchOpts = metav1.PatchOptions{}
1788+
)
1789+
1790+
lastUpdated := o.now()
1791+
1792+
for _, sub := range subs {
1793+
wg.Add(1)
1794+
go func(sub *v1alpha1.Subscription) {
1795+
defer wg.Done()
1796+
1797+
patch := map[string]interface{}{
1798+
"status": map[string]interface{}{
1799+
"conditions": sub.Status.Conditions,
1800+
"currentCSV": sub.Status.CurrentCSV,
1801+
"installPlanRef": sub.Status.InstallPlanRef,
1802+
"installPlan": sub.Status.Install,
1803+
"installPlanGeneration": sub.Status.InstallPlanGeneration,
1804+
"lastUpdated": lastUpdated,
1805+
},
1806+
}
1807+
1808+
patchBytes, err := json.Marshal(patch)
1809+
if err != nil {
1810+
errs = append(errs, err)
1811+
return
1812+
}
1813+
1814+
if _, err := o.client.OperatorsV1alpha1().Subscriptions(sub.Namespace).Patch(
1815+
context.TODO(),
1816+
sub.GetName(),
1817+
types.MergePatchType,
1818+
patchBytes,
1819+
patchOpts,
1820+
"status",
1821+
); err != nil {
1822+
mu.Lock()
1823+
defer mu.Unlock()
1824+
errs = append(errs, err)
1825+
}
1826+
}(sub)
1827+
}
1828+
wg.Wait()
1829+
return subs, utilerrors.NewAggregate(errs)
1830+
}
1831+
17661832
func (o *Operator) updateSubscriptionStatuses(subs []*v1alpha1.Subscription) ([]*v1alpha1.Subscription, error) {
17671833
var (
17681834
errs []error

0 commit comments

Comments
 (0)