Skip to content

Commit 586a673

Browse files
Merge pull request #1059 from dinhxuanvu/installplan-approval
Bug 1758008: Manual approval strategy ignored for subsequent releases
2 parents 4cb99da + 738cd76 commit 586a673

File tree

2 files changed

+129
-5
lines changed

2 files changed

+129
-5
lines changed

pkg/controller/operators/catalog/operator.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -928,22 +928,30 @@ func (o *Operator) ensureInstallPlan(logger *logrus.Entry, namespace string, sub
928928
for _, sub := range subs {
929929
ownerWasAdded = ownerWasAdded || !ownerutil.EnsureOwner(installPlan, sub)
930930
}
931+
932+
out := installPlan.DeepCopy()
931933
if ownerWasAdded {
932-
_, err := o.client.OperatorsV1alpha1().InstallPlans(installPlan.GetNamespace()).Update(installPlan)
934+
out, err = o.client.OperatorsV1alpha1().InstallPlans(installPlan.GetNamespace()).Update(installPlan)
933935
if err != nil {
934936
return nil, err
935937
}
936938
}
937939

938-
installPlan.Status.Phase = v1alpha1.InstallPlanPhaseInstalling
939-
for _, step := range installPlan.Status.Plan {
940+
// Use provided `installPlanApproval` to determine the appropreciate
941+
// phase
942+
if installPlanApproval == v1alpha1.ApprovalAutomatic {
943+
out.Status.Phase = v1alpha1.InstallPlanPhaseInstalling
944+
} else {
945+
out.Status.Phase = v1alpha1.InstallPlanPhaseRequiresApproval
946+
}
947+
for _, step := range out.Status.Plan {
940948
step.Status = v1alpha1.StepStatusUnknown
941949
}
942-
_, err = o.client.OperatorsV1alpha1().InstallPlans(namespace).UpdateStatus(installPlan)
950+
res, err := o.client.OperatorsV1alpha1().InstallPlans(namespace).UpdateStatus(out)
943951
if err != nil {
944952
return nil, err
945953
}
946-
return reference.GetReference(installPlan)
954+
return reference.GetReference(res)
947955
}
948956
}
949957
logger.Warn("no installplan found with matching manifests, creating new one")

test/e2e/subscription_e2e_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,122 @@ func TestSubscriptionUpdatesMultipleIntermediates(t *testing.T) {
871871
// TODO: check installplans, subscription status, etc
872872
}
873873

