Skip to content

Commit eee6809

Browse files
committed
machine_config: add BootImageSkewEnforcement API
1 parent a0fb5f4 commit eee6809

16 files changed

+8309
-3
lines changed

openapi/generated_openapi/zz_generated.openapi.go

Lines changed: 81 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

openapi/openapi.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27587,6 +27587,24 @@
2758727587
}
2758827588
}
2758927589
},
27590+
"com.github.openshift.api.operator.v1.ClusterBootImage": {
27591+
"description": "ClusterBootImage describes the boot image of a cluster. It stores the RHCOS version of the boot image and the OCP release version which shipped with that RHCOS boot image.",
27592+
"type": "object",
27593+
"required": [
27594+
"ocpVersion"
27595+
],
27596+
"properties": {
27597+
"ocpVersion": {
27598+
"description": "ocpVersion provides a string which represents the OCP version of the boot image",
27599+
"type": "string",
27600+
"default": ""
27601+
},
27602+
"rhcosVersion": {
27603+
"description": "rhcosVersion provides a string which represents the RHCOS version of the boot image",
27604+
"type": "string"
27605+
}
27606+
}
27607+
},
2759027608
"com.github.openshift.api.operator.v1.ClusterCSIDriver": {
2759127609
"description": "ClusterCSIDriver object allows management and configuration of a CSI driver operator installed by default in OpenShift. Name of the object must be name of the CSI driver it operates. See CSIDriverName type for list of allowed values.\n\nCompatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer).",
2759227610
"type": "object",
@@ -30928,6 +30946,11 @@
3092830946
"forceRedeploymentReason"
3092930947
],
3093030948
"properties": {
30949+
"bootImageSkewEnforcement": {
30950+
"description": "bootImageSkewEnforcement allows an admin to set the behavior of the boot image skew enforcement mechanism.",
30951+
"default": {},
30952+
"$ref": "#/definitions/com.github.openshift.api.operator.v1.SkewEnforcementSelector"
30953+
},
3093130954
"failedRevisionLimit": {
3093230955
"description": "failedRevisionLimit is the number of failed static pod installer revisions to keep on disk and in the api -1 = unlimited, 0 or unset = 5 (default)",
3093330956
"type": "integer",
@@ -33280,6 +33303,32 @@
3328033303
}
3328133304
}
3328233305
},
33306+
"com.github.openshift.api.operator.v1.SkewEnforcementSelector": {
33307+
"type": "object",
33308+
"required": [
33309+
"mode"
33310+
],
33311+
"properties": {
33312+
"clusterBootImage": {
33313+
"description": "clusterBootImage describes the current boot image of the cluster. This will be used to enforce the skew limit. Only permitted when mode is set to \"Automatic\" or \"Manual\".",
33314+
"default": {},
33315+
"$ref": "#/definitions/com.github.openshift.api.operator.v1.ClusterBootImage"
33316+
},
33317+
"mode": {
33318+
"description": "mode determines the underlying behavior of skew enforcement mechanism. Valid values are Automatic, Manual and Disabled. Automatic means that the MCO will store the OCP version associated with the last boot image update in the clusterBootImage field. Manual means that the cluster admin is expected to perform manual boot image updates and store OCP version associated with the last boot image update in the clusterBootImage field. In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the skew limit described by the release image. Disabled means that the MCO will permit upgrades when the boot image exceeds the skew limit described by the release image. This may affect the cluster's ability to scale.",
33319+
"type": "string",
33320+
"default": ""
33321+
}
33322+
},
33323+
"x-kubernetes-unions": [
33324+
{
33325+
"discriminator": "mode",
33326+
"fields-to-discriminateBy": {
33327+
"clusterBootImage": "ClusterBootImage"
33328+
}
33329+
}
33330+
]
33331+
},
3328333332
"com.github.openshift.api.operator.v1.StaticIPAMAddresses": {
3328433333
"description": "StaticIPAMAddresses provides IP address and Gateway for static IPAM addresses",
3328533334
"type": "object",
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
2+
name: "MachineConfiguration"
3+
crdName: machineconfigurations.operator.openshift.io
4+
featureGates:
5+
- BootImageSkewEnforcement
6+
tests:
7+
onCreate:
8+
- name: Should be able to create a minimal MachineConfiguration
9+
initial: |
10+
apiVersion: operator.openshift.io/v1
11+
kind: MachineConfiguration
12+
spec: {} # No spec is required for a MachineConfiguration
13+
expected: |
14+
apiVersion: operator.openshift.io/v1
15+
kind: MachineConfiguration
16+
spec:
17+
logLevel: Normal
18+
operatorLogLevel: Normal
19+
- name: Should be able to create an manual BootImageSkewEnforcement configuration knob
20+
initial: |
21+
apiVersion: operator.openshift.io/v1
22+
kind: MachineConfiguration
23+
spec:
24+
bootImageSkewEnforcement:
25+
mode: Manual
26+
clusterBootImage:
27+
ocpVersion: "4.18.2"
28+
rhcosVersion: "9.6.20250523-1"
29+
expected: |
30+
apiVersion: operator.openshift.io/v1
31+
kind: MachineConfiguration
32+
spec:
33+
logLevel: Normal
34+
operatorLogLevel: Normal
35+
bootImageSkewEnforcement:
36+
mode: Manual
37+
clusterBootImage:
38+
ocpVersion: "4.18.2"
39+
rhcosVersion: "9.6.20250523-1"
40+
- name: Should be able to create an automatic BootImageSkewEnforcement configuration knob
41+
initial: |
42+
apiVersion: operator.openshift.io/v1
43+
kind: MachineConfiguration
44+
spec:
45+
bootImageSkewEnforcement:
46+
mode: Automatic
47+
clusterBootImage:
48+
ocpVersion: "4.18.2"
49+
rhcosVersion: "9.6.20250523-1"
50+
expected: |
51+
apiVersion: operator.openshift.io/v1
52+
kind: MachineConfiguration
53+
spec:
54+
logLevel: Normal
55+
operatorLogLevel: Normal
56+
bootImageSkewEnforcement:
57+
mode: Automatic
58+
clusterBootImage:
59+
ocpVersion: "4.18.2"
60+
rhcosVersion: "9.6.20250523-1"
61+
- name: Should be able to create a disabled BootImageSkewEnforcement configuration knob
62+
initial: |
63+
apiVersion: operator.openshift.io/v1
64+
kind: MachineConfiguration
65+
spec:
66+
bootImageSkewEnforcement:
67+
mode: Disabled
68+
expected: |
69+
apiVersion: operator.openshift.io/v1
70+
kind: MachineConfiguration
71+
spec:
72+
logLevel: Normal
73+
operatorLogLevel: Normal
74+
bootImageSkewEnforcement:
75+
mode: Disabled
76+
- name: Should not be able to add ClusterBootImage field if bootImageSkewEnforcement.mode is set to Disabled
77+
initial: |
78+
apiVersion: operator.openshift.io/v1
79+
kind: MachineConfiguration
80+
spec:
81+
bootImageSkewEnforcement:
82+
mode: Disabled
83+
clusterBootImage:
84+
ocpVersion: "4.18.2"
85+
rhcosVersion: "9.6.20250523-1"
86+
expectedError: "clusterBootImage is required when type is Automatic or Manual, and forbidden otherwise"
87+
- name: ClusterBootImage field should be set if bootImageSkewEnforcement.mode is set to Automatic
88+
initial: |
89+
apiVersion: operator.openshift.io/v1
90+
kind: MachineConfiguration
91+
spec:
92+
bootImageSkewEnforcement:
93+
mode: Automatic
94+
expectedError: "clusterBootImage is required when type is Automatic or Manual, and forbidden otherwise"
95+
- name: ClusterBootImage field should be set if bootImageSkewEnforcement.mode is set to Manual
96+
initial: |
97+
apiVersion: operator.openshift.io/v1
98+
kind: MachineConfiguration
99+
spec:
100+
bootImageSkewEnforcement:
101+
mode: Manual
102+
expectedError: "clusterBootImage is required when type is Automatic or Manual, and forbidden otherwise"

operator/v1/types_machineconfiguration.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,66 @@ type MachineConfigurationSpec struct {
5656
// +openshift:enable:FeatureGate=NodeDisruptionPolicy
5757
// +optional
5858
NodeDisruptionPolicy NodeDisruptionPolicyConfig `json:"nodeDisruptionPolicy"`
59+
// bootImageSkewEnforcement allows an admin to set the behavior of the boot image skew enforcement mechanism.
60+
// +openshift:enable:FeatureGate=BootImageSkewEnforcement
61+
// +optional
62+
BootImageSkewEnforcement SkewEnforcementSelector `json:"bootImageSkewEnforcement"`
63+
}
64+
65+
// +kubebuilder:validation:XValidation:rule="has(self.mode) && (self.mode == 'Automatic' || self.mode =='Manual') ? has(self.clusterBootImage) : !has(self.clusterBootImage)",message="clusterBootImage is required when type is Automatic or Manual, and forbidden otherwise"
66+
// +union
67+
type SkewEnforcementSelector struct {
68+
// mode determines the underlying behavior of skew enforcement mechanism.
69+
// Valid values are Automatic, Manual and Disabled.
70+
// Automatic means that the MCO will store the OCP version associated with the last boot image update in the
71+
// clusterBootImage field.
72+
// Manual means that the cluster admin is expected to perform manual boot image updates and store OCP version
73+
// associated with the last boot image update in the clusterBootImage field.
74+
// In Automatic and Manual mode, the MCO will prevent upgrades when the boot image skew exceeds the
75+
// skew limit described by the release image.
76+
// Disabled means that the MCO will permit upgrades when the boot image exceeds the skew limit
77+
// described by the release image. This may affect the cluster's ability to scale.
78+
// +unionDiscriminator
79+
// +required
80+
Mode SkewEnforcementSelectorMode `json:"mode"`
81+
82+
// clusterBootImage describes the current boot image of the cluster. This will be used to enforce the skew limit.
83+
// Only permitted when mode is set to "Automatic" or "Manual".
84+
// +optional
85+
ClusterBootImage ClusterBootImage `json:"clusterBootImage,omitempty"`
5986
}
6087

88+
// ClusterBootImage describes the boot image of a cluster. It stores the RHCOS version of the boot image and
89+
// the OCP release version which shipped with that RHCOS boot image.
90+
type ClusterBootImage struct {
91+
// ocpVersion provides a string which represents the OCP version of the boot image
92+
// +kubebuilder:validation:XValidation:rule="self.matches('^[0-9]+\\\\.[0-9]+\\\\.[0-9]+$')",message="bootImageOCPVersion must match the OCP semver compatible format of x.y.z"
93+
// +kubebuilder:validation:MaxLength:=8
94+
// +required
95+
OCPVersion string `json:"ocpVersion"`
96+
97+
// rhcosVersion provides a string which represents the RHCOS version of the boot image
98+
// +kubebuilder:validation:XValidation:rule="self.matches('^[0-9]+\\\\.[0-9]+\\\\.[0-9]{8}-[0-9]+$')",message="rhcosVersion must match format [major].[minor].[datestamp(YYYYMMDD)]-[buildnumber]"
99+
// +kubebuilder:validation:MaxLength:=15
100+
// +optional
101+
RHCOSVersion string `json:"rhcosVersion,omitempty"`
102+
}
103+
104+
// SkewEnforcementSelectorMode is a string enum used to indicate the cluster's boot image skew enforcement mode.
105+
// +kubebuilder:validation:Enum:="Automatic";"Manual";"Disabled"
106+
type SkewEnforcementSelectorMode string
107+
108+
const (
109+
// Automatic represents a configuration mode that allows automatic skew enforcement.
110+
Automatic SkewEnforcementSelectorMode = "Automatic"
111+
112+
// Manual represents a configuration mode that allows manual skew enforcement.
113+
Manual SkewEnforcementSelectorMode = "Manual"
114+
115+
// Disabled represents a configuration mode that disables boot image skew enforcement.
116+
Disabled SkewEnforcementSelectorMode = "Disabled"
117+
)
118+
61119
type MachineConfigurationStatus struct {
62120
// observedGeneration is the last generation change you've dealt with
63121
// +optional

0 commit comments

Comments
 (0)