diff --git a/api/v2alpha1/helmrelease_types.go b/api/v2alpha1/helmrelease_types.go index b73eb7f..8ba42a0 100644 --- a/api/v2alpha1/helmrelease_types.go +++ b/api/v2alpha1/helmrelease_types.go @@ -52,16 +52,19 @@ type HelmReleaseSpec struct { // HelmReleaseStatus defines the observed state of HelmRelease type HelmReleaseStatus struct { + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + // +optional Conditions []Condition `json:"conditions,omitempty"` - // LastAppliedRevision is the revision of the last successfully applied source. + // LatestAppliedRevision is the revision of the last successfully applied source. // +optional - LastAppliedRevision string `json:"lastAppliedRevision,omitempty"` + LatestAppliedRevision string `json:"lastAppliedRevision,omitempty"` - // LastReleaseRevision is the revision of the last successfully Helm release. + // LatestReleaseRevision is the revision of the last successfully Helm release. // +optional - LastReleaseRevision int `json:"lastReleaseRevision,omitempty"` + LatestReleaseRevision int `json:"lastReleaseRevision,omitempty"` } // HelmReleaseProgressing resets the conditions of the given HelmRelease to a single @@ -103,6 +106,7 @@ func HelmReleaseNotReady(hr HelmRelease, reason, message string) HelmRelease { Reason: reason, Message: message, }) + hr.Status.ObservedGeneration = hr.Generation return hr } @@ -118,8 +122,9 @@ func HelmReleaseReady(hr HelmRelease, revision string, releaseRevision int, reas Reason: reason, Message: message, }) - hr.Status.LastAppliedRevision = revision - hr.Status.LastReleaseRevision = releaseRevision + hr.Status.ObservedGeneration = hr.Generation + hr.Status.LatestAppliedRevision = revision + hr.Status.LatestReleaseRevision = releaseRevision return hr } diff --git a/config/crd/bases/helm.fluxcd.io_helmreleases.yaml b/config/crd/bases/helm.fluxcd.io_helmreleases.yaml index 6c844bc..bdc81f9 100644 --- a/config/crd/bases/helm.fluxcd.io_helmreleases.yaml +++ b/config/crd/bases/helm.fluxcd.io_helmreleases.yaml @@ -107,13 +107,16 @@ spec: type: object type: array lastAppliedRevision: - description: LastAppliedRevision is the revision of the last successfully + description: LatestAppliedRevision is the revision of the last successfully applied source. type: string lastReleaseRevision: - description: LastReleaseRevision is the revision of the last successfully + description: LatestReleaseRevision is the revision of the last successfully Helm release. type: integer + observedGeneration: + format: int64 + type: integer type: object type: object version: v2alpha1 diff --git a/controllers/helmrelease_controller.go b/controllers/helmrelease_controller.go index 3b3c775..53bab9d 100644 --- a/controllers/helmrelease_controller.go +++ b/controllers/helmrelease_controller.go @@ -189,7 +189,7 @@ func (r *HelmReleaseReconciler) release(log logr.Logger, hr v2.HelmRelease, sour return v2.HelmReleaseNotReady(hr, v2.ReconciliationFailedReason, "Helm install failed"), err } v2.SetHelmReleaseCondition(&hr, v2.InstallCondition, corev1.ConditionTrue, v2.InstallSucceededReason, "Helm installation succeeded") - } else { + } else if r.shouldUpgrade(&hr, source, rel) { if rel, err = r.upgrade(cfg, loadedChart, hr); err != nil { v2.SetHelmReleaseCondition(&hr, v2.UpgradeCondition, corev1.ConditionFalse, v2.UpgradeFailedReason, err.Error()) return v2.HelmReleaseNotReady(hr, v2.ReconciliationFailedReason, "Helm upgrade failed"), err @@ -220,6 +220,19 @@ func (r *HelmReleaseReconciler) upgrade(cfg *action.Configuration, chart *chart. return upgrade.Run(hr.Name, chart, hr.GetValues()) } +func (r *HelmReleaseReconciler) shouldUpgrade(hr *v2.HelmRelease, source sourcev1.Source, rel *release.Release) bool { + switch { + case hr.Status.LatestAppliedRevision != source.GetArtifact().Revision: + return true + case hr.Status.LatestReleaseRevision != rel.Version: + return true + case hr.Generation != hr.Status.ObservedGeneration: + return true + default: + return false + } +} + func (r *HelmReleaseReconciler) lock(name string) (unlock func(), err error) { lockFile := path.Join(os.TempDir(), name+".lock") mutex := lockedfile.MutexAt(lockFile)