-
Notifications
You must be signed in to change notification settings - Fork 587
MCO-993: MachineOSBuild API #1773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
...tion/v1alpha1/tests/machineosbuilds.machineconfiguration.openshift.io/OnClusterBuild.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this | ||
| name: "[TechPreview] MachineOSBuild" | ||
| crdName: machineosbuilds.machineconfiguration.openshift.io | ||
| featureGate: OnClusterBuild | ||
| tests: | ||
| onCreate: | ||
| - name: Should be able to create a minimal MachineOSBuild | ||
| initial: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSBuild | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| configGeneration: 1 | ||
| desiredConfig: | ||
| name: rendered-worker-abcd | ||
| version: 1 | ||
| machineOSConfig: | ||
| name: worker | ||
| renderedImagePushspec: quay.io/cdoern/mco:latest | ||
| expected: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSBuild | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| configGeneration: 1 | ||
| desiredConfig: | ||
| name: rendered-worker-abcd | ||
| version: 1 | ||
| machineOSConfig: | ||
| name: worker | ||
| renderedImagePushspec: quay.io/cdoern/mco:latest | ||
| - name: fail on invalid version | ||
| initial: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSBuild | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| configGeneration: 1 | ||
| desiredConfig: | ||
| name: rendered-worker-abcd | ||
| version: 0 | ||
| machineOSConfig: | ||
| name: worker | ||
| renderedImagePushspec: quay.io/cdoern/mco:latest | ||
| expectedError: "Invalid value: 0: spec.version in body should be greater than or equal to 1" | ||
| - name: fail on invalid configGeneration | ||
| initial: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSBuild | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| configGeneration: 0 | ||
| desiredConfig: | ||
| name: rendered-worker-abcd | ||
| version: 1 | ||
| machineOSConfig: | ||
| name: worker | ||
| renderedImagePushspec: quay.io/cdoern/mco:latest | ||
| expectedError: "Invalid value: 0: spec.configGeneration in body should be greater than or equal to 1" | ||
|
|
116 changes: 116 additions & 0 deletions
116
...ion/v1alpha1/tests/machineosconfigs.machineconfiguration.openshift.io/OnClusterBuild.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this | ||
| name: "[TechPreview] MachineOSConfig" | ||
| crdName: machineosconfigs.machineconfiguration.openshift.io | ||
| featureGate: OnClusterBuild | ||
| tests: | ||
| onCreate: | ||
| - name: Should be able to create a minimal MachineOSConfig | ||
| initial: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSConfig | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| machineConfigPool: | ||
| name: worker | ||
| buildInputs: | ||
| imageBuilder: | ||
| imageBuilderType: PodImageBuilder | ||
| baseOSImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| baseImagePullSecret: | ||
| name: foo | ||
| baseOSExtensionsImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| renderedImagePushSecret: | ||
| name: foo | ||
| renderedImagePushspec: quay.io/cdoern/renderedImg:latest | ||
| buildOutputs: | ||
| currentImagePullSecret: | ||
| name: foo | ||
| expected: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSConfig | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| machineConfigPool: | ||
| name: worker | ||
| buildInputs: | ||
| imageBuilder: | ||
| imageBuilderType: PodImageBuilder | ||
| baseOSImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| baseImagePullSecret: | ||
| name: foo | ||
| baseOSExtensionsImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| renderedImagePushSecret: | ||
| name: foo | ||
| renderedImagePushspec: quay.io/cdoern/renderedImg:latest | ||
| buildOutputs: | ||
| currentImagePullSecret: | ||
| name: foo | ||
| - name: Fail on invalid rendered image pushspec | ||
| initial: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSConfig | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| machineConfigPool: | ||
| name: worker | ||
| buildInputs: | ||
| imageBuilder: | ||
| imageBuilderType: PodImageBuilder | ||
| baseOSImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| baseImagePullSecret: | ||
| name: foo | ||
| baseOSExtensionsImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| renderedImagePushSecret: | ||
| name: foo | ||
| renderedImagePushspec: foo.bar | ||
| buildOutputs: | ||
| currentImagePullSecret: | ||
| name: foo | ||
| expectedError: "Invalid value: \"string\": the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme" | ||
| - name: Fail on invalid base image pullspec | ||
| initial: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSConfig | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| machineConfigPool: | ||
| name: worker | ||
| buildInputs: | ||
| imageBuilder: | ||
| imageBuilderType: PodImageBuilder | ||
| baseOSImagePullspec: foo.bar | ||
| baseImagePullSecret: | ||
| name: foo | ||
| baseOSExtensionsImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| renderedImagePushSecret: | ||
| name: foo | ||
| renderedImagePushspec: quay.io/cdoern/renderedImg:latest | ||
| buildOutputs: | ||
| currentImagePullSecret: | ||
| name: foo | ||
| expectedError: "Invalid value: \"string\": the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme" | ||
| - name: Fail on no pull secret | ||
| initial: | | ||
| apiVersion: machineconfiguration.openshift.io/v1alpha1 | ||
| kind: MachineOSConfig | ||
| metadata: | ||
| name: foobar | ||
| spec: | ||
| machineConfigPool: | ||
| name: worker | ||
| buildInputs: | ||
| imageBuilder: | ||
| imageBuilderType: PodImageBuilder | ||
| baseOSImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| baseOSExtensionsImagePullspec: example.io/my-project/image-v1.0_23@sha256:2c3ea52ac3a41c6d58e85977c3149413e3fa4b70eb2397426456863adbf43306 | ||
| renderedImagePushSecret: | ||
| name: foo | ||
| renderedImagePushspec: quay.io/cdoern/renderedImg:latest | ||
| buildOutputs: | ||
| currentImagePullSecret: | ||
| name: foo | ||
| expectedError: "Invalid value: \"null\": some validation rules were not checked because the object was invalid; correct the existing errors to complete validation" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| package v1alpha1 | ||
|
|
||
| import ( | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| ) | ||
|
|
||
| // +genclient | ||
| // +genclient:nonNamespaced | ||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
| // +kubebuilder:object:root=true | ||
| // +kubebuilder:resource:path=machineosbuilds,scope=Cluster | ||
| // +kubebuilder:subresource:status | ||
| // +openshift:api-approved.openshift.io=https://github.com/openshift/api/pull/1773 | ||
| // +openshift:enable:FeatureGate=OnClusterBuild | ||
| // +openshift:file-pattern=cvoRunLevel=0000_80,operatorName=machine-config,operatorOrdering=01 | ||
| // +kubebuilder:metadata:labels=openshift.io/operator-managed= | ||
| // +kubebuilder:printcolumn:name="Prepared",type="string",JSONPath=.status.conditions[?(@.type=="Prepared")].status | ||
| // +kubebuilder:printcolumn:name="Building",type="string",JSONPath=.status.conditions[?(@.type=="Building")].status | ||
| // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=.status.conditions[?(@.type=="Ready")].status | ||
| // +kubebuilder:printcolumn:name="Interrupted",type="string",JSONPath=.status.conditions[?(@.type=="Interrupted")].status | ||
| // +kubebuilder:printcolumn:name="Restarted",type="string",JSONPath=.status.conditions[?(@.type=="Restarted")].status | ||
| // +kubebuilder:printcolumn:name="Failed",type="string",JSONPath=.status.conditions[?(@.type=="Failed")].status | ||
|
|
||
| // MachineOSBuild describes a build process managed and deployed by the MCO | ||
| // Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. | ||
| // +openshift:compatibility-gen:level=4 | ||
| type MachineOSBuild struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
| metav1.ObjectMeta `json:"metadata,omitempty"` | ||
|
|
||
| // spec describes the configuration of the machine os build | ||
| // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="machineOSBuildSpec is immutable once set" | ||
| // +kubebuilder:validation:Required | ||
| Spec MachineOSBuildSpec `json:"spec"` | ||
|
|
||
| // status describes the lst observed state of this machine os build | ||
| // +optional | ||
| Status MachineOSBuildStatus `json:"status"` | ||
| } | ||
|
|
||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||
|
|
||
| // MachineOSBuildList describes all of the Builds on the system | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // | ||
| // Compatibility level 4: No compatibility is provided, the API can change at any point for any reason. These capabilities should not be used by applications needing long term support. | ||
| // +openshift:compatibility-gen:level=4 | ||
| type MachineOSBuildList struct { | ||
| metav1.TypeMeta `json:",inline"` | ||
| metav1.ListMeta `json:"metadata"` | ||
|
|
||
| Items []MachineOSBuild `json:"items"` | ||
| } | ||
|
|
||
| // MachineOSBuildSpec describes information about a build process primarily populated from a MachineOSConfig object. | ||
| type MachineOSBuildSpec struct { | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // configGeneration tracks which version of MachineOSConfig this build is based off of | ||
| // +kubebuilder:validation:Minimum=1 | ||
| // +kubebuilder:validation:Required | ||
| ConfigGeneration int64 `json:"configGeneration"` | ||
| // desiredConfig is the desired config we want to build an image for. | ||
| // +kubebuilder:validation:Required | ||
| DesiredConfig RenderedMachineConfigReference `json:"desiredConfig"` | ||
| // machineOSConfig is the config object which the build is based off of | ||
| // +kubebuilder:validation:Required | ||
| MachineOSConfig MachineOSConfigReference `json:"machineOSConfig"` | ||
| // version tracks the newest MachineOSBuild for each MachineOSConfig | ||
| // +kubebuilder:validation:Minimum=1 | ||
| // +kubebuilder:validation:Required | ||
| Version int64 `json:"version"` | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // renderedImagePushspec is set from the MachineOSConfig | ||
| // The format of the image pullspec is: | ||
| // host[:port][/namespace]/name:<tag> or svc_name.namespace.svc[:port]/repository/name:<tag> | ||
| // +kubebuilder:validation:MinLength=1 | ||
| // +kubebuilder:validation:MaxLength=447 | ||
| // +kubebuilder:validation:XValidation:rule=`((self.split(':').size() == 2 && self.split(':')[1].matches('^([a-zA-Z0-9-./:])+$')) || self.matches('^[^.]+\\.[^.]+\\.svc:\\d+\\/[^\\/]+\\/[^\\/]+:[^\\/]+$'))`,message="the OCI Image reference must end with a valid :<tag>, where '<digest>' is 64 characters long and '<tag>' is any valid string Or it must be a valid .svc followed by a port, repository, image name, and tag." | ||
| // +kubebuilder:validation:XValidation:rule=`((self.split(':').size() == 2 && 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-_.]*?$')) || self.matches('^[^.]+\\.[^.]+\\.svc:\\d+\\/[^\\/]+\\/[^\\/]+:[^\\/]+$'))`,message="the OCI Image name should follow the host[:port][/namespace]/name format, resembling a valid URL without the scheme. Or it must be a valid .svc followed by a port, repository, image name, and tag." | ||
| // +kubebuilder:validation:Required | ||
| RenderedImagePushspec string `json:"renderedImagePushspec"` | ||
| } | ||
|
|
||
| // MachineOSBuildStatus describes the state of a build and other helpful information. | ||
| type MachineOSBuildStatus struct { | ||
| // conditions are state related conditions for the build. Valid types are: | ||
| // Prepared, Building, Failed, Interrupted, and Succeeded | ||
| // once a Build is marked as Failed, no future conditions can be set. This is enforced by the MCO. | ||
| // +patchMergeKey=type | ||
| // +patchStrategy=merge | ||
| // +listType=map | ||
| // +listMapKey=type | ||
| // +optional | ||
| Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // ImageBuilderType describes the image builder set in the MachineOSConfig | ||
| // +unionDiscriminator | ||
| BuilderReference *MachineOSBuilderReference `json:"builderReference"` | ||
| // relatedObjects is a list of objects that are related to the build process. | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| RelatedObjects []ObjectReference `json:"relatedObjects,omitempty"` | ||
| // buildStart describes when the build started. | ||
| // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="buildStart is immutable once set" | ||
| // +kubebuilder:validation:Required | ||
| BuildStart *metav1.Time `json:"buildStart"` | ||
| // buildEnd describes when the build ended. | ||
| // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="buildEnd is immutable once set" | ||
| //+optional | ||
| BuildEnd *metav1.Time `json:"buildEnd,omitempty"` | ||
| // finalImagePushSpec describes the fully qualified pushspec produced by this build that the final image can be. Must be in sha format. | ||
| // +kubebuilder:validation:XValidation:rule=`((self.split('@').size() == 2 && self.split('@')[1].matches('^sha256:[a-f0-9]{64}$')))`,message="the OCI Image reference must end with a valid '@sha256:<digest>' suffix, where '<digest>' is 64 characters long" | ||
| // +optional | ||
| FinalImagePushspec string `json:"finalImagePullspec,omitempty"` | ||
| } | ||
|
|
||
| // MachineOSBuilderReference describes which ImageBuilder backend to use for this build/ | ||
| // +union | ||
| // +kubebuilder:validation:XValidation:rule="has(self.imageBuilderType) && self.imageBuilderType == 'PodImageBuilder' ? true : !has(self.buildPod)",message="buildPod is required when imageBuilderType is PodImageBuilder, and forbidden otherwise" | ||
| type MachineOSBuilderReference struct { | ||
| // ImageBuilderType describes the image builder set in the MachineOSConfig | ||
| // +unionDiscriminator | ||
| ImageBuilderType MachineOSImageBuilderType `json:"imageBuilderType"` | ||
|
|
||
| // relatedObjects is a list of objects that are related to the build process. | ||
| // +unionMember,optional | ||
| PodImageBuilder *ObjectReference `json:"buildPod,omitempty"` | ||
| } | ||
|
|
||
| // BuildProgess highlights some of the key phases of a build to be tracked in Conditions. | ||
| type BuildProgress string | ||
|
|
||
| const ( | ||
| // prepared indicates that the build has finished preparing. A build is prepared | ||
| // by gathering the build inputs, validating them, and making sure we can do an update as specified. | ||
| MachineOSBuildPrepared BuildProgress = "Prepared" | ||
| // building indicates that the build has been kicked off with the specified image builder | ||
| MachineOSBuilding BuildProgress = "Building" | ||
| // failed indicates that during the build or preparation process, the build failed. | ||
| MachineOSBuildFailed BuildProgress = "Failed" | ||
| // interrupted indicates that the user stopped the build process by modifying part of the build config | ||
| MachineOSBuildInterrupted BuildProgress = "Interrupted" | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // succeeded indicates that the build has completed and the image is ready to roll out. | ||
| MachineOSBuildSucceeded BuildProgress = "Succeeded" | ||
| ) | ||
|
|
||
| // Refers to the name of a rendered MachineConfig (e.g., "rendered-worker-ec40d2965ff81bce7cd7a7e82a680739", etc.): | ||
| // the build targets this MachineConfig, this is often used to tell us whether we need an update. | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| type RenderedMachineConfigReference struct { | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // name is the name of the rendered MachineConfig object. | ||
| // +kubebuilder:validation:MaxLength:=253 | ||
| // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$` | ||
| // +kubebuilder:validation:Required | ||
| Name string `json:"name"` | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // ObjectReference contains enough information to let you inspect or modify the referred object. | ||
| type ObjectReference struct { | ||
| // group of the referent. | ||
| // +kubebuilder:validation:Required | ||
| Group string `json:"group"` | ||
| // resource of the referent. | ||
| // +kubebuilder:validation:Required | ||
| Resource string `json:"resource"` | ||
| // namespace of the referent. | ||
| // +optional | ||
| Namespace string `json:"namespace,omitempty"` | ||
| // name of the referent. | ||
| // +kubebuilder:validation:Required | ||
| Name string `json:"name"` | ||
| } | ||
cdoern marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // MachineOSConfigReference refers to the MachineOSConfig this build is based off of | ||
| type MachineOSConfigReference struct { | ||
| // name of the MachineOSConfig | ||
| // +kubebuilder:validation:Required | ||
| Name string `json:"name"` | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.