...

Source file src/edge-infra.dev/pkg/k8s/runtime/controller/reconcile/progressing.go

Documentation: edge-infra.dev/pkg/k8s/runtime/controller/reconcile

     1  package reconcile
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"edge-infra.dev/pkg/k8s/meta/status"
     8  	"edge-infra.dev/pkg/k8s/object"
     9  	"edge-infra.dev/pkg/k8s/runtime/conditions"
    10  	"edge-infra.dev/pkg/k8s/runtime/patch"
    11  )
    12  
    13  // Progressing updates the Reconciling condition for an object that is progressing
    14  // through a reconciler. If specific reconciliation states are detected, that
    15  // Reconciling condition is immediately patched so that it is reflected in the
    16  // K8s control plane to provide feedback to users:
    17  //
    18  //   - If the object's ObservedGeneration does not match the object's current
    19  //     generation, a contextual progressing reason is used.
    20  //   - For objects that embed [ReconcileRequestStatus], if [ReconcileRequestAnnotation]
    21  //     is present and it differs from the last handled reconcile request value
    22  //
    23  // The progressing condition is not perrsisted immediately because reconcilers
    24  // which always requeue on some interval would thrash on their Ready status when
    25  // reconciliation _should_ arrive to the same result if the object generation
    26  // has not changed. This behavior is intended to make a trade-off between
    27  // keeping the K8s API up to date with the latest object state as quickly as
    28  // possible vs status churning.
    29  func Progressing(ctx context.Context,
    30  	obj conditions.Setter,
    31  	patcher *patch.SerialPatcher,
    32  	patchOpts ...patch.Option) error {
    33  	conditions.Progressing(obj, status.ProgressingReason, "Reconciliation in progress")
    34  
    35  	obsGen, err := object.GetStatusObservedGeneration(obj)
    36  	switch {
    37  	case err != nil && !errors.Is(err, object.ErrObservedGenerationNotFound):
    38  		return err
    39  	case err == nil:
    40  		if obsGen != obj.GetGeneration() {
    41  			conditions.Progressing(obj, status.ProgressingReason,
    42  				"processing object: new generation %d -> %d", obsGen, obj.GetGeneration())
    43  			return patcher.Patch(ctx, obj, patchOpts...)
    44  		}
    45  	}
    46  
    47  	var recAtVal string
    48  	if v, ok := GetAnnotation(obj.GetAnnotations()); ok {
    49  		recAtVal = v
    50  	}
    51  	lastRecHandledAtVal, err := GetStatusLastHandledReconcileAt(obj)
    52  	switch {
    53  	case !errors.Is(err, ErrLastHandledReconcileAtNotFound):
    54  		return err
    55  	case err != nil && recAtVal != lastRecHandledAtVal:
    56  		return patcher.Patch(ctx, obj, patchOpts...)
    57  	}
    58  
    59  	return nil
    60  }
    61  

View as plain text