Skip to content

Commit 7f6da18

Browse files
author
Jeff Peeler
committed
fix(catalog): re-install resources in existing installplan
This specifically fixes the scenario where a subscription is deleted and recreated in a namespace with an additional subscription. When the subscription of interest is deleted, the associated installplan remains due to the other subscription's owner reference. Because the existing installplan manifests match, no additional work is done. This is a problem if resources that were originally installed have been deleted. Now after a subscription is recreated, the proper owner references are re-added onto the install plan as well as all the resources are checked that they are installed.
1 parent d1be59c commit 7f6da18

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

pkg/controller/operators/catalog/operator.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,26 @@ func (o *Operator) ensureInstallPlan(logger *logrus.Entry, namespace string, sub
881881
for _, installPlan := range installPlans {
882882
if installPlan.Status.CSVManifestsMatch(steps) {
883883
logger.Infof("found InstallPlan with matching manifests: %s", installPlan.GetName())
884+
885+
ownerWasAdded := false
886+
for _, sub := range subs {
887+
ownerWasAdded = ownerWasAdded || !ownerutil.EnsureOwner(installPlan, sub)
888+
}
889+
if ownerWasAdded {
890+
_, err := o.client.OperatorsV1alpha1().InstallPlans(installPlan.GetNamespace()).Update(installPlan)
891+
if err != nil {
892+
return nil, err
893+
}
894+
}
895+
896+
installPlan.Status.Phase = v1alpha1.InstallPlanPhaseInstalling
897+
for _, step := range installPlan.Status.Plan {
898+
step.Status = v1alpha1.StepStatusUnknown
899+
}
900+
_, err = o.client.OperatorsV1alpha1().InstallPlans(namespace).UpdateStatus(installPlan)
901+
if err != nil {
902+
return nil, err
903+
}
884904
return reference.GetReference(installPlan)
885905
}
886906
}

pkg/controller/operators/catalog/subscriptions_test.go

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package catalog
33
import (
44
"context"
55
"fmt"
6+
"reflect"
67
"testing"
78
"time"
89

@@ -17,6 +18,7 @@ import (
1718
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver"
1819
"github.com/operator-framework/operator-lifecycle-manager/pkg/fakes"
1920
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/clientfake"
21+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
2022
)
2123

2224
func TestSyncSubscriptions(t *testing.T) {
@@ -638,6 +640,163 @@ func TestSyncSubscriptions(t *testing.T) {
638640
},
639641
},
640642
},
643+
{
644+
name: "Status/HaveCurrentCSV/SameManifests",
645+
fields: fields{
646+
clientOptions: []clientfake.Option{clientfake.WithSelfLinks(t)},
647+
existingOLMObjs: []runtime.Object{
648+
&v1alpha1.ClusterServiceVersion{
649+
ObjectMeta: metav1.ObjectMeta{
650+
Name: "csv.v.1",
651+
Namespace: testNamespace,
652+
},
653+
Status: v1alpha1.ClusterServiceVersionStatus{
654+
Phase: v1alpha1.CSVPhaseSucceeded,
655+
},
656+
},
657+
&v1alpha1.Subscription{
658+
ObjectMeta: metav1.ObjectMeta{
659+
Name: "sub",
660+
Namespace: testNamespace,
661+
},
662+
Spec: &v1alpha1.SubscriptionSpec{
663+
CatalogSource: "src",
664+
CatalogSourceNamespace: testNamespace,
665+
},
666+
Status: v1alpha1.SubscriptionStatus{
667+
CurrentCSV: "",
668+
State: "",
669+
},
670+
},
671+
&v1alpha1.InstallPlan{
672+
ObjectMeta: metav1.ObjectMeta{
673+
Name: "install-ip123",
674+
Namespace: testNamespace,
675+
SelfLink: fmt.Sprintf("/apis/%s/namespaces/%s/%s/%s", v1alpha1.SchemeGroupVersion.String(), "installplans", testNamespace, "install-ip123"),
676+
},
677+
Spec: v1alpha1.InstallPlanSpec{
678+
ClusterServiceVersionNames: []string{
679+
"csv.v.1",
680+
},
681+
Approval: v1alpha1.ApprovalAutomatic,
682+
Approved: true,
683+
},
684+
Status: v1alpha1.InstallPlanStatus{
685+
Phase: v1alpha1.InstallPlanPhaseComplete,
686+
CatalogSources: []string{
687+
"src",
688+
},
689+
Plan: []*v1alpha1.Step{
690+
{
691+
Resolving: "csv.v.1",
692+
Resource: v1alpha1.StepResource{
693+
CatalogSource: "src",
694+
CatalogSourceNamespace: testNamespace,
695+
Group: v1alpha1.GroupName,
696+
Version: v1alpha1.GroupVersion,
697+
Kind: v1alpha1.ClusterServiceVersionKind,
698+
Name: "csv.v.1",
699+
Manifest: "{}",
700+
},
701+
},
702+
},
703+
},
704+
},
705+
},
706+
resolveSteps: []*v1alpha1.Step{
707+
{
708+
Resolving: "csv.v.1",
709+
Resource: v1alpha1.StepResource{
710+
CatalogSource: "src",
711+
CatalogSourceNamespace: testNamespace,
712+
Group: v1alpha1.GroupName,
713+
Version: v1alpha1.GroupVersion,
714+
Kind: v1alpha1.ClusterServiceVersionKind,
715+
Name: "csv.v.1",
716+
Manifest: "{}",
717+
},
718+
},
719+
},
720+
resolveSubs: []*v1alpha1.Subscription{
721+
{
722+
TypeMeta: metav1.TypeMeta{
723+
Kind: v1alpha1.SubscriptionKind,
724+
APIVersion: v1alpha1.SubscriptionCRDAPIVersion,
725+
},
726+
ObjectMeta: metav1.ObjectMeta{
727+
Name: "sub",
728+
Namespace: testNamespace,
729+
},
730+
Spec: &v1alpha1.SubscriptionSpec{
731+
CatalogSource: "src",
732+
CatalogSourceNamespace: testNamespace,
733+
},
734+
Status: v1alpha1.SubscriptionStatus{
735+
CurrentCSV: "csv.v.1",
736+
State: "SubscriptionStateAtLatest",
737+
},
738+
},
739+
},
740+
},
741+
args: args{
742+
obj: &v1alpha1.Subscription{
743+
ObjectMeta: metav1.ObjectMeta{
744+
Name: "sub",
745+
Namespace: testNamespace,
746+
},
747+
Spec: &v1alpha1.SubscriptionSpec{
748+
CatalogSource: "src",
749+
CatalogSourceNamespace: testNamespace,
750+
},
751+
Status: v1alpha1.SubscriptionStatus{
752+
CurrentCSV: "",
753+
State: "",
754+
},
755+
},
756+
},
757+
wantInstallPlan: &v1alpha1.InstallPlan{
758+
ObjectMeta: metav1.ObjectMeta{
759+
Name: "install-ip123",
760+
Namespace: testNamespace,
761+
SelfLink: fmt.Sprintf("/apis/%s/namespaces/%s/%s/%s", v1alpha1.SchemeGroupVersion.String(), "installplans", testNamespace, "install-ip123"),
762+
OwnerReferences: []metav1.OwnerReference{{
763+
APIVersion: v1alpha1.SubscriptionCRDAPIVersion,
764+
Kind: v1alpha1.SubscriptionKind,
765+
Name: "sub",
766+
Controller: &ownerutil.NotController,
767+
BlockOwnerDeletion: &ownerutil.DontBlockOwnerDeletion,
768+
}},
769+
},
770+
Spec: v1alpha1.InstallPlanSpec{
771+
ClusterServiceVersionNames: []string{
772+
"csv.v.1",
773+
},
774+
Approval: v1alpha1.ApprovalAutomatic,
775+
Approved: true,
776+
},
777+
Status: v1alpha1.InstallPlanStatus{
778+
Phase: v1alpha1.InstallPlanPhaseInstalling,
779+
CatalogSources: []string{
780+
"src",
781+
},
782+
Plan: []*v1alpha1.Step{
783+
{
784+
Resolving: "csv.v.1",
785+
Resource: v1alpha1.StepResource{
786+
CatalogSource: "src",
787+
CatalogSourceNamespace: testNamespace,
788+
Group: v1alpha1.GroupName,
789+
Version: v1alpha1.GroupVersion,
790+
Kind: v1alpha1.ClusterServiceVersionKind,
791+
Name: "csv.v.1",
792+
Manifest: "{}",
793+
},
794+
Status: v1alpha1.StepStatusUnknown,
795+
},
796+
},
797+
},
798+
},
799+
},
641800
}
642801
for _, tt := range tests {
643802
t.Run(tt.name, func(t *testing.T) {
@@ -686,6 +845,9 @@ func TestSyncSubscriptions(t *testing.T) {
686845
require.NoError(t, err)
687846
require.Equal(t, 1, len(installPlans.Items))
688847
ip := installPlans.Items[0]
848+
if (!reflect.DeepEqual(tt.wantInstallPlan.ObjectMeta, metav1.ObjectMeta{})) {
849+
require.Equal(t, tt.wantInstallPlan.ObjectMeta, ip.ObjectMeta)
850+
}
689851
require.Equal(t, tt.wantInstallPlan.Spec, ip.Spec)
690852
require.Equal(t, tt.wantInstallPlan.Status, ip.Status)
691853
}

0 commit comments

Comments
 (0)