@@ -48,7 +48,6 @@ import (
4848 "sigs.k8s.io/cluster-api/controlplane/kubeadm/internal"
4949 runtimeclient "sigs.k8s.io/cluster-api/exp/runtime/client"
5050 "sigs.k8s.io/cluster-api/feature"
51- "sigs.k8s.io/cluster-api/internal/contract"
5251 "sigs.k8s.io/cluster-api/internal/util/ssa"
5352 "sigs.k8s.io/cluster-api/util"
5453 "sigs.k8s.io/cluster-api/util/cache"
@@ -66,6 +65,7 @@ import (
6665
6766const (
6867 kcpManagerName = "capi-kubeadmcontrolplane"
68+ kcpMetadataManagerName = "capi-kubeadmcontrolplane-metadata"
6969 kubeadmControlPlaneKind = "KubeadmControlPlane"
7070)
7171
@@ -80,6 +80,7 @@ const (
8080// KubeadmControlPlaneReconciler reconciles a KubeadmControlPlane object.
8181type KubeadmControlPlaneReconciler struct {
8282 Client client.Client
83+ APIReader client.Reader
8384 SecretCachingClient client.Client
8485 RuntimeClient runtimeclient.Client
8586 controller controller.Controller
@@ -106,6 +107,9 @@ type KubeadmControlPlaneReconciler struct {
106107 overridePreflightChecksFunc func (ctx context.Context , controlPlane * internal.ControlPlane , excludeFor ... * clusterv1.Machine ) ctrl.Result
107108 overrideCanUpdateMachineFunc func (ctx context.Context , machine * clusterv1.Machine , machineUpToDateResult internal.UpToDateResult ) (bool , error )
108109 overrideCanExtensionsUpdateMachine func (ctx context.Context , machine * clusterv1.Machine , machineUpToDateResult internal.UpToDateResult , extensionHandlers []string ) (bool , []string , error )
110+ // Note: This field is only used for unit tests that use fake client because the fake client does not properly set resourceVersion
111+ // on BootstrapConfig/InfraMachine after ssa.Patch and then ssa.RemoveManagedFieldsForLabelsAndAnnotations would fail.
112+ disableRemoveManagedFieldsForLabelsAndAnnotations bool
109113}
110114
111115func (r * KubeadmControlPlaneReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , options controller.Options ) error {
@@ -842,23 +846,21 @@ func (r *KubeadmControlPlaneReconciler) syncMachines(ctx context.Context, contro
842846 }
843847 patchHelpers [machineName ] = patchHelper
844848
845- labelsAndAnnotationsManagedFieldPaths := []contract.Path {
846- {"f:metadata" , "f:annotations" },
847- {"f:metadata" , "f:labels" },
848- }
849849 infraMachine , infraMachineFound := controlPlane .InfraResources [machineName ]
850850 // Only update the InfraMachine if it is already found, otherwise just skip it.
851851 // This could happen e.g. if the cache is not up-to-date yet.
852852 if infraMachineFound {
853- // Cleanup managed fields of all InfrastructureMachines to drop ownership of labels and annotations
854- // from "manager". We do this so that InfrastructureMachines that are created using the Create method
855- // can also work with SSA. Otherwise, labels and annotations would be co-owned by our "old" "manager"
856- // and "capi-kubeadmcontrolplane" and then we would not be able to e.g. drop labels and annotations.
857- if err := ssa .DropManagedFields (ctx , r .Client , infraMachine , kcpManagerName , labelsAndAnnotationsManagedFieldPaths ); err != nil {
853+ // Drop managedFields for manager:Update and capi-kubeadmcontrolplane:Apply for all objects created with CAPI <= v1.11.
854+ // Starting with CAPI v1.12 we have a new managedField structure where capi-kubeadmcontrolplane-metadata will own
855+ // labels and annotations and capi-kubeadmcontrolplane everything else.
856+ // Note: We have to call ssa.MigrateManagedFields for every Machine created with CAPI <= v1.11 once.
857+ // Given that this was introduced in CAPI v1.12 and our n-3 upgrade policy this can
858+ // be removed with CAPI v1.15.
859+ if err := ssa .MigrateManagedFields (ctx , r .Client , infraMachine , kcpManagerName , kcpMetadataManagerName ); err != nil {
858860 return errors .Wrapf (err , "failed to clean up managedFields of InfrastructureMachine %s" , klog .KObj (infraMachine ))
859861 }
860862 // Update in-place mutating fields on InfrastructureMachine.
861- if err := r .updateExternalObject (ctx , infraMachine , infraMachine .GroupVersionKind (), controlPlane .KCP , controlPlane .Cluster ); err != nil {
863+ if err := r .updateLabelsAndAnnotations (ctx , infraMachine , infraMachine .GroupVersionKind (), controlPlane .KCP , controlPlane .Cluster ); err != nil {
862864 return errors .Wrapf (err , "failed to update InfrastructureMachine %s" , klog .KObj (infraMachine ))
863865 }
864866 }
@@ -867,15 +869,17 @@ func (r *KubeadmControlPlaneReconciler) syncMachines(ctx context.Context, contro
867869 // Only update the KubeadmConfig if it is already found, otherwise just skip it.
868870 // This could happen e.g. if the cache is not up-to-date yet.
869871 if kubeadmConfigFound {
870- // Cleanup managed fields of all KubeadmConfigs to drop ownership of labels and annotations
871- // from "manager". We do this so that KubeadmConfigs that are created using the Create method
872- // can also work with SSA. Otherwise, labels and annotations would be co-owned by our "old" "manager"
873- // and "capi-kubeadmcontrolplane" and then we would not be able to e.g. drop labels and annotations.
874- if err := ssa .DropManagedFields (ctx , r .Client , kubeadmConfig , kcpManagerName , labelsAndAnnotationsManagedFieldPaths ); err != nil {
872+ // Drop managedFields for manager:Update and capi-kubeadmcontrolplane:Apply for all objects created with CAPI <= v1.11.
873+ // Starting with CAPI v1.12 we have a new managedField structure where capi-kubeadmcontrolplane-metadata will own
874+ // labels and annotations and capi-kubeadmcontrolplane everything else.
875+ // Note: We have to call ssa.MigrateManagedFields for every Machine created with CAPI <= v1.11 once.
876+ // Given that this was introduced in CAPI v1.12 and our n-3 upgrade policy this can
877+ // be removed with CAPI v1.15.
878+ if err := ssa .MigrateManagedFields (ctx , r .Client , kubeadmConfig , kcpManagerName , kcpMetadataManagerName ); err != nil {
875879 return errors .Wrapf (err , "failed to clean up managedFields of KubeadmConfig %s" , klog .KObj (kubeadmConfig ))
876880 }
877881 // Update in-place mutating fields on BootstrapConfig.
878- if err := r .updateExternalObject (ctx , kubeadmConfig , bootstrapv1 .GroupVersion .WithKind ("KubeadmConfig" ), controlPlane .KCP , controlPlane .Cluster ); err != nil {
882+ if err := r .updateLabelsAndAnnotations (ctx , kubeadmConfig , bootstrapv1 .GroupVersion .WithKind ("KubeadmConfig" ), controlPlane .KCP , controlPlane .Cluster ); err != nil {
879883 return errors .Wrapf (err , "failed to update KubeadmConfig %s" , klog .KObj (kubeadmConfig ))
880884 }
881885 }
@@ -1017,7 +1021,6 @@ func reconcileMachineUpToDateCondition(_ context.Context, controlPlane *internal
10171021 Reason : clusterv1 .MachineNotUpToDateReason ,
10181022 Message : message ,
10191023 })
1020-
10211024 continue
10221025 }
10231026 conditions .Set (machine , metav1.Condition {
0 commit comments