Skip to content

Commit b2a0315

Browse files
authored
Merge pull request kubernetes#72184 from sbezverk/RuntimeClassName_field
RuntimeClassName - Update DropDisabled[Alpha]Fields behaviour
2 parents ae88c2d + 27a8967 commit b2a0315

File tree

3 files changed

+103
-5
lines changed

3 files changed

+103
-5
lines changed

pkg/api/pod/util.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,9 @@ func DropDisabledFields(podSpec, oldPodSpec *api.PodSpec) {
277277

278278
dropDisabledRunAsGroupField(podSpec, oldPodSpec)
279279

280-
if !utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) {
280+
if !utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) && !runtimeClassInUse(oldPodSpec) {
281+
// Set RuntimeClassName to nil only if feature is disabled and it is not used
281282
podSpec.RuntimeClassName = nil
282-
if oldPodSpec != nil {
283-
oldPodSpec.RuntimeClassName = nil
284-
}
285283
}
286284

287285
dropDisabledProcMountField(podSpec, oldPodSpec)
@@ -397,3 +395,14 @@ func subpathInUse(podSpec *api.PodSpec) bool {
397395
}
398396
return false
399397
}
398+
399+
// runtimeClassInUse returns true if the pod spec is non-nil and has a RuntimeClassName set
400+
func runtimeClassInUse(podSpec *api.PodSpec) bool {
401+
if podSpec == nil {
402+
return false
403+
}
404+
if podSpec.RuntimeClassName != nil {
405+
return true
406+
}
407+
return false
408+
}

pkg/api/pod/util_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,92 @@ func TestDropSubPath(t *testing.T) {
429429
}
430430
}
431431
}
432+
433+
func TestDropRuntimeClass(t *testing.T) {
434+
runtimeClassName := "some_container_engine"
435+
podWithoutRuntimeClass := func() *api.Pod {
436+
return &api.Pod{
437+
Spec: api.PodSpec{
438+
RuntimeClassName: nil,
439+
},
440+
}
441+
}
442+
podWithRuntimeClass := func() *api.Pod {
443+
return &api.Pod{
444+
Spec: api.PodSpec{
445+
RuntimeClassName: &runtimeClassName,
446+
},
447+
}
448+
}
449+
450+
podInfo := []struct {
451+
description string
452+
hasPodRuntimeClassName bool
453+
pod func() *api.Pod
454+
}{
455+
{
456+
description: "pod Without RuntimeClassName",
457+
hasPodRuntimeClassName: false,
458+
pod: podWithoutRuntimeClass,
459+
},
460+
{
461+
description: "pod With RuntimeClassName",
462+
hasPodRuntimeClassName: true,
463+
pod: podWithRuntimeClass,
464+
},
465+
{
466+
description: "is nil",
467+
hasPodRuntimeClassName: false,
468+
pod: func() *api.Pod { return nil },
469+
},
470+
}
471+
472+
for _, enabled := range []bool{true, false} {
473+
for _, oldPodInfo := range podInfo {
474+
for _, newPodInfo := range podInfo {
475+
oldPodHasRuntimeClassName, oldPod := oldPodInfo.hasPodRuntimeClassName, oldPodInfo.pod()
476+
newPodHasRuntimeClassName, newPod := newPodInfo.hasPodRuntimeClassName, newPodInfo.pod()
477+
if newPod == nil {
478+
continue
479+
}
480+
481+
t.Run(fmt.Sprintf("feature enabled=%v, old pod %v, new pod %v", enabled, oldPodInfo.description, newPodInfo.description), func(t *testing.T) {
482+
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RuntimeClass, enabled)()
483+
484+
var oldPodSpec *api.PodSpec
485+
if oldPod != nil {
486+
oldPodSpec = &oldPod.Spec
487+
}
488+
DropDisabledFields(&newPod.Spec, oldPodSpec)
489+
490+
// old pod should never be changed
491+
if !reflect.DeepEqual(oldPod, oldPodInfo.pod()) {
492+
t.Errorf("old pod changed: %v", diff.ObjectReflectDiff(oldPod, oldPodInfo.pod()))
493+
}
494+
495+
switch {
496+
case enabled || oldPodHasRuntimeClassName:
497+
// new pod should not be changed if the feature is enabled, or if the old pod had RuntimeClass
498+
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
499+
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodInfo.pod()))
500+
}
501+
case newPodHasRuntimeClassName:
502+
// new pod should be changed
503+
if reflect.DeepEqual(newPod, newPodInfo.pod()) {
504+
t.Errorf("new pod was not changed")
505+
}
506+
// new pod should not have RuntimeClass
507+
if !reflect.DeepEqual(newPod, podWithoutRuntimeClass()) {
508+
t.Errorf("new pod had PodRuntimeClassName: %v", diff.ObjectReflectDiff(newPod, podWithoutRuntimeClass()))
509+
}
510+
default:
511+
// new pod should not need to be changed
512+
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
513+
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodInfo.pod()))
514+
}
515+
}
516+
})
517+
}
518+
}
519+
}
520+
}

pkg/apis/core/validation/validation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3053,7 +3053,7 @@ func ValidatePodSpec(spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
30533053
}
30543054
}
30553055

3056-
if spec.RuntimeClassName != nil && utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) {
3056+
if spec.RuntimeClassName != nil {
30573057
allErrs = append(allErrs, ValidateRuntimeClassName(*spec.RuntimeClassName, fldPath.Child("runtimeClassName"))...)
30583058
}
30593059

0 commit comments

Comments
 (0)