@@ -32,6 +32,7 @@ import (
3232 corev1 "k8s.io/api/core/v1"
3333 apierrors "k8s.io/apimachinery/pkg/api/errors"
3434 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35+ "k8s.io/apimachinery/pkg/labels"
3536 "k8s.io/apimachinery/pkg/runtime"
3637 "k8s.io/apimachinery/pkg/types"
3738 "k8s.io/utils/ptr"
@@ -122,6 +123,7 @@ type UpgradePlanReconciler struct {
122123// +kubebuilder:rbac:groups=management.harvesterhci.io,resources=upgradeplans/status,verbs=get;update;patch
123124// +kubebuilder:rbac:groups=management.harvesterhci.io,resources=upgradeplans/finalizers,verbs=update
124125// +kubebuilder:rbac:groups=batch,namespace=harvester-system,resources=jobs,verbs=get;list;watch;create;update
126+ // +kubebuilder:rbac:groups=core,resources=nodes,verbs=get;list;watch
125127// +kubebuilder:rbac:groups=upgrade.cattle.io,namespace=cattle-system,resources=plans,verbs=get;list;watch;create;update
126128
127129// Reconcile is part of the main kubernetes reconciliation loop which aims to
@@ -347,6 +349,18 @@ func (r *UpgradePlanReconciler) finalize(ctx context.Context, upgradePlan *manag
347349 return ctrl.Result {}, nil
348350}
349351
352+ func (r * UpgradePlanReconciler ) isSingleNodeCluster (ctx context.Context ) (bool , error ) {
353+ var nodeList corev1.NodeList
354+ if err := r .List (ctx , & nodeList , & client.ListOptions {
355+ LabelSelector : labels .SelectorFromSet (labels.Set {
356+ harvesterManagedLabel : "true" ,
357+ }),
358+ }); err != nil {
359+ return false , err
360+ }
361+ return len (nodeList .Items ) == 1 , nil
362+ }
363+
350364func (r * UpgradePlanReconciler ) getOrCreatePlanForImagePreload (
351365 ctx context.Context ,
352366 up * managementv1beta1.UpgradePlan ,
@@ -387,10 +401,14 @@ func (r *UpgradePlanReconciler) getOrCreatePlanForNodeUpgrade(
387401 Namespace : cattleSystemNamespace ,
388402 Name : fmt .Sprintf ("%s-%s" , up .Name , nodeComponent ),
389403 }
404+ single , err := r .isSingleNodeCluster (ctx )
405+ if err != nil {
406+ return nil , err
407+ }
390408 return getOrCreate (
391409 ctx , r .Client , r .Scheme , nn ,
392410 func () * upgradev1.Plan { return & upgradev1.Plan {} },
393- func () * upgradev1.Plan { return constructPlanForNodeUpgrade (up ) },
411+ func () * upgradev1.Plan { return constructPlanForNodeUpgrade (up , ! single ) },
394412 up ,
395413 )
396414}
@@ -628,7 +646,7 @@ func constructPlanForImagePreload(upgradePlan *managementv1beta1.UpgradePlan) *u
628646 return constructPlan (upgradePlan .Name , prepareComponent , 1 , selector , false , container , version )
629647}
630648
631- func constructPlanForNodeUpgrade (upgradePlan * managementv1beta1.UpgradePlan ) * upgradev1.Plan {
649+ func constructPlanForNodeUpgrade (upgradePlan * managementv1beta1.UpgradePlan , maintenance bool ) * upgradev1.Plan {
632650 selector := & metav1.LabelSelector {
633651 MatchExpressions : []metav1.LabelSelectorRequirement {
634652 {
@@ -645,7 +663,7 @@ func constructPlanForNodeUpgrade(upgradePlan *managementv1beta1.UpgradePlan) *up
645663 }
646664 version := getKubernetesVersion (upgradePlan )
647665
648- return constructPlan (upgradePlan .Name , nodeComponent , 1 , selector , true , container , version )
666+ return constructPlan (upgradePlan .Name , nodeComponent , 1 , selector , maintenance , container , version )
649667}
650668
651669func isJobFinished (job * batchv1.Job ) (finished , success bool ) {
0 commit comments