Skip to content

Commit dff224a

Browse files
committed
Refactors phases to functions
1 parent dc8e95a commit dff224a

File tree

1 file changed

+110
-29
lines changed

1 file changed

+110
-29
lines changed

controllers/imageclusterinstall_controller.go

Lines changed: 110 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
_ "crypto/sha512"
2727
"encoding/base64"
2828
"encoding/json"
29+
"errors"
2930
"fmt"
3031
"net"
3132
"net/url"
@@ -37,7 +38,7 @@ import (
3738

3839
"gopkg.in/yaml.v3"
3940
corev1 "k8s.io/api/core/v1"
40-
"k8s.io/apimachinery/pkg/api/errors"
41+
k8sapierrors "k8s.io/apimachinery/pkg/api/errors"
4142
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4243
"k8s.io/apimachinery/pkg/runtime"
4344
"k8s.io/apimachinery/pkg/types"
@@ -161,7 +162,6 @@ func (r *ImageClusterInstallReconciler) Reconcile(ctx context.Context, req ctrl.
161162
return ctrl.Result{}, err
162163
}
163164

164-
/////// Requirements not met yet: setting defaults //////
165165
cond := hivev1.ClusterInstallCondition{
166166
Type: hivev1.ClusterInstallRequirementsMet,
167167
Status: corev1.ConditionFalse,
@@ -172,31 +172,87 @@ func (r *ImageClusterInstallReconciler) Reconcile(ctx context.Context, req ctrl.
172172
r.setRequirementsMetCondition(ctx, ici, cond.Status, cond.Reason, cond.Message)
173173
}()
174174

175-
/////// Requirements not met yet: starting config (CD, BMH) validation //////
175+
// 1. Config validation phase
176+
// Possible reasons for not meeting requirements and exiting reconcile:
177+
// - ConfigurationPending: it's either the user needs to complete the ImageClusterInstall definition, or some of referenced
178+
// resources (CD or BMH) are not available yet. In both cases the reconcile ends, and will be triggered again when the
179+
// problem is resolved.
180+
// - ConfigurationFailed: sets this reason when AutomatedCleaningMode cannot be modified in BMH.
181+
cd, bmh, err := r.validateConfiguration(ctx, ici, &cond, log)
182+
if err != nil {
183+
return ctrl.Result{}, err
184+
}
185+
186+
// 2. Host validation phase
187+
// Possible reasons for not meeting requirements and exiting reconcile:
188+
// - HostValidationPending: if BMH provisioning or hardware inspection is not ready yet, reconcile is requeued for 30s later.
189+
// - HostValidationFailed: in case of any errors or invalid BMH configuration the reconcile ends here.
190+
res, err := r.validateHost(ctx, ici, bmh, cd, &cond, log)
191+
if err != nil {
192+
return res, err
193+
}
194+
195+
// 3. Image creation phase
196+
// Possible reasons for not meeting requirements and exiting reconcile:
197+
// - ImageCreationPending: when lock cannot be acquired, reconcile gets requeued for 5s later to try again.
198+
// - ImageCreationFailed: any other unexpected error stops the reconcile loop with this reason.
199+
imageUrl, res, err := r.createImage(ctx, ici, req, bmh, cd, &cond, log)
200+
if !res.IsZero() || err != nil {
201+
return res, err
202+
}
203+
204+
// 4. Host configuration phase
205+
// Possible reasons for not meeting requirements and exiting reconcile:
206+
// - HostConfigurationPending: sets this reason in following scenarios:
207+
// > earlier DataImage instance is still being deleted for some reason (requeue after 30s)
208+
// > current DataImage was just created less than a second ago so BMO might not be notified yet (requeue after 1s)
209+
// > image-based-install-managed annotation is not set yet in BMH (no requeue)
210+
// - HostConfigurationFailed: any unexpected errors during this phase will lead to this reason and finish reconcile.
211+
// Reason for meeting requirements and completing reconcile:
212+
// - HostConfigurationSucceeded: all the finishing steps went fine (like setting the boot time to now),
213+
// and RequirementsMet condition can finally be true.
214+
res, err = r.configureHost(ctx, ici, imageUrl, bmh, &cond, log)
215+
if !res.IsZero() || err != nil {
216+
return res, err
217+
}
218+
219+
return ctrl.Result{}, nil
220+
}
221+
222+
func GetClusterConfigDir(namespacesDir, namespace, uid string) string {
223+
return filepath.Join(namespacesDir, namespace, uid, FilesDir, ClusterConfigDir)
224+
}
225+
226+
func (r *ImageClusterInstallReconciler) validateConfiguration(
227+
ctx context.Context,
228+
ici *v1alpha1.ImageClusterInstall,
229+
cond *hivev1.ClusterInstallCondition,
230+
log logrus.FieldLogger,
231+
) (*hivev1.ClusterDeployment, *bmh_v1alpha1.BareMetalHost, error) {
176232
cond.Reason = v1alpha1.ConfigurationPendingReason
177233

178234
if ici.Spec.ClusterDeploymentRef == nil || ici.Spec.ClusterDeploymentRef.Name == "" {
179235
cond.Message = "ClusterDeploymentRef is unset"
180-
return ctrl.Result{}, nil
236+
return nil, nil, errors.New(cond.Message)
181237
}
182238

183-
clusterDeployment, err := r.getCD(ctx, ici)
239+
cd, err := r.getCD(ctx, ici)
184240
if err != nil {
185241
cond.Message = fmt.Sprintf("failed to get ClusterDeployment %s/%s", ici.Namespace, ici.Spec.ClusterDeploymentRef.Name)
186242
log.WithError(err).Error(cond.Message)
187-
return ctrl.Result{}, err
243+
return nil, nil, err
188244
}
189245

190246
if ici.Spec.BareMetalHostRef == nil {
191247
cond.Message = "no BareMetalHostRef set, nothing to do without provided bmh"
192-
return ctrl.Result{}, nil
248+
return nil, nil, errors.New(cond.Message)
193249
}
194250

195251
bmh, err := r.getBMH(ctx, ici.Spec.BareMetalHostRef)
196252
if err != nil {
197253
cond.Message = fmt.Sprintf("failed to get BareMetalHost %s/%s", ici.Spec.BareMetalHostRef.Namespace, ici.Spec.BareMetalHostRef.Name)
198254
log.WithError(err).Error(cond.Message)
199-
return ctrl.Result{}, err
255+
return nil, nil, err
200256
}
201257

202258
// AutomatedCleaningMode is set at the beginning of this flow because we don't want ironic to format the disk
@@ -208,27 +264,48 @@ func (r *ImageClusterInstallReconciler) Reconcile(ctx context.Context, req ctrl.
208264
cond.Reason = v1alpha1.ConfigurationFailedReason
209265
cond.Message = fmt.Sprintf("failed to disable automated cleaning mode for BareMetalHost %s/%s", bmh.Namespace, bmh.Name)
210266
log.WithError(err).Error(cond.Message)
211-
return ctrl.Result{}, err
267+
return nil, nil, err
212268
}
213269
}
214270

215-
/////// Requirements not met yet: config validated, starting host validation //////
271+
return cd, bmh, nil
272+
}
273+
274+
func (r *ImageClusterInstallReconciler) validateHost(
275+
ctx context.Context,
276+
ici *v1alpha1.ImageClusterInstall,
277+
bmh *bmh_v1alpha1.BareMetalHost,
278+
cd *hivev1.ClusterDeployment,
279+
cond *hivev1.ClusterInstallCondition,
280+
log logrus.FieldLogger,
281+
) (ctrl.Result, error) {
216282
cond.Reason = v1alpha1.HostValidationFailedReason
217283

218-
if res, err := r.validateBMH(ctx, ici, bmh, &cond); !res.IsZero() || err != nil {
284+
if res, err := r.validateBMH(ici, bmh, cond); !res.IsZero() || err != nil {
219285
return res, err
220286
}
221287

222-
if err = r.setClusterInstallMetadata(ctx, log, ici, clusterDeployment); err != nil {
288+
if err := r.setClusterInstallMetadata(ctx, log, ici, cd); err != nil {
223289
cond.Message = "failed to set ImageClusterInstall data"
224290
log.WithError(err).Error(cond.Message)
225291
return ctrl.Result{}, err
226292
}
227293

228-
/////// Requirements not met yet: host validated, starting image creation //////
294+
return ctrl.Result{}, nil
295+
}
296+
297+
func (r *ImageClusterInstallReconciler) createImage(
298+
ctx context.Context,
299+
ici *v1alpha1.ImageClusterInstall,
300+
req ctrl.Request,
301+
bmh *bmh_v1alpha1.BareMetalHost,
302+
cd *hivev1.ClusterDeployment,
303+
cond *hivev1.ClusterInstallCondition,
304+
log logrus.FieldLogger,
305+
) (string, ctrl.Result, error) {
229306
cond.Reason = v1alpha1.ImageCreationFailedReason
230307

231-
res, err := r.writeInputData(ctx, log, ici, clusterDeployment, bmh)
308+
res, err := r.writeInputData(ctx, log, ici, cd, bmh)
232309
if !res.IsZero() || err != nil {
233310
cond.Reason = v1alpha1.ImageCreationPendingReason
234311
cond.Message = "could not acquire lock for image data"
@@ -237,19 +314,28 @@ func (r *ImageClusterInstallReconciler) Reconcile(ctx context.Context, req ctrl.
237314
cond.Message = "failed to create image"
238315
log.WithError(err).Error(cond.Message)
239316
}
240-
return res, err
317+
return "", res, err
241318
}
242319

243-
r.labelReferencedObjectsForBackup(ctx, log, ici, clusterDeployment)
320+
r.labelReferencedObjectsForBackup(ctx, log, ici, cd)
244321

245322
imageUrl, err := url.JoinPath(r.BaseURL, "images", req.Namespace, fmt.Sprintf("%s.iso", ici.ObjectMeta.UID))
246323
if err != nil {
247324
cond.Message = "failed to create image url"
248325
log.WithError(err).Error(cond.Message)
249-
return ctrl.Result{}, err
326+
return "", ctrl.Result{}, err
250327
}
251328

252-
/////// Requirements not met yet: image created, starting host configuration //////
329+
return imageUrl, ctrl.Result{}, nil
330+
}
331+
func (r *ImageClusterInstallReconciler) configureHost(
332+
ctx context.Context,
333+
ici *v1alpha1.ImageClusterInstall,
334+
imageUrl string,
335+
bmh *bmh_v1alpha1.BareMetalHost,
336+
cond *hivev1.ClusterInstallCondition,
337+
log logrus.FieldLogger,
338+
) (ctrl.Result, error) {
253339
cond.Reason = v1alpha1.HostConfigurationFailedReason
254340

255341
dataImage, res, err := r.ensureBMHDataImage(ctx, log, bmh, imageUrl)
@@ -267,8 +353,8 @@ func (r *ImageClusterInstallReconciler) Reconcile(ctx context.Context, req ctrl.
267353
// in case the dataImage was created less than a second ago requeue to allow BMO some time to get
268354
// notified about the newly created DataImage before adding the reboot annotation in updateBMHProvisioningState
269355
cond.Reason = v1alpha1.HostConfigurationPendingReason
270-
cond.Message = "Waiting for BareMetalHost to get DataImage"
271-
return ctrl.Result{RequeueAfter: r.Options.DataImageCoolDownPeriod}, err
356+
cond.Message = "Waiting for DataImage to cool down"
357+
return ctrl.Result{RequeueAfter: r.Options.DataImageCoolDownPeriod}, errors.New(cond.Message)
272358
}
273359

274360
if err := r.updateBMHProvisioningState(ctx, log, bmh, dataImage); err != nil {
@@ -281,7 +367,7 @@ func (r *ImageClusterInstallReconciler) Reconcile(ctx context.Context, req ctrl.
281367
cond.Reason = v1alpha1.HostConfigurationPendingReason
282368
cond.Message = fmt.Sprintf("Waiting for BMH to get %s annotation", ibioManagedBMH)
283369
log.Info(cond.Message)
284-
return ctrl.Result{}, nil
370+
return ctrl.Result{}, errors.New(cond.Message)
285371
}
286372

287373
if ici.Status.BareMetalHostRef == nil {
@@ -306,12 +392,7 @@ func (r *ImageClusterInstallReconciler) Reconcile(ctx context.Context, req ctrl.
306392
return ctrl.Result{}, nil
307393
}
308394

309-
func GetClusterConfigDir(namespacesDir, namespace, uid string) string {
310-
return filepath.Join(namespacesDir, namespace, uid, FilesDir, ClusterConfigDir)
311-
}
312-
313395
func (r *ImageClusterInstallReconciler) validateBMH(
314-
ctx context.Context,
315396
ici *v1alpha1.ImageClusterInstall,
316397
bmh *bmh_v1alpha1.BareMetalHost,
317398
cond *hivev1.ClusterInstallCondition) (ctrl.Result, error) {
@@ -539,7 +620,7 @@ func (r *ImageClusterInstallReconciler) ensureBMHDataImage(
539620
return dataImage, ctrl.Result{}, nil
540621
}
541622

542-
if err != nil && !errors.IsNotFound(err) {
623+
if err != nil && !k8sapierrors.IsNotFound(err) {
543624
return dataImage, ctrl.Result{}, err
544625
}
545626
log.Infof("creating new dataImage for BareMetalHost (%s/%s)", bmh.Name, bmh.Namespace)
@@ -600,7 +681,7 @@ func (r *ImageClusterInstallReconciler) removeBMHDataImage(ctx context.Context,
600681

601682
bmh := &bmh_v1alpha1.BareMetalHost{}
602683
if err := r.Get(ctx, bmhRef, bmh); err != nil {
603-
if errors.IsNotFound(err) {
684+
if k8sapierrors.IsNotFound(err) {
604685
log.Warnf("Referenced BareMetalHost %s/%s does not exist, not waiting for dataImage deletion", bmhRef.Namespace, bmhRef.Name)
605686
return nil, nil
606687
} else {
@@ -634,7 +715,7 @@ func (r *ImageClusterInstallReconciler) deleteDataImage(ctx context.Context, log
634715
dataImage := &bmh_v1alpha1.DataImage{}
635716

636717
if err := r.Get(ctx, dataImageRef, dataImage); err != nil {
637-
if errors.IsNotFound(err) {
718+
if k8sapierrors.IsNotFound(err) {
638719
log.Infof("Can't find DataImage from BareMetalHost %s/%s, Nothing to remove", dataImageRef.Namespace, dataImageRef.Name)
639720
return nil, nil
640721
}

0 commit comments

Comments
 (0)