Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: CI flakes #127

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 18 additions & 61 deletions internal/controller/nonadminbackup_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
Expand Down Expand Up @@ -159,7 +158,6 @@ func (r *NonAdminBackupReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// - bool: true if reconciliation should be requeued, false otherwise
// - error: any error encountered during the process
func (r *NonAdminBackupReconciler) setStatusAndConditionForDeletionAndCallDelete(ctx context.Context, logger logr.Logger, nab *nacv1alpha1.NonAdminBackup) (bool, error) {
requeueRequired := false
updatedPhase := updateNonAdminPhase(&nab.Status.Phase, nacv1alpha1.NonAdminPhaseDeleting)
updatedCondition := meta.SetStatusCondition(&nab.Status.Conditions,
metav1.Condition{
Expand All @@ -175,19 +173,10 @@ func (r *NonAdminBackupReconciler) setStatusAndConditionForDeletionAndCallDelete
return false, err
}
logger.V(1).Info("NonAdminBackup status marked for deletion")
requeueRequired = true // Requeue to ensure latest NAB object in the next reconciliation steps
} else {
logger.V(1).Info("NonAdminBackup status unchanged during deletion")
}
if nab.ObjectMeta.DeletionTimestamp.IsZero() {
logger.V(1).Info("Marking NonAdminBackup for deletion", constant.NameString, nab.Name)
if err := r.Delete(ctx, nab); err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once this is called, update predicate is triggered. So, this should be last step to avoid running multiple reconciles

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if you just return false, nil then reconcile will enter another step and will not exit as last step?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may need a 3rd state as it was in the very initial implementation which means "exit cleanly now" to avoid complexity moving parts to the steps where they don't belong. Moving this to the last step e.g. removeNabFinalizerUponVeleroBackupDeletion also doesn't makes sense to me as this step is actually to remove finalizer and not call delete on an object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what I did was add this as the last step of deletion, so return false will not do anything more

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this works with the path where Deletion happens via DeleteBackupRequest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be as it was, only change was the order of steps

logger.Error(err, "Failed to call Delete on the NonAdminBackup object")
return false, err
}
requeueRequired = true // Requeue to allow deletion to proceed
}
return requeueRequired, nil
return false, nil
}

// setStatusForDirectKubernetesAPIDeletion updates the status and conditions when a NonAdminBackup
Expand Down Expand Up @@ -247,19 +236,15 @@ func (r *NonAdminBackupReconciler) setStatusForDirectKubernetesAPIDeletion(ctx c
func (r *NonAdminBackupReconciler) createVeleroDeleteBackupRequest(ctx context.Context, logger logr.Logger, nab *nacv1alpha1.NonAdminBackup) (bool, error) {
// This function is called just after setStatusAndConditionForDeletionAndCallDelete - standard delete path, which already
// requeued the reconciliation to get the latest NAB object. There is no need to fetch the latest NAB object here.
if !controllerutil.ContainsFinalizer(nab, constant.NabFinalizerName) ||
nab.Status.VeleroBackup == nil ||
nab.Status.VeleroBackup.NACUUID == constant.EmptyString {
if nab.Status.VeleroBackup == nil || nab.Status.VeleroBackup.NACUUID == constant.EmptyString {
return false, nil
}

// Initiate deletion of the VeleroBackup object only when the finalizer exists.
// For the ForceDelete we do not create DeleteBackupRequest
veleroBackupNACUUID := nab.Status.VeleroBackup.NACUUID
veleroBackup, err := function.GetVeleroBackupByLabel(ctx, r.Client, r.OADPNamespace, veleroBackupNACUUID)

if err != nil {
// Log error if multiple VeleroBackup objects are found
logger.Error(err, findSingleVBError, constant.UUIDString, veleroBackupNACUUID)
return false, err
}
Expand All @@ -271,7 +256,6 @@ func (r *NonAdminBackupReconciler) createVeleroDeleteBackupRequest(ctx context.C

deleteBackupRequest, err := function.GetVeleroDeleteBackupRequestByLabel(ctx, r.Client, r.OADPNamespace, veleroBackupNACUUID)
if err != nil {
// Log error if multiple DeleteBackupRequest objects are found
logger.Error(err, findSingleVDBRError, constant.UUIDString, veleroBackupNACUUID)
return false, err
}
Expand Down Expand Up @@ -317,7 +301,7 @@ func (r *NonAdminBackupReconciler) createVeleroDeleteBackupRequest(ctx context.C
logger.V(1).Info("NonAdminBackup DeleteBackupRequest Status unchanged")
}

return false, nil // Continue so initNabDeletion can initialize deletion of a NonAdminBackup object
return true, nil
}

// deleteVeleroBackupAndDeleteBackupRequestObjects deletes both the VeleroBackup and any associated
Expand All @@ -338,9 +322,9 @@ func (r *NonAdminBackupReconciler) deleteVeleroBackupAndDeleteBackupRequestObjec
return false, nil
}

deleted := false
veleroBackupNACUUID := nab.Status.VeleroBackup.NACUUID
veleroBackup, err := function.GetVeleroBackupByLabel(ctx, r.Client, r.OADPNamespace, veleroBackupNACUUID)

if err != nil {
// Case where more than one VeleroBackup is found with the same label UUID
// TODO (migi): Determine if all objects with this UUID should be deleted
Expand All @@ -354,24 +338,26 @@ func (r *NonAdminBackupReconciler) deleteVeleroBackupAndDeleteBackupRequestObjec
return false, err
}
logger.V(1).Info("VeleroBackup deletion initiated", constant.NameString, veleroBackup.Name)
deleted = true
} else {
logger.V(1).Info("VeleroBackup already deleted")
}

deleteBackupRequest, err := function.GetVeleroDeleteBackupRequestByLabel(ctx, r.Client, r.OADPNamespace, veleroBackupNACUUID)
if err != nil {
// Log error if multiple DeleteBackupRequest objects are found
logger.Error(err, findSingleVDBRError, constant.UUIDString, veleroBackupNACUUID)
return false, err
}

if deleteBackupRequest != nil {
if err = r.Delete(ctx, deleteBackupRequest); err != nil {
logger.Error(err, "Failed to delete VeleroDeleteBackupRequest", constant.NameString, deleteBackupRequest.Name)
return false, err
}
logger.V(1).Info("VeleroDeleteBackupRequest deletion initiated", constant.NameString, deleteBackupRequest.Name)
deleted = true
}
return false, nil // Continue so initNabDeletion can initialize deletion of an NonAdminBackup object
return deleted, nil
}

