Skip to content

Commit 3cf0bfe

Browse files
lmicciniclaude
andcommitted
Fix NodeSelector nil-vs-pointer reconcile loop in all service reconcilers
When the OSCP has no nodeSelector defined, instance.Spec.NodeSelector is a nil map. Taking its address (&instance.Spec.NodeSelector) creates a non-nil pointer to a nil map, which is structurally different from a nil pointer. controllerutil.CreateOrPatch detects this as a diff via reflect.DeepEqual and sends an update patch on every reconcile, bumping the sub-CR's Generation. The ObservedGeneration readiness check then reports the sub-CR as "in progress", triggering another OSCP reconcile and creating an infinite loop (~1 update/second). Guard all 25 NodeSelector inheritance assignments with len(instance.Spec.NodeSelector) > 0 so the assignment is skipped when the OSCP nodeSelector is nil or empty, avoiding the spurious diff. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 64e838e commit 3cf0bfe

23 files changed

Lines changed: 25 additions & 25 deletions

internal/openstack/barbican.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr
149149
instance.Spec.Barbican.Template.BarbicanAPI.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal)
150150
}
151151

152-
if instance.Spec.Barbican.Template.NodeSelector == nil {
152+
if instance.Spec.Barbican.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
153153
instance.Spec.Barbican.Template.NodeSelector = &instance.Spec.NodeSelector
154154
}
155155

internal/openstack/cinder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl
172172
instance.Spec.Cinder.Template.CinderAPI.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal)
173173
}
174174

175-
if instance.Spec.Cinder.Template.NodeSelector == nil {
175+
if instance.Spec.Cinder.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
176176
instance.Spec.Cinder.Template.NodeSelector = &instance.Spec.NodeSelector
177177
}
178178

internal/openstack/designate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont
156156
instance.Spec.Designate.Template.DesignateAPI.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal)
157157
}
158158

159-
if instance.Spec.Designate.Template.NodeSelector == nil {
159+
if instance.Spec.Designate.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
160160
instance.Spec.Designate.Template.NodeSelector = &instance.Spec.NodeSelector
161161
}
162162

internal/openstack/dnsmasq.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func ReconcileDNSMasqs(ctx context.Context, instance *corev1beta1.OpenStackContr
4040
instance.Spec.DNS.Template = &networkv1.DNSMasqSpecCore{}
4141
}
4242

43-
if instance.Spec.DNS.Template.NodeSelector == nil {
43+
if instance.Spec.DNS.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
4444
instance.Spec.DNS.Template.NodeSelector = &instance.Spec.NodeSelector
4545
}
4646

internal/openstack/galera.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ func reconcileGalera(
266266
return galeraReady, galera, nil
267267
}
268268

269-
if spec.NodeSelector == nil {
269+
if spec.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
270270
spec.NodeSelector = &instance.Spec.NodeSelector
271271
}
272272

internal/openstack/glance.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl
9494
instance.Spec.Glance.Template.NotificationBusInstance = nil
9595
}
9696

97-
if instance.Spec.Glance.Template.NodeSelector == nil {
97+
if instance.Spec.Glance.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
9898
instance.Spec.Glance.Template.NodeSelector = &instance.Spec.NodeSelector
9999
}
100100

internal/openstack/heat.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl
5454
// Note: Migration from rabbitMqClusterName to messagingBus.cluster is handled by the webhook
5555
// via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts.
5656

57-
if instance.Spec.Heat.Template.NodeSelector == nil {
57+
if instance.Spec.Heat.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
5858
instance.Spec.Heat.Template.NodeSelector = &instance.Spec.NodeSelector
5959
}
6060

internal/openstack/horizon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func ReconcileHorizon(ctx context.Context, instance *corev1beta1.OpenStackContro
5050
instance.Spec.Horizon.Template = &horizonv1.HorizonSpecCore{}
5151
}
5252

53-
if instance.Spec.Horizon.Template.NodeSelector == nil {
53+
if instance.Spec.Horizon.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
5454
instance.Spec.Horizon.Template.NodeSelector = &instance.Spec.NodeSelector
5555
}
5656

internal/openstack/ironic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl
5858
// via annotation-based triggers. No direct spec mutation here to avoid GitOps conflicts.
5959
// This applies to both Ironic main template and IronicNeutronAgent.
6060

61-
if instance.Spec.Ironic.Template.NodeSelector == nil {
61+
if instance.Spec.Ironic.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
6262
instance.Spec.Ironic.Template.NodeSelector = &instance.Spec.NodeSelector
6363
}
6464

internal/openstack/keystone.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo
106106
instance.Spec.Keystone.Template.TLS.API.Internal.SecretName = endpointDetails.GetEndptCertSecret(service.EndpointInternal)
107107
}
108108

109-
if instance.Spec.Keystone.Template.NodeSelector == nil {
109+
if instance.Spec.Keystone.Template.NodeSelector == nil && len(instance.Spec.NodeSelector) > 0 {
110110
instance.Spec.Keystone.Template.NodeSelector = &instance.Spec.NodeSelector
111111
}
112112

0 commit comments

Comments
 (0)