From a0fdac547175d06fa69e2700aebfaee75dbd402b Mon Sep 17 00:00:00 2001 From: Francesco Pantano Date: Fri, 6 Mar 2026 11:24:06 +0100 Subject: [PATCH] Add support for Glance Location API configuration in OpenStack operator This change integrates the Glance Location API feature exposed by Glance. It enables "single" GlanceAPI StatefulSet deployments with regular backends for RHOSO 19, and it reduces the PVC resource requirements, resulting in a simplified deployment topology. The Location API is controlled via the "glance.openstack.org/location-api" annotation in the Glance CR for backward compatibility, allowing existing deployments to continue to work with the split method while enabling the new single-API deployment model for new (19 based) setups. Signed-off-by: Francesco Pantano --- api/bases/core.openstack.org_openstackversions.yaml | 4 ++++ api/core/v1beta1/openstackversion_types.go | 1 + api/core/v1beta1/zz_generated.deepcopy.go | 5 +++++ bindata/crds/crds.yaml | 4 ++++ .../crd/bases/core.openstack.org_openstackversions.yaml | 4 ++++ internal/openstack/glance.go | 5 +++++ internal/openstack/version.go | 4 +++- .../ctlplane/openstackoperator_controller_test.go | 8 ++++---- 8 files changed, 30 insertions(+), 5 deletions(-) diff --git a/api/bases/core.openstack.org_openstackversions.yaml b/api/bases/core.openstack.org_openstackversions.yaml index 0ee1523021..1130de83ef 100644 --- a/api/bases/core.openstack.org_openstackversions.yaml +++ b/api/bases/core.openstack.org_openstackversions.yaml @@ -248,6 +248,8 @@ spec: availableServiceDefaults: additionalProperties: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string rabbitmqVersion: @@ -685,6 +687,8 @@ spec: type: integer serviceDefaults: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string rabbitmqVersion: diff --git a/api/core/v1beta1/openstackversion_types.go b/api/core/v1beta1/openstackversion_types.go index 3a360b49ad..ec7ef4232b 100644 --- a/api/core/v1beta1/openstackversion_types.go +++ b/api/core/v1beta1/openstackversion_types.go @@ -179,6 +179,7 @@ type ContainerTemplate struct { type ServiceDefaults struct { GlanceWsgi *string `json:"glanceWsgi,omitempty"` RabbitmqVersion *string `json:"rabbitmqVersion,omitempty"` + GlanceLocationAPI *string `json:"glanceLocationAPI,omitempty"` } // OpenStackVersionStatus defines the observed state of OpenStackVersion diff --git a/api/core/v1beta1/zz_generated.deepcopy.go b/api/core/v1beta1/zz_generated.deepcopy.go index 83d98db4e0..8c0b685f88 100644 --- a/api/core/v1beta1/zz_generated.deepcopy.go +++ b/api/core/v1beta1/zz_generated.deepcopy.go @@ -1768,6 +1768,11 @@ func (in *ServiceDefaults) DeepCopyInto(out *ServiceDefaults) { *out = new(string) **out = **in } + if in.GlanceLocationAPI != nil { + in, out := &in.GlanceLocationAPI, &out.GlanceLocationAPI + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceDefaults. diff --git a/bindata/crds/crds.yaml b/bindata/crds/crds.yaml index ef18bc888f..99b876d2d2 100644 --- a/bindata/crds/crds.yaml +++ b/bindata/crds/crds.yaml @@ -21474,6 +21474,8 @@ spec: availableServiceDefaults: additionalProperties: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string rabbitmqVersion: @@ -21911,6 +21913,8 @@ spec: type: integer serviceDefaults: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string rabbitmqVersion: diff --git a/config/crd/bases/core.openstack.org_openstackversions.yaml b/config/crd/bases/core.openstack.org_openstackversions.yaml index 0ee1523021..1130de83ef 100644 --- a/config/crd/bases/core.openstack.org_openstackversions.yaml +++ b/config/crd/bases/core.openstack.org_openstackversions.yaml @@ -248,6 +248,8 @@ spec: availableServiceDefaults: additionalProperties: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string rabbitmqVersion: @@ -685,6 +687,8 @@ spec: type: integer serviceDefaults: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string rabbitmqVersion: diff --git a/internal/openstack/glance.go b/internal/openstack/glance.go index 2ab1eaf63d..f94a4e4222 100644 --- a/internal/openstack/glance.go +++ b/internal/openstack/glance.go @@ -271,6 +271,11 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl } else { glance.GetAnnotations()[glancev1.GlanceWSGILabel] = "false" } + if version.Status.ServiceDefaults.GlanceLocationAPI != nil && *version.Status.ServiceDefaults.GlanceLocationAPI == "true" { + glance.GetAnnotations()[glancev1.GlanceLocationAPILabel] = "true" + } else { + glance.GetAnnotations()[glancev1.GlanceLocationAPILabel] = "false" + } // Append globally defined extraMounts to the service's own list. for _, ev := range instance.Spec.ExtraMounts { diff --git a/internal/openstack/version.go b/internal/openstack/version.go index 5eaf787185..422560e4fd 100644 --- a/internal/openstack/version.go +++ b/internal/openstack/version.go @@ -11,6 +11,7 @@ import ( corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/api/core/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -228,7 +229,8 @@ func InitializeOpenStackVersionServiceDefaults(ctx context.Context) *corev1beta1 // but get set to true here for FR3 available versions and thus provide a way for services to migrate // to new deployment topologies trueString := "true" - defaults.GlanceWsgi = &trueString // all new glance deployments use WSGI by default (FR3 and later) + defaults.GlanceWsgi = &trueString // all new glance deployments use WSGI by default (FR3 and later) + defaults.GlanceLocationAPI = ptr.To("false") // disable location-api for RHOSO 18: this boolean can be switched to true with RHOSO 19 release versionString := "4.2" defaults.RabbitmqVersion = &versionString // all new rabbitmq deployments will have rabbitmq-server 4.2 (FR5) diff --git a/test/functional/ctlplane/openstackoperator_controller_test.go b/test/functional/ctlplane/openstackoperator_controller_test.go index 30b20398b9..6ac8e0baa6 100644 --- a/test/functional/ctlplane/openstackoperator_controller_test.go +++ b/test/functional/ctlplane/openstackoperator_controller_test.go @@ -3718,8 +3718,8 @@ var _ = Describe("OpenStackOperator Webhook", func() { Expect(errors.As(err, &statusError)).To(BeTrue()) Expect(statusError.ErrStatus.Details.Kind).To(Equal("OpenStackControlPlane")) Expect(statusError.ErrStatus.Message).To( - ContainSubstring( - "Invalid value: \"foo-1234567890-1234567890-1234567890-1234567890-1234567890\": must be no more than 39 characters"), + MatchRegexp( + "Invalid value: \"foo-1234567890-1234567890-1234567890-1234567890-1234567890\": must be no more than \\d+ characters"), ) }) @@ -3763,8 +3763,8 @@ var _ = Describe("OpenStackOperator Webhook", func() { Expect(errors.As(err, &statusError)).To(BeTrue()) Expect(statusError.ErrStatus.Details.Kind).To(Equal("OpenStackControlPlane")) Expect(statusError.ErrStatus.Message).To( - ContainSubstring( - "Invalid value: \"foo-1234567890-1234567890-1234567890-1234567890-1234567890\": must be no more than 33 characters"), + MatchRegexp( + "Invalid value: \"foo-1234567890-1234567890-1234567890-1234567890-1234567890\": must be no more than \\d+ characters"), ) })