// removeNabFinalizerUponVeleroBackupDeletion ensures the associated VeleroBackup object is deleted
Expand All @@ -393,40 +379,19 @@ func (r *NonAdminBackupReconciler) deleteVeleroBackupAndDeleteBackupRequestObjec
// - A boolean indicating whether to requeue the reconcile loop (true if waiting for VeleroBackup deletion).
// - An error if any update operation or deletion check fails.
func (r *NonAdminBackupReconciler) removeNabFinalizerUponVeleroBackupDeletion(ctx context.Context, logger logr.Logger, nab *nacv1alpha1.NonAdminBackup) (bool, error) {
// We do not need to gather latest NAB object here:
// 1. the NAB object was already requeued by setStatusAndConditionForDeletionAndCallDelete
// 2. removal of NAB finalizer is the last step in the delete paths that will requeue the reconciliation if the
// corresponding VeleroBackup object is found based on the NACUUID stored in the NAB status for which we already
// have the latest NAB object (point 1 above).
if !nab.ObjectMeta.DeletionTimestamp.IsZero() {
if !nab.Spec.ForceDeleteBackup && nab.Status.VeleroBackup != nil && nab.Status.VeleroBackup.NACUUID != constant.EmptyString {
veleroBackupNACUUID := nab.Status.VeleroBackup.NACUUID

veleroBackup, err := function.GetVeleroBackupByLabel(ctx, r.Client, r.OADPNamespace, veleroBackupNACUUID)
if err != nil {
// Case in which more then one VeleroBackup is found with the same label UUID
// TODO (migi): Should we delete all of the objects with such UUID ?
logger.Error(err, findSingleVBError, constant.UUIDString, veleroBackupNACUUID)
return false, err
}

if veleroBackup != nil {
logger.V(1).Info("Waiting for VeleroBackup to be deleted", constant.NameString, veleroBackupNACUUID)
return true, nil // Requeue
}
}
// VeleroBackup is deleted, proceed with deleting the NonAdminBackup
logger.V(1).Info("VeleroBackup deleted, removing NonAdminBackup finalizer")

controllerutil.RemoveFinalizer(nab, constant.NabFinalizerName)

if err := r.Update(ctx, nab); err != nil {
logger.Error(err, "Failed to remove finalizer from NonAdminBackup")
controllerutil.RemoveFinalizer(nab, constant.NabFinalizerName)
if err := r.Update(ctx, nab); err != nil {
logger.Error(err, "Failed to remove finalizer from NonAdminBackup")
return false, err
}
if nab.ObjectMeta.DeletionTimestamp.IsZero() {
logger.V(1).Info("Marking NonAdminBackup for deletion", constant.NameString, nab.Name)
if err := r.Delete(ctx, nab); err != nil {
logger.Error(err, "Failed to call Delete on the NonAdminBackup object")
return false, err
}

logger.V(1).Info("NonAdminBackup finalizer removed and object deleted")
}
logger.V(1).Info("NonAdminBackup finalizer removed and object deleted")
return false, nil
}

Expand Down Expand Up @@ -530,14 +495,6 @@ func (r *NonAdminBackupReconciler) validateSpec(ctx context.Context, logger logr
//
// This function generates a UUID and stores it in the VeleroBackup status field of NonAdminBackup.
func (r *NonAdminBackupReconciler) setBackupUUIDInStatus(ctx context.Context, logger logr.Logger, nab *nacv1alpha1.NonAdminBackup) (bool, error) {
// Get the latest version of the NAB object just before checking if the NACUUID is set
// to ensure we do not miss any updates to the NAB object
nabOriginal := nab.DeepCopy()
if err := r.Get(ctx, types.NamespacedName{Name: nabOriginal.Name, Namespace: nabOriginal.Namespace}, nab); err != nil {
logger.Error(err, "Failed to re-fetch NonAdminBackup")
return false, err
}

if nab.Status.VeleroBackup == nil || nab.Status.VeleroBackup.NACUUID == constant.EmptyString {
veleroBackupNACUUID := function.GenerateNacObjectUUID(nab.Namespace, nab.Name)
nab.Status.VeleroBackup = &nacv1alpha1.VeleroBackup{
Expand Down
Loading
Loading