Add AllowSidecarResizePolicy to relax resize policy validation check of sidecar containers

This commit is contained in:
vivzbansal 2024-11-11 23:05:31 +00:00
parent f5d1fdf772
commit 95591abd02
3 changed files with 187 additions and 1 deletions

View File

@ -416,6 +416,8 @@ func GetValidationOptionsFromPodSpecAndMeta(podSpec, oldPodSpec *api.PodSpec, po
}
opts.AllowPodLifecycleSleepActionZeroValue = opts.AllowPodLifecycleSleepActionZeroValue || podLifecycleSleepActionZeroValueInUse(podSpec)
// If oldPod has resize policy set on the restartable init container, we must allow it
opts.AllowSidecarResizePolicy = hasRestartableInitContainerResizePolicy(oldPodSpec)
}
if oldPodMeta != nil && !opts.AllowInvalidPodDeletionCost {
// This is an update, so validate only if the existing object was valid.
@ -1373,3 +1375,17 @@ func useOnlyRecursiveSELinuxChangePolicy(oldPodSpec *api.PodSpec) bool {
// No feature gate + no value in the old object -> only Recursive is allowed
return true
}
// hasRestartableInitContainerResizePolicy returns true if the pod spec is non-nil and
// it has any init container with ContainerRestartPolicyAlways and non-nil ResizePolicy.
func hasRestartableInitContainerResizePolicy(podSpec *api.PodSpec) bool {
if podSpec == nil {
return false
}
for _, c := range podSpec.InitContainers {
if IsRestartableInitContainer(&c) && len(c.ResizePolicy) > 0 {
return true
}
}
return false
}

View File

@ -4036,3 +4036,171 @@ func TestDropSELinuxChangePolicy(t *testing.T) {
})
}
}
func TestValidateAllowSidecarResizePolicy(t *testing.T) {
restartPolicyAlways := api.ContainerRestartPolicyAlways
testCases := []struct {
name string
oldPodSpec *api.PodSpec
wantOption bool
}{
{
name: "old pod spec is nil",
wantOption: false,
},
{
name: "one sidecar container + one regular init container, no resize policy set on any of them",
oldPodSpec: &api.PodSpec{
InitContainers: []api.Container{
{
Name: "c1-restartable-init",
Image: "image",
RestartPolicy: &restartPolicyAlways,
},
{
Name: "c1-init",
Image: "image",
},
},
},
wantOption: false,
},
{
name: "one sidecar container + one regular init container, resize policy set on regular init container",
oldPodSpec: &api.PodSpec{
InitContainers: []api.Container{
{
Name: "c1-restartable-init",
Image: "image",
RestartPolicy: &restartPolicyAlways,
},
{
Name: "c1-init",
Image: "image",
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
},
},
wantOption: false,
},
{
name: "one sidecar container + one regular init container, resize policy set on sidecar container",
oldPodSpec: &api.PodSpec{
InitContainers: []api.Container{
{
Name: "c1-restartable-init",
Image: "image",
RestartPolicy: &restartPolicyAlways,
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
{
Name: "c1-init",
Image: "image",
},
},
},
wantOption: true,
},
{
name: "one sidecar container + one regular init container, resize policy set on both of them",
oldPodSpec: &api.PodSpec{
InitContainers: []api.Container{
{
Name: "c1-restartable-init",
Image: "image",
RestartPolicy: &restartPolicyAlways,
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
{
Name: "c1-init",
Image: "image",
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
},
},
wantOption: true,
},
{
name: "two sidecar containers, resize policy set on one of them",
oldPodSpec: &api.PodSpec{
InitContainers: []api.Container{
{
Name: "c1-restartable-init",
Image: "image",
RestartPolicy: &restartPolicyAlways,
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
{
Name: "c2-restartable-init",
Image: "image",
RestartPolicy: &restartPolicyAlways,
},
},
},
wantOption: true,
},
{
name: "two regular init containers, resize policy set on both of them",
oldPodSpec: &api.PodSpec{
InitContainers: []api.Container{
{
Name: "c1-init",
Image: "image",
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
{
Name: "c2-init",
Image: "image",
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
},
},
wantOption: false,
},
{
name: "two non-init containers, resize policy set on both of them",
oldPodSpec: &api.PodSpec{
Containers: []api.Container{
{
Name: "c1",
Image: "image",
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
{
Name: "c2",
Image: "image",
ResizePolicy: []api.ContainerResizePolicy{
{ResourceName: api.ResourceCPU, RestartPolicy: api.NotRequired},
},
},
},
},
wantOption: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
gotOptions := GetValidationOptionsFromPodSpecAndMeta(&api.PodSpec{}, tc.oldPodSpec, nil, nil)
if tc.wantOption != gotOptions.AllowSidecarResizePolicy {
t.Errorf("Got AllowSidecarResizePolicy=%t, want %t", gotOptions.AllowSidecarResizePolicy, tc.wantOption)
}
})
}
}

View File

@ -3543,7 +3543,7 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
}
}
if len(ctr.ResizePolicy) > 0 {
if !opts.AllowSidecarResizePolicy && len(ctr.ResizePolicy) > 0 {
allErrs = append(allErrs, field.Invalid(idxPath.Child("resizePolicy"), ctr.ResizePolicy, "must not be set for init containers"))
}
}
@ -4051,6 +4051,8 @@ type PodValidationOptions struct {
AllowOnlyRecursiveSELinuxChangePolicy bool
// Indicates whether PodLevelResources feature is enabled or disabled.
PodLevelResourcesEnabled bool
// Allow sidecar containers resize policy for backward compatibility
AllowSidecarResizePolicy bool
}
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,