Skip to content

Commit c3c0000

Browse files
committed
[traits-controller] use retryOnConflict to reduce conflicts
1 parent 58bd3d1 commit c3c0000

1 file changed

Lines changed: 40 additions & 25 deletions

File tree

internal/controller/traits_controller.go

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ import (
2121
"context"
2222
"slices"
2323
"strings"
24+
"time"
2425

2526
"k8s.io/apimachinery/pkg/api/meta"
2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2728
"k8s.io/apimachinery/pkg/runtime"
29+
"k8s.io/client-go/util/retry"
2830
ctrl "sigs.k8s.io/controller-runtime"
2931
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
3032
logger "sigs.k8s.io/controller-runtime/pkg/log"
@@ -64,9 +66,9 @@ func (tc *TraitsController) Reconcile(ctx context.Context, req ctrl.Request) (ct
6466
return ctrl.Result{}, nil
6567
}
6668

67-
// ensure HV is ready
68-
if !meta.IsStatusConditionTrue(hv.Status.Conditions, kvmv1.ConditionTypeReady) {
69-
return ctrl.Result{}, nil
69+
// ensure hypervisorID is set
70+
if hv.Status.HypervisorID == "" {
71+
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
7072
}
7173

7274
customTraitsApplied := slices.Collect(func(yield func(string) bool) {
@@ -88,14 +90,7 @@ func (tc *TraitsController) Reconcile(ctx context.Context, req ctrl.Request) (ct
8890
// fetch current traits, to ensure we don't add duplicates
8991
current, err := resourceproviders.GetTraits(ctx, tc.serviceClient, hv.Status.HypervisorID).Extract()
9092
if err != nil {
91-
// set status condition
92-
meta.SetStatusCondition(&hv.Status.Conditions, metav1.Condition{
93-
Type: ConditionTypeTraitsUpdated,
94-
Status: metav1.ConditionFalse,
95-
Reason: ConditionTraitsFailed,
96-
Message: err.Error(),
97-
})
98-
return ctrl.Result{}, tc.Status().Update(ctx, hv)
93+
return ctrl.Result{}, tc.UpdateStatusCondition(ctx, hv, err, "Failed to get current traits from placement")
9994
}
10095

10196
var targetTraits []string
@@ -122,26 +117,46 @@ func (tc *TraitsController) Reconcile(ctx context.Context, req ctrl.Request) (ct
122117

123118
if result.Err != nil {
124119
// set status condition
125-
meta.SetStatusCondition(&hv.Status.Conditions, metav1.Condition{
126-
Type: ConditionTypeTraitsUpdated,
127-
Status: metav1.ConditionFalse,
128-
Reason: ConditionTraitsFailed,
129-
Message: result.Err.Error(),
130-
})
131-
return ctrl.Result{}, tc.Status().Update(ctx, hv)
120+
return ctrl.Result{}, tc.UpdateStatusCondition(ctx, hv, result.Err, "Failed to update traits in placement")
132121
}
133122
}
134123

135124
// update status
136125
hv.Status.Traits = targetTraits
137-
meta.SetStatusCondition(&hv.Status.Conditions, metav1.Condition{
138-
Type: ConditionTypeTraitsUpdated,
139-
Status: metav1.ConditionTrue,
140-
Reason: ConditionTraitsSuccess,
141-
Message: "Traits successfully updated",
142-
})
126+
return ctrl.Result{}, tc.UpdateStatusCondition(ctx, hv, nil, "Traits successfully updated")
127+
}
128+
129+
// UpdateStatusCondition updates the TraitsUpdated condition of the Hypervisor status and handles conflicts by retrying.
130+
func (tc *TraitsController) UpdateStatusCondition(ctx context.Context, orig *kvmv1.Hypervisor, err error, msg string) error {
131+
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
132+
hv := &kvmv1.Hypervisor{}
133+
if err := tc.Get(ctx, k8sclient.ObjectKeyFromObject(orig), hv); err != nil {
134+
return err
135+
}
136+
// set status condition
137+
var reason, message string
138+
var status = metav1.ConditionTrue
139+
reason = ConditionTraitsSuccess
140+
message = msg
141+
142+
if err != nil {
143+
status = metav1.ConditionFalse
144+
reason = ConditionTraitsFailed
145+
message = err.Error()
146+
if msg != "" {
147+
message = msg + ": " + message
148+
}
149+
}
143150

144-
return ctrl.Result{}, tc.Status().Update(ctx, hv)
151+
hv.Status.Traits = orig.Status.Traits
152+
meta.SetStatusCondition(&hv.Status.Conditions, metav1.Condition{
153+
Type: ConditionTypeTraitsUpdated,
154+
Status: status,
155+
Reason: reason,
156+
Message: message,
157+
})
158+
return tc.Status().Update(ctx, hv)
159+
})
145160
}
146161

147162
// SetupWithManager sets up the controller with the Manager.

0 commit comments

Comments
 (0)