diff --git a/pkg/api/v1/backward_compatibility_test.go b/pkg/api/v1/backward_compatibility_test.go index 0bcfa3e31b6..c5b6f93607e 100644 --- a/pkg/api/v1/backward_compatibility_test.go +++ b/pkg/api/v1/backward_compatibility_test.go @@ -153,6 +153,68 @@ func TestCompatibility_v1_PodSecurityContext(t *testing.T) { "spec.hostPID", }, }, + { + name: "reseting defaults for pre-v1.1 mirror pods", + input: ` +{ + "kind":"Pod", + "apiVersion":"v1", + "metadata":{ + "name":"my-pod-name", + "namespace":"my-pod-namespace", + "annotations": { + "kubernetes.io/config.mirror": "mirror" + } + }, + "spec": { + "containers":[{ + "name":"a", + "image":"my-container-image", + "resources": { + "limits": { + "cpu": "100m" + } + } + }] + } +} +`, + absentKeys: []string{ + "spec.terminationGracePeriodSeconds", + "spec.containers[0].resources.requests", + }, + }, + { + name: "preserving defaults for v1.1+ mirror pods", + input: ` + { + "kind":"Pod", + "apiVersion":"v1", + "metadata":{ + "name":"my-pod-name", + "namespace":"my-pod-namespace", + "annotations": { + "kubernetes.io/config.mirror": "cbe924f710c7e26f7693d6a341bcfad0" + } + }, + "spec": { + "containers":[{ + "name":"a", + "image":"my-container-image", + "resources": { + "limits": { + "cpu": "100m" + } + } + }] + } + } + `, + expectedKeys: map[string]string{ + "spec.terminationGracePeriodSeconds": "30", + "spec.containers[0].resources.requests": "map[cpu:100m]", + }, + }, } validator := func(obj runtime.Object) fielderrors.ValidationErrorList { diff --git a/pkg/api/v1/conversion.go b/pkg/api/v1/conversion.go index 34faf94cd4e..ce4b440ec86 100644 --- a/pkg/api/v1/conversion.go +++ b/pkg/api/v1/conversion.go @@ -24,12 +24,22 @@ import ( "k8s.io/kubernetes/pkg/conversion" ) +const ( + // Annotation key used to identify mirror pods. + mirrorAnnotationKey = "kubernetes.io/config.mirror" + + // Value used to identify mirror pods from pre-v1.1 kubelet. + mirrorAnnotationValue_1_0 = "mirror" +) + func addConversionFuncs() { // Add non-generated conversion functions err := api.Scheme.AddConversionFuncs( + convert_api_Pod_To_v1_Pod, convert_api_PodSpec_To_v1_PodSpec, convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec, convert_api_ServiceSpec_To_v1_ServiceSpec, + convert_v1_Pod_To_api_Pod, convert_v1_PodSpec_To_api_PodSpec, convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec, convert_v1_ServiceSpec_To_api_ServiceSpec, @@ -386,9 +396,32 @@ func convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi } else { out.ImagePullSecrets = nil } + return nil } +func convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { + if err := autoconvert_api_Pod_To_v1_Pod(in, out, s); err != nil { + return err + } + // We need to reset certain fields for mirror pods from pre-v1.1 kubelet + // (#15960). + // TODO: Remove this code after we drop support for v1.0 kubelets. + if value, ok := in.Annotations[mirrorAnnotationKey]; ok && value == mirrorAnnotationValue_1_0 { + // Reset the TerminationGracePeriodSeconds. + out.Spec.TerminationGracePeriodSeconds = nil + // Reset the resource requests. + for i := range out.Spec.Containers { + out.Spec.Containers[i].Resources.Requests = nil + } + } + return nil +} + +func convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { + return autoconvert_v1_Pod_To_api_Pod(in, out, s) +} + func convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error { if err := autoconvert_api_ServiceSpec_To_v1_ServiceSpec(in, out, s); err != nil { return err diff --git a/pkg/api/v1/conversion_generated.go b/pkg/api/v1/conversion_generated.go index 1e92993c74b..2846a4a2b61 100644 --- a/pkg/api/v1/conversion_generated.go +++ b/pkg/api/v1/conversion_generated.go @@ -1887,10 +1887,6 @@ func autoconvert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) er return nil } -func convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error { - return autoconvert_api_Pod_To_v1_Pod(in, out, s) -} - func autoconvert_api_PodAttachOptions_To_v1_PodAttachOptions(in *api.PodAttachOptions, out *PodAttachOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*api.PodAttachOptions))(in) @@ -4912,10 +4908,6 @@ func autoconvert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) er return nil } -func convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error { - return autoconvert_v1_Pod_To_api_Pod(in, out, s) -} - func autoconvert_v1_PodAttachOptions_To_api_PodAttachOptions(in *PodAttachOptions, out *api.PodAttachOptions, s conversion.Scope) error { if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found { defaulting.(func(*PodAttachOptions))(in)