mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #99144 from bart0sh/PR0094-promote-HugePageStorageMediumSize-to-GA
promote huge page storage medium size to GA
This commit is contained in:
		@@ -21,11 +21,9 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	v1 "k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
					 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
						"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
				
			||||||
	v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
 | 
					 | 
				
			||||||
	apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
 | 
						apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -331,19 +329,6 @@ func usesHugePagesInProjectedEnv(item api.Container) bool {
 | 
				
			|||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// usesMultipleHugePageResources returns true if the pod spec uses more than
 | 
					 | 
				
			||||||
// one size of hugepage
 | 
					 | 
				
			||||||
func usesMultipleHugePageResources(podSpec *api.PodSpec) bool {
 | 
					 | 
				
			||||||
	hugePageResources := sets.NewString()
 | 
					 | 
				
			||||||
	resourceSet := helper.ToPodResourcesSet(podSpec)
 | 
					 | 
				
			||||||
	for resourceStr := range resourceSet {
 | 
					 | 
				
			||||||
		if v1helper.IsHugePageResourceName(v1.ResourceName(resourceStr)) {
 | 
					 | 
				
			||||||
			hugePageResources.Insert(resourceStr)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return len(hugePageResources) > 1
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func checkContainerUseIndivisibleHugePagesValues(container api.Container) bool {
 | 
					func checkContainerUseIndivisibleHugePagesValues(container api.Container) bool {
 | 
				
			||||||
	for resourceName, quantity := range container.Resources.Limits {
 | 
						for resourceName, quantity := range container.Resources.Limits {
 | 
				
			||||||
		if helper.IsHugePageResourceName(resourceName) {
 | 
							if helper.IsHugePageResourceName(resourceName) {
 | 
				
			||||||
@@ -425,8 +410,6 @@ func haveSameExpandedDNSConfig(podSpec, oldPodSpec *api.PodSpec) bool {
 | 
				
			|||||||
func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, podMeta, oldPodMeta *metav1.ObjectMeta) apivalidation.PodValidationOptions {
 | 
					func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, podMeta, oldPodMeta *metav1.ObjectMeta) apivalidation.PodValidationOptions {
 | 
				
			||||||
	// default pod validation options based on feature gate
 | 
						// default pod validation options based on feature gate
 | 
				
			||||||
	opts := apivalidation.PodValidationOptions{
 | 
						opts := apivalidation.PodValidationOptions{
 | 
				
			||||||
		// Allow multiple huge pages on pod create if feature is enabled
 | 
					 | 
				
			||||||
		AllowMultipleHugePageResources: utilfeature.DefaultFeatureGate.Enabled(features.HugePageStorageMediumSize),
 | 
					 | 
				
			||||||
		// Allow pod spec to use hugepages in downward API if feature is enabled
 | 
							// Allow pod spec to use hugepages in downward API if feature is enabled
 | 
				
			||||||
		AllowDownwardAPIHugePages:   utilfeature.DefaultFeatureGate.Enabled(features.DownwardAPIHugePages),
 | 
							AllowDownwardAPIHugePages:   utilfeature.DefaultFeatureGate.Enabled(features.DownwardAPIHugePages),
 | 
				
			||||||
		AllowInvalidPodDeletionCost: !utilfeature.DefaultFeatureGate.Enabled(features.PodDeletionCost),
 | 
							AllowInvalidPodDeletionCost: !utilfeature.DefaultFeatureGate.Enabled(features.PodDeletionCost),
 | 
				
			||||||
@@ -438,8 +421,6 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if oldPodSpec != nil {
 | 
						if oldPodSpec != nil {
 | 
				
			||||||
		// if old spec used multiple huge page sizes, we must allow it
 | 
					 | 
				
			||||||
		opts.AllowMultipleHugePageResources = opts.AllowMultipleHugePageResources || usesMultipleHugePageResources(oldPodSpec)
 | 
					 | 
				
			||||||
		// if old spec used hugepages in downward api, we must allow it
 | 
							// if old spec used hugepages in downward api, we must allow it
 | 
				
			||||||
		opts.AllowDownwardAPIHugePages = opts.AllowDownwardAPIHugePages || usesHugePagesInProjectedVolume(oldPodSpec)
 | 
							opts.AllowDownwardAPIHugePages = opts.AllowDownwardAPIHugePages || usesHugePagesInProjectedVolume(oldPodSpec)
 | 
				
			||||||
		// determine if any container is using hugepages in env var
 | 
							// determine if any container is using hugepages in env var
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,6 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
						"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
				
			||||||
	podshelper "k8s.io/kubernetes/pkg/apis/core/pods"
 | 
						podshelper "k8s.io/kubernetes/pkg/apis/core/pods"
 | 
				
			||||||
	corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
 | 
						corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
 | 
				
			||||||
	v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/capabilities"
 | 
						"k8s.io/kubernetes/pkg/capabilities"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/cluster/ports"
 | 
						"k8s.io/kubernetes/pkg/cluster/ports"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
@@ -3313,8 +3312,6 @@ func validateContainersOnlyForPod(containers []core.Container, fldPath *field.Pa
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// PodValidationOptions contains the different settings for pod validation
 | 
					// PodValidationOptions contains the different settings for pod validation
 | 
				
			||||||
type PodValidationOptions struct {
 | 
					type PodValidationOptions struct {
 | 
				
			||||||
	// Allow pod spec to have more than one huge page resource (with different sizes)
 | 
					 | 
				
			||||||
	AllowMultipleHugePageResources bool
 | 
					 | 
				
			||||||
	// Allow pod spec to use hugepages in downward API
 | 
						// Allow pod spec to use hugepages in downward API
 | 
				
			||||||
	AllowDownwardAPIHugePages bool
 | 
						AllowDownwardAPIHugePages bool
 | 
				
			||||||
	// Allow invalid pod-deletion-cost annotation value for backward compatibility.
 | 
						// Allow invalid pod-deletion-cost annotation value for backward compatibility.
 | 
				
			||||||
@@ -3327,23 +3324,6 @@ type PodValidationOptions struct {
 | 
				
			|||||||
	AllowExpandedDNSConfig bool
 | 
						AllowExpandedDNSConfig bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ValidatePodSingleHugePageResources checks if there are multiple huge
 | 
					 | 
				
			||||||
// pages resources in the pod object.
 | 
					 | 
				
			||||||
func ValidatePodSingleHugePageResources(pod *core.Pod, specPath *field.Path) field.ErrorList {
 | 
					 | 
				
			||||||
	allErrs := field.ErrorList{}
 | 
					 | 
				
			||||||
	resourceSet := helper.ToPodResourcesSet(&pod.Spec)
 | 
					 | 
				
			||||||
	hugePageResources := sets.NewString()
 | 
					 | 
				
			||||||
	for resourceStr := range resourceSet {
 | 
					 | 
				
			||||||
		if v1helper.IsHugePageResourceName(v1.ResourceName(resourceStr)) {
 | 
					 | 
				
			||||||
			hugePageResources.Insert(resourceStr)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(hugePageResources) > 1 {
 | 
					 | 
				
			||||||
		allErrs = append(allErrs, field.Invalid(specPath, hugePageResources.List(), "must use a single hugepage size in a pod spec"))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return allErrs
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
 | 
					// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
 | 
				
			||||||
// and is called by ValidatePodCreate and ValidatePodUpdate.
 | 
					// and is called by ValidatePodCreate and ValidatePodUpdate.
 | 
				
			||||||
func validatePodMetadataAndSpec(pod *core.Pod, opts PodValidationOptions) field.ErrorList {
 | 
					func validatePodMetadataAndSpec(pod *core.Pod, opts PodValidationOptions) field.ErrorList {
 | 
				
			||||||
@@ -3373,10 +3353,6 @@ func validatePodMetadataAndSpec(pod *core.Pod, opts PodValidationOptions) field.
 | 
				
			|||||||
	allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.Containers, specPath.Child("containers"))...)
 | 
						allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.Containers, specPath.Child("containers"))...)
 | 
				
			||||||
	allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...)
 | 
						allErrs = append(allErrs, validateContainersOnlyForPod(pod.Spec.InitContainers, specPath.Child("initContainers"))...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !opts.AllowMultipleHugePageResources {
 | 
					 | 
				
			||||||
		allErrs = append(allErrs, ValidatePodSingleHugePageResources(pod, specPath)...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -4074,10 +4050,6 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod, opts PodValidationOptions) fiel
 | 
				
			|||||||
	allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"), opts)...)
 | 
						allErrs = append(allErrs, ValidatePodSpecificAnnotationUpdates(newPod, oldPod, fldPath.Child("annotations"), opts)...)
 | 
				
			||||||
	specPath := field.NewPath("spec")
 | 
						specPath := field.NewPath("spec")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !opts.AllowMultipleHugePageResources {
 | 
					 | 
				
			||||||
		allErrs = append(allErrs, ValidatePodSingleHugePageResources(newPod, specPath)...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// validate updateable fields:
 | 
						// validate updateable fields:
 | 
				
			||||||
	// 1.  spec.containers[*].image
 | 
						// 1.  spec.containers[*].image
 | 
				
			||||||
	// 2.  spec.initContainers[*].image
 | 
						// 2.  spec.initContainers[*].image
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4453,7 +4453,6 @@ func TestValidateVolumes(t *testing.T) {
 | 
				
			|||||||
func TestHugePagesIsolation(t *testing.T) {
 | 
					func TestHugePagesIsolation(t *testing.T) {
 | 
				
			||||||
	testCases := map[string]struct {
 | 
						testCases := map[string]struct {
 | 
				
			||||||
		pod         *core.Pod
 | 
							pod         *core.Pod
 | 
				
			||||||
		enableHugePageStorageMediumSize bool
 | 
					 | 
				
			||||||
		expectError bool
 | 
							expectError bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		"Valid: request hugepages-2Mi": {
 | 
							"Valid: request hugepages-2Mi": {
 | 
				
			||||||
@@ -4482,7 +4481,7 @@ func TestHugePagesIsolation(t *testing.T) {
 | 
				
			|||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"Valid: HugePageStorageMediumSize enabled: request more than one hugepages size": {
 | 
							"Valid: request more than one hugepages size": {
 | 
				
			||||||
			pod: &core.Pod{
 | 
								pod: &core.Pod{
 | 
				
			||||||
				ObjectMeta: metav1.ObjectMeta{Name: "hugepages-shared", Namespace: "ns"},
 | 
									ObjectMeta: metav1.ObjectMeta{Name: "hugepages-shared", Namespace: "ns"},
 | 
				
			||||||
				Spec: core.PodSpec{
 | 
									Spec: core.PodSpec{
 | 
				
			||||||
@@ -4509,10 +4508,9 @@ func TestHugePagesIsolation(t *testing.T) {
 | 
				
			|||||||
					DNSPolicy:     core.DNSClusterFirst,
 | 
										DNSPolicy:     core.DNSClusterFirst,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			enableHugePageStorageMediumSize: true,
 | 
					 | 
				
			||||||
			expectError: false,
 | 
								expectError: false,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"Invalid: HugePageStorageMediumSize disabled: request hugepages-1Gi, limit hugepages-2Mi and hugepages-1Gi": {
 | 
							"Valid: request hugepages-1Gi, limit hugepages-2Mi and hugepages-1Gi": {
 | 
				
			||||||
			pod: &core.Pod{
 | 
								pod: &core.Pod{
 | 
				
			||||||
				ObjectMeta: metav1.ObjectMeta{Name: "hugepages-multiple", Namespace: "ns"},
 | 
									ObjectMeta: metav1.ObjectMeta{Name: "hugepages-multiple", Namespace: "ns"},
 | 
				
			||||||
				Spec: core.PodSpec{
 | 
									Spec: core.PodSpec{
 | 
				
			||||||
@@ -4523,6 +4521,7 @@ func TestHugePagesIsolation(t *testing.T) {
 | 
				
			|||||||
								Requests: core.ResourceList{
 | 
													Requests: core.ResourceList{
 | 
				
			||||||
									core.ResourceName(core.ResourceCPU):    resource.MustParse("10"),
 | 
														core.ResourceName(core.ResourceCPU):    resource.MustParse("10"),
 | 
				
			||||||
									core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
 | 
														core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
 | 
				
			||||||
 | 
														core.ResourceName("hugepages-2Mi"):     resource.MustParse("1Gi"),
 | 
				
			||||||
									core.ResourceName("hugepages-1Gi"):     resource.MustParse("2Gi"),
 | 
														core.ResourceName("hugepages-1Gi"):     resource.MustParse("2Gi"),
 | 
				
			||||||
								},
 | 
													},
 | 
				
			||||||
								Limits: core.ResourceList{
 | 
													Limits: core.ResourceList{
 | 
				
			||||||
@@ -4538,7 +4537,6 @@ func TestHugePagesIsolation(t *testing.T) {
 | 
				
			|||||||
					DNSPolicy:     core.DNSClusterFirst,
 | 
										DNSPolicy:     core.DNSClusterFirst,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			expectError: true,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"Invalid: not requesting cpu and memory": {
 | 
							"Invalid: not requesting cpu and memory": {
 | 
				
			||||||
			pod: &core.Pod{
 | 
								pod: &core.Pod{
 | 
				
			||||||
@@ -4590,40 +4588,10 @@ func TestHugePagesIsolation(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			expectError: true,
 | 
								expectError: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"Invalid: HugePageStorageMediumSize disabled: request more than one hugepages size": {
 | 
					 | 
				
			||||||
			pod: &core.Pod{
 | 
					 | 
				
			||||||
				ObjectMeta: metav1.ObjectMeta{Name: "hugepages-shared", Namespace: "ns"},
 | 
					 | 
				
			||||||
				Spec: core.PodSpec{
 | 
					 | 
				
			||||||
					Containers: []core.Container{
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
 | 
					 | 
				
			||||||
							Resources: core.ResourceRequirements{
 | 
					 | 
				
			||||||
								Requests: core.ResourceList{
 | 
					 | 
				
			||||||
									core.ResourceName(core.ResourceCPU):    resource.MustParse("10"),
 | 
					 | 
				
			||||||
									core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
 | 
					 | 
				
			||||||
									core.ResourceName("hugepages-2Mi"):     resource.MustParse("1Gi"),
 | 
					 | 
				
			||||||
									core.ResourceName("hugepages-1Gi"):     resource.MustParse("1Gi"),
 | 
					 | 
				
			||||||
								},
 | 
					 | 
				
			||||||
								Limits: core.ResourceList{
 | 
					 | 
				
			||||||
									core.ResourceName(core.ResourceCPU):    resource.MustParse("10"),
 | 
					 | 
				
			||||||
									core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
 | 
					 | 
				
			||||||
									core.ResourceName("hugepages-2Mi"):     resource.MustParse("1Gi"),
 | 
					 | 
				
			||||||
									core.ResourceName("hugepages-1Gi"):     resource.MustParse("1Gi"),
 | 
					 | 
				
			||||||
								},
 | 
					 | 
				
			||||||
							},
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
					RestartPolicy: core.RestartPolicyAlways,
 | 
					 | 
				
			||||||
					DNSPolicy:     core.DNSClusterFirst,
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			expectError: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for tcName, tc := range testCases {
 | 
						for tcName, tc := range testCases {
 | 
				
			||||||
		t.Run(tcName, func(t *testing.T) {
 | 
							t.Run(tcName, func(t *testing.T) {
 | 
				
			||||||
			defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePageStorageMediumSize, tc.enableHugePageStorageMediumSize)()
 | 
								errs := ValidatePodCreate(tc.pod, PodValidationOptions{})
 | 
				
			||||||
			errs := ValidatePodCreate(tc.pod, PodValidationOptions{AllowMultipleHugePageResources: tc.enableHugePageStorageMediumSize})
 | 
					 | 
				
			||||||
			if tc.expectError && len(errs) == 0 {
 | 
								if tc.expectError && len(errs) == 0 {
 | 
				
			||||||
				t.Errorf("Unexpected success")
 | 
									t.Errorf("Unexpected success")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -486,6 +486,7 @@ const (
 | 
				
			|||||||
	// owner: @bart0sh
 | 
						// owner: @bart0sh
 | 
				
			||||||
	// alpha: v1.18
 | 
						// alpha: v1.18
 | 
				
			||||||
	// beta: v1.19
 | 
						// beta: v1.19
 | 
				
			||||||
 | 
						// GA: 1.22
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	// Enables usage of HugePages-<size> in a volume medium,
 | 
						// Enables usage of HugePages-<size> in a volume medium,
 | 
				
			||||||
	// e.g. emptyDir:
 | 
						// e.g. emptyDir:
 | 
				
			||||||
@@ -844,7 +845,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
 | 
				
			|||||||
	CronJobControllerV2:                            {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
 | 
						CronJobControllerV2:                            {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
 | 
				
			||||||
	DaemonSetUpdateSurge:                           {Default: true, PreRelease: featuregate.Beta},                    // on by default in 1.22
 | 
						DaemonSetUpdateSurge:                           {Default: true, PreRelease: featuregate.Beta},                    // on by default in 1.22
 | 
				
			||||||
	ImmutableEphemeralVolumes:                      {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
 | 
						ImmutableEphemeralVolumes:                      {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.24
 | 
				
			||||||
	HugePageStorageMediumSize:                      {Default: true, PreRelease: featuregate.Beta},
 | 
						HugePageStorageMediumSize:                      {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.23
 | 
				
			||||||
	DownwardAPIHugePages:                           {Default: false, PreRelease: featuregate.Beta},                   // on by default in 1.22
 | 
						DownwardAPIHugePages:                           {Default: false, PreRelease: featuregate.Beta},                   // on by default in 1.22
 | 
				
			||||||
	AnyVolumeDataSource:                            {Default: false, PreRelease: featuregate.Alpha},
 | 
						AnyVolumeDataSource:                            {Default: false, PreRelease: featuregate.Alpha},
 | 
				
			||||||
	DefaultPodTopologySpread:                       {Default: true, PreRelease: featuregate.Beta},
 | 
						DefaultPodTopologySpread:                       {Default: true, PreRelease: featuregate.Beta},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,15 +22,13 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/types"
 | 
						"k8s.io/apimachinery/pkg/types"
 | 
				
			||||||
	utilyaml "k8s.io/apimachinery/pkg/util/yaml"
 | 
						utilyaml "k8s.io/apimachinery/pkg/util/yaml"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
					 | 
				
			||||||
	api "k8s.io/kubernetes/pkg/apis/core"
 | 
						api "k8s.io/kubernetes/pkg/apis/core"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
						"k8s.io/kubernetes/pkg/apis/core/helper"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: remove this import if
 | 
						// TODO: remove this import if
 | 
				
			||||||
	// api.Registry.GroupOrDie(v1.GroupName).GroupVersion.String() is changed
 | 
						// api.Registry.GroupOrDie(v1.GroupName).GroupVersion.String() is changed
 | 
				
			||||||
@@ -137,10 +135,7 @@ func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v
 | 
				
			|||||||
	if err = defaultFn(newPod); err != nil {
 | 
						if err = defaultFn(newPod); err != nil {
 | 
				
			||||||
		return true, pod, err
 | 
							return true, pod, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts := validation.PodValidationOptions{
 | 
						if errs := validation.ValidatePodCreate(newPod, validation.PodValidationOptions{}); len(errs) > 0 {
 | 
				
			||||||
		AllowMultipleHugePageResources: utilfeature.DefaultFeatureGate.Enabled(features.HugePageStorageMediumSize),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if errs := validation.ValidatePodCreate(newPod, opts); len(errs) > 0 {
 | 
					 | 
				
			||||||
		return true, pod, fmt.Errorf("invalid pod: %v", errs)
 | 
							return true, pod, fmt.Errorf("invalid pod: %v", errs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	v1Pod := &v1.Pod{}
 | 
						v1Pod := &v1.Pod{}
 | 
				
			||||||
@@ -164,17 +159,13 @@ func tryDecodePodList(data []byte, defaultFn defaultFunc) (parsed bool, pods v1.
 | 
				
			|||||||
		return false, pods, err
 | 
							return false, pods, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts := validation.PodValidationOptions{
 | 
					 | 
				
			||||||
		AllowMultipleHugePageResources: utilfeature.DefaultFeatureGate.Enabled(features.HugePageStorageMediumSize),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Apply default values and validate pods.
 | 
						// Apply default values and validate pods.
 | 
				
			||||||
	for i := range newPods.Items {
 | 
						for i := range newPods.Items {
 | 
				
			||||||
		newPod := &newPods.Items[i]
 | 
							newPod := &newPods.Items[i]
 | 
				
			||||||
		if err = defaultFn(newPod); err != nil {
 | 
							if err = defaultFn(newPod); err != nil {
 | 
				
			||||||
			return true, pods, err
 | 
								return true, pods, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if errs := validation.ValidatePodCreate(newPod, opts); len(errs) > 0 {
 | 
							if errs := validation.ValidatePodCreate(newPod, validation.PodValidationOptions{}); len(errs) > 0 {
 | 
				
			||||||
			err = fmt.Errorf("invalid pod: %v", errs)
 | 
								err = fmt.Errorf("invalid pod: %v", errs)
 | 
				
			||||||
			return true, pods, err
 | 
								return true, pods, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,23 +109,16 @@ func TestPluginEmptyRootContext(t *testing.T) {
 | 
				
			|||||||
func TestPluginHugetlbfs(t *testing.T) {
 | 
					func TestPluginHugetlbfs(t *testing.T) {
 | 
				
			||||||
	testCases := map[string]struct {
 | 
						testCases := map[string]struct {
 | 
				
			||||||
		medium v1.StorageMedium
 | 
							medium v1.StorageMedium
 | 
				
			||||||
		enableHugePageStorageMediumSize bool
 | 
					 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		"HugePageStorageMediumSize enabled: medium without size": {
 | 
							"medium without size": {
 | 
				
			||||||
			medium:                          "HugePages",
 | 
					 | 
				
			||||||
			enableHugePageStorageMediumSize: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		"HugePageStorageMediumSize disabled: medium without size": {
 | 
					 | 
				
			||||||
			medium: "HugePages",
 | 
								medium: "HugePages",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"HugePageStorageMediumSize enabled: medium with size": {
 | 
							"medium with size": {
 | 
				
			||||||
			medium: "HugePages-2Mi",
 | 
								medium: "HugePages-2Mi",
 | 
				
			||||||
			enableHugePageStorageMediumSize: true,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for tcName, tc := range testCases {
 | 
						for tcName, tc := range testCases {
 | 
				
			||||||
		t.Run(tcName, func(t *testing.T) {
 | 
							t.Run(tcName, func(t *testing.T) {
 | 
				
			||||||
			defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePageStorageMediumSize, tc.enableHugePageStorageMediumSize)()
 | 
					 | 
				
			||||||
			doTestPlugin(t, pluginTestConfig{
 | 
								doTestPlugin(t, pluginTestConfig{
 | 
				
			||||||
				medium:                        tc.medium,
 | 
									medium:                        tc.medium,
 | 
				
			||||||
				expectedSetupMounts:           1,
 | 
									expectedSetupMounts:           1,
 | 
				
			||||||
@@ -385,7 +378,6 @@ func TestGetHugePagesMountOptions(t *testing.T) {
 | 
				
			|||||||
		medium         v1.StorageMedium
 | 
							medium         v1.StorageMedium
 | 
				
			||||||
		shouldFail     bool
 | 
							shouldFail     bool
 | 
				
			||||||
		expectedResult string
 | 
							expectedResult string
 | 
				
			||||||
		enableHugePageStorageMediumSize bool
 | 
					 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		"ProperValues": {
 | 
							"ProperValues": {
 | 
				
			||||||
			pod: &v1.Pod{
 | 
								pod: &v1.Pod{
 | 
				
			||||||
@@ -504,7 +496,6 @@ func TestGetHugePagesMountOptions(t *testing.T) {
 | 
				
			|||||||
			medium:         v1.StorageMediumHugePages,
 | 
								medium:         v1.StorageMediumHugePages,
 | 
				
			||||||
			shouldFail:     true,
 | 
								shouldFail:     true,
 | 
				
			||||||
			expectedResult: "",
 | 
								expectedResult: "",
 | 
				
			||||||
			enableHugePageStorageMediumSize: true,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"PodWithNoHugePagesRequest": {
 | 
							"PodWithNoHugePagesRequest": {
 | 
				
			||||||
			pod:            &v1.Pod{},
 | 
								pod:            &v1.Pod{},
 | 
				
			||||||
@@ -530,7 +521,6 @@ func TestGetHugePagesMountOptions(t *testing.T) {
 | 
				
			|||||||
			medium:         v1.StorageMediumHugePagesPrefix + "1Gi",
 | 
								medium:         v1.StorageMediumHugePagesPrefix + "1Gi",
 | 
				
			||||||
			shouldFail:     false,
 | 
								shouldFail:     false,
 | 
				
			||||||
			expectedResult: "pagesize=1Gi",
 | 
								expectedResult: "pagesize=1Gi",
 | 
				
			||||||
			enableHugePageStorageMediumSize: true,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"InitContainerAndContainerHasProperValuesMultipleSizes": {
 | 
							"InitContainerAndContainerHasProperValuesMultipleSizes": {
 | 
				
			||||||
			pod: &v1.Pod{
 | 
								pod: &v1.Pod{
 | 
				
			||||||
@@ -558,7 +548,6 @@ func TestGetHugePagesMountOptions(t *testing.T) {
 | 
				
			|||||||
			medium:         v1.StorageMediumHugePagesPrefix + "2Mi",
 | 
								medium:         v1.StorageMediumHugePagesPrefix + "2Mi",
 | 
				
			||||||
			shouldFail:     false,
 | 
								shouldFail:     false,
 | 
				
			||||||
			expectedResult: "pagesize=2Mi",
 | 
								expectedResult: "pagesize=2Mi",
 | 
				
			||||||
			enableHugePageStorageMediumSize: true,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		"MediumWithoutSizeMultipleSizes": {
 | 
							"MediumWithoutSizeMultipleSizes": {
 | 
				
			||||||
			pod: &v1.Pod{
 | 
								pod: &v1.Pod{
 | 
				
			||||||
@@ -621,7 +610,6 @@ func TestGetHugePagesMountOptions(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for testCaseName, testCase := range testCases {
 | 
						for testCaseName, testCase := range testCases {
 | 
				
			||||||
		t.Run(testCaseName, func(t *testing.T) {
 | 
							t.Run(testCaseName, func(t *testing.T) {
 | 
				
			||||||
			defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePageStorageMediumSize, testCase.enableHugePageStorageMediumSize)()
 | 
					 | 
				
			||||||
			value, err := getPageSizeMountOption(testCase.medium, testCase.pod)
 | 
								value, err := getPageSizeMountOption(testCase.medium, testCase.pod)
 | 
				
			||||||
			if testCase.shouldFail && err == nil {
 | 
								if testCase.shouldFail && err == nil {
 | 
				
			||||||
				t.Errorf("%s: Unexpected success", testCaseName)
 | 
									t.Errorf("%s: Unexpected success", testCaseName)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user