diff --git a/machineconfiguration/v1alpha1/tests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml b/machineconfiguration/v1alpha1/tests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml index cc75fb5e52d..adb55a4401b 100644 --- a/machineconfiguration/v1alpha1/tests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml +++ b/machineconfiguration/v1alpha1/tests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml @@ -305,6 +305,85 @@ tests: osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + - name: Should reject updating spec.defaultStream to a stream not in status.availableStreams + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: rhel-coreos + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + updated: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: non-existent-stream + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + expectedError: "spec.defaultStream must reference an existing stream name from status.availableStreams" + + - name: Should accept status update removing a stream when spec is unchanged + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: rhel-coreos + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + updated: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: rhel-coreos + status: + defaultStream: rhel10-coreos + availableStreams: + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + expected: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: rhel-coreos + status: + defaultStream: rhel10-coreos + availableStreams: + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + - name: Should reject an status update without defaultStream initial: | apiVersion: machineconfiguration.openshift.io/v1alpha1 @@ -434,3 +513,138 @@ tests: osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 expectedStatusError: "status.defaultStream: Too long: may not be more than 253 bytes" + + - name: Should allow status update when spec.defaultStream is stale after forced upgrade + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: old-removed-stream + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + updated: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: old-removed-stream + status: + defaultStream: rhel10-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + expected: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: old-removed-stream + status: + defaultStream: rhel10-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + + - name: Should reject changing stale spec.defaultStream to another invalid value after forced upgrade + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: old-removed-stream + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + updated: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: another-invalid-stream + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + expectedError: "spec.defaultStream must reference an existing stream name from status.availableStreams" + + - name: Should allow updating stale spec.defaultStream to a valid stream after forced upgrade + initial: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: old-removed-stream + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + updated: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: rhel-coreos + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e + expected: | + apiVersion: machineconfiguration.openshift.io/v1alpha1 + kind: OSImageStream + metadata: + name: cluster + spec: + defaultStream: rhel-coreos + status: + defaultStream: rhel-coreos + availableStreams: + - name: rhel-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7a6f5e4d3c2b1a0f9e8 + - name: rhel10-coreos + osImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b + osExtensionsImage: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e diff --git a/machineconfiguration/v1alpha1/types_osimagestream.go b/machineconfiguration/v1alpha1/types_osimagestream.go index 20cc963896c..07ba93d0a6f 100644 --- a/machineconfiguration/v1alpha1/types_osimagestream.go +++ b/machineconfiguration/v1alpha1/types_osimagestream.go @@ -23,6 +23,7 @@ import ( // +openshift:enable:FeatureGate=OSStreams // +kubebuilder:metadata:labels=openshift.io/operator-managed= // +kubebuilder:validation:XValidation:rule="self.metadata.name == 'cluster'",message="osimagestream is a singleton, .metadata.name must be 'cluster'" +// +kubebuilder:validation:XValidation:rule="self.spec == oldSelf.spec || !has(self.spec.defaultStream) || !has(self.status) || self.spec.defaultStream in self.status.availableStreams.map(s, s.name)",message="spec.defaultStream must reference an existing stream name from status.availableStreams" type OSImageStream struct { metav1.TypeMeta `json:",inline"` @@ -84,6 +85,16 @@ type OSImageStreamSpec struct { // status.availableStreams to apply as the default for MachineConfigPools // that do not specify a stream override. // + // When status.availableStreams has been populated by the operator, updating + // this field requires that the new value references the name of one of the + // streams in status.availableStreams. Status-only updates by the operator + // are not subject to this constraint, allowing the operator to update + // availableStreams independently of this field. + // During initial creation, before the operator has populated status, any + // valid value is accepted. + // + // When omitted, the operator determines the default stream automatically. + // // It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, // consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). // diff --git a/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_osimagestreams.crd.yaml b/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_osimagestreams.crd.yaml index 50a36f06d4d..68257363c3d 100644 --- a/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_osimagestreams.crd.yaml +++ b/machineconfiguration/v1alpha1/zz_generated.crd-manifests/0000_80_machine-config_01_osimagestreams.crd.yaml @@ -62,6 +62,16 @@ spec: status.availableStreams to apply as the default for MachineConfigPools that do not specify a stream override. + When status.availableStreams has been populated by the operator, updating + this field requires that the new value references the name of one of the + streams in status.availableStreams. Status-only updates by the operator + are not subject to this constraint, allowing the operator to update + availableStreams independently of this field. + During initial creation, before the operator has populated status, any + valid value is accepted. + + When omitted, the operator determines the default stream automatically. + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). maxLength: 253 @@ -184,6 +194,10 @@ spec: x-kubernetes-validations: - message: osimagestream is a singleton, .metadata.name must be 'cluster' rule: self.metadata.name == 'cluster' + - message: spec.defaultStream must reference an existing stream name from + status.availableStreams + rule: self.spec == oldSelf.spec || !has(self.spec.defaultStream) || !has(self.status) + || self.spec.defaultStream in self.status.availableStreams.map(s, s.name) served: true storage: true subresources: diff --git a/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml b/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml index 67d07f7fab1..9e76484095e 100644 --- a/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml +++ b/machineconfiguration/v1alpha1/zz_generated.featuregated-crd-manifests/osimagestreams.machineconfiguration.openshift.io/OSStreams.yaml @@ -62,6 +62,16 @@ spec: status.availableStreams to apply as the default for MachineConfigPools that do not specify a stream override. + When status.availableStreams has been populated by the operator, updating + this field requires that the new value references the name of one of the + streams in status.availableStreams. Status-only updates by the operator + are not subject to this constraint, allowing the operator to update + availableStreams independently of this field. + During initial creation, before the operator has populated status, any + valid value is accepted. + + When omitted, the operator determines the default stream automatically. + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). maxLength: 253 @@ -184,6 +194,10 @@ spec: x-kubernetes-validations: - message: osimagestream is a singleton, .metadata.name must be 'cluster' rule: self.metadata.name == 'cluster' + - message: spec.defaultStream must reference an existing stream name from + status.availableStreams + rule: self.spec == oldSelf.spec || !has(self.spec.defaultStream) || !has(self.status) + || self.spec.defaultStream in self.status.availableStreams.map(s, s.name) served: true storage: true subresources: diff --git a/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go b/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go index 574d524ec92..aad6325b4bb 100644 --- a/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go +++ b/machineconfiguration/v1alpha1/zz_generated.swagger_doc_generated.go @@ -186,7 +186,7 @@ func (OSImageStreamSet) SwaggerDoc() map[string]string { var map_OSImageStreamSpec = map[string]string{ "": "OSImageStreamSpec defines the desired state of a OSImageStream.", - "defaultStream": "defaultStream is the desired name of the stream that should be used as the default when no specific stream is requested by a MachineConfigPool.\n\nThis field is set by the installer during installation. Users may need to update it if the currently selected stream is no longer available, for example when the stream has reached its End of Life. The MachineConfigOperator uses this value to determine which stream from status.availableStreams to apply as the default for MachineConfigPools that do not specify a stream override.\n\nIt must be a valid RFC 1123 subdomain between 1 and 253 characters in length, consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.').", + "defaultStream": "defaultStream is the desired name of the stream that should be used as the default when no specific stream is requested by a MachineConfigPool.\n\nThis field is set by the installer during installation. Users may need to update it if the currently selected stream is no longer available, for example when the stream has reached its End of Life. The MachineConfigOperator uses this value to determine which stream from status.availableStreams to apply as the default for MachineConfigPools that do not specify a stream override.\n\nWhen status.availableStreams has been populated by the operator, updating this field requires that the new value references the name of one of the streams in status.availableStreams. Status-only updates by the operator are not subject to this constraint, allowing the operator to update availableStreams independently of this field. During initial creation, before the operator has populated status, any valid value is accepted.\n\nWhen omitted, the operator determines the default stream automatically.\n\nIt must be a valid RFC 1123 subdomain between 1 and 253 characters in length, consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.').", } func (OSImageStreamSpec) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index c2746f05d0b..31b8bc287a9 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -45672,7 +45672,7 @@ func schema_openshift_api_machineconfiguration_v1alpha1_OSImageStreamSpec(ref co Properties: map[string]spec.Schema{ "defaultStream": { SchemaProps: spec.SchemaProps{ - Description: "defaultStream is the desired name of the stream that should be used as the default when no specific stream is requested by a MachineConfigPool.\n\nThis field is set by the installer during installation. Users may need to update it if the currently selected stream is no longer available, for example when the stream has reached its End of Life. The MachineConfigOperator uses this value to determine which stream from status.availableStreams to apply as the default for MachineConfigPools that do not specify a stream override.\n\nIt must be a valid RFC 1123 subdomain between 1 and 253 characters in length, consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.').", + Description: "defaultStream is the desired name of the stream that should be used as the default when no specific stream is requested by a MachineConfigPool.\n\nThis field is set by the installer during installation. Users may need to update it if the currently selected stream is no longer available, for example when the stream has reached its End of Life. The MachineConfigOperator uses this value to determine which stream from status.availableStreams to apply as the default for MachineConfigPools that do not specify a stream override.\n\nWhen status.availableStreams has been populated by the operator, updating this field requires that the new value references the name of one of the streams in status.availableStreams. Status-only updates by the operator are not subject to this constraint, allowing the operator to update availableStreams independently of this field. During initial creation, before the operator has populated status, any valid value is accepted.\n\nWhen omitted, the operator determines the default stream automatically.\n\nIt must be a valid RFC 1123 subdomain between 1 and 253 characters in length, consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.').", Type: []string{"string"}, Format: "", }, diff --git a/payload-manifests/crds/0000_80_machine-config_01_osimagestreams.crd.yaml b/payload-manifests/crds/0000_80_machine-config_01_osimagestreams.crd.yaml index 50a36f06d4d..68257363c3d 100644 --- a/payload-manifests/crds/0000_80_machine-config_01_osimagestreams.crd.yaml +++ b/payload-manifests/crds/0000_80_machine-config_01_osimagestreams.crd.yaml @@ -62,6 +62,16 @@ spec: status.availableStreams to apply as the default for MachineConfigPools that do not specify a stream override. + When status.availableStreams has been populated by the operator, updating + this field requires that the new value references the name of one of the + streams in status.availableStreams. Status-only updates by the operator + are not subject to this constraint, allowing the operator to update + availableStreams independently of this field. + During initial creation, before the operator has populated status, any + valid value is accepted. + + When omitted, the operator determines the default stream automatically. + It must be a valid RFC 1123 subdomain between 1 and 253 characters in length, consisting of lowercase alphanumeric characters, hyphens ('-'), and periods ('.'). maxLength: 253 @@ -184,6 +194,10 @@ spec: x-kubernetes-validations: - message: osimagestream is a singleton, .metadata.name must be 'cluster' rule: self.metadata.name == 'cluster' + - message: spec.defaultStream must reference an existing stream name from + status.availableStreams + rule: self.spec == oldSelf.spec || !has(self.spec.defaultStream) || !has(self.status) + || self.spec.defaultStream in self.status.availableStreams.map(s, s.name) served: true storage: true subresources: