Skip to content

Commit 8cb4d00

Browse files
authored
Merge pull request #9318 from sbueringer/pr-cc-mp-squashed-nits
🌱 Minor fixes for CC+MP implementation
2 parents 441e8a5 + 8965f4c commit 8cb4d00

File tree

22 files changed

+285
-264
lines changed

22 files changed

+285
-264
lines changed

internal/controllers/topology/cluster/blueprint.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (r *Reconciler) getBlueprint(ctx context.Context, cluster *clusterv1.Cluste
8080
return nil, errors.Wrapf(err, "failed to get infrastructure machine template for %s, MachineDeployment class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machineDeploymentClass.Class)
8181
}
8282

83-
// Get the bootstrap machine template.
83+
// Get the bootstrap config template.
8484
machineDeploymentBlueprint.BootstrapTemplate, err = r.getReference(ctx, machineDeploymentClass.Template.Bootstrap.Ref)
8585
if err != nil {
8686
return nil, errors.Wrapf(err, "failed to get bootstrap config template for %s, MachineDeployment class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machineDeploymentClass.Class)
@@ -109,7 +109,7 @@ func (r *Reconciler) getBlueprint(ctx context.Context, cluster *clusterv1.Cluste
109109
return nil, errors.Wrapf(err, "failed to get InfrastructureMachinePoolTemplate for %s, MachinePool class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machinePoolClass.Class)
110110
}
111111

112-
// Get the bootstrap config.
112+
// Get the bootstrap config template.
113113
machinePoolBlueprint.BootstrapTemplate, err = r.getReference(ctx, machinePoolClass.Template.Bootstrap.Ref)
114114
if err != nil {
115115
return nil, errors.Wrapf(err, "failed to get bootstrap config for %s, MachinePool class %q", tlog.KObj{Obj: blueprint.ClusterClass}, machinePoolClass.Class)

internal/controllers/topology/cluster/conditions.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,18 @@ func (r *Reconciler) reconcileTopologyReconciledCondition(s *scope.Scope, cluste
106106
}
107107

108108
// The topology is not considered as fully reconciled if one of the following is true:
109-
// * either the Control Plane or any of the MachineDeployments are still pending to pick up the new version
109+
// * either the Control Plane or any of the MachineDeployments/MachinePools are still pending to pick up the new version
110110
// (generally happens when upgrading the cluster)
111-
// * when there are MachineDeployments for which the upgrade has been deferred
112-
// * when new MachineDeployments are pending to be created
111+
// * when there are MachineDeployments/MachinePools for which the upgrade has been deferred
112+
// * when new MachineDeployments/MachinePools are pending to be created
113113
// (generally happens when upgrading the cluster)
114114
if s.UpgradeTracker.ControlPlane.IsPendingUpgrade ||
115115
s.UpgradeTracker.MachineDeployments.IsAnyPendingCreate() ||
116116
s.UpgradeTracker.MachineDeployments.IsAnyPendingUpgrade() ||
117-
s.UpgradeTracker.MachineDeployments.DeferredUpgrade() {
117+
s.UpgradeTracker.MachineDeployments.DeferredUpgrade() ||
118+
s.UpgradeTracker.MachinePools.IsAnyPendingCreate() ||
119+
s.UpgradeTracker.MachinePools.IsAnyPendingUpgrade() ||
120+
s.UpgradeTracker.MachinePools.DeferredUpgrade() {
118121
msgBuilder := &strings.Builder{}
119122
var reason string
120123

@@ -180,6 +183,11 @@ func (r *Reconciler) reconcileTopologyReconciledCondition(s *scope.Scope, cluste
180183
fmt.Fprintf(msgBuilder, " MachineDeployment(s) %s are upgrading",
181184
computeNameList(s.UpgradeTracker.MachineDeployments.UpgradingNames()),
182185
)
186+
187+
case len(s.UpgradeTracker.MachinePools.UpgradingNames()) > 0:
188+
fmt.Fprintf(msgBuilder, " MachinePool(s) %s are upgrading",
189+
computeNameList(s.UpgradeTracker.MachinePools.UpgradingNames()),
190+
)
183191
}
184192

185193
conditions.Set(

internal/controllers/topology/cluster/current_state.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ func (r *Reconciler) getCurrentMachinePoolState(ctx context.Context, blueprintMa
289289
state := make(scope.MachinePoolsStateMap)
290290

291291
// List all the machine pools in the current cluster and in a managed topology.
292+
// Note: This is a cached list call. We ensure in reconcile_state that the cache is up-to-date
293+
// after we create/update a MachinePool and we double-check if an MP already exists before
294+
// we create it.
292295
mp := &expv1.MachinePoolList{}
293296
err := r.Client.List(ctx, mp,
294297
client.MatchingLabels{
@@ -328,7 +331,7 @@ func (r *Reconciler) getCurrentMachinePoolState(ctx context.Context, blueprintMa
328331
// Gets the infraRef.
329332
infraRef := &m.Spec.Template.Spec.InfrastructureRef
330333
if infraRef.Name == "" {
331-
return nil, fmt.Errorf("%s does not have a reference to a InfrastructureMachineTemplate", tlog.KObj{Obj: m})
334+
return nil, fmt.Errorf("%s does not have a reference to a InfrastructureMachinePool", tlog.KObj{Obj: m})
332335
}
333336

334337
// If the mpTopology exists in the Cluster, lookup the corresponding mpBluePrint and align

internal/controllers/topology/cluster/desired_state.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (r *Reconciler) computeDesiredState(ctx context.Context, s *scope.Scope) (*
8484
if len(s.Current.MachinePools) > 0 {
8585
client, err := r.Tracker.GetClient(ctx, client.ObjectKeyFromObject(s.Current.Cluster))
8686
if err != nil {
87-
return nil, err
87+
return nil, errors.Wrap(err, "failed to check if any MachinePool is upgrading")
8888
}
8989
// Mark all the MachinePools that are currently upgrading.
9090
mpUpgradingNames, err := s.Current.MachinePools.Upgrading(ctx, client)
@@ -438,7 +438,7 @@ func (r *Reconciler) computeControlPlaneVersion(ctx context.Context, s *scope.Sc
438438
// change the UpgradeTracker accordingly, otherwise the hook call is completed and we
439439
// can remove this hook from the list of pending-hooks.
440440
if hookResponse.RetryAfterSeconds != 0 {
441-
log.Infof("MachineDeployments upgrade to version %q are blocked by %q hook", desiredVersion, runtimecatalog.HookName(runtimehooksv1.AfterControlPlaneUpgrade))
441+
log.Infof("MachineDeployments/MachinePools upgrade to version %q are blocked by %q hook", desiredVersion, runtimecatalog.HookName(runtimehooksv1.AfterControlPlaneUpgrade))
442442
} else {
443443
if err := hooks.MarkAsDone(ctx, r.Client, s.Current.Cluster, runtimehooksv1.AfterControlPlaneUpgrade); err != nil {
444444
return "", err
@@ -464,10 +464,11 @@ func (r *Reconciler) computeControlPlaneVersion(ctx context.Context, s *scope.Sc
464464
}
465465

466466
// If the control plane is not upgrading or scaling, we can assume the control plane is stable.
467-
// However, we should also check for the MachineDeployments upgrading.
468-
// If the MachineDeployments are upgrading, then do not pick up the desiredVersion yet.
469-
// We will pick up the new version after the MachineDeployments finish upgrading.
470-
if len(s.UpgradeTracker.MachineDeployments.UpgradingNames()) > 0 {
467+
// However, we should also check for the MachineDeployments/MachinePools upgrading.
468+
// If the MachineDeployments/MachinePools are upgrading, then do not pick up the desiredVersion yet.
469+
// We will pick up the new version after the MachineDeployments/MachinePools finish upgrading.
470+
if len(s.UpgradeTracker.MachineDeployments.UpgradingNames()) > 0 ||
471+
len(s.UpgradeTracker.MachinePools.UpgradingNames()) > 0 {
471472
return *currentVersion, nil
472473
}
473474

@@ -950,7 +951,7 @@ func computeMachinePool(_ context.Context, s *scope.Scope, machinePoolTopology c
950951
template: machinePoolBlueprint.BootstrapTemplate,
951952
templateClonedFromRef: contract.ObjToRef(machinePoolBlueprint.BootstrapTemplate),
952953
cluster: s.Current.Cluster,
953-
namePrefix: bootstrapTemplateNamePrefix(s.Current.Cluster.Name, machinePoolTopology.Name),
954+
namePrefix: bootstrapConfigNamePrefix(s.Current.Cluster.Name, machinePoolTopology.Name),
954955
currentObjectRef: currentBootstrapConfigRef,
955956
})
956957
if err != nil {
@@ -961,11 +962,11 @@ func computeMachinePool(_ context.Context, s *scope.Scope, machinePoolTopology c
961962
if bootstrapObjectLabels == nil {
962963
bootstrapObjectLabels = map[string]string{}
963964
}
964-
// Add ClusterTopologyMachinePoolLabel to the generated Bootstrap template
965+
// Add ClusterTopologyMachinePoolLabel to the generated Bootstrap config
965966
bootstrapObjectLabels[clusterv1.ClusterTopologyMachinePoolNameLabel] = machinePoolTopology.Name
966967
desiredMachinePool.BootstrapObject.SetLabels(bootstrapObjectLabels)
967968

968-
// Compute the Infrastructure ref.
969+
// Compute the InfrastructureMachinePool.
969970
var currentInfraMachinePoolRef *corev1.ObjectReference
970971
if currentMachinePool != nil && currentMachinePool.InfrastructureMachinePoolObject != nil {
971972
currentInfraMachinePoolRef = &currentMachinePool.Object.Spec.Template.Spec.InfrastructureRef
@@ -991,6 +992,11 @@ func computeMachinePool(_ context.Context, s *scope.Scope, machinePoolTopology c
991992
version := computeMachinePoolVersion(s, machinePoolTopology, currentMachinePool)
992993

993994
// Compute values that can be set both in the MachinePoolClass and in the MachinePoolTopology
995+
minReadySeconds := machinePoolClass.MinReadySeconds
996+
if machinePoolTopology.MinReadySeconds != nil {
997+
minReadySeconds = machinePoolTopology.MinReadySeconds
998+
}
999+
9941000
failureDomains := machinePoolClass.FailureDomains
9951001
if machinePoolTopology.FailureDomains != nil {
9961002
failureDomains = machinePoolTopology.FailureDomains
@@ -1031,8 +1037,9 @@ func computeMachinePool(_ context.Context, s *scope.Scope, machinePoolTopology c
10311037
Namespace: s.Current.Cluster.Namespace,
10321038
},
10331039
Spec: expv1.MachinePoolSpec{
1034-
ClusterName: s.Current.Cluster.Name,
1035-
FailureDomains: failureDomains,
1040+
ClusterName: s.Current.Cluster.Name,
1041+
MinReadySeconds: minReadySeconds,
1042+
FailureDomains: failureDomains,
10361043
Template: clusterv1.MachineTemplateSpec{
10371044
Spec: clusterv1.MachineSpec{
10381045
ClusterName: s.Current.Cluster.Name,

internal/controllers/topology/cluster/patches/patch.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (i PreserveFields) ApplyToHelper(opts *PatchOptions) {
5757
opts.preserveFields = i
5858
}
5959

60-
// patchObject overwrites spec in object with spec.template.spec of patchedTemplate,
60+
// patchObject overwrites spec in object with spec.template.spec of modifiedObject,
6161
// while preserving the configured fields.
6262
// For example, ControlPlane.spec will be overwritten with the patched
6363
// ControlPlaneTemplate.spec.template.spec but preserving spec.version and spec.replicas
@@ -66,7 +66,7 @@ func patchObject(ctx context.Context, object, modifiedObject *unstructured.Unstr
6666
return patchUnstructured(ctx, object, modifiedObject, "spec.template.spec", "spec", opts...)
6767
}
6868

69-
// patchTemplate overwrites spec.template.spec in template with spec.template.spec of patchedTemplate,
69+
// patchTemplate overwrites spec.template.spec in template with spec.template.spec of modifiedTemplate,
7070
// while preserving the configured fields.
7171
// For example, it's possible to patch BootstrapTemplate.spec.template.spec with a patched
7272
// BootstrapTemplate.spec.template.spec while preserving fields configured via opts.fieldsToPreserve.

internal/controllers/topology/cluster/patches/template.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (t *requestItemBuilder) Build() (*runtimehooksv1.GeneratePatchesRequestItem
9191
}
9292

9393
// getTemplateAsUnstructured is a utility func that returns a template matching the holderKind, holderFieldPath
94-
// and mdTopologyName from a GeneratePatchesRequest.
94+
// and topologyNames from a GeneratePatchesRequest.
9595
func getTemplateAsUnstructured(req *runtimehooksv1.GeneratePatchesRequest, holderKind, holderFieldPath string, topologyNames requestTopologyName) (*unstructured.Unstructured, error) {
9696
// Find the requestItem.
9797
requestItem := getRequestItem(req, holderKind, holderFieldPath, topologyNames)
@@ -119,7 +119,7 @@ func getRequestItemByUID(req *runtimehooksv1.GeneratePatchesRequest, uid types.U
119119
return nil
120120
}
121121

122-
// getRequestItem is a utility func that returns a template matching the holderKind, holderFiledPath and mdTopologyName from a GeneratePatchesRequest.
122+
// getRequestItem is a utility func that returns a template matching the holderKind, holderFiledPath and topologyNames from a GeneratePatchesRequest.
123123
func getRequestItem(req *runtimehooksv1.GeneratePatchesRequest, holderKind, holderFieldPath string, topologyNames requestTopologyName) *runtimehooksv1.GeneratePatchesRequestItem {
124124
for _, template := range req.Items {
125125
if holderKind != "" && template.HolderReference.Kind != holderKind {

internal/controllers/topology/cluster/reconcile_state.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,9 @@ func (r *Reconciler) callAfterClusterUpgrade(ctx context.Context, s *scope.Scope
250250
// Call the registered extensions for the hook after the cluster is fully upgraded.
251251
// A clusters is considered fully upgraded if:
252252
// - Control plane is stable (not upgrading, not scaling, not about to upgrade)
253-
// - MachineDeployments are not currently upgrading
254-
// - MachineDeployments are not pending an upgrade
255-
// - MachineDeployments are not pending create
253+
// - MachineDeployments/MachinePools are not currently upgrading
254+
// - MachineDeployments/MachinePools are not pending an upgrade
255+
// - MachineDeployments/MachinePools are not pending create
256256
if isControlPlaneStable(s) && // Control Plane stable checks
257257
len(s.UpgradeTracker.MachineDeployments.UpgradingNames()) == 0 && // Machine deployments are not upgrading or not about to upgrade
258258
!s.UpgradeTracker.MachineDeployments.IsAnyPendingCreate() && // No MachineDeployments are pending create
@@ -737,6 +737,10 @@ func (r *Reconciler) reconcileMachinePools(ctx context.Context, s *scope.Scope)
737737

738738
// Create MachinePools.
739739
if len(diff.toCreate) > 0 {
740+
// In current state we only got the MP list via a cached call.
741+
// As a consequence, in order to prevent the creation of duplicate MP due to stale reads,
742+
// we are now using a live client to double-check here that the MachinePool
743+
// to be created doesn't exist yet.
740744
currentMPTopologyNames, err := r.getCurrentMachinePools(ctx, s)
741745
if err != nil {
742746
return err
@@ -806,8 +810,6 @@ func (r *Reconciler) getCurrentMachinePools(ctx context.Context, s *scope.Scope)
806810
// createMachinePool creates a MachinePool and the corresponding templates.
807811
func (r *Reconciler) createMachinePool(ctx context.Context, s *scope.Scope, mp *scope.MachinePoolState) error {
808812
// Do not create the MachinePool if it is marked as pending create.
809-
// This will also block MHC creation because creating the MHC without the corresponding
810-
// MachinePool is unnecessary.
811813
mpTopologyName, ok := mp.Object.Labels[clusterv1.ClusterTopologyMachinePoolNameLabel]
812814
if !ok || mpTopologyName == "" {
813815
// Note: This is only an additional safety check and should not happen. The label will always be added when computing
@@ -868,7 +870,7 @@ func (r *Reconciler) createMachinePool(ctx context.Context, s *scope.Scope, mp *
868870
return nil
869871
}
870872

871-
// updateMachinePool updates a MachinePool. Also rotates the corresponding Templates if necessary.
873+
// updateMachinePool updates a MachinePool. Also updates the corresponding objects if necessary.
872874
func (r *Reconciler) updateMachinePool(ctx context.Context, s *scope.Scope, currentMP, desiredMP *scope.MachinePoolState) error {
873875
log := tlog.LoggerFrom(ctx).WithMachinePool(desiredMP.Object)
874876

@@ -882,20 +884,18 @@ func (r *Reconciler) updateMachinePool(ctx context.Context, s *scope.Scope, curr
882884
cluster := s.Current.Cluster
883885
infraCtx, _ := log.WithObject(desiredMP.InfrastructureMachinePoolObject).Into(ctx)
884886
if err := r.reconcileReferencedObject(infraCtx, reconcileReferencedObjectInput{
885-
cluster: cluster,
886-
current: currentMP.InfrastructureMachinePoolObject,
887-
desired: desiredMP.InfrastructureMachinePoolObject,
888-
versionGetter: contract.ControlPlane().Version().Get,
887+
cluster: cluster,
888+
current: currentMP.InfrastructureMachinePoolObject,
889+
desired: desiredMP.InfrastructureMachinePoolObject,
889890
}); err != nil {
890891
return errors.Wrapf(err, "failed to reconcile %s", tlog.KObj{Obj: currentMP.Object})
891892
}
892893

893894
bootstrapCtx, _ := log.WithObject(desiredMP.BootstrapObject).Into(ctx)
894895
if err := r.reconcileReferencedObject(bootstrapCtx, reconcileReferencedObjectInput{
895-
cluster: cluster,
896-
current: currentMP.BootstrapObject,
897-
desired: desiredMP.BootstrapObject,
898-
versionGetter: contract.ControlPlane().Version().Get,
896+
cluster: cluster,
897+
current: currentMP.BootstrapObject,
898+
desired: desiredMP.BootstrapObject,
899899
}); err != nil {
900900
return errors.Wrapf(err, "failed to reconcile %s", tlog.KObj{Obj: currentMP.Object})
901901
}

internal/controllers/topology/cluster/scope/blueprint.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ type MachinePoolBlueprint struct {
8787
// BootstrapTemplate holds the bootstrap template for a MachinePool referenced from ClusterClass.
8888
BootstrapTemplate *unstructured.Unstructured
8989

90-
// InfrastructureMachinePoolTemplate holds the infrastructure machine template for a MachinePool referenced from ClusterClass.
90+
// InfrastructureMachinePoolTemplate holds the infrastructure machine pool template for a MachinePool referenced from ClusterClass.
9191
InfrastructureMachinePoolTemplate *unstructured.Unstructured
9292
}
9393

internal/controllers/topology/cluster/scope/scope_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
)
2727

2828
func TestNew(t *testing.T) {
29-
t.Run("should set the right maxMachineDeploymentUpgradeConcurrency in UpgradeTracker from the cluster annotation", func(t *testing.T) {
29+
t.Run("should set the right maxUpgradeConcurrency in UpgradeTracker from the cluster annotation", func(t *testing.T) {
3030
tests := []struct {
3131
name string
3232
cluster *clusterv1.Cluster
@@ -53,7 +53,8 @@ func TestNew(t *testing.T) {
5353
for _, tt := range tests {
5454
g := NewWithT(t)
5555
s := New(tt.cluster)
56-
g.Expect(s.UpgradeTracker.MachineDeployments.maxMachineDeploymentUpgradeConcurrency).To(Equal(tt.want))
56+
g.Expect(s.UpgradeTracker.MachineDeployments.maxUpgradeConcurrency).To(Equal(tt.want))
57+
g.Expect(s.UpgradeTracker.MachinePools.maxUpgradeConcurrency).To(Equal(tt.want))
5758
}
5859
})
5960
}

internal/controllers/topology/cluster/scope/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ type MachinePoolState struct {
161161
}
162162

163163
// IsUpgrading determines if the MachinePool is upgrading.
164-
// A machine deployment is considered upgrading if at least one of the Machines of this
164+
// A machine pool is considered upgrading if at least one of the Machines of this
165165
// MachinePool has a different version.
166166
func (mp *MachinePoolState) IsUpgrading(ctx context.Context, c client.Client) (bool, error) {
167167
// If the MachinePool has no version there is no definitive way to check if it is upgrading. Therefore, return false.

0 commit comments

Comments
 (0)