@@ -35,6 +35,7 @@ import (
35
35
"sigs.k8s.io/cluster-api/feature"
36
36
"sigs.k8s.io/cluster-api/internal/contract"
37
37
"sigs.k8s.io/cluster-api/internal/controllers/topology/cluster/scope"
38
+ "sigs.k8s.io/cluster-api/internal/hooks"
38
39
tlog "sigs.k8s.io/cluster-api/internal/log"
39
40
runtimecatalog "sigs.k8s.io/cluster-api/internal/runtime/catalog"
40
41
)
@@ -313,6 +314,33 @@ func (r *Reconciler) computeControlPlaneVersion(ctx context.Context, s *scope.Sc
313
314
// Nb. We do not return early in the function if the control plane is already at the desired version so as
314
315
// to know if the control plane is being upgraded. This information
315
316
// is required when updating the TopologyReconciled condition on the cluster.
317
+
318
+ // Let's call the AfterControlPlaneUpgrade now that the control plane is upgraded.
319
+ if feature .Gates .Enabled (feature .RuntimeSDK ) {
320
+ // Call the hook only if it is marked. If it is not marked it means we don't need ot call the
321
+ // hook because we didn't go through an upgrade or we already called the hook after the upgrade.
322
+ if hooks .IsPending (runtimehooksv1 .AfterControlPlaneUpgrade , s .Current .Cluster ) {
323
+ hookRequest := & runtimehooksv1.AfterControlPlaneUpgradeRequest {
324
+ Cluster : * s .Current .Cluster ,
325
+ KubernetesVersion : desiredVersion ,
326
+ }
327
+ hookResponse := & runtimehooksv1.AfterControlPlaneUpgradeResponse {}
328
+ if err := r .RuntimeClient .CallAllExtensions (ctx , runtimehooksv1 .AfterControlPlaneUpgrade , s .Current .Cluster , hookRequest , hookResponse ); err != nil {
329
+ return "" , errors .Wrapf (err , "error calling the %s hook" , runtimecatalog .HookName (runtimehooksv1 .AfterControlPlaneUpgrade ))
330
+ }
331
+ s .HookResponseTracker .Add (runtimehooksv1 .AfterControlPlaneUpgrade , hookResponse )
332
+ if hookResponse .RetryAfterSeconds != 0 {
333
+ // We have to block the upgrade of the Machine deployments.
334
+ s .UpgradeTracker .MachineDeployments .HoldUpgrades (true )
335
+ } else {
336
+ // We are done with the hook for now. We don't need to call it anymore. Unmark it.
337
+ if err := hooks .MarkAsDone (ctx , r .Client , s .Current .Cluster , runtimehooksv1 .AfterControlPlaneUpgrade ); err != nil {
338
+ return "" , errors .Wrapf (err , "failed to unmark the %s hook" , runtimecatalog .HookName (runtimehooksv1 .AfterControlPlaneUpgrade ))
339
+ }
340
+ }
341
+ }
342
+ }
343
+
316
344
return * currentVersion , nil
317
345
}
318
346
@@ -354,9 +382,15 @@ func (r *Reconciler) computeControlPlaneVersion(ctx context.Context, s *scope.Sc
354
382
// Cannot pickup the new version right now. Need to try again later.
355
383
return * currentVersion , nil
356
384
}
385
+
386
+ // We are picking up the new version here.
387
+ // Mark the AfterControlPlaneUpgrade and the AfterClusterUpgrade hooks so that we call them once we are done with the upgrade.
388
+ if err := hooks .MarkAsPending (ctx , r .Client , s .Current .Cluster , runtimehooksv1 .AfterControlPlaneUpgrade , runtimehooksv1 .AfterClusterUpgrade ); err != nil {
389
+ return "" , errors .Wrapf (err , "failed to mark the %s hook" , []string {runtimecatalog .HookName (runtimehooksv1 .AfterControlPlaneUpgrade ), runtimecatalog .HookName (runtimehooksv1 .AfterClusterUpgrade )})
390
+ }
357
391
}
358
392
359
- // Control plane and machine deployments are stable.
393
+ // Control plane and machine deployments are stable. All the required hook are called.
360
394
// Ready to pick up the topology version.
361
395
return desiredVersion , nil
362
396
}
0 commit comments