diff --git a/pkg/cvo/availableupdates.go b/pkg/cvo/availableupdates.go index 7a79c773b..71ab235a0 100644 --- a/pkg/cvo/availableupdates.go +++ b/pkg/cvo/availableupdates.go @@ -49,15 +49,7 @@ func (optr *Operator) syncAvailableUpdates(ctx context.Context, config *configv1 channel := config.Spec.Channel desiredArch := optr.getDesiredArchitecture(config.Spec.DesiredUpdate) - currentArch := runtime.GOARCH - - if optr.release.Architecture == configv1.ClusterVersionArchitectureMulti { - currentArch = "multi" - } - - if desiredArch == "" { - desiredArch = currentArch - } + currentArch := optr.getCurrentArchitecture() // updates are only checked at most once per minimumUpdateCheckInterval or if the generation changes optrAvailableUpdates := optr.getAvailableUpdates() @@ -330,7 +322,14 @@ func (optr *Operator) getDesiredArchitecture(update *configv1.Update) string { if update != nil { return string(update.Architecture) } - return "" + return optr.getCurrentArchitecture() +} + +func (optr *Operator) getCurrentArchitecture() string { + if optr.release.Architecture == configv1.ClusterVersionArchitectureMulti { + return string(configv1.ClusterVersionArchitectureMulti) + } + return runtime.GOARCH } func calculateAvailableUpdatesStatus(ctx context.Context, clusterID string, transport *http.Transport, userAgent, updateService, desiredArch, diff --git a/pkg/cvo/availableupdates_test.go b/pkg/cvo/availableupdates_test.go index a9fcbeeed..99a2ab84d 100644 --- a/pkg/cvo/availableupdates_test.go +++ b/pkg/cvo/availableupdates_test.go @@ -111,14 +111,19 @@ func osusWithSingleConditionalEdge() (*httptest.Server, clusterconditions.Condit return osus, mockPromql, updates, from } -func newOperator(url, version string, promqlMock clusterconditions.Condition) (*availableUpdates, *Operator) { - currentRelease := configv1.Release{Version: version, Image: "payload/" + version} +func newOperator(url, version string, promqlMock clusterconditions.Condition, arch string) (*availableUpdates, *Operator) { + var currentReleaseArch configv1.ClusterVersionArchitecture + if arch == string(configv1.ClusterVersionArchitectureMulti) { + currentReleaseArch = configv1.ClusterVersionArchitectureMulti + } + currentRelease := configv1.Release{Version: version, Image: "payload/" + version, Architecture: currentReleaseArch} + registry := clusterconditions.NewConditionRegistry() registry.Register("Always", &always.Always{}) registry.Register("PromQL", promqlMock) operator := &Operator{ updateService: url, - architecture: "amd64", + architecture: arch, proxyLister: notFoundProxyLister{}, cmConfigManagedLister: notFoundConfigMapLister{}, conditionRegistry: registry, @@ -126,7 +131,7 @@ func newOperator(url, version string, promqlMock clusterconditions.Condition) (* release: currentRelease, } availableUpdates := &availableUpdates{ - Architecture: runtime.GOARCH, + Architecture: arch, Current: configv1.Release{Version: version, Image: "payload/" + version}, } return availableUpdates, operator @@ -149,7 +154,7 @@ var availableUpdatesCmpOpts = []cmp.Option{ func TestSyncAvailableUpdates(t *testing.T) { fakeOsus, mockPromql, expectedConditionalUpdates, version := osusWithSingleConditionalEdge() defer fakeOsus.Close() - expectedAvailableUpdates, optr := newOperator(fakeOsus.URL, version, mockPromql) + expectedAvailableUpdates, optr := newOperator(fakeOsus.URL, version, mockPromql, runtime.GOARCH) expectedAvailableUpdates.UpdateService = fakeOsus.URL expectedAvailableUpdates.ConditionalUpdates = expectedConditionalUpdates expectedAvailableUpdates.Channel = cvFixture.Spec.Channel @@ -231,7 +236,7 @@ func TestSyncAvailableUpdates_ConditionalUpdateRecommendedConditions(t *testing. t.Run(tc.name, func(t *testing.T) { fakeOsus, mockPromql, conditionalUpdates, version := osusWithSingleConditionalEdge() defer fakeOsus.Close() - availableUpdates, optr := newOperator(fakeOsus.URL, version, mockPromql) + availableUpdates, optr := newOperator(fakeOsus.URL, version, mockPromql, runtime.GOARCH) optr.availableUpdates = availableUpdates optr.availableUpdates.ConditionalUpdates = conditionalUpdates expectedConditions := []metav1.Condition{{}} @@ -435,3 +440,58 @@ func TestEvaluateConditionalUpdate(t *testing.T) { }) } } + +func TestSyncAvailableUpdatesMultiArchAfterMigration(t *testing.T) { + fakeOsus, mockPromql, expectedConditionalUpdates, version := osusWithSingleConditionalEdge() + defer fakeOsus.Close() + + expectedAvailableUpdates, optr := newOperator(fakeOsus.URL, version, mockPromql, "Multi") + + cv := cvFixture.DeepCopy() + cv.Spec.DesiredUpdate = &configv1.Update{ + Architecture: configv1.ClusterVersionArchitectureMulti, + Version: version, + Image: optr.release.Image, + Force: false, + } + + expectedAvailableUpdates.UpdateService = fakeOsus.URL + expectedAvailableUpdates.ConditionalUpdates = expectedConditionalUpdates + expectedAvailableUpdates.Channel = cv.Spec.Channel + expectedAvailableUpdates.Condition = configv1.ClusterOperatorStatusCondition{ + Type: configv1.RetrievedUpdates, + Status: configv1.ConditionTrue, + } + + err := optr.syncAvailableUpdates(context.Background(), cv) + + if err != nil { + t.Fatalf("syncAvailableUpdates() unexpected error: %v", err) + } + if diff := cmp.Diff(expectedAvailableUpdates, optr.availableUpdates, availableUpdatesCmpOpts...); diff != "" { + t.Fatalf("available updates differ from expected:\n%s", diff) + } +} + +func TestSyncAvailableUpdatesMultiArchAfterMigrationDesiredUpdateNil(t *testing.T) { + fakeOsus, mockPromql, expectedConditionalUpdates, version := osusWithSingleConditionalEdge() + defer fakeOsus.Close() + + expectedAvailableUpdates, optr := newOperator(fakeOsus.URL, version, mockPromql, "Multi") + expectedAvailableUpdates.UpdateService = fakeOsus.URL + expectedAvailableUpdates.ConditionalUpdates = expectedConditionalUpdates + expectedAvailableUpdates.Channel = cvFixture.Spec.Channel + expectedAvailableUpdates.Condition = configv1.ClusterOperatorStatusCondition{ + Type: configv1.RetrievedUpdates, + Status: configv1.ConditionTrue, + } + + err := optr.syncAvailableUpdates(context.Background(), cvFixture) + + if err != nil { + t.Fatalf("syncAvailableUpdates() unexpected error: %v", err) + } + if diff := cmp.Diff(expectedAvailableUpdates, optr.availableUpdates, availableUpdatesCmpOpts...); diff != "" { + t.Fatalf("available updates differ from expected:\n%s", diff) + } +}