Skip to content

Commit 96fbc86

Browse files
🌱 Requeue for Machine Available condition (#12953)
* Requeue for machine Available condition * Address feedback
1 parent 3278bbb commit 96fbc86

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

internal/controllers/machine/machine_controller.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ func (r *Reconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, opt
195195
return nil
196196
}
197197

198-
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Result, reterr error) {
198+
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (retres ctrl.Result, reterr error) {
199199
// Fetch the Machine instance
200200
m := &clusterv1.Machine{}
201201
if err := r.Client.Get(ctx, req.NamespacedName, m); err != nil {
@@ -255,7 +255,8 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re
255255
}
256256

257257
defer func() {
258-
r.updateStatus(ctx, s)
258+
updateRes := r.updateStatus(ctx, s)
259+
retres = util.LowestNonZeroResult(retres, updateRes)
259260

260261
// Always attempt to patch the object and status after each reconciliation.
261262
// Patch ObservedGeneration only if the reconciliation completed successfully

internal/controllers/machine/machine_controller_status.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import (
4242
// machine being partially deleted but also for running machines being disrupted e.g. by deleting the node.
4343
// Additionally, this func should ensure that the conditions managed by this controller are always set in order to
4444
// comply with the recommendation in the Kubernetes API guidelines.
45-
func (r *Reconciler) updateStatus(ctx context.Context, s *scope) {
45+
func (r *Reconciler) updateStatus(ctx context.Context, s *scope) ctrl.Result {
4646
// Update status from the Bootstrap Config external resource.
4747
// Note: some of the status fields derived from the Bootstrap Config are managed in reconcileBootstrap, e.g. status.BootstrapReady, etc.
4848
// here we are taking care only of the delta (condition).
@@ -67,9 +67,9 @@ func (r *Reconciler) updateStatus(ctx context.Context, s *scope) {
6767
setDeletingCondition(ctx, s.machine, s.reconcileDeleteExecuted, s.deletingReason, s.deletingMessage)
6868
setUpdatingCondition(ctx, s.machine, s.updatingReason, s.updatingMessage)
6969
setReadyCondition(ctx, s.machine)
70-
setAvailableCondition(ctx, s.machine)
71-
7270
setMachinePhaseAndLastUpdated(ctx, s.machine)
71+
72+
return setAvailableCondition(ctx, s.machine)
7373
}
7474

7575
func setBootstrapReadyCondition(_ context.Context, machine *clusterv1.Machine, bootstrapConfig *unstructured.Unstructured, bootstrapConfigIsNotFound bool) {
@@ -774,7 +774,7 @@ func calculateDeletingConditionForSummary(machine *clusterv1.Machine) conditions
774774
}
775775
}
776776

777-
func setAvailableCondition(ctx context.Context, machine *clusterv1.Machine) {
777+
func setAvailableCondition(ctx context.Context, machine *clusterv1.Machine) ctrl.Result {
778778
log := ctrl.LoggerFrom(ctx)
779779
readyCondition := conditions.Get(machine, clusterv1.MachineReadyCondition)
780780

@@ -788,7 +788,7 @@ func setAvailableCondition(ctx context.Context, machine *clusterv1.Machine) {
788788
Reason: clusterv1.MachineAvailableInternalErrorReason,
789789
Message: "Please check controller logs for errors",
790790
})
791-
return
791+
return ctrl.Result{}
792792
}
793793

794794
if readyCondition.Status != metav1.ConditionTrue {
@@ -797,23 +797,25 @@ func setAvailableCondition(ctx context.Context, machine *clusterv1.Machine) {
797797
Status: metav1.ConditionFalse,
798798
Reason: clusterv1.MachineNotReadyReason,
799799
})
800-
return
800+
return ctrl.Result{}
801801
}
802802

803-
if time.Since(readyCondition.LastTransitionTime.Time) >= time.Duration(ptr.Deref(machine.Spec.MinReadySeconds, 0))*time.Second {
803+
t := time.Since(readyCondition.LastTransitionTime.Time) - time.Duration(ptr.Deref(machine.Spec.MinReadySeconds, 0))*time.Second
804+
if t >= 0 {
804805
conditions.Set(machine, metav1.Condition{
805806
Type: clusterv1.MachineAvailableCondition,
806807
Status: metav1.ConditionTrue,
807808
Reason: clusterv1.MachineAvailableReason,
808809
})
809-
return
810+
return ctrl.Result{}
810811
}
811812

812813
conditions.Set(machine, metav1.Condition{
813814
Type: clusterv1.MachineAvailableCondition,
814815
Status: metav1.ConditionFalse,
815816
Reason: clusterv1.MachineWaitingForMinReadySecondsReason,
816817
})
818+
return ctrl.Result{RequeueAfter: -t}
817819
}
818820

819821
func setMachinePhaseAndLastUpdated(_ context.Context, m *clusterv1.Machine) {

internal/controllers/machine/machine_controller_status_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2929
utilfeature "k8s.io/component-base/featuregate/testing"
3030
"k8s.io/utils/ptr"
31+
ctrl "sigs.k8s.io/controller-runtime"
3132
"sigs.k8s.io/controller-runtime/pkg/client"
3233

3334
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
@@ -1967,6 +1968,7 @@ func TestAvailableCondition(t *testing.T) {
19671968
name string
19681969
machine *clusterv1.Machine
19691970
expectCondition metav1.Condition
1971+
expectRes ctrl.Result
19701972
}{
19711973
{
19721974
name: "Not Ready",
@@ -1990,6 +1992,7 @@ func TestAvailableCondition(t *testing.T) {
19901992
Status: metav1.ConditionFalse,
19911993
Reason: clusterv1.MachineNotReadyReason,
19921994
},
1995+
expectRes: ctrl.Result{},
19931996
},
19941997
{
19951998
name: "Ready but still waiting for MinReadySeconds",
@@ -2014,6 +2017,7 @@ func TestAvailableCondition(t *testing.T) {
20142017
Status: metav1.ConditionFalse,
20152018
Reason: clusterv1.MachineWaitingForMinReadySecondsReason,
20162019
},
2020+
expectRes: ctrl.Result{RequeueAfter: 10 * time.Second},
20172021
},
20182022
{
20192023
name: "Ready and available",
@@ -2038,18 +2042,24 @@ func TestAvailableCondition(t *testing.T) {
20382042
Status: metav1.ConditionTrue,
20392043
Reason: clusterv1.MachineAvailableReason,
20402044
},
2045+
expectRes: ctrl.Result{},
20412046
},
20422047
}
20432048

20442049
for _, tc := range testCases {
20452050
t.Run(tc.name, func(t *testing.T) {
20462051
g := NewWithT(t)
20472052

2048-
setAvailableCondition(ctx, tc.machine)
2053+
res := setAvailableCondition(ctx, tc.machine)
20492054

20502055
availableCondition := conditions.Get(tc.machine, clusterv1.MachineAvailableCondition)
20512056
g.Expect(availableCondition).ToNot(BeNil())
20522057
g.Expect(*availableCondition).To(conditions.MatchCondition(tc.expectCondition, conditions.IgnoreLastTransitionTime(true)))
2058+
2059+
g.Expect(res.IsZero()).To(Equal(tc.expectRes.IsZero()))
2060+
if !tc.expectRes.IsZero() {
2061+
g.Expect(res.RequeueAfter).To(BeNumerically("~", tc.expectRes.RequeueAfter, 100*time.Millisecond))
2062+
}
20532063
})
20542064
}
20552065
}

0 commit comments

Comments
 (0)