Skip to content

Commit

Permalink
Upgrade Longhorn (#26)
Browse files Browse the repository at this point in the history
* Add Longhorn definition

Signed-off-by: Atanas Dinov <[email protected]>

* Reconcile Longhorn upgrades

Signed-off-by: Atanas Dinov <[email protected]>

* Upgrade Longhorn

Signed-off-by: Atanas Dinov <[email protected]>

---------

Signed-off-by: Atanas Dinov <[email protected]>
  • Loading branch information
atanasdinov authored Jul 29, 2024
1 parent 758afa1 commit d7f8252
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 0 deletions.
1 change: 1 addition & 0 deletions api/v1alpha1/upgradeplan_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const (

KubernetesUpgradedCondition = "KubernetesUpgraded"
RancherUpgradedCondition = "RancherUpgraded"
LonghornUpgradedCondition = "LonghornUpgraded"

// UpgradePending indicates that the upgrade process has not begun.
UpgradePending = "Pending"
Expand Down
74 changes: 74 additions & 0 deletions internal/controller/reconcile_longhorn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package controller

import (
"context"
"fmt"
"slices"

helmcattlev1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1"
lifecyclev1alpha1 "github.com/suse-edge/upgrade-controller/api/v1alpha1"
"github.com/suse-edge/upgrade-controller/internal/upgrade"
"github.com/suse-edge/upgrade-controller/pkg/release"

batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func (r *UpgradePlanReconciler) reconcileLonghorn(ctx context.Context, upgradePlan *lifecyclev1alpha1.UpgradePlan, longhorn *release.HelmChart) (ctrl.Result, error) {
helmRelease, err := retrieveHelmRelease(longhorn.Name)
if err != nil {
return ctrl.Result{}, fmt.Errorf("retrieving helm release: %w", err)
}

if helmRelease == nil {
setSkippedCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, "Longhorn installation is not found")
return ctrl.Result{Requeue: true}, nil
}

chart := &helmcattlev1.HelmChart{}

if err = r.Get(ctx, upgrade.ChartNamespacedName(helmRelease.Name), chart); err != nil {
if !errors.IsNotFound(err) {
return ctrl.Result{}, err
}

setInProgressCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, "Longhorn is being upgraded")
return ctrl.Result{}, r.createHelmChart(ctx, longhorn, helmRelease, upgradePlan.Name)
}

if chart.Spec.Version != longhorn.Version {
setInProgressCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, "Longhorn is being upgraded")

return ctrl.Result{}, r.updateHelmChart(ctx, upgradePlan, chart, longhorn)
}

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)
}

idx := slices.IndexFunc(job.Status.Conditions, func(condition batchv1.JobCondition) bool {
return condition.Status == corev1.ConditionTrue &&
(condition.Type == batchv1.JobComplete || condition.Type == batchv1.JobFailed)
})

if idx == -1 {
// Upgrade job is still ongoing.
return ctrl.Result{}, nil
}

condition := job.Status.Conditions[idx]

switch condition.Type {
case batchv1.JobComplete:
setSuccessfulCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, "Longhorn is upgraded")
case batchv1.JobFailed:
setFailedCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, fmt.Sprintf("Error occurred: %s", condition.Message))
}

return ctrl.Result{Requeue: true}, nil
}
3 changes: 3 additions & 0 deletions internal/controller/upgradeplan_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (r *UpgradePlanReconciler) executePlan(ctx context.Context, upgradePlan *li
setPendingCondition(upgradePlan, lifecyclev1alpha1.OperatingSystemUpgradedCondition, "OS upgrade is not yet started")
setPendingCondition(upgradePlan, lifecyclev1alpha1.KubernetesUpgradedCondition, "Kubernetes upgrade is not yet started")
setPendingCondition(upgradePlan, lifecyclev1alpha1.RancherUpgradedCondition, "Rancher upgrade is not yet started")
setPendingCondition(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition, "Longhorn upgrade is not yet started")

return ctrl.Result{Requeue: true}, nil
}
Expand All @@ -104,6 +105,8 @@ func (r *UpgradePlanReconciler) executePlan(ctx context.Context, upgradePlan *li
return r.reconcileKubernetes(ctx, upgradePlan, &release.Components.Kubernetes)
case !isHelmUpgradeFinished(upgradePlan, lifecyclev1alpha1.RancherUpgradedCondition):
return r.reconcileRancher(ctx, upgradePlan, &release.Components.Rancher)
case !isHelmUpgradeFinished(upgradePlan, lifecyclev1alpha1.LonghornUpgradedCondition):
return r.reconcileLonghorn(ctx, upgradePlan, &release.Components.Longhorn)
}

logger := log.FromContext(ctx)
Expand Down
5 changes: 5 additions & 0 deletions manifests/release-3.0.1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ components:
version: v2.8.5
repository: https://charts.rancher.com/server-charts/prime
namespace: cattle-system
longhorn:
chart: longhorn
version: v1.6.1
repository: https://charts.longhorn.io
namespace: longhorn-system
operatingSystem:
version: 6.0
zypperID: SL-Micro
Expand Down
1 change: 1 addition & 0 deletions pkg/release/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Components struct {
Kubernetes Kubernetes `yaml:"kubernetes"`
OperatingSystem OperatingSystem `yaml:"operatingSystem"`
Rancher HelmChart `yaml:"rancher"`
Longhorn HelmChart `yaml:"longhorn"`
}

type Kubernetes struct {
Expand Down

0 comments on commit d7f8252

Please sign in to comment.