From 05e349fa979b46a5a264ec70a7e8239eb8a3745e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20Hu=C3=9F?= Date: Thu, 28 Sep 2023 21:50:20 +0200 Subject: [PATCH] Allow access to Pod field `shareProcessNamespace`. (#14454) * Allow access to Pod field `shareProcessNamespace`. Feature is guarded by feature flag "kubernetes.podspec-shareprocessnamespace". Fixes #14137. * Add missing test for shareProcessNamespace --- config/core/300-resources/configuration.yaml | 4 + config/core/300-resources/revision.yaml | 4 + config/core/300-resources/service.yaml | 4 + config/core/configmaps/features.yaml | 8 +- hack/schemapatch-config.yaml | 13 +- pkg/apis/config/features.go | 3 + pkg/apis/config/features_test.go | 473 ++++++++++--------- pkg/apis/serving/fieldmask.go | 4 +- pkg/apis/serving/k8s_validation_test.go | 18 + 9 files changed, 300 insertions(+), 231 deletions(-) diff --git a/config/core/300-resources/configuration.yaml b/config/core/300-resources/configuration.yaml index acd9c2cc6d..4153b68ab8 100644 --- a/config/core/300-resources/configuration.yaml +++ b/config/core/300-resources/configuration.yaml @@ -629,6 +629,10 @@ spec: serviceAccountName: description: 'ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' type: string + shareProcessNamespace: + description: This is accessible behind a feature flag - kubernetes.podspec-shareproccessnamespace + type: boolean + x-kubernetes-preserve-unknown-fields: true timeoutSeconds: description: TimeoutSeconds is the maximum duration in seconds that the request instance is allowed to respond to a request. If unspecified, a system default will be provided. type: integer diff --git a/config/core/300-resources/revision.yaml b/config/core/300-resources/revision.yaml index 9cc3fe276b..76b5aa03b4 100644 --- a/config/core/300-resources/revision.yaml +++ b/config/core/300-resources/revision.yaml @@ -608,6 +608,10 @@ spec: serviceAccountName: description: 'ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' type: string + shareProcessNamespace: + description: This is accessible behind a feature flag - kubernetes.podspec-shareproccessnamespace + type: boolean + x-kubernetes-preserve-unknown-fields: true timeoutSeconds: description: TimeoutSeconds is the maximum duration in seconds that the request instance is allowed to respond to a request. If unspecified, a system default will be provided. type: integer diff --git a/config/core/300-resources/service.yaml b/config/core/300-resources/service.yaml index 922461fafd..f1fd73ec23 100644 --- a/config/core/300-resources/service.yaml +++ b/config/core/300-resources/service.yaml @@ -633,6 +633,10 @@ spec: serviceAccountName: description: 'ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' type: string + shareProcessNamespace: + description: This is accessible behind a feature flag - kubernetes.podspec-shareproccessnamespace + type: boolean + x-kubernetes-preserve-unknown-fields: true timeoutSeconds: description: TimeoutSeconds is the maximum duration in seconds that the request instance is allowed to respond to a request. If unspecified, a system default will be provided. type: integer diff --git a/config/core/configmaps/features.yaml b/config/core/configmaps/features.yaml index 014fb7bae1..f4c42983a1 100644 --- a/config/core/configmaps/features.yaml +++ b/config/core/configmaps/features.yaml @@ -22,7 +22,7 @@ metadata: app.kubernetes.io/component: controller app.kubernetes.io/version: devel annotations: - knative.dev/example-checksum: "eb70e734" + knative.dev/example-checksum: "f2fc138e" data: _example: |- ################################ @@ -126,6 +126,12 @@ data: # See: https://knative.dev/docs/serving/feature-flags/#kubernetes-security-context kubernetes.podspec-securitycontext: "disabled" + # Indicated whether sharing the process namespace via ShareProcessNamespace pod spec is allowed. + # This can be especially useful for sharing data from images directly between sidecars + # + # See: https://knative.dev/docs/serving/configuration/feature-flags/#kubernetes-share-process-namespace + kubernetes.podspec-shareprocessnamespace: "disabled" + # Indicates whether Kubernetes PriorityClassName support is enabled # # WARNING: Cannot safely be disabled once enabled. diff --git a/hack/schemapatch-config.yaml b/hack/schemapatch-config.yaml index d7b9babb9f..a79e033487 100644 --- a/hack/schemapatch-config.yaml +++ b/hack/schemapatch-config.yaml @@ -69,6 +69,7 @@ k8s.io/api/core/v1.PodSpec: - RuntimeClassName - SchedulerName - SecurityContext + - ShareProcessNamespace - Tolerations - TopologySpreadConstraints fieldOverrides: @@ -130,9 +131,15 @@ k8s.io/api/core/v1.PodSpec: SecurityContext: description: "This is accessible behind a feature flag - kubernetes.podspec-securitycontext" additionalMarkers: - # Part of a feature flag - so we want to omit the schema and preserve unknown fields - - kubebuilder:validation:DropProperties - - kubebuilder:pruning:PreserveUnknownFields + # Part of a feature flag - so we want to omit the schema and preserve unknown fields + - kubebuilder:validation:DropProperties + - kubebuilder:pruning:PreserveUnknownFields + ShareProcessNamespace: + description: "This is accessible behind a feature flag - kubernetes.podspec-shareproccessnamespace" + additionalMarkers: + # Part of a feature flag - so we want to omit the schema and preserve unknown fields + - kubebuilder:validation:DropProperties + - kubebuilder:pruning:PreserveUnknownFields Tolerations: description: "This is accessible behind a feature flag - kubernetes.podspec-tolerations" itemOverride: diff --git a/pkg/apis/config/features.go b/pkg/apis/config/features.go index 32b7345a8c..4e9d0aefde 100644 --- a/pkg/apis/config/features.go +++ b/pkg/apis/config/features.go @@ -59,6 +59,7 @@ func defaultFeaturesConfig() *Features { PodSpecNodeSelector: Disabled, PodSpecRuntimeClassName: Disabled, PodSpecSecurityContext: Disabled, + PodSpecShareProcessNamespace: Disabled, PodSpecPriorityClassName: Disabled, PodSpecSchedulerName: Disabled, ContainerSpecAddCapabilities: Disabled, @@ -91,6 +92,7 @@ func NewFeaturesConfigFromMap(data map[string]string) (*Features, error) { asFlag("kubernetes.podspec-nodeselector", &nc.PodSpecNodeSelector), asFlag("kubernetes.podspec-runtimeclassname", &nc.PodSpecRuntimeClassName), asFlag("kubernetes.podspec-securitycontext", &nc.PodSpecSecurityContext), + asFlag("kubernetes.podspec-shareprocessnamespace", &nc.PodSpecShareProcessNamespace), asFlag("kubernetes.podspec-priorityclassname", &nc.PodSpecPriorityClassName), asFlag("kubernetes.podspec-schedulername", &nc.PodSpecSchedulerName), asFlag("kubernetes.containerspec-addcapabilities", &nc.ContainerSpecAddCapabilities), @@ -127,6 +129,7 @@ type Features struct { PodSpecNodeSelector Flag PodSpecRuntimeClassName Flag PodSpecSecurityContext Flag + PodSpecShareProcessNamespace Flag PodSpecPriorityClassName Flag PodSpecSchedulerName Flag ContainerSpecAddCapabilities Flag diff --git a/pkg/apis/config/features_test.go b/pkg/apis/config/features_test.go index 5e929e7fc3..2b465cbb6b 100644 --- a/pkg/apis/config/features_test.go +++ b/pkg/apis/config/features_test.go @@ -67,6 +67,7 @@ func TestFeaturesConfiguration(t *testing.T) { PodSpecNodeSelector: Enabled, PodSpecRuntimeClassName: Enabled, PodSpecSecurityContext: Enabled, + PodSpecShareProcessNamespace: Enabled, PodSpecTolerations: Enabled, PodSpecPriorityClassName: Enabled, PodSpecSchedulerName: Enabled, @@ -85,6 +86,7 @@ func TestFeaturesConfiguration(t *testing.T) { "kubernetes.podspec-nodeselector": "Enabled", "kubernetes.podspec-runtimeclassname": "Enabled", "kubernetes.podspec-securitycontext": "Enabled", + "kubernetes.podspec-shareprocessnamespace": "Enabled", "kubernetes.podspec-tolerations": "Enabled", "kubernetes.podspec-priorityclassname": "Enabled", "kubernetes.podspec-schedulername": "Enabled", @@ -328,232 +330,251 @@ func TestFeaturesConfiguration(t *testing.T) { data: map[string]string{ "kubernetes.podspec-securitycontext": "Disabled", }, - }, { - name: "kubernetes.containerspec-addcapabilities Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - ContainerSpecAddCapabilities: Disabled, - }), - data: map[string]string{ - "kubernetes.containerspec-addcapabilities": "Disabled", - }, - }, { - name: "kubernetes.containerspec-addcapabilities Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - ContainerSpecAddCapabilities: Enabled, - }), - data: map[string]string{ - "kubernetes.containerspec-addcapabilities": "Enabled", - }, - }, { - name: "kubernetes.containerspec-addcapabilities Allowed", - wantErr: false, - wantFeatures: defaultWith(&Features{ - ContainerSpecAddCapabilities: Allowed, - }), - data: map[string]string{ - "kubernetes.containerspec-addcapabilities": "Allowed", - }, - }, { - name: "tag-header-based-routing Allowed", - wantErr: false, - wantFeatures: defaultWith(&Features{ - TagHeaderBasedRouting: Allowed, - }), - data: map[string]string{ - "tag-header-based-routing": "Allowed", - }, - }, { - name: "tag-header-based-routing Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - TagHeaderBasedRouting: Enabled, - }), - data: map[string]string{ - "tag-header-based-routing": "Enabled", - }, - }, { - name: "kubernetes.podspec-volumes-emptyDir Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecVolumesEmptyDir: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-volumes-emptydir": "Disabled", - }, - }, { - name: "kubernetes.podspec-volumes-emptyDir Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecVolumesEmptyDir: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-volumes-emptydir": "Enabled", - }, - }, { - name: "kubernetes.podspec-persistent-volume-claim Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecPersistentVolumeClaim: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-persistent-volume-claim": "Disabled", - }, - }, { - name: "kubernetes.podspec-persistent-volume-claim Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecPersistentVolumeClaim: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-persistent-volume-claim": "Enabled", - }, - }, { - name: "kubernetes.podspec-persistent-volume-write Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecPersistentVolumeWrite: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-persistent-volume-write": "Disabled", - }, - }, { - name: "kubernetes.podspec-persistent-volume-claim Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecPersistentVolumeWrite: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-persistent-volume-write": "Enabled", - }, - }, { - name: "kubernetes.podspec-init-containers Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecInitContainers: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-init-containers": "Disabled", - }, - }, { - name: "kubernetes.podspec-init-container Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecInitContainers: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-init-containers": "Enabled", - }, - }, { - name: "kubernetes.podspec-priorityclassname Allowed", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecPriorityClassName: Allowed, - }), - data: map[string]string{ - "kubernetes.podspec-priorityclassname": "Allowed", - }, - }, { - name: "kubernetes.podspec-priorityclassname Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecPriorityClassName: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-priorityclassname": "Enabled", - }, - }, { - name: "kubernetes.podspec-priorityclassname Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecPriorityClassName: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-priorityclassname": "Disabled", - }, - }, { - name: "kubernetes.podspec-schedulername Allowed", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecSchedulerName: Allowed, - }), - data: map[string]string{ - "kubernetes.podspec-schedulername": "Allowed", - }, - }, { - name: "kubernetes.podspec-schedulername Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecSchedulerName: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-schedulername": "Enabled", - }, - }, { - name: "kubernetes.podspec-schedulername Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecSchedulerName: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-schedulername": "Disabled", - }, - }, { - name: "kubernetes.podspec-dnspolicy Allowed", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecDNSPolicy: Allowed, - }), - data: map[string]string{ - "kubernetes.podspec-dnspolicy": "Allowed", - }, - }, { - name: "kubernetes.podspec-dnspolicy Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecDNSPolicy: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-dnspolicy": "Enabled", - }, - }, { - name: "kubernetes.podspec-dnspolicy Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecDNSPolicy: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-dnspolicy": "Disabled", - }, - }, { - name: "kubernetes.podspec-dnsconfig Allowed", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecDNSConfig: Allowed, - }), - data: map[string]string{ - "kubernetes.podspec-dnsconfig": "Allowed", - }, - }, { - name: "kubernetes.podspec-dnsconfig Enabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecDNSConfig: Enabled, - }), - data: map[string]string{ - "kubernetes.podspec-dnsconfig": "Enabled", - }, - }, { - name: "kubernetes.podspec-dnsconfig Disabled", - wantErr: false, - wantFeatures: defaultWith(&Features{ - PodSpecDNSConfig: Disabled, - }), - data: map[string]string{ - "kubernetes.podspec-dnsconfig": "Disabled", - }, - }} + }, + { + name: "shared process namespace Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecShareProcessNamespace: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-shareprocessnamespace": "Allowed", + }, + }, { + name: "shared process namespace Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecShareProcessNamespace: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-shareprocessnamespace": "Disabled", + }, + }, { + name: "kubernetes.containerspec-addcapabilities Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + ContainerSpecAddCapabilities: Disabled, + }), + data: map[string]string{ + "kubernetes.containerspec-addcapabilities": "Disabled", + }, + }, { + name: "kubernetes.containerspec-addcapabilities Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + ContainerSpecAddCapabilities: Enabled, + }), + data: map[string]string{ + "kubernetes.containerspec-addcapabilities": "Enabled", + }, + }, { + name: "kubernetes.containerspec-addcapabilities Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + ContainerSpecAddCapabilities: Allowed, + }), + data: map[string]string{ + "kubernetes.containerspec-addcapabilities": "Allowed", + }, + }, { + name: "tag-header-based-routing Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + TagHeaderBasedRouting: Allowed, + }), + data: map[string]string{ + "tag-header-based-routing": "Allowed", + }, + }, { + name: "tag-header-based-routing Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + TagHeaderBasedRouting: Enabled, + }), + data: map[string]string{ + "tag-header-based-routing": "Enabled", + }, + }, { + name: "kubernetes.podspec-volumes-emptyDir Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecVolumesEmptyDir: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-volumes-emptydir": "Disabled", + }, + }, { + name: "kubernetes.podspec-volumes-emptyDir Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecVolumesEmptyDir: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-volumes-emptydir": "Enabled", + }, + }, { + name: "kubernetes.podspec-persistent-volume-claim Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecPersistentVolumeClaim: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-persistent-volume-claim": "Disabled", + }, + }, { + name: "kubernetes.podspec-persistent-volume-claim Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecPersistentVolumeClaim: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-persistent-volume-claim": "Enabled", + }, + }, { + name: "kubernetes.podspec-persistent-volume-write Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecPersistentVolumeWrite: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-persistent-volume-write": "Disabled", + }, + }, { + name: "kubernetes.podspec-persistent-volume-claim Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecPersistentVolumeWrite: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-persistent-volume-write": "Enabled", + }, + }, { + name: "kubernetes.podspec-init-containers Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecInitContainers: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-init-containers": "Disabled", + }, + }, { + name: "kubernetes.podspec-init-container Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecInitContainers: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-init-containers": "Enabled", + }, + }, { + name: "kubernetes.podspec-priorityclassname Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecPriorityClassName: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-priorityclassname": "Allowed", + }, + }, { + name: "kubernetes.podspec-priorityclassname Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecPriorityClassName: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-priorityclassname": "Enabled", + }, + }, { + name: "kubernetes.podspec-priorityclassname Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecPriorityClassName: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-priorityclassname": "Disabled", + }, + }, { + name: "kubernetes.podspec-schedulername Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecSchedulerName: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-schedulername": "Allowed", + }, + }, { + name: "kubernetes.podspec-schedulername Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecSchedulerName: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-schedulername": "Enabled", + }, + }, { + name: "kubernetes.podspec-schedulername Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecSchedulerName: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-schedulername": "Disabled", + }, + }, { + name: "kubernetes.podspec-dnspolicy Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSPolicy: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-dnspolicy": "Allowed", + }, + }, { + name: "kubernetes.podspec-dnspolicy Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSPolicy: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnspolicy": "Enabled", + }, + }, { + name: "kubernetes.podspec-dnspolicy Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSPolicy: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnspolicy": "Disabled", + }, + }, { + name: "kubernetes.podspec-dnsconfig Allowed", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSConfig: Allowed, + }), + data: map[string]string{ + "kubernetes.podspec-dnsconfig": "Allowed", + }, + }, { + name: "kubernetes.podspec-dnsconfig Enabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSConfig: Enabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnsconfig": "Enabled", + }, + }, { + name: "kubernetes.podspec-dnsconfig Disabled", + wantErr: false, + wantFeatures: defaultWith(&Features{ + PodSpecDNSConfig: Disabled, + }), + data: map[string]string{ + "kubernetes.podspec-dnsconfig": "Disabled", + }, + }} for _, tt := range configTests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/apis/serving/fieldmask.go b/pkg/apis/serving/fieldmask.go index 20bff397c3..769370d764 100644 --- a/pkg/apis/serving/fieldmask.go +++ b/pkg/apis/serving/fieldmask.go @@ -245,6 +245,9 @@ func PodSpecMask(ctx context.Context, in *corev1.PodSpec) *corev1.PodSpec { // This is further validated in ValidatePodSecurityContext. out.SecurityContext = in.SecurityContext } + if cfg.Features.PodSpecShareProcessNamespace != config.Disabled { + out.ShareProcessNamespace = in.ShareProcessNamespace + } if cfg.Features.PodSpecPriorityClassName != config.Disabled { out.PriorityClassName = in.PriorityClassName } @@ -270,7 +273,6 @@ func PodSpecMask(ctx context.Context, in *corev1.PodSpec) *corev1.PodSpec { out.HostNetwork = false out.HostPID = false out.HostIPC = false - out.ShareProcessNamespace = nil out.Hostname = "" out.Subdomain = "" out.Priority = nil diff --git a/pkg/apis/serving/k8s_validation_test.go b/pkg/apis/serving/k8s_validation_test.go index 16bf426a64..0f10a25c2a 100644 --- a/pkg/apis/serving/k8s_validation_test.go +++ b/pkg/apis/serving/k8s_validation_test.go @@ -150,6 +150,13 @@ func withPodSpecSchedulerNameEnabled() configOption { } } +func withPodSpecProcessNamespaceEnabled() configOption { + return func(cfg *config.Config) *config.Config { + cfg.Features.PodSpecShareProcessNamespace = config.Enabled + return cfg + } +} + func withPodSpecInitContainersEnabled() configOption { return func(cfg *config.Config) *config.Config { cfg.Features.PodSpecInitContainers = config.Enabled @@ -1135,6 +1142,7 @@ func TestPodSpecMultiContainerValidation(t *testing.T) { func TestPodSpecFeatureValidation(t *testing.T) { runtimeClassName := "test" + shareProcessNamespace := true featureData := []struct { name string @@ -1287,6 +1295,16 @@ func TestPodSpecFeatureValidation(t *testing.T) { Paths: []string{"schedulerName"}, }, cfgOpts: []configOption{withPodSpecSchedulerNameEnabled()}, + }, { + name: "ShareProcessNamespace", + featureSpec: corev1.PodSpec{ + ShareProcessNamespace: &shareProcessNamespace, + }, + err: &apis.FieldError{ + Message: "must not set the field(s)", + Paths: []string{"shareProcessNamespace"}, + }, + cfgOpts: []configOption{withPodSpecProcessNamespaceEnabled()}, }} featureTests := []struct {