From 9ff9b847f2f37053355688e031e19b9b14bf08e9 Mon Sep 17 00:00:00 2001 From: danmanor Date: Sat, 20 Apr 2024 12:29:03 +0300 Subject: [PATCH] MGMT-17620: Change the way release images are handled in RestAPI flow to retrieve multiarch release image in case a multi-arch OpenShift version, single-arch requested and it exist. --- internal/versions/rest_api_versions.go | 25 +-- internal/versions/rest_api_versions_test.go | 182 +++++++++++--------- subsystem/cluster_v2_test.go | 4 +- subsystem/feature_support_levels_test.go | 6 +- subsystem/operators_test.go | 2 +- 5 files changed, 115 insertions(+), 104 deletions(-) diff --git a/internal/versions/rest_api_versions.go b/internal/versions/rest_api_versions.go index 10e52814cb09..561a4e68931a 100644 --- a/internal/versions/rest_api_versions.go +++ b/internal/versions/rest_api_versions.go @@ -2,13 +2,11 @@ package versions import ( context "context" - "fmt" "strings" "sync" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - "github.com/lib/pq" "github.com/openshift/assisted-service/internal/common" "github.com/openshift/assisted-service/internal/oc" models "github.com/openshift/assisted-service/models" @@ -47,19 +45,14 @@ func (h *restAPIVersionsHandler) GetReleaseImage(_ context.Context, openshiftVer } query := h.db.Session(&gorm.Session{}).Where(&models.ReleaseImage{}) - if cpuArchitecture == common.MultiCPUArchitecture { - query = query.Where("cardinality(cpu_architectures) > 1") - } else { - query = query.Where(h.db.Session(&gorm.Session{}). - Where("cpu_architectures @> ? AND ? @> cpu_architectures", pq.StringArray{cpuArchitecture}, pq.StringArray{cpuArchitecture}). - Or("cpu_architecture = ?", cpuArchitecture)) - } + query = query.Where(h.db.Session(&gorm.Session{}). + Where("? = Any(cpu_architectures)", cpuArchitecture). + Or("cpu_architecture = ?", cpuArchitecture), + ) // Find the exact version if versionFormat == common.MajorMinorPatchVersion { - query = query.Where(h.db.Session(&gorm.Session{}). - Where("version = ?", openshiftVersion). - Or("version = ?", openshiftVersion+"-multi")) + query = query.Where("version = ?", openshiftVersion) var releaseImage models.ReleaseImage err := query.Take(&releaseImage).Error if err != nil { @@ -79,19 +72,13 @@ func (h *restAPIVersionsHandler) GetReleaseImage(_ context.Context, openshiftVer // openshiftVersion must be major.minor, find the latest version matching - // In case openshiftVersion is in the format of major.minor-multi - editedVersion := strings.TrimSuffix(openshiftVersion, "-multi") - + query = query.Where("openshift_version = ?", openshiftVersion) var releaseImages models.ReleaseImages err := query.Find(&releaseImages).Error if err != nil { return nil, err } - releaseImages = funk.Filter(releaseImages, func(releaseImage *models.ReleaseImage) bool { - return strings.HasPrefix(*releaseImage.Version, fmt.Sprintf("%s.", editedVersion)) - }).([]*models.ReleaseImage) - if len(releaseImages) == 0 { return nil, errors.Errorf("no release image found for openshiftVersion: '%s' and CPU architecture '%s'", openshiftVersion, cpuArchitecture) } diff --git a/internal/versions/rest_api_versions_test.go b/internal/versions/rest_api_versions_test.go index ece86e3e4cb1..429e5f95dc95 100644 --- a/internal/versions/rest_api_versions_test.go +++ b/internal/versions/rest_api_versions_test.go @@ -65,7 +65,7 @@ var _ = Describe("GetReleaseImage", func() { Expect(releaseImage).Should(BeNil()) }) - It("gets the latest matching release image with major.minor openshiftVersion", func() { + It("gets the latest matching release image with major.minor openshiftVersion - production support level, multi appears after", func() { releaseImages := models.ReleaseImages{ { OpenshiftVersion: swag.String("4.14"), @@ -85,58 +85,124 @@ var _ = Describe("GetReleaseImage", func() { SupportLevel: models.ReleaseImageSupportLevelProduction, Default: false, }, + { + OpenshiftVersion: swag.String("4.14-multi"), + Version: swag.String("4.14.2-multi"), + CPUArchitecture: swag.String(common.MultiCPUArchitecture), + CPUArchitectures: []string{common.X86CPUArchitecture, common.ARM64CPUArchitecture}, + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.2-multi"), + SupportLevel: models.ReleaseImageSupportLevelProduction, + Default: false, + }, { OpenshiftVersion: swag.String("4.14"), Version: swag.String("4.14.3"), CPUArchitecture: swag.String(common.X86CPUArchitecture), CPUArchitectures: []string{common.X86CPUArchitecture}, URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.3-x86_64"), - SupportLevel: models.OpenshiftVersionSupportLevelBeta, + SupportLevel: models.ReleaseImageSupportLevelProduction, Default: false, }, { OpenshiftVersion: swag.String("4.14"), - Version: swag.String("4.14.3"), + Version: swag.String("4.14.4"), CPUArchitecture: swag.String(common.ARM64CPUArchitecture), CPUArchitectures: []string{common.ARM64CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.3-aarch64"), + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.4-aarch64"), SupportLevel: models.ReleaseImageSupportLevelProduction, Default: false, }, + } + + err := db.Create(releaseImages).Error + Expect(err).ShouldNot(HaveOccurred()) + + releaseImage, err := handler.GetReleaseImage(ctx, "4.14", common.X86CPUArchitecture, pullSecret) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*releaseImage.Version).Should(Equal("4.14.3")) // latest with matching CPU arch + + releaseImage, err = handler.GetReleaseImage(ctx, "4.14", common.MultiCPUArchitecture, pullSecret) + Expect(err).Should(HaveOccurred()) // The version doesn't match + Expect(releaseImage).To(BeNil()) + + releaseImage, err = handler.GetReleaseImage(ctx, "4.14-multi", common.X86CPUArchitecture, pullSecret) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*releaseImage.Version).Should(Equal("4.14.2-multi")) // latest multi release image, single arch requested + + releaseImage, err = handler.GetReleaseImage(ctx, "4.14-multi", common.S390xCPUArchitecture, pullSecret) + Expect(err).Should(HaveOccurred()) // No CPU architecture match + Expect(releaseImage).To(BeNil()) + + releaseImage, err = handler.GetReleaseImage(ctx, "4.14-multi", common.MultiCPUArchitecture, pullSecret) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*releaseImage.Version).Should(Equal("4.14.2-multi")) // latest multi release image, multi arch requested + }) + + It("gets the latest matching release image with major.minor openshiftVersion - some production and some beta support level, multi appears before", func() { + releaseImages := models.ReleaseImages{ { - OpenshiftVersion: swag.String("4.14-multi"), - Version: swag.String("4.14.3-multi"), + OpenshiftVersion: swag.String("4.15"), + Version: swag.String("4.15.1"), + CPUArchitecture: swag.String(common.X86CPUArchitecture), + CPUArchitectures: []string{common.X86CPUArchitecture}, + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.15.1-x86_64"), + SupportLevel: models.ReleaseImageSupportLevelProduction, + Default: false, + }, + { + OpenshiftVersion: swag.String("4.15-multi"), + Version: swag.String("4.15.1-multi"), CPUArchitecture: swag.String(common.MultiCPUArchitecture), CPUArchitectures: []string{common.X86CPUArchitecture, common.ARM64CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.3-multi"), + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.15.1-multi"), SupportLevel: models.ReleaseImageSupportLevelProduction, Default: false, }, { OpenshiftVersion: swag.String("4.15"), - Version: swag.String("4.15.1"), + Version: swag.String("4.15.2"), CPUArchitecture: swag.String(common.X86CPUArchitecture), CPUArchitectures: []string{common.X86CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.15.1-x86_64"), - SupportLevel: models.OpenshiftVersionSupportLevelBeta, + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.15.2-x86_64"), + SupportLevel: models.ReleaseImageSupportLevelProduction, Default: false, }, { OpenshiftVersion: swag.String("4.15"), - Version: swag.String("4.15.2"), + Version: swag.String("4.15.3"), CPUArchitecture: swag.String(common.X86CPUArchitecture), CPUArchitectures: []string{common.X86CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.15.2-x86_64"), + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.15.3-x86_64"), SupportLevel: models.OpenshiftVersionSupportLevelBeta, Default: false, }, + } + + err := db.Create(releaseImages).Error + Expect(err).ShouldNot(HaveOccurred()) + + releaseImage, err := handler.GetReleaseImage(ctx, "4.15", common.X86CPUArchitecture, pullSecret) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*releaseImage.Version).Should(Equal("4.15.2")) // latest non-beta matching CPU architecture + + releaseImage, err = handler.GetReleaseImage(ctx, "4.15-multi", common.X86CPUArchitecture, pullSecret) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*releaseImage.Version).Should(Equal("4.15.1-multi")) // latest matching multi when multi appears before + + releaseImage, err = handler.GetReleaseImage(ctx, "4.15-multi", common.MultiCPUArchitecture, pullSecret) + Expect(err).ShouldNot(HaveOccurred()) + Expect(*releaseImage.Version).Should(Equal("4.15.1-multi")) + }) + + It("gets the latest matching release image with major.minor openshiftVersion - all beta support level", func() { + releaseImages := models.ReleaseImages{ { OpenshiftVersion: swag.String("4.16-multi"), Version: swag.String("4.16.1-multi"), CPUArchitecture: swag.String(common.MultiCPUArchitecture), CPUArchitectures: []string{common.X86CPUArchitecture, common.ARM64CPUArchitecture}, URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.16.1-multi"), - SupportLevel: models.ReleaseImageSupportLevelProduction, + SupportLevel: models.OpenshiftVersionSupportLevelBeta, Default: false, }, { @@ -145,7 +211,16 @@ var _ = Describe("GetReleaseImage", func() { CPUArchitecture: swag.String(common.X86CPUArchitecture), CPUArchitectures: []string{common.X86CPUArchitecture}, URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.16.1-x86_64"), - SupportLevel: models.ReleaseImageSupportLevelProduction, + SupportLevel: models.OpenshiftVersionSupportLevelBeta, + Default: false, + }, + { + OpenshiftVersion: swag.String("4.16"), + Version: swag.String("4.16.2"), + CPUArchitecture: swag.String(common.X86CPUArchitecture), + CPUArchitectures: []string{common.X86CPUArchitecture}, + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.16.2-x86_64"), + SupportLevel: models.OpenshiftVersionSupportLevelBeta, Default: false, }, } @@ -153,17 +228,17 @@ var _ = Describe("GetReleaseImage", func() { err := db.Create(releaseImages).Error Expect(err).ShouldNot(HaveOccurred()) - releaseImage, err := handler.GetReleaseImage(ctx, "4.14", common.X86CPUArchitecture, pullSecret) + releaseImage, err := handler.GetReleaseImage(ctx, "4.16", common.X86CPUArchitecture, pullSecret) Expect(err).ShouldNot(HaveOccurred()) - Expect(*releaseImage.Version).Should(Equal("4.14.2")) + Expect(*releaseImage.Version).Should(Equal("4.16.2")) - releaseImage, err = handler.GetReleaseImage(ctx, "4.15", common.X86CPUArchitecture, pullSecret) + releaseImage, err = handler.GetReleaseImage(ctx, "4.16-multi", common.X86CPUArchitecture, pullSecret) Expect(err).ShouldNot(HaveOccurred()) - Expect(*releaseImage.Version).Should(Equal("4.15.2")) + Expect(*releaseImage.Version).Should(Equal("4.16.1-multi")) - releaseImage, err = handler.GetReleaseImage(ctx, "4.16", common.X86CPUArchitecture, pullSecret) + releaseImage, err = handler.GetReleaseImage(ctx, "4.16-multi", common.MultiCPUArchitecture, pullSecret) Expect(err).ShouldNot(HaveOccurred()) - Expect(*releaseImage.Version).Should(Equal("4.16.1")) + Expect(*releaseImage.Version).Should(Equal("4.16.1-multi")) }) It("gets the exact matching release image with major.minor.patch / prerelease openshiftVersion", func() { @@ -348,68 +423,17 @@ var _ = Describe("GetReleaseImage", func() { Expect(*releaseImage.Version).Should(Equal("4.14.1-multi")) }) - It("gets successfully image using major.minor.patch openshiftVersion in multiarch query - without multi suffix", func() { - releaseImages := models.ReleaseImages{ - { - OpenshiftVersion: swag.String("4.14-multi"), - Version: swag.String("4.14.1-multi"), - CPUArchitecture: swag.String(common.MultiCPUArchitecture), - CPUArchitectures: []string{common.X86CPUArchitecture, common.ARM64CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.1-multi"), - SupportLevel: models.ReleaseImageSupportLevelProduction, - Default: false, - }, - { - OpenshiftVersion: swag.String("4.14-multi"), - Version: swag.String("4.14.2-multi"), - CPUArchitecture: swag.String(common.MultiCPUArchitecture), - CPUArchitectures: []string{common.X86CPUArchitecture, common.ARM64CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.2-multi"), - SupportLevel: models.ReleaseImageSupportLevelProduction, - Default: false, - }, - } - - err := db.Create(releaseImages).Error - Expect(err).ShouldNot(HaveOccurred()) - - releaseImage, err := handler.GetReleaseImage(ctx, "4.14.1", common.MultiCPUArchitecture, pullSecret) - Expect(err).ShouldNot(HaveOccurred()) - Expect(*releaseImage.Version).Should(Equal("4.14.1-multi")) - }) - - It("gets successfully image using major.minor openshiftVersion in multiarch query - with multi suffix", func() { + It("gets successfully image using major.minor.patch openshiftVersion in single arch query - with multi suffix", func() { releaseImages := models.ReleaseImages{ { - OpenshiftVersion: swag.String("4.14-multi"), - Version: swag.String("4.14.1-multi"), - CPUArchitecture: swag.String(common.MultiCPUArchitecture), - CPUArchitectures: []string{common.X86CPUArchitecture, common.ARM64CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.1-multi"), - SupportLevel: models.ReleaseImageSupportLevelProduction, - Default: false, - }, - { - OpenshiftVersion: swag.String("4.14-multi"), - Version: swag.String("4.14.2-multi"), - CPUArchitecture: swag.String(common.MultiCPUArchitecture), - CPUArchitectures: []string{common.X86CPUArchitecture, common.ARM64CPUArchitecture}, - URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.2-multi"), + OpenshiftVersion: swag.String("4.14"), + Version: swag.String("4.14.1"), + CPUArchitecture: swag.String(common.X86CPUArchitecture), + CPUArchitectures: []string{common.X86CPUArchitecture}, + URL: swag.String("quay.io/openshift-release-dev/ocp-release:4.14.1-x86_64"), SupportLevel: models.ReleaseImageSupportLevelProduction, Default: false, }, - } - - err := db.Create(releaseImages).Error - Expect(err).ShouldNot(HaveOccurred()) - - releaseImage, err := handler.GetReleaseImage(ctx, "4.14-multi", common.MultiCPUArchitecture, pullSecret) - Expect(err).ShouldNot(HaveOccurred()) - Expect(*releaseImage.Version).Should(Equal("4.14.2-multi")) - }) - - It("gets successfully image using major.minor openshiftVersion in multiarch query - without multi suffix", func() { - releaseImages := models.ReleaseImages{ { OpenshiftVersion: swag.String("4.14-multi"), Version: swag.String("4.14.1-multi"), @@ -433,9 +457,9 @@ var _ = Describe("GetReleaseImage", func() { err := db.Create(releaseImages).Error Expect(err).ShouldNot(HaveOccurred()) - releaseImage, err := handler.GetReleaseImage(ctx, "4.14", common.MultiCPUArchitecture, pullSecret) + releaseImage, err := handler.GetReleaseImage(ctx, "4.14.1-multi", common.X86CPUArchitecture, pullSecret) Expect(err).ShouldNot(HaveOccurred()) - Expect(*releaseImage.Version).Should(Equal("4.14.2-multi")) + Expect(*releaseImage.Version).Should(Equal("4.14.1-multi")) }) It("gets successfully image using major.minor.patch openshiftVersion in multiarch query with different version format", func() { diff --git a/subsystem/cluster_v2_test.go b/subsystem/cluster_v2_test.go index 305a0ae71a76..ea7e77118d7a 100644 --- a/subsystem/cluster_v2_test.go +++ b/subsystem/cluster_v2_test.go @@ -540,11 +540,11 @@ var _ = Describe("[V2ClusterTests] multiarch", func() { clusterReq, err := user2BMClient.Installer.V2RegisterCluster(ctx, &installer.V2RegisterClusterParams{ NewClusterParams: &models.ClusterCreateParams{ Name: swag.String("test-cluster"), - OpenshiftVersion: swag.String("4.12"), + OpenshiftVersion: swag.String("4.12-multi"), PullSecret: swag.String(fmt.Sprintf(psTemplate, FakePS2)), BaseDNSDomain: "example.com", UserManagedNetworking: swag.Bool(true), - CPUArchitecture: common.MultiCPUArchitecture, + CPUArchitecture: common.S390xCPUArchitecture, }, }) Expect(err).NotTo(HaveOccurred()) diff --git a/subsystem/feature_support_levels_test.go b/subsystem/feature_support_levels_test.go index 3f088e5b885a..36baf2da57aa 100644 --- a/subsystem/feature_support_levels_test.go +++ b/subsystem/feature_support_levels_test.go @@ -102,7 +102,7 @@ var _ = Describe("Feature support levels API", func() { Context("Update cluster", func() { It("Update umn true won't fail on 4.13 with multi release without infra-env", func() { - cluster, err := registerNewCluster("4.13", common.MultiCPUArchitecture, models.ClusterHighAvailabilityModeFull, swag.Bool(true)) + cluster, err := registerNewCluster("4.13-multi", common.MultiCPUArchitecture, models.ClusterHighAvailabilityModeFull, swag.Bool(true)) Expect(err).NotTo(HaveOccurred()) Expect(cluster.Payload.CPUArchitecture).To(Equal(common.MultiCPUArchitecture)) @@ -117,7 +117,7 @@ var _ = Describe("Feature support levels API", func() { It("Update umn true fail on 4.13 with s390x with infra-env", func() { expectedError := "cannot use Cluster Managed Networking because it's not compatible with the s390x architecture on version 4.13" - cluster, err := registerNewCluster("4.13", common.MultiCPUArchitecture, models.ClusterHighAvailabilityModeFull, swag.Bool(true)) + cluster, err := registerNewCluster("4.13-multi", common.S390xCPUArchitecture, models.ClusterHighAvailabilityModeFull, swag.Bool(true)) Expect(err).NotTo(HaveOccurred()) Expect(cluster.Payload.CPUArchitecture).To(Equal(common.MultiCPUArchitecture)) @@ -138,7 +138,7 @@ var _ = Describe("Feature support levels API", func() { It("Create infra-env after updating OLM operators on s390x architecture ", func() { expectedError := "cannot use OpenShift Virtualization because it's not compatible with the s390x architecture on version 4.13" - cluster, err := registerNewCluster("4.13", common.MultiCPUArchitecture, models.ClusterHighAvailabilityModeFull, swag.Bool(true)) + cluster, err := registerNewCluster("4.13-multi", common.S390xCPUArchitecture, models.ClusterHighAvailabilityModeFull, swag.Bool(true)) Expect(err).NotTo(HaveOccurred()) Expect(cluster.Payload.CPUArchitecture).To(Equal(common.MultiCPUArchitecture)) diff --git a/subsystem/operators_test.go b/subsystem/operators_test.go index bf65ed49573b..a9888b77a0e4 100644 --- a/subsystem/operators_test.go +++ b/subsystem/operators_test.go @@ -317,7 +317,7 @@ var _ = Describe("Operators endpoint tests", func() { swag.String(models.ClusterCPUArchitectureArm64), nil, ) - Expect(cluster.Payload.CPUArchitecture).To(Equal(models.ClusterCPUArchitectureArm64)) + Expect(cluster.Payload.CPUArchitecture).To(Equal(common.MultiCPUArchitecture)) Expect(len(cluster.Payload.MonitoredOperators)).To(Equal(1)) infraEnvParams := installer.RegisterInfraEnvParams{