Skip to content

Commit 57a5454

Browse files
authored
Merge pull request #3772 from vincepri/backport3759-3740
🌱 [0.3] Backport 3740, 3759, and 3723
2 parents af66309 + cbdb964 commit 57a5454

File tree

7 files changed

+92
-74
lines changed

7 files changed

+92
-74
lines changed

controllers/machine_controller.go

+12-18
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,6 @@ func patchMachine(ctx context.Context, patchHelper *patch.Helper, machine *clust
235235
}
236236

237237
func (r *MachineReconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.Machine) (ctrl.Result, error) {
238-
logger := r.Log.WithValues("machine", m.Name, "namespace", m.Namespace)
239-
logger = logger.WithValues("cluster", cluster.Name)
240238

241239
// If the Machine belongs to a cluster, add an owner reference.
242240
if r.shouldAdopt(m) {
@@ -248,28 +246,24 @@ func (r *MachineReconciler) reconcile(ctx context.Context, cluster *clusterv1.Cl
248246
})
249247
}
250248

251-
// Call the inner reconciliation methods.
252-
reconciliationErrors := []error{
253-
r.reconcileBootstrap(ctx, cluster, m),
254-
r.reconcileInfrastructure(ctx, cluster, m),
255-
r.reconcileNodeRef(ctx, cluster, m),
249+
phases := []func(context.Context, *clusterv1.Cluster, *clusterv1.Machine) (ctrl.Result, error){
250+
r.reconcileBootstrap,
251+
r.reconcileInfrastructure,
252+
r.reconcileNodeRef,
256253
}
257254

258-
// Parse the errors, making sure we record if there is a RequeueAfterError.
259255
res := ctrl.Result{}
260256
errs := []error{}
261-
for _, err := range reconciliationErrors {
262-
if requeueErr, ok := errors.Cause(err).(capierrors.HasRequeueAfterError); ok {
263-
// Only record and log the first RequeueAfterError.
264-
if !res.Requeue {
265-
res.Requeue = true
266-
res.RequeueAfter = requeueErr.GetRequeueAfter()
267-
logger.Error(err, "Reconciliation for Machine asked to requeue")
268-
}
257+
for _, phase := range phases {
258+
// Call the inner reconciliation methods.
259+
phaseResult, err := phase(ctx, cluster, m)
260+
if err != nil {
261+
errs = append(errs, err)
262+
}
263+
if len(errs) > 0 {
269264
continue
270265
}
271-
272-
errs = append(errs, err)
266+
res = util.LowestNonZeroResult(res, phaseResult)
273267
}
274268
return res, kerrors.NewAggregate(errs)
275269
}

controllers/machine_controller_noderef.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -18,68 +18,69 @@ package controllers
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"time"
2223

2324
"github.com/pkg/errors"
2425
apicorev1 "k8s.io/api/core/v1"
2526
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
2627
"sigs.k8s.io/cluster-api/controllers/noderefutil"
27-
capierrors "sigs.k8s.io/cluster-api/errors"
2828
"sigs.k8s.io/cluster-api/util"
29+
ctrl "sigs.k8s.io/controller-runtime"
2930
"sigs.k8s.io/controller-runtime/pkg/client"
3031
)
3132

3233
var (
3334
ErrNodeNotFound = errors.New("cannot find node with matching ProviderID")
3435
)
3536

36-
func (r *MachineReconciler) reconcileNodeRef(ctx context.Context, cluster *clusterv1.Cluster, machine *clusterv1.Machine) error {
37+
func (r *MachineReconciler) reconcileNodeRef(ctx context.Context, cluster *clusterv1.Cluster, machine *clusterv1.Machine) (ctrl.Result, error) {
3738
logger := r.Log.WithValues("machine", machine.Name, "namespace", machine.Namespace)
3839
// Check that the Machine hasn't been deleted or in the process.
3940
if !machine.DeletionTimestamp.IsZero() {
40-
return nil
41+
return ctrl.Result{}, nil
4142
}
4243

4344
// Check that the Machine doesn't already have a NodeRef.
4445
if machine.Status.NodeRef != nil {
45-
return nil
46+
return ctrl.Result{}, nil
4647
}
4748

4849
logger = logger.WithValues("cluster", cluster.Name)
4950

5051
// Check that the Machine has a valid ProviderID.
5152
if machine.Spec.ProviderID == nil || *machine.Spec.ProviderID == "" {
5253
logger.Info("Machine doesn't have a valid ProviderID yet")
53-
return nil
54+
return ctrl.Result{}, nil
5455
}
5556

5657
providerID, err := noderefutil.NewProviderID(*machine.Spec.ProviderID)
5758
if err != nil {
58-
return err
59+
return ctrl.Result{}, err
5960
}
6061

6162
remoteClient, err := r.Tracker.GetClient(ctx, util.ObjectKey(cluster))
6263
if err != nil {
63-
return err
64+
return ctrl.Result{}, err
6465
}
6566

6667
// Get the Node reference.
6768
nodeRef, err := r.getNodeReference(remoteClient, providerID)
6869
if err != nil {
6970
if err == ErrNodeNotFound {
70-
return errors.Wrapf(&capierrors.RequeueAfterError{RequeueAfter: 20 * time.Second},
71-
"cannot assign NodeRef to Machine %q in namespace %q, no matching Node", machine.Name, machine.Namespace)
71+
logger.Info(fmt.Sprintf("Cannot assign NodeRef to Machine: %s, requeuing", ErrNodeNotFound.Error()))
72+
return ctrl.Result{RequeueAfter: 20 * time.Second}, nil
7273
}
7374
logger.Error(err, "Failed to assign NodeRef")
7475
r.recorder.Event(machine, apicorev1.EventTypeWarning, "FailedSetNodeRef", err.Error())
75-
return err
76+
return ctrl.Result{}, err
7677
}
7778

7879
// Set the Machine NodeRef.
7980
machine.Status.NodeRef = nodeRef
8081
logger.Info("Set Machine's NodeRef", "noderef", machine.Status.NodeRef.Name)
8182
r.recorder.Event(machine, apicorev1.EventTypeNormal, "SuccessfulSetNodeRef", machine.Status.NodeRef.Name)
82-
return nil
83+
return ctrl.Result{}, nil
8384
}
8485

8586
func (r *MachineReconciler) getNodeReference(c client.Reader, providerID *noderefutil.ProviderID) (*apicorev1.ObjectReference, error) {

controllers/machine_controller_phases.go

+34-31
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ import (
2929
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3030
"k8s.io/apimachinery/pkg/runtime/schema"
3131
"k8s.io/utils/pointer"
32-
"sigs.k8s.io/cluster-api/util/annotations"
33-
"sigs.k8s.io/cluster-api/util/conditions"
34-
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
35-
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
36-
"sigs.k8s.io/controller-runtime/pkg/handler"
37-
3832
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3"
3933
"sigs.k8s.io/cluster-api/controllers/external"
4034
capierrors "sigs.k8s.io/cluster-api/errors"
4135
"sigs.k8s.io/cluster-api/util"
36+
"sigs.k8s.io/cluster-api/util/annotations"
37+
"sigs.k8s.io/cluster-api/util/conditions"
38+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
4239
"sigs.k8s.io/cluster-api/util/patch"
40+
ctrl "sigs.k8s.io/controller-runtime"
41+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
42+
"sigs.k8s.io/controller-runtime/pkg/handler"
4343
)
4444

4545
var (
@@ -172,38 +172,40 @@ func (r *MachineReconciler) reconcileExternal(ctx context.Context, cluster *clus
172172
}
173173

174174
// reconcileBootstrap reconciles the Spec.Bootstrap.ConfigRef object on a Machine.
175-
func (r *MachineReconciler) reconcileBootstrap(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.Machine) error {
175+
func (r *MachineReconciler) reconcileBootstrap(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.Machine) (ctrl.Result, error) {
176+
logger := r.Log.WithValues("machine", m.Name, "namespace", m.Namespace)
177+
176178
// If the bootstrap data is populated, set ready and return.
177179
if m.Spec.Bootstrap.DataSecretName != nil {
178180
m.Status.BootstrapReady = true
179181
conditions.MarkTrue(m, clusterv1.BootstrapReadyCondition)
180-
return nil
182+
return ctrl.Result{}, nil
181183
}
182184

183185
// If the Boostrap ref is nil (and so the machine should use user generated data secret), return.
184186
if m.Spec.Bootstrap.ConfigRef == nil {
185-
return nil
187+
return ctrl.Result{}, nil
186188
}
187189

188190
// Call generic external reconciler if we have an external reference.
189191
externalResult, err := r.reconcileExternal(ctx, cluster, m, m.Spec.Bootstrap.ConfigRef)
190192
if err != nil {
191-
return err
193+
return ctrl.Result{}, err
192194
}
193195
if externalResult.Paused {
194-
return nil
196+
return ctrl.Result{}, nil
195197
}
196198
bootstrapConfig := externalResult.Result
197199

198200
// If the bootstrap config is being deleted, return early.
199201
if !bootstrapConfig.GetDeletionTimestamp().IsZero() {
200-
return nil
202+
return ctrl.Result{}, nil
201203
}
202204

203205
// Determine if the bootstrap provider is ready.
204206
ready, err := external.IsReady(bootstrapConfig)
205207
if err != nil {
206-
return err
208+
return ctrl.Result{}, err
207209
}
208210

209211
// Report a summary of current status of the bootstrap object defined for this machine.
@@ -214,26 +216,28 @@ func (r *MachineReconciler) reconcileBootstrap(ctx context.Context, cluster *clu
214216

215217
// If the bootstrap provider is not ready, requeue.
216218
if !ready {
217-
return errors.Wrapf(&capierrors.RequeueAfterError{RequeueAfter: externalReadyWait},
218-
"Bootstrap provider for Machine %q in namespace %q is not ready, requeuing", m.Name, m.Namespace)
219+
logger.Info("Bootstrap provider is not ready, requeuing")
220+
return ctrl.Result{RequeueAfter: externalReadyWait}, nil
219221
}
220222

221223
// Get and set the name of the secret containing the bootstrap data.
222224
secretName, _, err := unstructured.NestedString(bootstrapConfig.Object, "status", "dataSecretName")
223225
if err != nil {
224-
return errors.Wrapf(err, "failed to retrieve dataSecretName from bootstrap provider for Machine %q in namespace %q", m.Name, m.Namespace)
226+
return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve dataSecretName from bootstrap provider for Machine %q in namespace %q", m.Name, m.Namespace)
225227
} else if secretName == "" {
226-
return errors.Errorf("retrieved empty dataSecretName from bootstrap provider for Machine %q in namespace %q", m.Name, m.Namespace)
228+
return ctrl.Result{}, errors.Errorf("retrieved empty dataSecretName from bootstrap provider for Machine %q in namespace %q", m.Name, m.Namespace)
227229
}
228230

229231
m.Spec.Bootstrap.Data = nil
230232
m.Spec.Bootstrap.DataSecretName = pointer.StringPtr(secretName)
231233
m.Status.BootstrapReady = true
232-
return nil
234+
return ctrl.Result{}, nil
233235
}
234236

235237
// reconcileInfrastructure reconciles the Spec.InfrastructureRef object on a Machine.
236-
func (r *MachineReconciler) reconcileInfrastructure(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.Machine) error {
238+
func (r *MachineReconciler) reconcileInfrastructure(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.Machine) (ctrl.Result, error) {
239+
logger := r.Log.WithValues("machine", m.Name, "namespace", m.Namespace)
240+
237241
// Call generic external reconciler.
238242
infraReconcileResult, err := r.reconcileExternal(ctx, cluster, m, &m.Spec.InfrastructureRef)
239243
if err != nil {
@@ -244,22 +248,22 @@ func (r *MachineReconciler) reconcileInfrastructure(ctx context.Context, cluster
244248
m.Status.FailureMessage = pointer.StringPtr(fmt.Sprintf("Machine infrastructure resource %v with name %q has been deleted after being ready",
245249
m.Spec.InfrastructureRef.GroupVersionKind(), m.Spec.InfrastructureRef.Name))
246250
}
247-
return err
251+
return ctrl.Result{}, err
248252
}
249253
// if the external object is paused, return without any further processing
250254
if infraReconcileResult.Paused {
251-
return nil
255+
return ctrl.Result{}, nil
252256
}
253257
infraConfig := infraReconcileResult.Result
254258

255259
if !infraConfig.GetDeletionTimestamp().IsZero() {
256-
return nil
260+
return ctrl.Result{}, nil
257261
}
258262

259263
// Determine if the infrastructure provider is ready.
260264
ready, err := external.IsReady(infraConfig)
261265
if err != nil {
262-
return err
266+
return ctrl.Result{}, err
263267
}
264268
m.Status.InfrastructureReady = ready
265269

@@ -271,23 +275,22 @@ func (r *MachineReconciler) reconcileInfrastructure(ctx context.Context, cluster
271275

272276
// If the infrastructure provider is not ready, return early.
273277
if !ready {
274-
return errors.Wrapf(&capierrors.RequeueAfterError{RequeueAfter: externalReadyWait},
275-
"Infrastructure provider for Machine %q in namespace %q is not ready, requeuing", m.Name, m.Namespace,
276-
)
278+
logger.Info("Infrastructure provider is not ready, requeuing")
279+
return ctrl.Result{RequeueAfter: externalReadyWait}, nil
277280
}
278281

279282
// Get Spec.ProviderID from the infrastructure provider.
280283
var providerID string
281284
if err := util.UnstructuredUnmarshalField(infraConfig, &providerID, "spec", "providerID"); err != nil {
282-
return errors.Wrapf(err, "failed to retrieve Spec.ProviderID from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
285+
return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve Spec.ProviderID from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
283286
} else if providerID == "" {
284-
return errors.Errorf("retrieved empty Spec.ProviderID from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
287+
return ctrl.Result{}, errors.Errorf("retrieved empty Spec.ProviderID from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
285288
}
286289

287290
// Get and set Status.Addresses from the infrastructure provider.
288291
err = util.UnstructuredUnmarshalField(infraConfig, &m.Status.Addresses, "status", "addresses")
289292
if err != nil && err != util.ErrUnstructuredFieldNotFound {
290-
return errors.Wrapf(err, "failed to retrieve addresses from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
293+
return ctrl.Result{}, errors.Wrapf(err, "failed to retrieve addresses from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
291294
}
292295

293296
// Get and set the failure domain from the infrastructure provider.
@@ -296,11 +299,11 @@ func (r *MachineReconciler) reconcileInfrastructure(ctx context.Context, cluster
296299
switch {
297300
case err == util.ErrUnstructuredFieldNotFound: // no-op
298301
case err != nil:
299-
return errors.Wrapf(err, "failed to failure domain from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
302+
return ctrl.Result{}, errors.Wrapf(err, "failed to failure domain from infrastructure provider for Machine %q in namespace %q", m.Name, m.Namespace)
300303
default:
301304
m.Spec.FailureDomain = pointer.StringPtr(failureDomain)
302305
}
303306

304307
m.Spec.ProviderID = pointer.StringPtr(providerID)
305-
return nil
308+
return ctrl.Result{}, nil
306309
}

0 commit comments

Comments
 (0)