From d554a92f810e20f03f9334a205ffcab960798993 Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Mon, 28 Sep 2020 14:49:52 +0200 Subject: [PATCH] Record last handled reconcile at annotation This makes it possible for e.g. the GOTK CLI to observe if the controller has handled the resource since the manual reconciliation request was made. It replaces the `LastObservedTime` status field, as this was prone to time skew issues and does not offer much additional value over the timestamps of the conditions. --- api/v2alpha1/helmrelease_types.go | 5 +++-- api/v2alpha1/zz_generated.deepcopy.go | 1 - .../helm.toolkit.fluxcd.io_helmreleases.yaml | 7 +++---- controllers/helmrelease_controller.go | 16 ++++++++-------- docs/api/helmrelease.md | 9 ++++----- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/api/v2alpha1/helmrelease_types.go b/api/v2alpha1/helmrelease_types.go index a3d88e1d0..c21a5325a 100644 --- a/api/v2alpha1/helmrelease_types.go +++ b/api/v2alpha1/helmrelease_types.go @@ -593,9 +593,10 @@ type HelmReleaseStatus struct { // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty"` - // LastObservedTime is the last time at which the HelmRelease was observed. + // LastHandledReconcileAt is the last manual reconciliation request (by + // annotating the HelmRelease) handled by the reconciler. // +optional - LastObservedTime metav1.Time `json:"lastObservedTime,omitempty"` + LastHandledReconcileAt string `json:"lastHandledReconcileAt,omitempty"` // Conditions holds the conditions for the HelmRelease. // +optional diff --git a/api/v2alpha1/zz_generated.deepcopy.go b/api/v2alpha1/zz_generated.deepcopy.go index 2327dae64..8110fed51 100644 --- a/api/v2alpha1/zz_generated.deepcopy.go +++ b/api/v2alpha1/zz_generated.deepcopy.go @@ -224,7 +224,6 @@ func (in *HelmReleaseSpec) DeepCopy() *HelmReleaseSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HelmReleaseStatus) DeepCopyInto(out *HelmReleaseStatus) { *out = *in - in.LastObservedTime.DeepCopyInto(&out.LastObservedTime) if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]Condition, len(*in)) diff --git a/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml b/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml index b1fcdc17b..923123498 100644 --- a/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml +++ b/config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml @@ -453,10 +453,9 @@ spec: description: LastAttemptedValuesChecksum is the SHA1 checksum of the values of the last reconciliation attempt. type: string - lastObservedTime: - description: LastObservedTime is the last time at which the HelmRelease - was observed. - format: date-time + lastHandledReconcileAt: + description: LastHandledReconcileAt is the last manual reconciliation + request (by annotating the HelmRelease) handled by the reconciler. type: string lastReleaseRevision: description: LastReleaseRevision is the revision of the last successful diff --git a/controllers/helmrelease_controller.go b/controllers/helmrelease_controller.go index 92567f9c8..5736bdcb9 100644 --- a/controllers/helmrelease_controller.go +++ b/controllers/helmrelease_controller.go @@ -126,7 +126,7 @@ func (r *HelmReleaseReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) hr, result, err := r.reconcile(ctx, log, hr) // Update status after reconciliation. - if updateStatusErr := r.updateStatus(ctx, &hr); updateStatusErr != nil { + if updateStatusErr := r.Status().Update(ctx, &hr); updateStatusErr != nil { log.Error(updateStatusErr, "unable to update status after reconciliation") return ctrl.Result{Requeue: true}, updateStatusErr } @@ -142,11 +142,16 @@ func (r *HelmReleaseReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) } func (r *HelmReleaseReconciler) reconcile(ctx context.Context, log logr.Logger, hr v2.HelmRelease) (v2.HelmRelease, ctrl.Result, error) { + // Record the value of the reconciliation request, if any + if v, ok := hr.GetAnnotations()[consts.ReconcileAtAnnotation]; ok { + hr.Status.LastHandledReconcileAt = v + } + // Observe HelmRelease generation. if hr.Status.ObservedGeneration != hr.Generation { hr.Status.ObservedGeneration = hr.Generation hr = v2.HelmReleaseProgressing(hr) - if updateStatusErr := r.updateStatus(ctx, &hr); updateStatusErr != nil { + if updateStatusErr := r.Status().Update(ctx, &hr); updateStatusErr != nil { log.Error(updateStatusErr, "unable to update status after generation update") return hr, ctrl.Result{Requeue: true}, updateStatusErr } @@ -294,7 +299,7 @@ func (r *HelmReleaseReconciler) reconcileRelease(ctx context.Context, log logr.L hr, hasNewState := v2.HelmReleaseAttempted(hr, revision, releaseRevision, valuesChecksum) if hasNewState { hr = v2.HelmReleaseProgressing(hr) - if updateStatusErr := r.updateStatus(ctx, &hr); updateStatusErr != nil { + if updateStatusErr := r.Status().Update(ctx, &hr); updateStatusErr != nil { log.Error(updateStatusErr, "unable to update status after state update") return hr, updateStatusErr } @@ -410,11 +415,6 @@ func (r *HelmReleaseReconciler) reconcileRelease(ctx context.Context, log logr.L return v2.HelmReleaseReady(hr), nil } -func (r *HelmReleaseReconciler) updateStatus(ctx context.Context, hr *v2.HelmRelease) error { - hr.Status.LastObservedTime = v1.Now() - return r.Status().Update(ctx, hr) -} - func (r *HelmReleaseReconciler) checkDependencies(hr v2.HelmRelease) error { for _, d := range hr.Spec.DependsOn { if d.Namespace == "" { diff --git a/docs/api/helmrelease.md b/docs/api/helmrelease.md index bbe6b79f7..4406851fa 100644 --- a/docs/api/helmrelease.md +++ b/docs/api/helmrelease.md @@ -901,16 +901,15 @@ int64 -lastObservedTime
+lastHandledReconcileAt
- -Kubernetes meta/v1.Time - +string (Optional) -

LastObservedTime is the last time at which the HelmRelease was observed.

+

LastHandledReconcileAt is the last manual reconciliation request (by +annotating the HelmRelease) handled by the reconciler.