@@ -20,6 +20,7 @@ package controller
2020import (
2121 "context"
2222 "fmt"
23+ "reflect"
2324 "slices"
2425 "strings"
2526
@@ -111,14 +112,15 @@ func (hv *HypervisorController) Reconcile(ctx context.Context, req ctrl.Request)
111112 return ctrl.Result {}, hv .Status ().Update (ctx , hypervisor )
112113 }
113114 }
114- return ctrl.Result {}, nil
115- }
116115
117- // transfer labels
118- for _ , label := range transferLabels {
119- if nodeLabels .Has (label ) {
120- hypervisor .Labels [label ] = nodeLabels .Get (label )
116+ // transport label/anotations changes
117+ before := hypervisor .DeepCopy ()
118+ updateLabelsAndAnnotations (& node .ObjectMeta , hypervisor )
119+ if ! reflect .DeepEqual (before , hypervisor ) {
120+ return ctrl.Result {}, hv .Patch (ctx , hypervisor , k8sclient .MergeFrom (before ))
121121 }
122+
123+ return ctrl.Result {}, nil
122124 }
123125
124126 // transport lifecycle label to hypervisor spec
@@ -127,31 +129,8 @@ func (hv *HypervisorController) Reconcile(ctx context.Context, req ctrl.Request)
127129 hypervisor .Spec .SkipTests = nodeLabels .Get (labelLifecycleMode ) == "skip-tests"
128130 }
129131
130- // transport aggregates annotation to hypervisor spec
131- if aggregates , found := node .Annotations [annotationAggregates ]; found {
132- // split aggregates string
133- hypervisor .Spec .Aggregates = slices .Collect (func (yield func (string ) bool ) {
134- for _ , agg := range strings .Split (aggregates , "," ) {
135- trimmed := strings .TrimSpace (agg )
136- if trimmed != "" && yield (trimmed ) {
137- return
138- }
139- }
140- })
141- }
142-
143- // transport custom traits annotation to hypervisor spec
144- if customTraits , found := node .Annotations [annotationCustomTraits ]; found {
145- // split custom traits string
146- hypervisor .Spec .CustomTraits = slices .Collect (func (yield func (string ) bool ) {
147- for _ , trait := range strings .Split (customTraits , "," ) {
148- trimmed := strings .TrimSpace (trait )
149- if trimmed != "" && yield (trimmed ) {
150- return
151- }
152- }
153- })
154- }
132+ // transport relevant annotations
133+ updateLabelsAndAnnotations (& node .ObjectMeta , hypervisor )
155134
156135 if err := controllerutil .SetOwnerReference (node , hypervisor , hv .Scheme , controllerutil .WithBlockOwnerDeletion (true )); err != nil {
157136 return ctrl.Result {}, fmt .Errorf ("failed setting controller reference: %w" , err )
@@ -183,3 +162,39 @@ func (hv *HypervisorController) SetupWithManager(mgr ctrl.Manager) error {
183162 WithEventFilter (novaVirtLabeledPredicate ).
184163 Complete (hv )
185164}
165+
166+ // updateLabelsAndAnnotations transports relevant annotations from the Node to the Hypervisor spec
167+ func updateLabelsAndAnnotations (node * metav1.ObjectMeta , hypervisor * kvmv1.Hypervisor ) {
168+ // transport aggregates annotation to hypervisor spec
169+ if aggregates , found := node .Annotations [annotationAggregates ]; found {
170+ // split aggregates string
171+ hypervisor .Spec .Aggregates = slices .Collect (func (yield func (string ) bool ) {
172+ for _ , agg := range strings .Split (aggregates , "," ) {
173+ trimmed := strings .TrimSpace (agg )
174+ if trimmed != "" && yield (trimmed ) {
175+ return
176+ }
177+ }
178+ })
179+ }
180+
181+ // transport custom traits annotation to hypervisor spec
182+ if customTraits , found := node .Annotations [annotationCustomTraits ]; found {
183+ // split custom traits string
184+ hypervisor .Spec .CustomTraits = slices .Collect (func (yield func (string ) bool ) {
185+ for _ , trait := range strings .Split (customTraits , "," ) {
186+ trimmed := strings .TrimSpace (trait )
187+ if trimmed != "" && yield (trimmed ) {
188+ return
189+ }
190+ }
191+ })
192+ }
193+
194+ // transfer labels
195+ for _ , transferLabel := range transferLabels {
196+ if label , ok := node .Labels [transferLabel ]; ok {
197+ hypervisor .Labels [transferLabel ] = label
198+ }
199+ }
200+ }
0 commit comments