@@ -21,7 +21,6 @@ import (
2121 "errors"
2222 "fmt"
2323 "reflect"
24- "sigs.k8s.io/controller-runtime/pkg/controller"
2524 "strings"
2625 "time"
2726
@@ -42,16 +41,19 @@ import (
4241 "k8s.io/utils/ptr"
4342 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
4443 kubeadmbootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
44+ runtime "sigs.k8s.io/cluster-api/exp/runtime/api/v1alpha1"
4545 capiutil "sigs.k8s.io/cluster-api/util"
4646 "sigs.k8s.io/cluster-api/util/annotations"
4747 "sigs.k8s.io/cluster-api/util/certs"
4848 "sigs.k8s.io/cluster-api/util/collections"
49+ "sigs.k8s.io/cluster-api/util/conditions"
4950 "sigs.k8s.io/cluster-api/util/failuredomains"
5051 "sigs.k8s.io/cluster-api/util/kubeconfig"
5152 "sigs.k8s.io/cluster-api/util/patch"
5253 "sigs.k8s.io/cluster-api/util/secret"
5354 ctrl "sigs.k8s.io/controller-runtime"
5455 "sigs.k8s.io/controller-runtime/pkg/client"
56+ "sigs.k8s.io/controller-runtime/pkg/controller"
5557 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
5658 "sigs.k8s.io/controller-runtime/pkg/log"
5759
@@ -444,16 +446,7 @@ func (c *K0sController) reconcileMachines(ctx context.Context, cluster *clusterv
444446
445447 if clusterIsUpdating {
446448 log .Log .Info ("Cluster is updating" , "currentVersion" , currentVersion , "newVersion" , kcp .Spec .Version , "strategy" , kcp .Spec .UpdateStrategy )
447- if kcp .Spec .UpdateStrategy == cpv1beta1 .UpdateRecreate {
448- // If the cluster is running in single mode, we can't use the Recreate strategy
449- if kcp .Spec .K0sConfigSpec .Args != nil {
450- for _ , arg := range kcp .Spec .K0sConfigSpec .Args {
451- if arg == "--single" {
452- return fmt .Errorf ("UpdateRecreate strategy is not allowed when the cluster is running in single mode" )
453- }
454- }
455- }
456- } else {
449+ if kcp .Spec .UpdateStrategy == cpv1beta1 .UpdateInPlace {
457450 kubeClient , err := c .getKubeClient (ctx , cluster )
458451 if err != nil {
459452 return fmt .Errorf ("error getting cluster client set for machine update: %w" , err )
@@ -463,6 +456,22 @@ func (c *K0sController) reconcileMachines(ctx context.Context, cluster *clusterv
463456 if err != nil {
464457 return fmt .Errorf ("error creating autopilot plan: %w" , err )
465458 }
459+
460+ for _ , m := range desiredMachines {
461+ err = c .markMachineForExternalUpdate (ctx , kcp , m )
462+ if err != nil {
463+ return fmt .Errorf ("error marking machine %s for external update: %w" , m .Name , err )
464+ }
465+ }
466+ } else {
467+ // If the cluster is running in single mode, we can't use the Recreate strategy
468+ if kcp .Spec .K0sConfigSpec .Args != nil {
469+ for _ , arg := range kcp .Spec .K0sConfigSpec .Args {
470+ if arg == "--single" {
471+ return fmt .Errorf ("Recreate and RecreateDeleteFirst strategies are not allowed when the cluster is running in single mode" )
472+ }
473+ }
474+ }
466475 }
467476 }
468477
@@ -559,13 +568,30 @@ func (c *K0sController) inplaceSyncMachineValues(ctx context.Context, kcp *cpv1b
559568 return err
560569 }
561570
571+ if versionMatches (machine , kcp .Spec .Version ) {
572+ delete (machine .Annotations , runtime .PendingHooksAnnotation )
573+ conditions .MarkTrue (machine , "UpToDate" )
574+ }
575+
562576 machine .Spec .NodeDrainTimeout = kcp .Spec .MachineTemplate .NodeDrainTimeout
563577 machine .Spec .NodeDeletionTimeout = kcp .Spec .MachineTemplate .NodeDeletionTimeout
564578 machine .Spec .NodeVolumeDetachTimeout = kcp .Spec .MachineTemplate .NodeVolumeDetachTimeout
565579
566580 return patchHelper .Patch (ctx , machine )
567581}
568582
583+ func (c * K0sController ) markMachineForExternalUpdate (ctx context.Context , _ * cpv1beta1.K0sControlPlane , machine * clusterv1.Machine ) error {
584+ patchHelper , err := patch .NewHelper (machine , c .Client )
585+ if err != nil {
586+ return err
587+ }
588+
589+ annotations .AddAnnotations (machine , map [string ]string {runtime .PendingHooksAnnotation : "ExternalUpdate" })
590+ conditions .MarkFalse (machine , "UpToDate" , "Waiting for update" , clusterv1 .ConditionSeverityInfo , "Machine marked for external update" )
591+
592+ return patchHelper .Patch (ctx , machine )
593+ }
594+
569595func (c * K0sController ) runMachineDeletionSequence (ctx context.Context , cluster * clusterv1.Cluster , kcp * cpv1beta1.K0sControlPlane , machine * clusterv1.Machine ) error {
570596 if err := c .deleteMachine (ctx , machine .Name , kcp ); err != nil {
571597 return fmt .Errorf ("error deleting machine from template: %w" , err )
0 commit comments