diff --git a/apis/core/v1beta1/openstackversion_types.go b/apis/core/v1beta1/openstackversion_types.go index ee8c1c2ed9..945d0dec04 100644 --- a/apis/core/v1beta1/openstackversion_types.go +++ b/apis/core/v1beta1/openstackversion_types.go @@ -18,6 +18,9 @@ package v1beta1 import ( "regexp" + "strings" + "golang.org/x/mod/semver" + "fmt" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/util" @@ -254,3 +257,38 @@ func GetOpenStackReleaseVersion(envVars []string) string { ) } + +// GetDeployedSemVersion - returns the current deployed version. It can be used +// to compare it against an available version and take decisions based on it +func (v *OpenStackVersion) GetDeployedSemVer() string { + if v.Status.DeployedVersion == nil { + return "" + } + if strings.HasPrefix(*v.Status.DeployedVersion, "^v") { + // we don't need to normalize the string + return *v.Status.DeployedVersion + } + return fmt.Sprintf("v%s", *v.Status.DeployedVersion) +} + +// IsGreaterSemVer - returns true when deployedVersion is greater than the +// targetVersion passed as input +func (v *OpenStackVersion) IsGreaterSemVer(targetVer string) bool{ + deployedVersion := v.GetDeployedSemVer() + // return false if there's no deployedVersion + if deployedVersion == "" { + return false + } + return semver.Compare(deployedVersion, targetVer) > 0 +} + +// IsLowerSemVer - returns true when deployedVersion is lower than a targetVersion +// that is used to compare it +func (v *OpenStackVersion) IsLowerSemVer(targetVer string) bool{ + deployedVersion := v.GetDeployedSemVer() + // return false if there's no deployedVersion + if deployedVersion == "" { + return false + } + return semver.Compare(deployedVersion, targetVer) < 0 +} diff --git a/apis/go.mod b/apis/go.mod index 6c3a7e759c..b6ae9b875a 100644 --- a/apis/go.mod +++ b/apis/go.mod @@ -33,6 +33,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/mod v0.20.0 golang.org/x/tools v0.24.0 // indirect k8s.io/api v0.29.15 k8s.io/apimachinery v0.29.15 @@ -115,3 +116,5 @@ replace github.com/openshift/api => github.com/openshift/api v0.0.0-202408300231 // custom RabbitmqClusterSpecCore for OpenStackControlplane (v2.9.0_patches_tag) replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20241017142550-a3524acedd49 //allow-merging + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/fmount/glance-operator/api v0.1.2-0.20250502133016-1b9e7f5e4180 diff --git a/apis/go.sum b/apis/go.sum index 8c553f526d..088d0985d0 100644 --- a/apis/go.sum +++ b/apis/go.sum @@ -14,6 +14,8 @@ github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fmount/glance-operator/api v0.1.2-0.20250502133016-1b9e7f5e4180 h1:crRHrF0uDIYm8es2Ya/ELO1el/uKOzY+NcdnEISQCLI= +github.com/fmount/glance-operator/api v0.1.2-0.20250502133016-1b9e7f5e4180/go.mod h1:dA/dH8jFvqX90KHPC9LN9RDOMRE+boriwwDjMMUJkL4= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= @@ -100,8 +102,6 @@ github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20250423054052-7 github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20250423054052-76f811364c48/go.mod h1:wA+iwrJQzpsMslseJZgEgqdTGlrYytNX2XkI4SQQNLw= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20250422103124-9adfe79423df h1:+OMlbs1XNLVF6U8Xk0YmlofKlvDizt3YV+OQkxx9InY= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20250422103124-9adfe79423df/go.mod h1:KkjCmRFNnIKxJcWZC96bk3CsmZmT0nyGJzOCF6Qzvy8= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20250407064150-1cff0f51b44d h1:DivsLnqDoMFnAWOOkOCoj9ilCM+6pFXRjvz4fSFSvJw= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20250407064150-1cff0f51b44d/go.mod h1:IRp2nEGLIQj9gZSc5aMJr5Wec9yBhr//6y7W41ur4KQ= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20250423034234-f96998c6fdac h1:HrBh3wx0po8AbTxH/+ZT6P51FQyvAssjQqhgPsbVE8Q= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20250423034234-f96998c6fdac/go.mod h1:H7Cd+GRpWmm+Viqu2eqNMGhK7qTE7SpSVo6qz1Gksec= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20250421055257-62660c8c5cba h1:ZJSh4+IWoojgMeY2Pe2kaG3lLPPxT81X9tSEV2Ke3hM= @@ -188,6 +188,8 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbR golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/go.mod b/go.mod index 8a899ee66b..c155845273 100644 --- a/go.mod +++ b/go.mod @@ -127,3 +127,5 @@ replace github.com/openshift/api => github.com/openshift/api v0.0.0-202408300231 // custom RabbitmqClusterSpecCore for OpenStackControlplane (v2.9.0_patches_tag) replace github.com/rabbitmq/cluster-operator/v2 => github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20241017142550-a3524acedd49 //allow-merging + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/fmount/glance-operator/api v0.1.2-0.20250502133016-1b9e7f5e4180 diff --git a/go.sum b/go.sum index 6f3076c135..bb699aab68 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fmount/glance-operator/api v0.1.2-0.20250502133016-1b9e7f5e4180 h1:crRHrF0uDIYm8es2Ya/ELO1el/uKOzY+NcdnEISQCLI= +github.com/fmount/glance-operator/api v0.1.2-0.20250502133016-1b9e7f5e4180/go.mod h1:dA/dH8jFvqX90KHPC9LN9RDOMRE+boriwwDjMMUJkL4= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= @@ -104,8 +106,6 @@ github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20250423054052-7 github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20250423054052-76f811364c48/go.mod h1:wA+iwrJQzpsMslseJZgEgqdTGlrYytNX2XkI4SQQNLw= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20250422103124-9adfe79423df h1:+OMlbs1XNLVF6U8Xk0YmlofKlvDizt3YV+OQkxx9InY= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20250422103124-9adfe79423df/go.mod h1:KkjCmRFNnIKxJcWZC96bk3CsmZmT0nyGJzOCF6Qzvy8= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20250407064150-1cff0f51b44d h1:DivsLnqDoMFnAWOOkOCoj9ilCM+6pFXRjvz4fSFSvJw= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20250407064150-1cff0f51b44d/go.mod h1:IRp2nEGLIQj9gZSc5aMJr5Wec9yBhr//6y7W41ur4KQ= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20250423034234-f96998c6fdac h1:HrBh3wx0po8AbTxH/+ZT6P51FQyvAssjQqhgPsbVE8Q= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20250423034234-f96998c6fdac/go.mod h1:H7Cd+GRpWmm+Viqu2eqNMGhK7qTE7SpSVo6qz1Gksec= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20250421055257-62660c8c5cba h1:ZJSh4+IWoojgMeY2Pe2kaG3lLPPxT81X9tSEV2Ke3hM= diff --git a/pkg/openstack/glance.go b/pkg/openstack/glance.go index dc91438461..394c24a34d 100644 --- a/pkg/openstack/glance.go +++ b/pkg/openstack/glance.go @@ -15,6 +15,7 @@ import ( "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "strconv" ) const ( @@ -23,17 +24,32 @@ const ( // label set by the service operator as in case of split glanceAPI type the // the label on public svc gets set to -external and internal instance svc // to -internal instead of the glance top level glanceType split - svcSelector = "tlGlanceAPI" + svcSelector = "tlGlanceAPI" + targetVersion = "v18.0.9" ) // ReconcileGlance - func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControlPlane, version *corev1beta1.OpenStackVersion, helper *helper.Helper) (ctrl.Result, error) { glanceName, altGlanceName := instance.GetServiceName(corev1beta1.GlanceName, instance.Spec.Glance.UniquePodNames) - // Ensure the alternate cinder CR doesn't exist, as the ramdomPodNames flag may have been toggled + apiAnnotations := map[string]string{} + + // Set WSGI annotation to either deploy GlanceAPI in wsgi mode or httpd + + // ProxyPass + // + // - wsgi=true for both greenfield deployments and when a minor update is + // performed from a version greater than v18.0.9 + // + // - wsgi=false keeps the httpd + proxypass deployment method. + // This is required when a minor update from a version < FR3 is performed + apiAnnotations["wsgi"] = GlanceWSGIAnnotation(version, targetVersion) + + // Ensure the alternate glance CR doesn't exist, as the ramdomPodNames flag may have + // been toggled glance := &glancev1.Glance{ ObjectMeta: metav1.ObjectMeta{ - Name: altGlanceName, - Namespace: instance.Namespace, + Name: altGlanceName, + Namespace: instance.Namespace, + Annotations: apiAnnotations, }, } if res, err := EnsureDeleted(ctx, helper, glance); err != nil { @@ -42,8 +58,9 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl glance = &glancev1.Glance{ ObjectMeta: metav1.ObjectMeta{ - Name: glanceName, - Namespace: instance.Namespace, + Name: glanceName, + Namespace: instance.Namespace, + Annotations: apiAnnotations, }, } Log := GetLogger(ctx) @@ -171,6 +188,9 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), glance, func() error { instance.Spec.Glance.Template.DeepCopyInto(&glance.Spec.GlanceSpecCore) glance.Spec.ContainerImage = *version.Status.ContainerImages.GlanceAPIImage + // Set apiAnnotations in the Glance CR: this is currently used to + // influence + glance.SetAnnotations(apiAnnotations) if glance.Spec.Secret == "" { glance.Spec.Secret = instance.Spec.Secret } @@ -243,3 +263,20 @@ func GlanceImageMatch(ctx context.Context, controlPlane *corev1beta1.OpenStackCo return true } + +// GlanceWSGIAnnotation - +func GlanceWSGIAnnotation(version *corev1beta1.OpenStackVersion, targetVersion string) string { + wsgi := true + // if there is no deployed version, it is a greenfield scenario and we can + // deploy in wsgi mode (which is the default) + if version.Status.DeployedVersion == nil { + return strconv.FormatBool(wsgi) + } + // Do not deploy Glance in wsgi mode, but keep http+ProxyPass model when the + // version is lower than FR3 (18.0.9). This is required because the previous + // Glance ContainerImage is incompatitble with WSGI. + if version.IsLowerSemVer(targetVersion) { + wsgi = false + } + return strconv.FormatBool(wsgi) +}