Skip to content

Commit 016c808

Browse files
committed
Hypervisor: Always reflect node annotations in hypervisor-spec
Only syncing on creation introduced a race-condition: The node may have been created, but the labels and annotations get synced later. To fix that, always sync the annotations, provided they are set. Should another CRD in the cluster manage these specs via another operator, we simply need to remove the annotations first.
1 parent 8013d62 commit 016c808

File tree

1 file changed

+21
-21
lines changed

1 file changed

+21
-21
lines changed

internal/controller/hypervisor_controller.go

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ package controller
2020
import (
2121
"context"
2222
"fmt"
23-
"reflect"
2423
"slices"
2524
"strings"
2625

2726
corev1 "k8s.io/api/core/v1"
27+
"k8s.io/apimachinery/pkg/api/equality"
2828
"k8s.io/apimachinery/pkg/api/errors"
2929
"k8s.io/apimachinery/pkg/api/meta"
3030
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -131,25 +131,16 @@ func (hv *HypervisorController) Reconcile(ctx context.Context, req ctrl.Request)
131131
return ctrl.Result{}, hv.Status().Update(ctx, hypervisor)
132132
}
133133

134-
// transport label changes
135134
before := hypervisor.DeepCopy()
136-
if transportLabels(&node.ObjectMeta, hypervisor) {
137-
return ctrl.Result{}, hv.Patch(ctx, hypervisor, k8sclient.MergeFrom(before))
135+
syncLabelsAndAnnotations(nodeLabels, hypervisor, node)
136+
if equality.Semantic.DeepEqual(hypervisor, before) {
137+
return ctrl.Result{}, nil
138138
}
139139

140-
return ctrl.Result{}, nil
140+
return ctrl.Result{}, hv.Patch(ctx, hypervisor, k8sclient.MergeFromWithOptions(before, k8sclient.MergeFromWithOptimisticLock{}))
141141
}
142142

143-
// transport lifecycle label to hypervisor spec
144-
if nodeLabels.Has(labelLifecycleMode) {
145-
hypervisor.Spec.LifecycleEnabled = true
146-
hypervisor.Spec.SkipTests = nodeLabels.Get(labelLifecycleMode) == "skip-tests"
147-
}
148-
149-
// transport relevant labels
150-
transportLabels(&node.ObjectMeta, hypervisor)
151-
// transport relevant annotations
152-
transportAggregatesAndTraits(&node.ObjectMeta, hypervisor)
143+
syncLabelsAndAnnotations(nodeLabels, hypervisor, node)
153144

154145
if err := controllerutil.SetOwnerReference(node, hypervisor, hv.Scheme, controllerutil.WithBlockOwnerDeletion(true)); err != nil {
155146
return ctrl.Result{}, fmt.Errorf("failed setting controller reference: %w", err)
@@ -163,6 +154,19 @@ func (hv *HypervisorController) Reconcile(ctx context.Context, req ctrl.Request)
163154
return ctrl.Result{}, nil
164155
}
165156

157+
func syncLabelsAndAnnotations(nodeLabels labels.Set, hypervisor *kvmv1.Hypervisor, node *corev1.Node) {
158+
// transport lifecycle label to hypervisor spec
159+
if nodeLabels.Has(labelLifecycleMode) {
160+
hypervisor.Spec.LifecycleEnabled = true
161+
hypervisor.Spec.SkipTests = nodeLabels.Get(labelLifecycleMode) == "skip-tests"
162+
}
163+
164+
// transport relevant labels
165+
transportLabels(&node.ObjectMeta, hypervisor)
166+
// transport relevant annotations
167+
transportAggregatesAndTraits(&node.ObjectMeta, hypervisor)
168+
}
169+
166170
func (hv *HypervisorController) SetupWithManager(mgr ctrl.Manager) error {
167171
novaVirtLabeledPredicate, err := predicate.LabelSelectorPredicate(metav1.LabelSelector{
168172
MatchExpressions: []metav1.LabelSelectorRequirement{
@@ -189,8 +193,7 @@ func (hv *HypervisorController) SetupWithManager(mgr ctrl.Manager) error {
189193
}
190194

191195
// transportAggregatesAndTraits transports relevant aggregates/traits from the Node to the Hypervisor spec
192-
func transportAggregatesAndTraits(node *metav1.ObjectMeta, hypervisor *kvmv1.Hypervisor) bool {
193-
before := hypervisor.DeepCopy()
196+
func transportAggregatesAndTraits(node *metav1.ObjectMeta, hypervisor *kvmv1.Hypervisor) {
194197
// transport aggregates annotation to hypervisor spec
195198
if aggregates, found := node.Annotations[annotationAggregates]; found {
196199
// split aggregates string
@@ -216,17 +219,14 @@ func transportAggregatesAndTraits(node *metav1.ObjectMeta, hypervisor *kvmv1.Hyp
216219
}
217220
})
218221
}
219-
return !reflect.DeepEqual(before, hypervisor)
220222
}
221223

222224
// transportLabels transports relevant labels from the Node to the Hypervisor spec
223-
func transportLabels(node *metav1.ObjectMeta, hypervisor *kvmv1.Hypervisor) bool {
224-
before := hypervisor.DeepCopy()
225+
func transportLabels(node *metav1.ObjectMeta, hypervisor *kvmv1.Hypervisor) {
225226
// transfer labels
226227
for _, transferLabel := range transferLabels {
227228
if label, ok := node.Labels[transferLabel]; ok {
228229
hypervisor.Labels[transferLabel] = label
229230
}
230231
}
231-
return !reflect.DeepEqual(before, hypervisor)
232232
}

0 commit comments

Comments
 (0)