diff --git a/machineconfiguration/v1/tests/machineconfignodes.machineconfiguration.openshift.io/ImageModeStatusReporting.yaml b/machineconfiguration/v1/tests/machineconfignodes.machineconfiguration.openshift.io/ImageModeStatusReporting.yaml new file mode 100644 index 00000000000..dc90dbfb4f5 --- /dev/null +++ b/machineconfiguration/v1/tests/machineconfignodes.machineconfiguration.openshift.io/ImageModeStatusReporting.yaml @@ -0,0 +1,188 @@ +apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this +name: "[FeatureGate] ImageModeStatusReporting" +crdName: machineconfignodes.machineconfiguration.openshift.io +featureGates: +- ImageModeStatusReporting +tests: + onCreate: + - name: Should be able to create MachineConfigNode when spec.configImage ImageModeStatusReporting is enabled + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + - name: spec.configImage.desiredImage should enforce MaxLength. + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: registry.example.com/a/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very//very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/j + expectedError: "the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + - name: Should not be able to create a MachineConfigNode with desiredImage set to a tag-based image reference + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/os-images:latest + expectedError: "the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + - name: spec.configImage.desiredImage should enforce 256 image digest format. + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/os-images@sha512:a2c24b2903ad327e06bf57ac1d34e4e99e284309ccc69a5ffcc640121c0f82a05a841e915edb1b633ca52692bd019e1fcdd09d3f0730ace8f49c96b3bd020216 + expectedError: "the OCI Image reference must end with a valid '@sha256:' suffix, where '' is 64 characters long" + onUpdate: + - name: Should be able to create MachineConfigNode with status.configImage when ImageModeStatusReporting is enabled when the current and desired images are the same + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + updated: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + status: + configImage: + currentImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + status: + configImage: + currentImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + - name: Should be able to create MachineConfigNode with status.configImage when ImageModeStatusReporting is enabled when the current and desired images are the different. + initial: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + updated: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + status: + configImage: + currentImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:c47856f56e1fdb7c9d10a1658e4ea85fbea44d71fb0e82898d152b47e0f894c6 + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + expected: | + apiVersion: machineconfiguration.openshift.io/v1 + kind: MachineConfigNode + metadata: + name: test-imagemodestatusreporting + spec: + node: + name: test-imagemodestatusreporting + pool: + name: worker + configVersion: + desired: rendered-worker-abc + configImage: + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + status: + configImage: + currentImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:c47856f56e1fdb7c9d10a1658e4ea85fbea44d71fb0e82898d152b47e0f894c6 + desiredImage: image-registry.openshift-image-registry.svc:5000/openshift-machine-config-operator/ocb-image@sha256:7a539f562d8d5d3b6bd7338ac014e34dabc9626cf344d30e412ef98a55cc1bf6 + diff --git a/machineconfiguration/v1/types_machineconfignode.go b/machineconfiguration/v1/types_machineconfignode.go index 5decf3738a0..effe1656e38 100644 --- a/machineconfiguration/v1/types_machineconfignode.go +++ b/machineconfiguration/v1/types_machineconfignode.go @@ -98,6 +98,13 @@ type MachineConfigNodeSpec struct { // the new machine config against the current machine config. // +required ConfigVersion MachineConfigNodeSpecMachineConfigVersion `json:"configVersion"` + + // configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + // When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + // When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + // +openshift:enable:FeatureGate=ImageModeStatusReporting + // +optional + ConfigImage MachineConfigNodeSpecConfigImage `json:"configImage,omitempty,omitzero"` } // MachineConfigNodeStatus holds the reported information on a particular machine config node. @@ -106,6 +113,8 @@ type MachineConfigNodeStatus struct { // UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, // Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, // and PinnedImageSetsDegraded. + // The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + // AppliedOSImage, AppliedFiles // +listType=map // +listMapKey=type // +kubebuilder:validation:MaxItems=20 @@ -120,6 +129,15 @@ type MachineConfigNodeStatus struct { // configVersion describes the current and desired machine config version for this node. // +optional ConfigVersion *MachineConfigNodeStatusMachineConfigVersion `json:"configVersion,omitempty"` + // configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + // When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + // When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + // When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + // When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + // and configVersion change during the same update. + // +openshift:enable:FeatureGate=ImageModeStatusReporting + // +optional + ConfigImage MachineConfigNodeStatusConfigImage `json:"configImage,omitempty,omitzero"` // pinnedImageSets describes the current and desired pinned image sets for this node. // +listType=map // +listMapKey=name @@ -244,6 +262,41 @@ type MachineConfigNodeSpecMachineConfigVersion struct { Desired string `json:"desired"` } +// MachineConfigNodeSpecConfigImage holds the desired image for the node. +// This structure is populated from the `machineconfiguration.openshift.io/desiredImage` +// annotation on the target node, which is set by the Machine Config Pool controller +// to signal the desired image pullspec for the node to update to. +type MachineConfigNodeSpecConfigImage struct { + // desiredImage is a required field that configures the image that the node should be updated to use. + // It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + // desiredImage must not be an empty string and must not exceed 447 characters in length. + // +required + DesiredImage ImageDigestFormat `json:"desiredImage,omitempty"` +} + +// MachineConfigNodeStatusConfigImage holds the observed state of the image +// on the node, including both the image targeted for an update and the image +// currently applied. This allows for monitoring the progress of the layering +// rollout. If Image Mode is enabled, desiredImage must be defined. +// +kubebuilder:validation:MinProperties:=1 +type MachineConfigNodeStatusConfigImage struct { + // currentImage is an optional field that represents the current image that is applied to the node. + // When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + // When specified, this means that the node is currently using this image. + // currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + // currentImage must not be an empty string and must not exceed 447 characters in length. + // +optional + CurrentImage ImageDigestFormat `json:"currentImage,omitzero,omitempty"` + // desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + // When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + // When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + // If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + // desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + // desiredImage must not be an empty string and must not exceed 447 characters in length. + // +optional + DesiredImage ImageDigestFormat `json:"desiredImage,omitzero,omitempty"` +} + // StateProgress is each possible state for each possible MachineConfigNodeType // +enum type StateProgress string @@ -263,8 +316,14 @@ const ( MachineConfigNodeResumed StateProgress = "Resumed" // MachineConfigNodeUpdateDrained describes the part of the in progress phase where the node drains MachineConfigNodeUpdateDrained StateProgress = "Drained" + // MachineConfigNodeUpdateFiles describes the part of the in progress phase where the nodes files changes + MachineConfigNodeUpdateFiles StateProgress = "AppliedFiles" + // MachineConfigNodeUpdateOS describes the part of the in progress phase where the OS config changes + MachineConfigNodeUpdateOS StateProgress = "AppliedOSImage" // MachineConfigNodeUpdateFilesAndOS describes the part of the in progress phase where the nodes files and OS config change MachineConfigNodeUpdateFilesAndOS StateProgress = "AppliedFilesAndOS" + // MachineConfigNodeImagePulledFromRegistry describes the part of the in progress phase where the update image is pulled from the registry + MachineConfigNodeImagePulledFromRegistry StateProgress = "ImagePulledFromRegistry" // MachineConfigNodeUpdateCordoned describes the part of the in progress phase where the node cordons MachineConfigNodeUpdateCordoned StateProgress = "Cordoned" // MachineConfigNodeUpdateUncordoned describes the part of the completing phase where the node uncordons diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml index a9b3e19a7b9..46d9a6ea46f 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml @@ -99,6 +99,30 @@ spec: spec: description: spec describes the configuration of the machine config node. properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + required: + - desiredImage + type: object configVersion: description: |- configVersion holds the desired config version for the node targeted by this machine config node resource. @@ -182,6 +206,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -241,6 +267,52 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + type: object configVersion: description: configVersion describes the current and desired machine config version for this node. diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml index 7a1aed97d2f..21d9caaa425 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml @@ -182,6 +182,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml index 487dc5beac9..a68b8d0adfe 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml @@ -99,6 +99,30 @@ spec: spec: description: spec describes the configuration of the machine config node. properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + required: + - desiredImage + type: object configVersion: description: |- configVersion holds the desired config version for the node targeted by this machine config node resource. @@ -182,6 +206,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -241,6 +267,52 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + type: object configVersion: description: configVersion describes the current and desired machine config version for this node. diff --git a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml index 013d6952b40..74d7000f652 100644 --- a/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml +++ b/machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml @@ -99,6 +99,30 @@ spec: spec: description: spec describes the configuration of the machine config node. properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + required: + - desiredImage + type: object configVersion: description: |- configVersion holds the desired config version for the node targeted by this machine config node resource. @@ -182,6 +206,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -241,6 +267,52 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + type: object configVersion: description: configVersion describes the current and desired machine config version for this node. diff --git a/machineconfiguration/v1/zz_generated.deepcopy.go b/machineconfiguration/v1/zz_generated.deepcopy.go index 521fd1af22d..c8a7667fe76 100644 --- a/machineconfiguration/v1/zz_generated.deepcopy.go +++ b/machineconfiguration/v1/zz_generated.deepcopy.go @@ -748,6 +748,7 @@ func (in *MachineConfigNodeSpec) DeepCopyInto(out *MachineConfigNodeSpec) { out.Node = in.Node out.Pool = in.Pool out.ConfigVersion = in.ConfigVersion + out.ConfigImage = in.ConfigImage return } @@ -761,6 +762,22 @@ func (in *MachineConfigNodeSpec) DeepCopy() *MachineConfigNodeSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineConfigNodeSpecConfigImage) DeepCopyInto(out *MachineConfigNodeSpecConfigImage) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineConfigNodeSpecConfigImage. +func (in *MachineConfigNodeSpecConfigImage) DeepCopy() *MachineConfigNodeSpecConfigImage { + if in == nil { + return nil + } + out := new(MachineConfigNodeSpecConfigImage) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MachineConfigNodeSpecMachineConfigVersion) DeepCopyInto(out *MachineConfigNodeSpecMachineConfigVersion) { *out = *in @@ -792,6 +809,7 @@ func (in *MachineConfigNodeStatus) DeepCopyInto(out *MachineConfigNodeStatus) { *out = new(MachineConfigNodeStatusMachineConfigVersion) **out = **in } + out.ConfigImage = in.ConfigImage if in.PinnedImageSets != nil { in, out := &in.PinnedImageSets, &out.PinnedImageSets *out = make([]MachineConfigNodeStatusPinnedImageSet, len(*in)) @@ -815,6 +833,22 @@ func (in *MachineConfigNodeStatus) DeepCopy() *MachineConfigNodeStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineConfigNodeStatusConfigImage) DeepCopyInto(out *MachineConfigNodeStatusConfigImage) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineConfigNodeStatusConfigImage. +func (in *MachineConfigNodeStatusConfigImage) DeepCopy() *MachineConfigNodeStatusConfigImage { + if in == nil { + return nil + } + out := new(MachineConfigNodeStatusConfigImage) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MachineConfigNodeStatusMachineConfigVersion) DeepCopyInto(out *MachineConfigNodeStatusMachineConfigVersion) { *out = *in diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml index 2fa1eb8e8f3..d80bfc5848d 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests.yaml @@ -117,6 +117,7 @@ machineconfignodes.machineconfiguration.openshift.io: Capability: "" Category: "" FeatureGates: + - ImageModeStatusReporting - IrreconcilableMachineConfig - MachineConfigNodes FilenameOperatorName: machine-config diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/ImageModeStatusReporting.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/ImageModeStatusReporting.yaml new file mode 100644 index 00000000000..c98d8d873e5 --- /dev/null +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/ImageModeStatusReporting.yaml @@ -0,0 +1,451 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.openshift.io: https://github.com/openshift/api/pull/2255 + api.openshift.io/filename-cvo-runlevel: "0000_80" + api.openshift.io/filename-operator: machine-config + api.openshift.io/filename-ordering: "01" + feature-gate.release.openshift.io/ImageModeStatusReporting: "true" + labels: + openshift.io/operator-managed: "" + name: machineconfignodes.machineconfiguration.openshift.io +spec: + group: machineconfiguration.openshift.io + names: + kind: MachineConfigNode + listKind: MachineConfigNodeList + plural: machineconfignodes + singular: machineconfignode + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.pool.name + name: PoolName + type: string + - jsonPath: .spec.configVersion.desired + name: DesiredConfig + type: string + - jsonPath: .status.configVersion.current + name: CurrentConfig + type: string + - jsonPath: .status.conditions[?(@.type=="Updated")].status + name: Updated + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePrepared")].status + name: UpdatePrepared + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateExecuted")].status + name: UpdateExecuted + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdatePostActionComplete")].status + name: UpdatePostActionComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="UpdateComplete")].status + name: UpdateComplete + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Resumed")].status + name: Resumed + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="AppliedFilesAndOS")].status + name: UpdatedFilesAndOS + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Cordoned")].status + name: CordonedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Drained")].status + name: DrainedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="RebootedNode")].status + name: RebootedNode + priority: 1 + type: string + - jsonPath: .status.conditions[?(@.type=="Uncordoned")].status + name: UncordonedNode + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + MachineConfigNode describes the health of the Machines on the system + Compatibility level 1: Stable within a major release for a minimum of 12 months or 3 minor releases (whichever is longer). + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec describes the configuration of the machine config node. + properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + required: + - desiredImage + type: object + configVersion: + description: |- + configVersion holds the desired config version for the node targeted by this machine config node resource. + The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates + the new machine config against the current machine config. + properties: + desired: + description: |- + desired is the name of the machine config that the the node should be upgraded to. + This value is set when the machine config pool generates a new version of its rendered configuration. + When this value is changed, the machine config daemon starts the node upgrade process. + This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + node: + description: node contains a reference to the node for this machine + config node. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + pool: + description: |- + pool contains a reference to the machine config pool that this machine config node's + referenced node belongs to. + properties: + name: + description: |- + name is the name of the object being referenced. For example, this can represent a machine + config pool or node name. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + required: + - configVersion + - node + - pool + type: object + status: + description: status describes the last observed state of this machine + config node. + properties: + conditions: + description: |- + conditions represent the observations of a machine config node's current state. Valid types are: + UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, + Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, + and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 20 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + type: object + configVersion: + description: configVersion describes the current and desired machine + config version for this node. + properties: + current: + description: |- + current is the name of the machine config currently in use on the node. + This value is updated once the machine config daemon has completed the update of the configuration for the node. + This value should match the desired version unless an upgrade is in progress. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + desired: + description: |- + desired is the MachineConfig the node wants to upgrade to. + This value gets set in the machine config node status once the machine config has been validated + against the current machine config. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start and + end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - desired + type: object + observedGeneration: + description: |- + observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. + This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec. + format: int64 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: observedGeneration must not decrease + rule: self >= oldSelf + pinnedImageSets: + description: pinnedImageSets describes the current and desired pinned + image sets for this node. + items: + description: MachineConfigNodeStatusPinnedImageSet holds information + about the current, desired, and failed pinned image sets for the + observed machine config node. + properties: + currentGeneration: + description: currentGeneration is the generation of the pinned + image set that has most recently been successfully pulled + and pinned on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: currentGeneration must not decrease + rule: self >= oldSelf + desiredGeneration: + description: desiredGeneration is the generation of the pinned + image set that is targeted to be pulled and pinned on this + node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: desiredGeneration must not decrease + rule: self >= oldSelf + lastFailedGeneration: + description: lastFailedGeneration is the generation of the most + recent pinned image set that failed to be pulled and pinned + on this node. + format: int32 + minimum: 1 + type: integer + x-kubernetes-validations: + - message: lastFailedGeneration must not decrease + rule: self >= oldSelf + lastFailedGenerationError: + description: |- + lastFailedGenerationError is the error explaining why the desired images failed to be pulled and pinned. + The error is an empty string if the image pull and pin is successful. + maxLength: 32768 + type: string + name: + description: |- + name is the name of the pinned image set. + Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting + of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end + with an alphanumeric character, and be at most 253 characters in length. + maxLength: 253 + type: string + x-kubernetes-validations: + - message: a lowercase RFC 1123 subdomain must consist of lower + case alphanumeric characters, '-' or '.', and must start + and end with an alphanumeric character. + rule: '!format.dns1123Subdomain().validate(self).hasValue()' + required: + - name + type: object + x-kubernetes-validations: + - message: desired generation must be greater than or equal to the + current generation + rule: 'has(self.desiredGeneration) && has(self.currentGeneration) + ? self.desiredGeneration >= self.currentGeneration : true' + - message: desired generation must be greater than or equal to the + last failed generation + rule: 'has(self.lastFailedGeneration) && has(self.desiredGeneration) + ? self.desiredGeneration >= self.lastFailedGeneration : true' + - message: last failed generation error must be defined on image + pull and pin failure + rule: 'has(self.lastFailedGeneration) ? has(self.lastFailedGenerationError) + : true' + maxItems: 100 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.node.name should match metadata.name + rule: self.metadata.name == self.spec.node.name + served: true + storage: true + subresources: + status: {} diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/IrreconcilableMachineConfig.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/IrreconcilableMachineConfig.yaml index f52bb9d9863..e33af1595d0 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/IrreconcilableMachineConfig.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/IrreconcilableMachineConfig.yaml @@ -182,6 +182,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/MachineConfigNodes.yaml b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/MachineConfigNodes.yaml index 3986ac89f9b..e555ea17e96 100644 --- a/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/MachineConfigNodes.yaml +++ b/machineconfiguration/v1/zz_generated.featuregated-crd-manifests/machineconfignodes.machineconfiguration.openshift.io/MachineConfigNodes.yaml @@ -182,6 +182,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/machineconfiguration/v1/zz_generated.swagger_doc_generated.go b/machineconfiguration/v1/zz_generated.swagger_doc_generated.go index 1105a2c77f2..3a0b0646a69 100644 --- a/machineconfiguration/v1/zz_generated.swagger_doc_generated.go +++ b/machineconfiguration/v1/zz_generated.swagger_doc_generated.go @@ -413,12 +413,22 @@ var map_MachineConfigNodeSpec = map[string]string{ "node": "node contains a reference to the node for this machine config node.", "pool": "pool contains a reference to the machine config pool that this machine config node's referenced node belongs to.", "configVersion": "configVersion holds the desired config version for the node targeted by this machine config node resource. The desired version represents the machine config the node will attempt to update to and gets set before the machine config operator validates the new machine config against the current machine config.", + "configImage": "configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications.", } func (MachineConfigNodeSpec) SwaggerDoc() map[string]string { return map_MachineConfigNodeSpec } +var map_MachineConfigNodeSpecConfigImage = map[string]string{ + "": "MachineConfigNodeSpecConfigImage holds the desired image for the node. This structure is populated from the `machineconfiguration.openshift.io/desiredImage` annotation on the target node, which is set by the Machine Config Pool controller to signal the desired image pullspec for the node to update to.", + "desiredImage": "desiredImage is a required field that configures the image that the node should be updated to use. It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. desiredImage must not be an empty string and must not exceed 447 characters in length.", +} + +func (MachineConfigNodeSpecConfigImage) SwaggerDoc() map[string]string { + return map_MachineConfigNodeSpecConfigImage +} + var map_MachineConfigNodeSpecMachineConfigVersion = map[string]string{ "": "MachineConfigNodeSpecMachineConfigVersion holds the desired config version for the current observed machine config node. When Current is not equal to Desired, the MachineConfigOperator is in an upgrade phase and the machine config node will take account of upgrade related events. Otherwise, they will be ignored given that certain operations happen both during the MCO's upgrade mode and the daily operations mode.", "desired": "desired is the name of the machine config that the the node should be upgraded to. This value is set when the machine config pool generates a new version of its rendered configuration. When this value is changed, the machine config daemon starts the node upgrade process. This value gets set in the machine config node spec once the machine config has been targeted for upgrade and before it is validated. Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end with an alphanumeric character, and be at most 253 characters in length.", @@ -430,9 +440,10 @@ func (MachineConfigNodeSpecMachineConfigVersion) SwaggerDoc() map[string]string var map_MachineConfigNodeStatus = map[string]string{ "": "MachineConfigNodeStatus holds the reported information on a particular machine config node.", - "conditions": "conditions represent the observations of a machine config node's current state. Valid types are: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded.", + "conditions": "conditions represent the observations of a machine config node's current state. Valid types are: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, AppliedOSImage, AppliedFiles", "observedGeneration": "observedGeneration represents the generation of the MachineConfigNode object observed by the Machine Config Operator's controller. This field is updated when the controller observes a change to the desiredConfig in the configVersion of the machine config node spec.", "configVersion": "configVersion describes the current and desired machine config version for this node.", + "configImage": "configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage and configVersion change during the same update.", "pinnedImageSets": "pinnedImageSets describes the current and desired pinned image sets for this node.", "irreconcilableChanges": "irreconcilableChanges is an optional field that contains the observed differences between this nodes configuration and the target rendered MachineConfig. This field will be set when there are changes to the target rendered MachineConfig that can only be applied to new nodes joining the cluster. Entries must be unique, keyed on the fieldPath field. Must not exceed 32 entries.", } @@ -441,6 +452,16 @@ func (MachineConfigNodeStatus) SwaggerDoc() map[string]string { return map_MachineConfigNodeStatus } +var map_MachineConfigNodeStatusConfigImage = map[string]string{ + "": "MachineConfigNodeStatusConfigImage holds the observed state of the image on the node, including both the image targeted for an update and the image currently applied. This allows for monitoring the progress of the layering rollout. If Image Mode is enabled, desiredImage must be defined.", + "currentImage": "currentImage is an optional field that represents the current image that is applied to the node. When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. When specified, this means that the node is currently using this image. currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. currentImage must not be an empty string and must not exceed 447 characters in length.", + "desiredImage": "desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. If currentImage and desiredImage match, the node has been successfully updated to use the desired image. desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. desiredImage must not be an empty string and must not exceed 447 characters in length.", +} + +func (MachineConfigNodeStatusConfigImage) SwaggerDoc() map[string]string { + return map_MachineConfigNodeStatusConfigImage +} + var map_MachineConfigNodeStatusMachineConfigVersion = map[string]string{ "": "MachineConfigNodeStatusMachineConfigVersion holds the current and desired config versions as last updated in the MCN status. When the current and desired versions do not match, the machine config pool is processing an upgrade and the machine config node will monitor the upgrade process. When the current and desired versions do match, the machine config node will ignore these events given that certain operations happen both during the MCO's upgrade mode and the daily operations mode.", "current": "current is the name of the machine config currently in use on the node. This value is updated once the machine config daemon has completed the update of the configuration for the node. This value should match the desired version unless an upgrade is in progress. Must be a lowercase RFC-1123 subdomain name (https://tools.ietf.org/html/rfc1123) consisting of only lowercase alphanumeric characters, hyphens (-), and periods (.), and must start and end with an alphanumeric character, and be at most 253 characters in length.", diff --git a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml index a9b3e19a7b9..46d9a6ea46f 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-CustomNoUpgrade.crd.yaml @@ -99,6 +99,30 @@ spec: spec: description: spec describes the configuration of the machine config node. properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + required: + - desiredImage + type: object configVersion: description: |- configVersion holds the desired config version for the node targeted by this machine config node resource. @@ -182,6 +206,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -241,6 +267,52 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + type: object configVersion: description: configVersion describes the current and desired machine config version for this node. diff --git a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml index 7a1aed97d2f..21d9caaa425 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-Default.crd.yaml @@ -182,6 +182,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. diff --git a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml index 487dc5beac9..a68b8d0adfe 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-DevPreviewNoUpgrade.crd.yaml @@ -99,6 +99,30 @@ spec: spec: description: spec describes the configuration of the machine config node. properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + required: + - desiredImage + type: object configVersion: description: |- configVersion holds the desired config version for the node targeted by this machine config node resource. @@ -182,6 +206,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -241,6 +267,52 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + type: object configVersion: description: configVersion describes the current and desired machine config version for this node. diff --git a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml index 013d6952b40..74d7000f652 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_machineconfignodes-TechPreviewNoUpgrade.crd.yaml @@ -99,6 +99,30 @@ spec: spec: description: spec describes the configuration of the machine config node. properties: + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields + When omitted, Image Mode is not be enabled and the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + When specified, Image Mode is enabled and will attempt to update the node to use the desired image. Following this, the node will follow the standard update process of creating a rendered MachineConfig and updating to its specifications. + properties: + desiredImage: + description: |- + desiredImage is a required field that configures the image that the node should be updated to use. + It must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + required: + - desiredImage + type: object configVersion: description: |- configVersion holds the desired config version for the node targeted by this machine config node resource. @@ -182,6 +206,8 @@ spec: UpdatePrepared, UpdateExecuted, UpdatePostActionComplete, UpdateComplete, Updated, Resumed, Drained, AppliedFilesAndOS, Cordoned, Uncordoned, RebootedNode, NodeDegraded, PinnedImageSetsProgressing, and PinnedImageSetsDegraded. + The following types are only available when the ImageModeStatusReporting feature gate is enabled: ImagePulledFromRegistry, + AppliedOSImage, AppliedFiles items: description: Condition contains details for one aspect of the current state of this API Resource. @@ -241,6 +267,52 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map + configImage: + description: |- + configImage is an optional field for configuring the OS image to be used for this node. This field will only exist if the node belongs to a pool opted into on-cluster image builds, and will override any MachineConfig referenced OSImageURL fields. + When omitted, this means that the Image Mode feature is not being used and the node will be up to date with the specific current rendered config version for the nodes MachinePool. + When specified, the Image Mode feature is enabled and the contents of this field show the observed state of the node image. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is not created, only the configVersion field will change. + When Image Mode is enabled and a new MachineConfig is applied such that a new OS image build is created, then only the configImage field will change. It is also possible that both the configImage + and configVersion change during the same update. + minProperties: 1 + properties: + currentImage: + description: |- + currentImage is an optional field that represents the current image that is applied to the node. + When omitted, this means that no image updates have been applied to the node and it will be up to date with the specific current rendered config version. + When specified, this means that the node is currently using this image. + currentImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + currentImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + desiredImage: + description: |- + desiredImage is an optional field that represents the currently observed state of image that the node should be updated to use. + When not specified, this means that Image Mode has been disabled and the node will up to date with the specific current rendered config version. + When specified, this means that Image Mode has been enabled and the node is actively progressing to update the node to this image. + If currentImage and desiredImage match, the node has been successfully updated to use the desired image. + desiredImage must be a fully qualified OCI image pull spec of the format host[:port][/namespace]/name@sha256:, where the digest must be exactly 64 characters in length and consist only of lowercase hexadecimal characters, a-f and 0-9. + desiredImage must not be an empty string and must not exceed 447 characters in length. + maxLength: 447 + minLength: 1 + type: string + x-kubernetes-validations: + - message: the OCI Image reference must end with a valid '@sha256:' + suffix, where '' is 64 characters long + rule: (self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')) + - message: the OCI Image name should follow the host[:port][/namespace]/name + format, resembling a valid URL without the scheme + rule: (self.split('@')[0].matches('^([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9-]+(:[0-9]{2,5})?/([a-zA-Z0-9-_]{0,61}/)?[a-zA-Z0-9-_.]*?$')) + type: object configVersion: description: configVersion describes the current and desired machine config version for this node.