From be2d4b59114850f335d7c1dbf7e8aadf5008339a 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_openstackcontrolplanes.yaml | 2 +- api/bases/core.openstack.org_openstackversions.yaml | 4 ++++ api/core/v1beta1/openstackversion_types.go | 1 + api/core/v1beta1/zz_generated.deepcopy.go | 5 +++++ api/go.mod | 2 ++ api/go.sum | 4 ++-- bindata/crds/crds.yaml | 6 +++++- bindata/crds/glance.openstack.org_glanceapis.yaml | 4 ++-- bindata/crds/glance.openstack.org_glances.yaml | 2 +- .../bases/core.openstack.org_openstackcontrolplanes.yaml | 2 +- .../crd/bases/core.openstack.org_openstackversions.yaml | 4 ++++ go.mod | 2 ++ go.sum | 4 ++-- internal/openstack/glance.go | 5 +++++ internal/openstack/version.go | 4 +++- .../ctlplane/openstackoperator_controller_test.go | 8 ++++---- 16 files changed, 44 insertions(+), 15 deletions(-) diff --git a/api/bases/core.openstack.org_openstackcontrolplanes.yaml b/api/bases/core.openstack.org_openstackcontrolplanes.yaml index 4a0ec3233..c7317bc23 100644 --- a/api/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/api/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -4658,7 +4658,7 @@ spec: type: string type: object type: - default: split + default: single enum: - split - single diff --git a/api/bases/core.openstack.org_openstackversions.yaml b/api/bases/core.openstack.org_openstackversions.yaml index ae79d6c77..902513873 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 type: object @@ -683,6 +685,8 @@ spec: type: integer serviceDefaults: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string type: object diff --git a/api/core/v1beta1/openstackversion_types.go b/api/core/v1beta1/openstackversion_types.go index 1f138156d..3410ac2f3 100644 --- a/api/core/v1beta1/openstackversion_types.go +++ b/api/core/v1beta1/openstackversion_types.go @@ -178,6 +178,7 @@ type ContainerTemplate struct { // but are associated with a specific OpenStack release version type ServiceDefaults struct { GlanceWsgi *string `json:"glanceWsgi,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 b8b1cf7fe..a77afa2ee 100644 --- a/api/core/v1beta1/zz_generated.deepcopy.go +++ b/api/core/v1beta1/zz_generated.deepcopy.go @@ -1763,6 +1763,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/api/go.mod b/api/go.mod index 104e02dcf..968163ddd 100644 --- a/api/go.mod +++ b/api/go.mod @@ -143,3 +143,5 @@ replace k8s.io/code-generator => k8s.io/code-generator v0.31.14 //allow-merging replace k8s.io/component-base => k8s.io/component-base v0.31.14 //allow-merging replace github.com/cert-manager/cmctl/v2 => github.com/cert-manager/cmctl/v2 v2.1.2-0.20241127223932-88edb96860cf //allow-merging + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/fmount/glance-operator/api v0.1.2-0.20260305205814-319db2e0e586 diff --git a/api/go.sum b/api/go.sum index 1e7493454..c326cfd10 100644 --- a/api/go.sum +++ b/api/go.sum @@ -16,6 +16,8 @@ github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/fmount/glance-operator/api v0.1.2-0.20260305205814-319db2e0e586 h1:JGoFeaOx2eHXnXSeE63wE+8RYfUcpBe/3G8+VCYPM8Y= +github.com/fmount/glance-operator/api v0.1.2-0.20260305205814-319db2e0e586/go.mod h1:4Y0Q6mnvhxYe4ZXhfr20NAZ23QOT5qsaU3R1E5tdd34= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= @@ -120,8 +122,6 @@ github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260304071337-6 github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260304071337-63312061d576/go.mod h1:Ta5iogB0ASRIz3tZBV5tmuWBkxKfLcCX/zm1sLLs4MM= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260302083231-563bef879f57 h1:vgIrNDgCARoTi/EvPG8U4DPt9YXeCbneJEAI1Yyi2KQ= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260302083231-563bef879f57/go.mod h1:mvJ6d6hH6vM9KH3Gs7Z7coAEaHe0oI4KNA+Q5sqM+tA= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260307070902-e95146e9e7f0 h1:qxvQv2nb4JKTUt+0izG6kEoicSgqUutqZOyz9SbtDVw= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260307070902-e95146e9e7f0/go.mod h1:HFww0mYz6ziCXbUqF5QH0OHVVfv+2At3zxG3gpIDjYA= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260304090236-61c1f63e5bfb h1:LRrECidXOAJXJts+1TJgum1ZGNJIQj3v73hdC+NSqo8= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260304090236-61c1f63e5bfb/go.mod h1:sXlGVZlqKvRJ0RXGb1ze6a7e5+N/ZOVqSpOTGrBVhIo= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260228155252-bb17197b83a6 h1:AtuwSvzQs3UoVY37KouH27un8uMqJ+mZvpCc/Y019Ho= diff --git a/bindata/crds/crds.yaml b/bindata/crds/crds.yaml index 0b90b4f9e..caa9a1b74 100644 --- a/bindata/crds/crds.yaml +++ b/bindata/crds/crds.yaml @@ -4923,7 +4923,7 @@ spec: type: string type: object type: - default: split + default: single enum: - split - single @@ -21459,6 +21459,8 @@ spec: availableServiceDefaults: additionalProperties: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string type: object @@ -21894,6 +21896,8 @@ spec: type: integer serviceDefaults: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string type: object diff --git a/bindata/crds/glance.openstack.org_glanceapis.yaml b/bindata/crds/glance.openstack.org_glanceapis.yaml index 23baebac7..473f0328c 100644 --- a/bindata/crds/glance.openstack.org_glanceapis.yaml +++ b/bindata/crds/glance.openstack.org_glanceapis.yaml @@ -58,7 +58,7 @@ spec: minimum: 1 type: integer apiType: - default: external + default: single enum: - internal - external @@ -1581,7 +1581,7 @@ spec: type: string type: object type: - default: split + default: single description: Type - represents the layout of the glanceAPI deployment. enum: - split diff --git a/bindata/crds/glance.openstack.org_glances.yaml b/bindata/crds/glance.openstack.org_glances.yaml index 730a56fb5..93a15c4fb 100644 --- a/bindata/crds/glance.openstack.org_glances.yaml +++ b/bindata/crds/glance.openstack.org_glances.yaml @@ -1575,7 +1575,7 @@ spec: type: string type: object type: - default: split + default: single description: Type - represents the layout of the glanceAPI deployment. enum: - split diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 4a0ec3233..c7317bc23 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -4658,7 +4658,7 @@ spec: type: string type: object type: - default: split + default: single enum: - split - single diff --git a/config/crd/bases/core.openstack.org_openstackversions.yaml b/config/crd/bases/core.openstack.org_openstackversions.yaml index ae79d6c77..902513873 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 type: object @@ -683,6 +685,8 @@ spec: type: integer serviceDefaults: properties: + glanceLocationAPI: + type: string glanceWsgi: type: string type: object diff --git a/go.mod b/go.mod index 016f20a72..94fba4a3e 100644 --- a/go.mod +++ b/go.mod @@ -181,3 +181,5 @@ replace k8s.io/code-generator => k8s.io/code-generator v0.31.14 //allow-merging replace k8s.io/component-base => k8s.io/component-base v0.31.14 //allow-merging replace github.com/cert-manager/cmctl/v2 => github.com/cert-manager/cmctl/v2 v2.1.2-0.20241127223932-88edb96860cf //allow-merging + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/fmount/glance-operator/api v0.1.2-0.20260305205814-319db2e0e586 diff --git a/go.sum b/go.sum index 8330a3694..56b18f86a 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjT github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fmount/glance-operator/api v0.1.2-0.20260305205814-319db2e0e586 h1:JGoFeaOx2eHXnXSeE63wE+8RYfUcpBe/3G8+VCYPM8Y= +github.com/fmount/glance-operator/api v0.1.2-0.20260305205814-319db2e0e586/go.mod h1:4Y0Q6mnvhxYe4ZXhfr20NAZ23QOT5qsaU3R1E5tdd34= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= @@ -144,8 +146,6 @@ github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260304071337-6 github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20260304071337-63312061d576/go.mod h1:Ta5iogB0ASRIz3tZBV5tmuWBkxKfLcCX/zm1sLLs4MM= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260302083231-563bef879f57 h1:vgIrNDgCARoTi/EvPG8U4DPt9YXeCbneJEAI1Yyi2KQ= github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20260302083231-563bef879f57/go.mod h1:mvJ6d6hH6vM9KH3Gs7Z7coAEaHe0oI4KNA+Q5sqM+tA= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260307070902-e95146e9e7f0 h1:qxvQv2nb4JKTUt+0izG6kEoicSgqUutqZOyz9SbtDVw= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20260307070902-e95146e9e7f0/go.mod h1:HFww0mYz6ziCXbUqF5QH0OHVVfv+2At3zxG3gpIDjYA= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260304090236-61c1f63e5bfb h1:LRrECidXOAJXJts+1TJgum1ZGNJIQj3v73hdC+NSqo8= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20260304090236-61c1f63e5bfb/go.mod h1:sXlGVZlqKvRJ0RXGb1ze6a7e5+N/ZOVqSpOTGrBVhIo= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20260228155252-bb17197b83a6 h1:AtuwSvzQs3UoVY37KouH27un8uMqJ+mZvpCc/Y019Ho= diff --git a/internal/openstack/glance.go b/internal/openstack/glance.go index 2ab1eaf63..f94a4e422 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 f15e6c191..551eb265b 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 return defaults } diff --git a/test/functional/ctlplane/openstackoperator_controller_test.go b/test/functional/ctlplane/openstackoperator_controller_test.go index f237bc269..ccbd1205a 100644 --- a/test/functional/ctlplane/openstackoperator_controller_test.go +++ b/test/functional/ctlplane/openstackoperator_controller_test.go @@ -3556,8 +3556,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"), ) }) @@ -3601,8 +3601,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"), ) })