From 31c7499908e48cb0b0501ce2ff56565aef90bfa8 Mon Sep 17 00:00:00 2001 From: Atanas Dinov Date: Tue, 30 Jul 2024 14:10:38 +0300 Subject: [PATCH] Skip chart version upgrades between identical releases (#27) Signed-off-by: Atanas Dinov --- internal/controller/helm.go | 6 ++++-- internal/controller/reconcile_longhorn.go | 14 ++++++++++++-- internal/controller/reconcile_rancher.go | 14 ++++++++++++-- internal/controller/upgradeplan_controller.go | 4 ++++ internal/upgrade/base.go | 9 +++++---- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/internal/controller/helm.go b/internal/controller/helm.go index faad219..05e2a47 100644 --- a/internal/controller/helm.go +++ b/internal/controller/helm.go @@ -66,6 +66,7 @@ func (r *UpgradePlanReconciler) updateHelmChart(ctx context.Context, upgradePlan chart.Annotations = map[string]string{} } chart.Annotations[upgrade.PlanAnnotation] = upgradePlan.Name + chart.Annotations[upgrade.ReleaseAnnotation] = upgradePlan.Spec.ReleaseVersion chart.Spec.ChartContent = "" chart.Spec.Chart = releaseChart.Name chart.Spec.Version = releaseChart.Version @@ -77,7 +78,7 @@ func (r *UpgradePlanReconciler) updateHelmChart(ctx context.Context, upgradePlan // Creates a HelmChart resource in order to trigger an upgrade // using the information from an existing Helm release. -func (r *UpgradePlanReconciler) createHelmChart(ctx context.Context, releaseChart *release.HelmChart, installedChart *helmrelease.Release, upgradePlanName string) error { +func (r *UpgradePlanReconciler) createHelmChart(ctx context.Context, upgradePlan *lifecyclev1alpha1.UpgradePlan, installedChart *helmrelease.Release, releaseChart *release.HelmChart) error { backoffLimit := int32(6) var values []byte @@ -99,7 +100,8 @@ func (r *UpgradePlanReconciler) createHelmChart(ctx context.Context, releaseChar Name: releaseChart.Name, Namespace: upgrade.ChartNamespace, Annotations: map[string]string{ - upgrade.PlanAnnotation: upgradePlanName, + upgrade.PlanAnnotation: upgradePlan.Name, + upgrade.ReleaseAnnotation: upgradePlan.Spec.ReleaseVersion, }, }, Spec: helmcattlev1.HelmChartSpec{ diff --git a/internal/controller/reconcile_longhorn.go b/internal/controller/reconcile_longhorn.go index a01714e..ec4d407 100644 --- a/internal/controller/reconcile_longhorn.go +++ b/internal/controller/reconcile_longhorn.go @@ -36,16 +36,26 @@ func (r *UpgradePlanReconciler) reconcileLonghorn(ctx context.Context, upgradePl return ctrl.Result{}, err } + if helmRelease.Chart.Metadata.Version == longhorn.Version { + setSkippedCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, versionAlreadyInstalledMessage(upgradePlan)) + return ctrl.Result{Requeue: true}, nil + } + setInProgressCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, "Longhorn is being upgraded") - return ctrl.Result{}, r.createHelmChart(ctx, longhorn, helmRelease, upgradePlan.Name) + return ctrl.Result{}, r.createHelmChart(ctx, upgradePlan, helmRelease, longhorn) } if chart.Spec.Version != longhorn.Version { setInProgressCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, "Longhorn is being upgraded") - return ctrl.Result{}, r.updateHelmChart(ctx, upgradePlan, chart, longhorn) } + releaseVersion := chart.Annotations[upgrade.ReleaseAnnotation] + if releaseVersion != upgradePlan.Spec.ReleaseVersion { + setSkippedCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, versionAlreadyInstalledMessage(upgradePlan)) + return ctrl.Result{Requeue: true}, nil + } + job := &batchv1.Job{} if err = r.Get(ctx, types.NamespacedName{Name: chart.Status.JobName, Namespace: upgrade.ChartNamespace}, job); err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) diff --git a/internal/controller/reconcile_rancher.go b/internal/controller/reconcile_rancher.go index ee4e84f..f897b8b 100644 --- a/internal/controller/reconcile_rancher.go +++ b/internal/controller/reconcile_rancher.go @@ -36,16 +36,26 @@ func (r *UpgradePlanReconciler) reconcileRancher(ctx context.Context, upgradePla return ctrl.Result{}, err } + if helmRelease.Chart.Metadata.Version == rancher.Version { + setSkippedCondition(upgradePlan, lifecyclev1alpha1.RancherUpgradedCondition, versionAlreadyInstalledMessage(upgradePlan)) + return ctrl.Result{Requeue: true}, nil + } + setInProgressCondition(upgradePlan, lifecyclev1alpha1.RancherUpgradedCondition, "Rancher is being upgraded") - return ctrl.Result{}, r.createHelmChart(ctx, rancher, helmRelease, upgradePlan.Name) + return ctrl.Result{}, r.createHelmChart(ctx, upgradePlan, helmRelease, rancher) } if chart.Spec.Version != rancher.Version { setInProgressCondition(upgradePlan, lifecyclev1alpha1.RancherUpgradedCondition, "Rancher is being upgraded") - return ctrl.Result{}, r.updateHelmChart(ctx, upgradePlan, chart, rancher) } + releaseVersion := chart.Annotations[upgrade.ReleaseAnnotation] + if releaseVersion != upgradePlan.Spec.ReleaseVersion { + setSkippedCondition(upgradePlan, lifecyclev1alpha1.RancherUpgradedCondition, versionAlreadyInstalledMessage(upgradePlan)) + return ctrl.Result{Requeue: true}, nil + } + job := &batchv1.Job{} if err = r.Get(ctx, types.NamespacedName{Name: chart.Status.JobName, Namespace: upgrade.ChartNamespace}, job); err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) diff --git a/internal/controller/upgradeplan_controller.go b/internal/controller/upgradeplan_controller.go index 2413008..72bd3d2 100644 --- a/internal/controller/upgradeplan_controller.go +++ b/internal/controller/upgradeplan_controller.go @@ -191,6 +191,10 @@ func setSkippedCondition(plan *lifecyclev1alpha1.UpgradePlan, conditionType, mes meta.SetStatusCondition(&plan.Status.Conditions, condition) } +func versionAlreadyInstalledMessage(plan *lifecyclev1alpha1.UpgradePlan) string { + return fmt.Sprintf("Component version is the same in release %s", plan.Spec.ReleaseVersion) +} + func (r *UpgradePlanReconciler) findUpgradePlanFromJob(ctx context.Context, job client.Object) []reconcile.Request { jobLabels := job.GetLabels() chartName, ok := jobLabels[chart.Label] diff --git a/internal/upgrade/base.go b/internal/upgrade/base.go index 5a7e0b7..5dd8b33 100644 --- a/internal/upgrade/base.go +++ b/internal/upgrade/base.go @@ -7,10 +7,11 @@ import ( ) const ( - planNamespace = "cattle-system" - PlanAnnotation = "lifecycle.suse.com/upgrade-plan" - controlPlaneKey = "control-plane" - workersKey = "workers" + planNamespace = "cattle-system" + PlanAnnotation = "lifecycle.suse.com/upgrade-plan" + ReleaseAnnotation = "lifecycle.suse.com/release" + controlPlaneKey = "control-plane" + workersKey = "workers" ControlPlaneLabel = "node-role.kubernetes.io/control-plane" )