874+
// TestSubscriptionUpdatesExistingInstallPlan ensures that an existing InstallPlan
875+
// has the appropriate approval requirement from Subscription.
876+
func TestSubscriptionUpdatesExistingInstallPlan(t *testing.T) {
877+
defer cleaner.NotifyTestComplete(t, true)
878+
879+
// Create CSV
880+
packageName := genName("nginx-")
881+
stableChannel := "stable"
882+
883+
namedStrategy := newNginxInstallStrategy(genName("dep-"), nil, nil)
884+
csvA := newCSV("nginx-a", testNamespace, "", semver.MustParse("0.1.0"), nil, nil, namedStrategy)
885+
csvB := newCSV("nginx-b", testNamespace, "nginx-a", semver.MustParse("0.2.0"), nil, nil, namedStrategy)
886+
887+
// Create PackageManifests
888+
manifests := []registry.PackageManifest{
889+
{
890+
PackageName: packageName,
891+
Channels: []registry.PackageChannel{
892+
{Name: stableChannel, CurrentCSVName: csvB.GetName()},
893+
},
894+
DefaultChannelName: stableChannel,
895+
},
896+
}
897+
898+
// Create the CatalogSource with just one version
899+
c := newKubeClient(t)
900+
crc := newCRClient(t)
901+
catalogSourceName := genName("mock-nginx-")
902+
_, cleanupCatalogSource := createInternalCatalogSource(t, c, crc, catalogSourceName, testNamespace, manifests, nil, []v1alpha1.ClusterServiceVersion{csvA, csvB})
903+
defer cleanupCatalogSource()
904+
905+
// Attempt to get the catalog source before creating install plan
906+
_, err := fetchCatalogSource(t, crc, catalogSourceName, testNamespace, catalogSourceRegistryPodSynced)
907+
require.NoError(t, err)
908+
909+
// Create a subscription to just get an InstallPlan for csvB
910+
subscriptionName := genName("sub-nginx-")
911+
createSubscriptionForCatalog(t, crc, testNamespace, subscriptionName, catalogSourceName, packageName, stableChannel, csvB.GetName(), v1alpha1.ApprovalAutomatic)
912+
913+
// Wait for csvB to be installed
914+
_, err = awaitCSV(t, crc, testNamespace, csvB.GetName(), csvSucceededChecker)
915+
require.NoError(t, err)
916+
917+
subscription, err := fetchSubscription(t, crc, testNamespace, subscriptionName, subscriptionHasInstallPlanChecker)
918+
fetchedInstallPlan, err := fetchInstallPlan(t, crc, subscription.Status.InstallPlanRef.Name, buildInstallPlanPhaseCheckFunc(v1alpha1.InstallPlanPhaseComplete))
919+
920+
// Delete this subscription
921+
err = crc.OperatorsV1alpha1().Subscriptions(testNamespace).DeleteCollection(metav1.NewDeleteOptions(0), metav1.ListOptions{})
922+
require.NoError(t, err)
923+
924+
// Create an InstallPlan for csvB
925+
ip := &v1alpha1.InstallPlan{
926+
ObjectMeta: metav1.ObjectMeta{
927+
GenerateName: "install-",
928+
Namespace: testNamespace,
929+
},
930+
Spec: v1alpha1.InstallPlanSpec{
931+
ClusterServiceVersionNames: []string{csvB.GetName()},
932+
Approval: v1alpha1.ApprovalAutomatic,
933+
Approved: false,
934+
},
935+
}
936+
ip2, err := crc.OperatorsV1alpha1().InstallPlans(testNamespace).Create(ip)
937+
require.NoError(t, err)
938+
939+
ip2.Status = v1alpha1.InstallPlanStatus{
940+
Plan: fetchedInstallPlan.Status.Plan,
941+
CatalogSources: []string{catalogSourceName},
942+
}
943+
944+
_, err = crc.OperatorsV1alpha1().InstallPlans(testNamespace).UpdateStatus(ip2)
945+
require.NoError(t, err)
946+
947+
subscriptionName = genName("sub-nginx-")
948+
cleanupSubscription := createSubscriptionForCatalog(t, crc, testNamespace, subscriptionName, catalogSourceName, packageName, stableChannel, csvA.GetName(), v1alpha1.ApprovalManual)
949+
defer cleanupSubscription()
950+
951+
subscription, err = fetchSubscription(t, crc, testNamespace, subscriptionName, subscriptionHasInstallPlanChecker)
952+
require.NoError(t, err)
953+
require.NotNil(t, subscription)
954+
955+
installPlanName := subscription.Status.Install.Name
956+
957+
// Wait for InstallPlan to be status: Complete before checking resource presence
958+
requiresApprovalChecker := buildInstallPlanPhaseCheckFunc(v1alpha1.InstallPlanPhaseRequiresApproval)
959+
fetchedInstallPlan, err = fetchInstallPlan(t, crc, installPlanName, requiresApprovalChecker)
960+
require.NoError(t, err)
961+
962+
// Approve the installplan and wait for csvA to be installed
963+
fetchedInstallPlan.Spec.Approved = true
964+
_, err = crc.OperatorsV1alpha1().InstallPlans(testNamespace).Update(fetchedInstallPlan)
965+
require.NoError(t, err)
966+
967+
// Wait for csvA to be installed
968+
_, err = awaitCSV(t, crc, testNamespace, csvA.GetName(), csvSucceededChecker)
969+
require.NoError(t, err)
970+
971+
// Wait for the subscription to begin upgrading to csvB
972+
subscription, err = fetchSubscription(t, crc, testNamespace, subscriptionName, subscriptionStateUpgradePendingChecker)
973+
require.NoError(t, err)
974+
975+
// Fetch existing csvB installPlan
976+
fetchedInstallPlan, err = fetchInstallPlan(t, crc, subscription.Status.InstallPlanRef.Name, requiresApprovalChecker)
977+
require.NoError(t, err)
978+
require.Equal(t, ip2.GetName(), subscription.Status.InstallPlanRef.Name, "expected new installplan is the same with pre-exising one")
979+
980+
// Approve the installplan and wait for csvB to be installed
981+
fetchedInstallPlan.Spec.Approved = true
982+
_, err = crc.OperatorsV1alpha1().InstallPlans(testNamespace).Update(fetchedInstallPlan)
983+
require.NoError(t, err)
984+
985+
// Wait for csvB to be installed
986+
_, err = awaitCSV(t, crc, testNamespace, csvB.GetName(), csvSucceededChecker)
987+
require.NoError(t, err)
988+
}
989+
874990
// TestSubscriptionStatusMissingTargetCatalogSource ensures that a Subscription has the appropriate status condition when
875991
// its target catalog is missing.
876992
//

0 commit comments

Comments
 (0)