Skip to content

Commit 0c94cde

Browse files
✨ Add lifecycle hooks for chained-upgrade (#12878)
* Add lifecycle hooks for chained-upgrade * Refactor hooks call in computeControlPlaneVersion, add Lifecycle hooks sequence tests * Drop duplicated UpgradeStep * Address feedback
1 parent ee6cfc6 commit 0c94cde

File tree

7 files changed

+2227
-1391
lines changed

7 files changed

+2227
-1391
lines changed

api/runtime/hooks/v1alpha1/lifecyclehooks_types.go

Lines changed: 195 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ type BeforeClusterUpgradeRequest struct {
9797
// toKubernetesVersion is the target Kubernetes version of the upgrade.
9898
// +required
9999
ToKubernetesVersion string `json:"toKubernetesVersion"`
100+
101+
// controlPlaneUpgrades is the list of version upgrade steps for the control plane.
102+
// +optional
103+
ControlPlaneUpgrades []UpgradeStepInfo `json:"controlPlaneUpgrades,omitempty"`
104+
105+
// workersUpgrades is the list of version upgrade steps for the workers.
106+
// +optional
107+
WorkersUpgrades []UpgradeStepInfo `json:"workersUpgrades,omitempty"`
108+
}
109+
110+
// UpgradeStepInfo provide info about a single version upgrade step.
111+
type UpgradeStepInfo struct {
112+
// version is the Kubernetes version for this upgrade step.
113+
// +required
114+
// +kubebuilder:validation:MinLength=1
115+
Version string `json:"version,omitempty"`
100116
}
101117

102118
var _ RetryResponseObject = &BeforeClusterUpgradeResponse{}
@@ -114,6 +130,50 @@ type BeforeClusterUpgradeResponse struct {
114130
// before the updated version is propagated to the underlying objects.
115131
func BeforeClusterUpgrade(*BeforeClusterUpgradeRequest, *BeforeClusterUpgradeResponse) {}
116132

133+
// BeforeControlPlaneUpgradeRequest is the request of the BeforeControlPlane hook.
134+
// +kubebuilder:object:root=true
135+
type BeforeControlPlaneUpgradeRequest struct {
136+
metav1.TypeMeta `json:",inline"`
137+
138+
// CommonRequest contains fields common to all request types.
139+
CommonRequest `json:",inline"`
140+
141+
// cluster is the cluster object the lifecycle hook corresponds to.
142+
// +required
143+
Cluster clusterv1beta1.Cluster `json:"cluster"`
144+
145+
// fromKubernetesVersion is the current Kubernetes version of the control plane for the next upgrade step.
146+
// +required
147+
FromKubernetesVersion string `json:"fromKubernetesVersion"`
148+
149+
// toKubernetesVersion is the target Kubernetes version of the control plane for the next upgrade step.
150+
// +required
151+
ToKubernetesVersion string `json:"toKubernetesVersion"`
152+
153+
// controlPlaneUpgrades is the list of the remaining version upgrade steps for the control plane, if any.
154+
// +optional
155+
ControlPlaneUpgrades []UpgradeStepInfo `json:"controlPlaneUpgrades,omitempty"`
156+
157+
// workersUpgrades is the list of the remaining version upgrade steps for workers, if any.
158+
// +optional
159+
WorkersUpgrades []UpgradeStepInfo `json:"workersUpgrades,omitempty"`
160+
}
161+
162+
var _ RetryResponseObject = &BeforeControlPlaneUpgradeResponse{}
163+
164+
// BeforeControlPlaneUpgradeResponse is the response of the BeforeControlPlaneUpgrade hook.
165+
// +kubebuilder:object:root=true
166+
type BeforeControlPlaneUpgradeResponse struct {
167+
metav1.TypeMeta `json:",inline"`
168+
169+
// CommonRetryResponse contains Status, Message and RetryAfterSeconds fields.
170+
CommonRetryResponse `json:",inline"`
171+
}
172+
173+
// BeforeControlPlaneUpgrade is the hook that will be called before a new version is propagated to the control plane object.
174+
func BeforeControlPlaneUpgrade(*BeforeControlPlaneUpgradeRequest, *BeforeControlPlaneUpgradeResponse) {
175+
}
176+
117177
// AfterControlPlaneUpgradeRequest is the request of the AfterControlPlaneUpgrade hook.
118178
// +kubebuilder:object:root=true
119179
type AfterControlPlaneUpgradeRequest struct {
@@ -126,9 +186,17 @@ type AfterControlPlaneUpgradeRequest struct {
126186
// +required
127187
Cluster clusterv1beta1.Cluster `json:"cluster"`
128188

129-
// kubernetesVersion is the Kubernetes version of the Control Plane after the upgrade.
189+
// kubernetesVersion is the Kubernetes version of the control plane after an upgrade step.
130190
// +required
131191
KubernetesVersion string `json:"kubernetesVersion"`
192+
193+
// controlPlaneUpgrades is the list of the remaining version upgrade steps for the control plane, if any.
194+
// +optional
195+
ControlPlaneUpgrades []UpgradeStepInfo `json:"controlPlaneUpgrades,omitempty"`
196+
197+
// workersUpgrades is the list of the remaining version upgrade steps for workers, if any.
198+
// +optional
199+
WorkersUpgrades []UpgradeStepInfo `json:"workersUpgrades,omitempty"`
132200
}
133201

134202
var _ RetryResponseObject = &AfterControlPlaneUpgradeResponse{}
@@ -146,6 +214,90 @@ type AfterControlPlaneUpgradeResponse struct {
146214
// Kubernetes version and before the target version is propagated to the workload machines.
147215
func AfterControlPlaneUpgrade(*AfterControlPlaneUpgradeRequest, *AfterControlPlaneUpgradeResponse) {}
148216

217+
// BeforeWorkersUpgradeRequest is the request of the BeforeWorkersUpgrade hook.
218+
// +kubebuilder:object:root=true
219+
type BeforeWorkersUpgradeRequest struct {
220+
metav1.TypeMeta `json:",inline"`
221+
222+
// CommonRequest contains fields common to all request types.
223+
CommonRequest `json:",inline"`
224+
225+
// cluster is the cluster object the lifecycle hook corresponds to.
226+
// +required
227+
Cluster clusterv1beta1.Cluster `json:"cluster"`
228+
229+
// fromKubernetesVersion is the current Kubernetes version of the workers for the next upgrade step.
230+
// +required
231+
FromKubernetesVersion string `json:"fromKubernetesVersion"`
232+
233+
// toKubernetesVersion is the target Kubernetes version of the workers for the next upgrade step.
234+
// +required
235+
ToKubernetesVersion string `json:"toKubernetesVersion"`
236+
237+
// controlPlaneUpgrades is the list of the remaining version upgrade steps for the control plane, if any.
238+
// +optional
239+
ControlPlaneUpgrades []UpgradeStepInfo `json:"controlPlaneUpgrades,omitempty"`
240+
241+
// workersUpgrades is the list of the remaining version upgrade steps for workers, if any.
242+
// +optional
243+
WorkersUpgrades []UpgradeStepInfo `json:"workersUpgrades,omitempty"`
244+
}
245+
246+
var _ RetryResponseObject = &BeforeWorkersUpgradeResponse{}
247+
248+
// BeforeWorkersUpgradeResponse is the response of the BeforeWorkersUpgrade hook.
249+
// +kubebuilder:object:root=true
250+
type BeforeWorkersUpgradeResponse struct {
251+
metav1.TypeMeta `json:",inline"`
252+
253+
// CommonRetryResponse contains Status, Message and RetryAfterSeconds fields.
254+
CommonRetryResponse `json:",inline"`
255+
}
256+
257+
// BeforeWorkersUpgrade is the hook that will be called before a new version is propagated to workers.
258+
func BeforeWorkersUpgrade(*BeforeWorkersUpgradeRequest, *BeforeWorkersUpgradeResponse) {
259+
}
260+
261+
// AfterWorkersUpgradeRequest is the request of the AfterWorkersUpgrade hook.
262+
// +kubebuilder:object:root=true
263+
type AfterWorkersUpgradeRequest struct {
264+
metav1.TypeMeta `json:",inline"`
265+
266+
// CommonRequest contains fields common to all request types.
267+
CommonRequest `json:",inline"`
268+
269+
// cluster is the cluster object the lifecycle hook corresponds to.
270+
// +required
271+
Cluster clusterv1beta1.Cluster `json:"cluster"`
272+
273+
// kubernetesVersion is the Kubernetes version of the workers after an upgrade step.
274+
// +required
275+
KubernetesVersion string `json:"kubernetesVersion"`
276+
277+
// controlPlaneUpgrades is the list of the remaining version upgrade steps for the control plane, if any.
278+
// +optional
279+
ControlPlaneUpgrades []UpgradeStepInfo `json:"controlPlaneUpgrades,omitempty"`
280+
281+
// workersUpgrades is the list of the remaining version upgrade steps for workers, if any.
282+
// +optional
283+
WorkersUpgrades []UpgradeStepInfo `json:"workersUpgrades,omitempty"`
284+
}
285+
286+
var _ RetryResponseObject = &AfterWorkersUpgradeResponse{}
287+
288+
// AfterWorkersUpgradeResponse is the response of the AfterWorkersUpgrade hook.
289+
// +kubebuilder:object:root=true
290+
type AfterWorkersUpgradeResponse struct {
291+
metav1.TypeMeta `json:",inline"`
292+
293+
// CommonRetryResponse contains Status, Message and RetryAfterSeconds fields.
294+
CommonRetryResponse `json:",inline"`
295+
}
296+
297+
// AfterWorkersUpgrade is the hook called after the control plane is successfully upgraded to the target
298+
// Kubernetes version and before the target version is propagated to the workload machines.
299+
func AfterWorkersUpgrade(*AfterWorkersUpgradeRequest, *AfterWorkersUpgradeResponse) {}
300+
149301
// AfterClusterUpgradeRequest is the request of the AfterClusterUpgrade hook.
150302
// +kubebuilder:object:root=true
151303
type AfterClusterUpgradeRequest struct {
@@ -243,18 +395,58 @@ func init() {
243395
"tasks before the new version is propagated to the control plane",
244396
})
245397

398+
catalogBuilder.RegisterHook(BeforeControlPlaneUpgrade, &runtimecatalog.HookMeta{
399+
Tags: []string{"Lifecycle Hooks"},
400+
Summary: "Cluster API Runtime will call this hook before the control plane is upgraded",
401+
Description: "This hook is called before a new version is propagated to the control plane object.\n" +
402+
"\n" +
403+
"Notes:\n" +
404+
"- This hook will be called only for Clusters with a managed topology\n" +
405+
"- When an upgrade is starting, BeforeControlPlaneUpgrade will be called after BeforeClusterUpgrade is completed\n" +
406+
"- When an upgrade is in progress BeforeControlPlaneUpgrade will be called for each intermediate version that will be applied " +
407+
"to the control plane (instead BeforeClusterUpgrade will be called only once at the beginning of the upgrade)" +
408+
"- This is a blocking hook; Runtime Extension implementers can use this hook to execute " +
409+
"tasks before the new version is propagated to the control plane",
410+
})
411+
246412
catalogBuilder.RegisterHook(AfterControlPlaneUpgrade, &runtimecatalog.HookMeta{
247413
Tags: []string{"Lifecycle Hooks"},
248414
Summary: "Cluster API Runtime will call this hook after the control plane is upgraded",
249415
Description: "Cluster API Runtime will call this hook after the a cluster's control plane has been upgraded to the version specified " +
250-
"in spec.topology.version, and immediately before the new version is going to be propagated to the MachineDeployments. " +
416+
"in spec.topology.version or to an intermediate version in the upgrade plan." +
251417
"A control plane upgrade is completed when all the machines in the control plane have been upgraded.\n" +
252418
"\n" +
253419
"Notes:\n" +
254420
"- This hook will be called only for Clusters with a managed topology\n" +
255421
"- The call's request contains the Cluster object and the Kubernetes version we upgraded to\n" +
256422
"- This is a blocking hook; Runtime Extension implementers can use this hook to execute " +
257-
"tasks before the new version is propagated to the MachineDeployments",
423+
"tasks before the new version is propagated to the MachineDeployments and Machine Pools",
424+
})
425+
426+
catalogBuilder.RegisterHook(BeforeWorkersUpgrade, &runtimecatalog.HookMeta{
427+
Tags: []string{"Lifecycle Hooks"},
428+
Summary: "Cluster API Runtime will call this hook before the workers are upgraded",
429+
Description: "This hook is called before a new version is propagated to workers.\n" +
430+
"\n" +
431+
"Notes:\n" +
432+
"- This hook will be called only for Clusters with a managed topology\n" +
433+
"- This hook will be called only if workers upgrade must be performed for an intermediate version of " +
434+
"a chained upgrade or when upgrading to the target spec.topology.version.\n" +
435+
"- This is a blocking hook; Runtime Extension implementers can use this hook to execute " +
436+
"tasks before the new version is propagated to the MachineDeployments and Machine Pools",
437+
})
438+
439+
catalogBuilder.RegisterHook(AfterWorkersUpgrade, &runtimecatalog.HookMeta{
440+
Tags: []string{"Lifecycle Hooks"},
441+
Summary: "Cluster API Runtime will call this hook after workers are upgraded",
442+
Description: "This hook is called after all the workers have been upgraded to the version specified in spec.topology.version " +
443+
"or to an intermediate version in the upgrade plan.\n" +
444+
"\n" +
445+
"Notes:\n" +
446+
"- This hook will be called only for Clusters with a managed topology\n" +
447+
"- The call's request contains the Cluster object, the current Kubernetes version and the Kubernetes version we are upgrading to\n" +
448+
"- This is a blocking hook; Runtime Extension implementers can use this hook to execute " +
449+
"tasks before the upgrade plan continues, or when already at the target spec.topology.version, before AfterClusterUpgrade is called.\n",
258450
})
259451

260452
catalogBuilder.RegisterHook(AfterClusterUpgrade, &runtimecatalog.HookMeta{

0 commit comments

Comments
 (0)