From 9b14503be9cad75422335be3cab5616571f63e75 Mon Sep 17 00:00:00 2001 From: Jatin Suri Date: Tue, 19 Aug 2025 15:50:40 -0400 Subject: [PATCH 1/2] Added basic validation for OKD featureset --- .../features/validate_features.go | 12 +++++++++++- .../openshift/api/config/v1/types_feature.go | 9 +++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go b/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go index fb3c07f3ff6e3..e08a6e627f254 100644 --- a/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go +++ b/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go @@ -50,6 +50,15 @@ func toFeatureGateV1(uncastObj runtime.Object) (*configv1.FeatureGate, field.Err type featureGateV1 struct { } +func validateOKDFeatureSet(spec configv1.FeatureGateSpec) field.ErrorList { + allErrs := field.ErrorList{} + if spec.FeatureSet == configv1.OKD { + allErrs = append(allErrs, field.NotSupported(field.NewPath("spec.featureSet"), spec.FeatureSet, []string{"OKD"})) + } + + return allErrs +} + func (featureGateV1) ValidateCreate(_ context.Context, uncastObj runtime.Object) field.ErrorList { obj, allErrs := toFeatureGateV1(uncastObj) if len(allErrs) > 0 { @@ -57,7 +66,7 @@ func (featureGateV1) ValidateCreate(_ context.Context, uncastObj runtime.Object) } allErrs = append(allErrs, validation.ValidateObjectMeta(&obj.ObjectMeta, false, customresourcevalidation.RequireNameCluster, field.NewPath("metadata"))...) - + allErrs = append(allErrs, validateOKDFeatureSet(obj.Spec)...) return allErrs } @@ -72,6 +81,7 @@ func (featureGateV1) ValidateUpdate(_ context.Context, uncastObj runtime.Object, } allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&obj.ObjectMeta, &oldObj.ObjectMeta, field.NewPath("metadata"))...) + allErrs = append(allErrs, validateOKDFeatureSet(obj.Spec)...) return allErrs } diff --git a/vendor/github.com/openshift/api/config/v1/types_feature.go b/vendor/github.com/openshift/api/config/v1/types_feature.go index 169e29c5c5bff..552631e203437 100644 --- a/vendor/github.com/openshift/api/config/v1/types_feature.go +++ b/vendor/github.com/openshift/api/config/v1/types_feature.go @@ -53,8 +53,12 @@ var ( // your cluster may fail in an unrecoverable way. CustomNoUpgrade FeatureSet = "CustomNoUpgrade" + // OKD turns on features for OKD. Turning this feature set ON is supported for OKD clusters, but NOT for OpenShift clusters + // this feature set on CANNOT BE UNDONE for OKD clusters and when enabled on OpenShift clusters it PREVENTS UPGRADES. + OKD FeatureSet = "OKD" + // AllFixedFeatureSets are the featuresets that have known featuregates. Custom doesn't for instance. LatencySensitive is dead - AllFixedFeatureSets = []FeatureSet{Default, TechPreviewNoUpgrade, DevPreviewNoUpgrade} + AllFixedFeatureSets = []FeatureSet{Default, TechPreviewNoUpgrade, DevPreviewNoUpgrade, OKD} ) type FeatureGateSpec struct { @@ -67,10 +71,11 @@ type FeatureGateSelection struct { // Turning on or off features may cause irreversible changes in your cluster which cannot be undone. // +unionDiscriminator // +optional - // +kubebuilder:validation:Enum=CustomNoUpgrade;DevPreviewNoUpgrade;TechPreviewNoUpgrade;"" + // +kubebuilder:validation:Enum=CustomNoUpgrade;DevPreviewNoUpgrade;TechPreviewNoUpgrade;OKD;"" // +kubebuilder:validation:XValidation:rule="oldSelf == 'CustomNoUpgrade' ? self == 'CustomNoUpgrade' : true",message="CustomNoUpgrade may not be changed" // +kubebuilder:validation:XValidation:rule="oldSelf == 'TechPreviewNoUpgrade' ? self == 'TechPreviewNoUpgrade' : true",message="TechPreviewNoUpgrade may not be changed" // +kubebuilder:validation:XValidation:rule="oldSelf == 'DevPreviewNoUpgrade' ? self == 'DevPreviewNoUpgrade' : true",message="DevPreviewNoUpgrade may not be changed" + // +kubebuilder:validation:XValidation:rule="oldSelf == 'OKD' ? self == 'OKD' : true",message="OKD may not be changed" FeatureSet FeatureSet `json:"featureSet,omitempty"` // customNoUpgrade allows the enabling or disabling of any feature. Turning this feature set on IS NOT SUPPORTED, CANNOT BE UNDONE, and PREVENTS UPGRADES. From 5a29732226025b1d9a0d79f46290ebd4ae6eba5e Mon Sep 17 00:00:00 2001 From: Jatin Suri Date: Tue, 19 Aug 2025 20:07:57 -0400 Subject: [PATCH 2/2] Added validation to check if a image is being built for OKD --- build/root/Makefile | 7 +++++++ openshift-hack/images/hyperkube/Dockerfile.rhel | 2 +- .../features/validate_features.go | 5 +++-- openshift-kube-apiserver/version/scos.go | 7 +++++++ openshift-kube-apiserver/version/version.go | 11 +++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 openshift-kube-apiserver/version/scos.go create mode 100644 openshift-kube-apiserver/version/version.go diff --git a/build/root/Makefile b/build/root/Makefile index 64fd4aa4fd5cb..deaf6d5fe3ffc 100644 --- a/build/root/Makefile +++ b/build/root/Makefile @@ -39,6 +39,8 @@ PRINT_HELP ?= WHAT ?= TESTS ?= BRANCH ?= +TAGS ?= +GO_BUILD_FLAGS := $(if ${TAGS},-tags=${TAGS},) # We don't need make's built-in rules. MAKEFLAGS += --no-builtin-rules @@ -61,6 +63,11 @@ $(error Both KUBE_GOFLAGS and GOFLAGS are set. Please use just GOFLAGS) endif endif +# Add build tags to GOFLAGS +ifneq ($(TAGS),) +GOFLAGS := $(GOFLAGS) $(GO_BUILD_FLAGS) +endif + # This controls the verbosity of the build. Higher numbers mean more output. KUBE_VERBOSE ?= 1 diff --git a/openshift-hack/images/hyperkube/Dockerfile.rhel b/openshift-hack/images/hyperkube/Dockerfile.rhel index 00c494e974214..ca05a675d9699 100644 --- a/openshift-hack/images/hyperkube/Dockerfile.rhel +++ b/openshift-hack/images/hyperkube/Dockerfile.rhel @@ -1,7 +1,7 @@ FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.24-openshift-4.21 AS builder WORKDIR /go/src/k8s.io/kubernetes COPY . . -RUN make WHAT='cmd/kube-apiserver cmd/kube-controller-manager cmd/kube-scheduler cmd/kubelet cmd/watch-termination openshift-hack/cmd/k8s-tests-ext' && \ +RUN make TAGS="${TAGS}" WHAT='cmd/kube-apiserver cmd/kube-controller-manager cmd/kube-scheduler cmd/kubelet cmd/watch-termination openshift-hack/cmd/k8s-tests-ext' && \ mkdir -p /tmp/build && \ cp openshift-hack/images/hyperkube/hyperkube openshift-hack/images/hyperkube/kubensenter /tmp/build && \ cp /go/src/k8s.io/kubernetes/_output/local/bin/linux/$(go env GOARCH)/{kube-apiserver,kube-controller-manager,kube-scheduler,kubelet,watch-termination,k8s-tests-ext} \ diff --git a/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go b/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go index e08a6e627f254..bb3b705b35015 100644 --- a/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go +++ b/openshift-kube-apiserver/admission/customresourcevalidation/features/validate_features.go @@ -13,6 +13,7 @@ import ( configv1 "github.com/openshift/api/config/v1" "k8s.io/kubernetes/openshift-kube-apiserver/admission/customresourcevalidation" + "k8s.io/kubernetes/openshift-kube-apiserver/version" ) const PluginName = "config.openshift.io/ValidateFeatureGate" @@ -52,8 +53,8 @@ type featureGateV1 struct { func validateOKDFeatureSet(spec configv1.FeatureGateSpec) field.ErrorList { allErrs := field.ErrorList{} - if spec.FeatureSet == configv1.OKD { - allErrs = append(allErrs, field.NotSupported(field.NewPath("spec.featureSet"), spec.FeatureSet, []string{"OKD"})) + if spec.FeatureSet == configv1.OKD && !version.IsSCOS() { + allErrs = append(allErrs, field.Forbidden(field.NewPath("spec.featureSet"), "OKD featureset is not supported on OpenShift clusters")) } return allErrs diff --git a/openshift-kube-apiserver/version/scos.go b/openshift-kube-apiserver/version/scos.go new file mode 100644 index 0000000000000..0bdba634cd42e --- /dev/null +++ b/openshift-kube-apiserver/version/scos.go @@ -0,0 +1,7 @@ +//go:build scos + +package version + +func init() { + SCOS = true +} \ No newline at end of file diff --git a/openshift-kube-apiserver/version/version.go b/openshift-kube-apiserver/version/version.go new file mode 100644 index 0000000000000..b09dd5665b8ef --- /dev/null +++ b/openshift-kube-apiserver/version/version.go @@ -0,0 +1,11 @@ +package version + +var ( + // SCOS is a setting to enable CentOS Stream CoreOS-only modifications + SCOS = false +) + +// IsSCOS returns true if CentOS Stream CoreOS-only modifications are enabled +func IsSCOS() bool { + return SCOS +} \ No newline at end of file