pod terminationGracePeriodSeconds is always valid (#124461)
* Pod terminationGracePeriodSeconds is always valid Validation of a pod spec will always use the pod's TerminationGracePeriodSeconds value. A set of pod test-helpers have been created to help construct Pods. * remove unused func * reduction * reduce 2 * simplify test * report invalid grace period * update SupplementalGroupPolicy tests
This commit is contained in:
		
							
								
								
									
										293
									
								
								pkg/api/pod/testing/make.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										293
									
								
								pkg/api/pod/testing/make.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,293 @@ | ||||
| /* | ||||
| Copyright 2024 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package testing | ||||
|  | ||||
| import ( | ||||
| 	v1 "k8s.io/api/core/v1" | ||||
| 	"k8s.io/apimachinery/pkg/api/resource" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/utils/ptr" | ||||
| ) | ||||
|  | ||||
| // Tweak is a function that modifies a Pod. | ||||
| type Tweak func(*api.Pod) | ||||
| type TweakContainer func(*api.Container) | ||||
|  | ||||
| // MakePod helps construct Pod objects (which pass API validation) more | ||||
| // legibly and tersely than a Go struct definition.  By default this produces | ||||
| // a Pod with a single container, ctr.  The caller can pass any number of tweak | ||||
| // functions to further modify the result. | ||||
| func MakePod(name string, tweaks ...Tweak) *api.Pod { | ||||
| 	// NOTE: Any field that would be populated by defaulting needs to be | ||||
| 	// present and valid here. | ||||
| 	pod := &api.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      name, | ||||
| 			Namespace: metav1.NamespaceDefault, | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			Containers:                    []api.Container{MakeContainer("ctr")}, | ||||
| 			DNSPolicy:                     api.DNSClusterFirst, | ||||
| 			RestartPolicy:                 api.RestartPolicyAlways, | ||||
| 			TerminationGracePeriodSeconds: ptr.To[int64](v1.DefaultTerminationGracePeriodSeconds), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tweak := range tweaks { | ||||
| 		tweak(pod) | ||||
| 	} | ||||
|  | ||||
| 	return pod | ||||
| } | ||||
|  | ||||
| func MakePodSpec(policy api.RestartPolicy, tweaks ...Tweak) api.PodSpec { | ||||
| 	return MakePod("", append([]Tweak{SetRestartPolicy(policy)}, tweaks...)...).Spec | ||||
| } | ||||
|  | ||||
| func SetNamespace(ns string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Namespace = ns | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetResourceVersion(rv string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.ResourceVersion = rv | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetContainers(containers ...api.Container) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.Containers = containers | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetInitContainers(containers ...api.Container) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.InitContainers = containers | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetEphemeralContainers(containers ...api.EphemeralContainer) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.EphemeralContainers = containers | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetVolumes(volumes ...api.Volume) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.Volumes = volumes | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func MakeEmptyVolume(name string) api.Volume { | ||||
| 	return api.Volume{Name: name, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}} | ||||
| } | ||||
|  | ||||
| func SetNodeSelector(nodeSelector map[string]string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.NodeSelector = nodeSelector | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetNodeName(name string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.NodeName = name | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetActiveDeadlineSeconds(deadline int64) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.ActiveDeadlineSeconds = &deadline | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetServiceAccountName(name string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.ServiceAccountName = name | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetSecurityContext(ctx *api.PodSecurityContext) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.SecurityContext = ctx | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetAffinity(affinity *api.Affinity) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.Affinity = affinity | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetHostAliases(hostAliases ...api.HostAlias) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.HostAliases = hostAliases | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetPriorityClassName(name string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.PriorityClassName = name | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetRuntimeClassName(name string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.RuntimeClassName = &name | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetOverhead(overhead api.ResourceList) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.Overhead = overhead | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetDNSPolicy(policy api.DNSPolicy) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.DNSPolicy = policy | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetRestartPolicy(policy api.RestartPolicy) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.RestartPolicy = policy | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetTolerations(tolerations ...api.Toleration) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.Tolerations = tolerations | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetAnnotations(annos map[string]string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Annotations = annos | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetLabels(annos map[string]string) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Labels = annos | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetSchedulingGates(gates ...api.PodSchedulingGate) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.SchedulingGates = gates | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetTerminationGracePeriodSeconds(grace int64) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.TerminationGracePeriodSeconds = &grace | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetOS(name api.OSName) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.OS = &api.PodOS{Name: name} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetStatus(status api.PodStatus) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Status = status | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetResourceClaims(claims ...api.PodResourceClaim) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.ResourceClaims = claims | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetTopologySpreadConstraints(tsc ...api.TopologySpreadConstraint) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.Spec.TopologySpreadConstraints = tsc | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetObjectMeta(objectMeta metav1.ObjectMeta) Tweak { | ||||
| 	return func(pod *api.Pod) { | ||||
| 		pod.ObjectMeta = objectMeta | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func MakeContainer(name string, tweaks ...TweakContainer) api.Container { | ||||
| 	cnr := api.Container{ | ||||
| 		Name: name, Image: "image", ImagePullPolicy: "IfNotPresent", | ||||
| 		TerminationMessagePolicy: "File", | ||||
| 		TerminationMessagePath:   v1.TerminationMessagePathDefault, | ||||
| 	} | ||||
|  | ||||
| 	for _, tweak := range tweaks { | ||||
| 		tweak(&cnr) | ||||
| 	} | ||||
|  | ||||
| 	return cnr | ||||
| } | ||||
|  | ||||
| func SetContainerImage(image string) TweakContainer { | ||||
| 	return func(cnr *api.Container) { | ||||
| 		cnr.Image = image | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func MakeResourceRequirements(requests, limits map[string]string) api.ResourceRequirements { | ||||
| 	rr := api.ResourceRequirements{Requests: api.ResourceList{}, Limits: api.ResourceList{}} | ||||
| 	for k, v := range requests { | ||||
| 		rr.Requests[api.ResourceName(k)] = resource.MustParse(v) | ||||
| 	} | ||||
| 	for k, v := range limits { | ||||
| 		rr.Limits[api.ResourceName(k)] = resource.MustParse(v) | ||||
| 	} | ||||
| 	return rr | ||||
| } | ||||
|  | ||||
| func SetContainerResources(rr api.ResourceRequirements) TweakContainer { | ||||
| 	return func(cnr *api.Container) { | ||||
| 		cnr.Resources = rr | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetContainerPorts(ports ...api.ContainerPort) TweakContainer { | ||||
| 	return func(cnr *api.Container) { | ||||
| 		cnr.Ports = ports | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetContainerResizePolicy(policies ...api.ContainerResizePolicy) TweakContainer { | ||||
| 	return func(cnr *api.Container) { | ||||
| 		cnr.ResizePolicy = policies | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetContainerSecurityContext(ctx api.SecurityContext) TweakContainer { | ||||
| 	return func(cnr *api.Container) { | ||||
| 		cnr.SecurityContext = &ctx | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func SetContainerRestartPolicy(policy api.ContainerRestartPolicy) TweakContainer { | ||||
| 	return func(cnr *api.Container) { | ||||
| 		cnr.RestartPolicy = &policy | ||||
| 	} | ||||
| } | ||||
| @@ -34,6 +34,7 @@ import ( | ||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" | ||||
| 	"k8s.io/kubernetes/pkg/api/pod" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/apps" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	corevalidation "k8s.io/kubernetes/pkg/apis/core/validation" | ||||
| @@ -1503,29 +1504,15 @@ func TestValidateDaemonSetUpdate(t *testing.T) { | ||||
| 	validSelector2 := map[string]string{"c": "d"} | ||||
| 	invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} | ||||
|  | ||||
| 	validPodSpecAbc := api.PodSpec{ | ||||
| 		RestartPolicy: api.RestartPolicyAlways, | ||||
| 		DNSPolicy:     api.DNSClusterFirst, | ||||
| 		Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 	} | ||||
| 	validPodSpecDef := api.PodSpec{ | ||||
| 		RestartPolicy: api.RestartPolicyAlways, | ||||
| 		DNSPolicy:     api.DNSClusterFirst, | ||||
| 		Containers:    []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 	} | ||||
| 	validPodSpecNodeSelector := api.PodSpec{ | ||||
| 		NodeSelector:  validSelector, | ||||
| 		NodeName:      "xyz", | ||||
| 		RestartPolicy: api.RestartPolicyAlways, | ||||
| 		DNSPolicy:     api.DNSClusterFirst, | ||||
| 		Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 	} | ||||
| 	validPodSpecVolume := api.PodSpec{ | ||||
| 		Volumes:       []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, | ||||
| 		RestartPolicy: api.RestartPolicyAlways, | ||||
| 		DNSPolicy:     api.DNSClusterFirst, | ||||
| 		Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 	} | ||||
| 	validPodSpecAbc := podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 		podtest.SetContainers(podtest.MakeContainer("abc"))) | ||||
| 	validPodSpecDef := podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 		podtest.SetContainers(podtest.MakeContainer("def"))) | ||||
| 	validPodSpecNodeSelector := podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 		podtest.SetNodeSelector(validSelector), | ||||
| 		podtest.SetNodeName("xyz")) | ||||
| 	validPodSpecVolume := podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 		podtest.SetVolumes(api.Volume{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}})) | ||||
|  | ||||
| 	validPodTemplateAbc := api.PodTemplate{ | ||||
| 		Template: api.PodTemplateSpec{ | ||||
| @@ -1570,11 +1557,8 @@ func TestValidateDaemonSetUpdate(t *testing.T) { | ||||
| 	} | ||||
| 	invalidPodTemplate := api.PodTemplate{ | ||||
| 		Template: api.PodTemplateSpec{ | ||||
| 			Spec: api.PodSpec{ | ||||
| 			// no containers specified | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, podtest.SetContainers()), | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validSelector, | ||||
| 			}, | ||||
| @@ -1992,11 +1976,7 @@ func TestValidateDaemonSet(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validSelector, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 		}, | ||||
| 	} | ||||
| 	validHostNetPodTemplate := api.PodTemplate{ | ||||
| @@ -2004,35 +1984,22 @@ func TestValidateDaemonSet(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validSelector, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				SecurityContext: &api.PodSecurityContext{ | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 				podtest.SetSecurityContext(&api.PodSecurityContext{ | ||||
| 					HostNetwork: true, | ||||
| 				}, | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers: []api.Container{{ | ||||
| 					Name:                     "abc", | ||||
| 					Image:                    "image", | ||||
| 					ImagePullPolicy:          "IfNotPresent", | ||||
| 					TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 					Ports: []api.ContainerPort{{ | ||||
| 				}), | ||||
| 				podtest.SetContainers(podtest.MakeContainer("abc", | ||||
| 					podtest.SetContainerPorts(api.ContainerPort{ | ||||
| 						ContainerPort: 12345, | ||||
| 						Protocol:      api.ProtocolTCP, | ||||
| 					}}, | ||||
| 				}}, | ||||
| 			}, | ||||
| 					}))), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
| 	invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} | ||||
| 	invalidPodTemplate := api.PodTemplate{ | ||||
| 		Template: api.PodTemplateSpec{ | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 			}, | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: invalidSelector, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, podtest.SetLabels(invalidSelector)), | ||||
| 		}, | ||||
| 	} | ||||
| 	successCases := []apps.DaemonSet{{ | ||||
| @@ -2157,14 +2124,7 @@ func TestValidateDaemonSet(t *testing.T) { | ||||
| 			Spec: apps.DaemonSetSpec{ | ||||
| 				Selector: &metav1.LabelSelector{MatchLabels: validSelector}, | ||||
| 				Template: api.PodTemplateSpec{ | ||||
| 					Spec: api.PodSpec{ | ||||
| 						RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 						DNSPolicy:     api.DNSClusterFirst, | ||||
| 						Containers:    []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 					}, | ||||
| 					ObjectMeta: metav1.ObjectMeta{ | ||||
| 						Labels: validSelector, | ||||
| 					}, | ||||
| 					Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure, podtest.SetLabels(validSelector)), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| @@ -2176,14 +2136,7 @@ func TestValidateDaemonSet(t *testing.T) { | ||||
| 			Spec: apps.DaemonSetSpec{ | ||||
| 				Selector: &metav1.LabelSelector{MatchLabels: validSelector}, | ||||
| 				Template: api.PodTemplateSpec{ | ||||
| 					Spec: api.PodSpec{ | ||||
| 						RestartPolicy: api.RestartPolicyNever, | ||||
| 						DNSPolicy:     api.DNSClusterFirst, | ||||
| 						Containers:    []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 					}, | ||||
| 					ObjectMeta: metav1.ObjectMeta{ | ||||
| 						Labels: validSelector, | ||||
| 					}, | ||||
| 					Spec: podtest.MakePodSpec(api.RestartPolicyNever, podtest.SetLabels(validSelector)), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| @@ -2195,12 +2148,8 @@ func TestValidateDaemonSet(t *testing.T) { | ||||
| 					ObjectMeta: metav1.ObjectMeta{ | ||||
| 						Labels: validSelector, | ||||
| 					}, | ||||
| 					Spec: api.PodSpec{ | ||||
| 						RestartPolicy:       api.RestartPolicyAlways, | ||||
| 						DNSPolicy:           api.DNSClusterFirst, | ||||
| 						Containers:          []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						EphemeralContainers: []api.EphemeralContainer{{EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "debug", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}}, | ||||
| 					}, | ||||
| 					Spec: podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 						podtest.SetEphemeralContainers(api.EphemeralContainer{EphemeralContainerCommon: api.EphemeralContainerCommon{Name: "debug", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}})), | ||||
| 				}, | ||||
| 				UpdateStrategy: apps.DaemonSetUpdateStrategy{ | ||||
| 					Type: apps.OnDeleteDaemonSetStrategyType, | ||||
| @@ -2258,16 +2207,7 @@ func validDeployment(tweaks ...func(d *apps.Deployment)) *apps.Deployment { | ||||
| 						"name": "abc", | ||||
| 					}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{{ | ||||
| 						Name:                     "nginx", | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          api.PullNever, | ||||
| 						TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 					}}, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 			}, | ||||
| 			RollbackTo: &apps.RollbackConfig{ | ||||
| 				Revision: 1, | ||||
| @@ -2598,11 +2538,7 @@ func TestValidateDeploymentUpdate(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 		}, | ||||
| 	} | ||||
| 	readWriteVolumePodTemplate := api.PodTemplate{ | ||||
| @@ -2610,22 +2546,16 @@ func TestValidateDeploymentUpdate(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 				Volumes:       []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 				podtest.SetVolumes(api.Volume{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
| 	invalidLabels := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} | ||||
| 	invalidPodTemplate := api.PodTemplate{ | ||||
| 		Template: api.PodTemplateSpec{ | ||||
| 			Spec: api.PodSpec{ | ||||
| 			// no containers specified | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, podtest.SetContainers()), | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: invalidLabels, | ||||
| 			}, | ||||
| @@ -2922,11 +2852,7 @@ func TestValidateReplicaSetStatusUpdate(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 		}, | ||||
| 	} | ||||
| 	type rcUpdateTest struct { | ||||
| @@ -3004,11 +2930,7 @@ func TestValidateReplicaSetUpdate(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 		}, | ||||
| 	} | ||||
| 	readWriteVolumePodTemplate := api.PodTemplate{ | ||||
| @@ -3016,21 +2938,15 @@ func TestValidateReplicaSetUpdate(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 				Volumes:       []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 				podtest.SetVolumes(api.Volume{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
| 	invalidLabels := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} | ||||
| 	invalidPodTemplate := api.PodTemplate{ | ||||
| 		Template: api.PodTemplateSpec{ | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, podtest.SetContainers()), | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: invalidLabels, | ||||
| 			}, | ||||
| @@ -3180,11 +3096,7 @@ func TestValidateReplicaSet(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 		}, | ||||
| 	} | ||||
| 	validHostNetPodTemplate := api.PodTemplate{ | ||||
| @@ -3192,23 +3104,15 @@ func TestValidateReplicaSet(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				SecurityContext: &api.PodSecurityContext{ | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 				podtest.SetSecurityContext(&api.PodSecurityContext{ | ||||
| 					HostNetwork: true, | ||||
| 				}, | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers: []api.Container{{ | ||||
| 					Name:                     "abc", | ||||
| 					Image:                    "image", | ||||
| 					ImagePullPolicy:          "IfNotPresent", | ||||
| 					TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 					Ports: []api.ContainerPort{{ | ||||
| 				}), | ||||
| 				podtest.SetContainers(podtest.MakeContainer("abc", podtest.SetContainerPorts(api.ContainerPort{ | ||||
| 					ContainerPort: 12345, | ||||
| 					Protocol:      api.ProtocolTCP, | ||||
| 					}}, | ||||
| 				}}, | ||||
| 			}, | ||||
| 				}))), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
| 	readWriteVolumePodTemplate := api.PodTemplate{ | ||||
| @@ -3216,21 +3120,15 @@ func TestValidateReplicaSet(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validLabels, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				Volumes:       []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}}, | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 				podtest.SetVolumes(api.Volume{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
| 	invalidLabels := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"} | ||||
| 	invalidPodTemplate := api.PodTemplate{ | ||||
| 		Template: api.PodTemplateSpec{ | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: invalidLabels, | ||||
| 			}, | ||||
| @@ -3364,11 +3262,7 @@ func TestValidateReplicaSet(t *testing.T) { | ||||
| 			Spec: apps.ReplicaSetSpec{ | ||||
| 				Selector: &metav1.LabelSelector{MatchLabels: validLabels}, | ||||
| 				Template: api.PodTemplateSpec{ | ||||
| 					Spec: api.PodSpec{ | ||||
| 						RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 						DNSPolicy:     api.DNSClusterFirst, | ||||
| 						Containers:    []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 					}, | ||||
| 					Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					ObjectMeta: metav1.ObjectMeta{ | ||||
| 						Labels: validLabels, | ||||
| 					}, | ||||
| @@ -3383,11 +3277,7 @@ func TestValidateReplicaSet(t *testing.T) { | ||||
| 			Spec: apps.ReplicaSetSpec{ | ||||
| 				Selector: &metav1.LabelSelector{MatchLabels: validLabels}, | ||||
| 				Template: api.PodTemplateSpec{ | ||||
| 					Spec: api.PodSpec{ | ||||
| 						RestartPolicy: api.RestartPolicyNever, | ||||
| 						DNSPolicy:     api.DNSClusterFirst, | ||||
| 						Containers:    []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 					}, | ||||
| 					Spec: podtest.MakePodSpec(api.RestartPolicyNever), | ||||
| 					ObjectMeta: metav1.ObjectMeta{ | ||||
| 						Labels: validLabels, | ||||
| 					}, | ||||
|   | ||||
| @@ -30,6 +30,7 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/batch" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	corevalidation "k8s.io/kubernetes/pkg/apis/core/validation" | ||||
| @@ -61,11 +62,7 @@ func getValidPodTemplateSpecForManual(selector *metav1.LabelSelector) api.PodTem | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Labels: selector.MatchLabels, | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 			DNSPolicy:     api.DNSClusterFirst, | ||||
| 			Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 		}, | ||||
| 		Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -80,12 +77,8 @@ func getValidPodTemplateSpecForGenerated(selector *metav1.LabelSelector) api.Pod | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Labels: selector.MatchLabels, | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy:  api.RestartPolicyOnFailure, | ||||
| 			DNSPolicy:      api.DNSClusterFirst, | ||||
| 			Containers:     []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			InitContainers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 		}, | ||||
| 		Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure, | ||||
| 			podtest.SetInitContainers(podtest.MakeContainer("def"))), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -165,7 +158,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						}, { | ||||
| 							Action: batch.PodFailurePolicyActionCount, | ||||
| 							OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ | ||||
| 								ContainerName: pointer.String("abc"), | ||||
| 								ContainerName: pointer.String("ctr"), | ||||
| 								Operator:      batch.PodFailurePolicyOnExitCodesOpIn, | ||||
| 								Values:        []int32{1, 2, 3}, | ||||
| 							}, | ||||
| @@ -395,12 +388,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{batch.LegacyControllerUidLabel: "1a2b3c", batch.LegacyJobNameLabel: "myjob"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy:  api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:      api.DNSClusterFirst, | ||||
| 							Containers:     []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							InitContainers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -819,7 +807,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						Rules: []batch.PodFailurePolicyRule{{ | ||||
| 							Action: batch.PodFailurePolicyActionFailJob, | ||||
| 							OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ | ||||
| 								ContainerName: pointer.String("abc"), | ||||
| 								ContainerName: pointer.String("ctr"), | ||||
| 								Operator:      batch.PodFailurePolicyOnExitCodesOpIn, | ||||
| 								Values:        []int32{1, 2, 3}, | ||||
| 							}, | ||||
| @@ -862,7 +850,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						Rules: []batch.PodFailurePolicyRule{{ | ||||
| 							Action: batch.PodFailurePolicyActionIgnore, | ||||
| 							OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ | ||||
| 								ContainerName: pointer.String("abc"), | ||||
| 								ContainerName: pointer.String("ctr"), | ||||
| 								Operator:      batch.PodFailurePolicyOnExitCodesOpIn, | ||||
| 								Values:        []int32{1, 2, 3}, | ||||
| 							}, | ||||
| @@ -889,7 +877,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						Rules: []batch.PodFailurePolicyRule{{ | ||||
| 							Action: "UnknownAction", | ||||
| 							OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ | ||||
| 								ContainerName: pointer.String("abc"), | ||||
| 								ContainerName: pointer.String("ctr"), | ||||
| 								Operator:      batch.PodFailurePolicyOnExitCodesOpIn, | ||||
| 								Values:        []int32{1, 2, 3}, | ||||
| 							}, | ||||
| @@ -1033,11 +1021,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: validGeneratedSelector.MatchLabels, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 					PodFailurePolicy: &batch.PodFailurePolicy{ | ||||
| 						Rules: []batch.PodFailurePolicyRule{}, | ||||
| @@ -1251,11 +1235,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{"y": "z"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1275,11 +1255,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{"controller-uid": "4d5e6f"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1299,11 +1275,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: validManualSelector.MatchLabels, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyAlways, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1323,11 +1295,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: validManualSelector.MatchLabels, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: "Invalid", | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec("Invalid"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1395,12 +1363,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{batch.LegacyJobNameLabel: "myjob"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy:  api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:      api.DNSClusterFirst, | ||||
| 							Containers:     []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							InitContainers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1420,12 +1383,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{batch.LegacyJobNameLabel: "myjob"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy:  api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:      api.DNSClusterFirst, | ||||
| 							Containers:     []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							InitContainers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1462,12 +1420,7 @@ func TestValidateJob(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{batch.JobNameLabel: "myjob", batch.LegacyControllerUidLabel: "1a2b3c", batch.LegacyJobNameLabel: "myjob"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy:  api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:      api.DNSClusterFirst, | ||||
| 							Containers:     []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							InitContainers: []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -2882,11 +2835,7 @@ func TestValidateCronJob(t *testing.T) { | ||||
| 				JobTemplate: batch.JobTemplateSpec{ | ||||
| 					Spec: batch.JobSpec{ | ||||
| 						Template: api.PodTemplateSpec{ | ||||
| 							Spec: api.PodSpec{ | ||||
| 								RestartPolicy: api.RestartPolicyAlways, | ||||
| 								DNSPolicy:     api.DNSClusterFirst, | ||||
| 								Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							}, | ||||
| 							Spec: podtest.MakePodSpec(api.RestartPolicyAlways), | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| @@ -2904,11 +2853,7 @@ func TestValidateCronJob(t *testing.T) { | ||||
| 				JobTemplate: batch.JobTemplateSpec{ | ||||
| 					Spec: batch.JobSpec{ | ||||
| 						Template: api.PodTemplateSpec{ | ||||
| 							Spec: api.PodSpec{ | ||||
| 								RestartPolicy: "Invalid", | ||||
| 								DNSPolicy:     api.DNSClusterFirst, | ||||
| 								Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							}, | ||||
| 							Spec: podtest.MakePodSpec("Invalid"), | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
|   | ||||
| @@ -3039,7 +3039,7 @@ func validatePodResourceClaim(podMeta *metav1.ObjectMeta, claim core.PodResource | ||||
| 	return allErrs | ||||
| } | ||||
|  | ||||
| func validateLivenessProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList { | ||||
| func validateLivenessProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	if probe == nil { | ||||
| @@ -3052,7 +3052,7 @@ func validateLivenessProbe(probe *core.Probe, gracePeriod int64, fldPath *field. | ||||
| 	return allErrs | ||||
| } | ||||
|  | ||||
| func validateReadinessProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList { | ||||
| func validateReadinessProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	if probe == nil { | ||||
| @@ -3065,7 +3065,7 @@ func validateReadinessProbe(probe *core.Probe, gracePeriod int64, fldPath *field | ||||
| 	return allErrs | ||||
| } | ||||
|  | ||||
| func validateStartupProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList { | ||||
| func validateStartupProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	if probe == nil { | ||||
| @@ -3078,7 +3078,7 @@ func validateStartupProbe(probe *core.Probe, gracePeriod int64, fldPath *field.P | ||||
| 	return allErrs | ||||
| } | ||||
|  | ||||
| func validateProbe(probe *core.Probe, gracePeriod int64, fldPath *field.Path) field.ErrorList { | ||||
| func validateProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	if probe == nil { | ||||
| @@ -3140,10 +3140,10 @@ func handlerFromLifecycle(lh *core.LifecycleHandler) commonHandler { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func validateSleepAction(sleep *core.SleepAction, gracePeriod int64, fldPath *field.Path) field.ErrorList { | ||||
| func validateSleepAction(sleep *core.SleepAction, gracePeriod *int64, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrors := field.ErrorList{} | ||||
| 	if sleep.Seconds <= 0 || sleep.Seconds > gracePeriod { | ||||
| 		invalidStr := fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d)", gracePeriod) | ||||
| 	if gracePeriod != nil && sleep.Seconds <= 0 || sleep.Seconds > *gracePeriod { | ||||
| 		invalidStr := fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d)", *gracePeriod) | ||||
| 		allErrors = append(allErrors, field.Invalid(fldPath, sleep.Seconds, invalidStr)) | ||||
| 	} | ||||
| 	return allErrors | ||||
| @@ -3257,7 +3257,7 @@ func validateTCPSocketAction(tcp *core.TCPSocketAction, fldPath *field.Path) fie | ||||
| func validateGRPCAction(grpc *core.GRPCAction, fldPath *field.Path) field.ErrorList { | ||||
| 	return ValidatePortNumOrName(intstr.FromInt32(grpc.Port), fldPath.Child("port")) | ||||
| } | ||||
| func validateHandler(handler commonHandler, gracePeriod int64, fldPath *field.Path) field.ErrorList { | ||||
| func validateHandler(handler commonHandler, gracePeriod *int64, fldPath *field.Path) field.ErrorList { | ||||
| 	numHandlers := 0 | ||||
| 	allErrors := field.ErrorList{} | ||||
| 	if handler.Exec != nil { | ||||
| @@ -3306,7 +3306,7 @@ func validateHandler(handler commonHandler, gracePeriod int64, fldPath *field.Pa | ||||
| 	return allErrors | ||||
| } | ||||
|  | ||||
| func validateLifecycle(lifecycle *core.Lifecycle, gracePeriod int64, fldPath *field.Path) field.ErrorList { | ||||
| func validateLifecycle(lifecycle *core.Lifecycle, gracePeriod *int64, fldPath *field.Path) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
| 	if lifecycle.PostStart != nil { | ||||
| 		allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PostStart), gracePeriod, fldPath.Child("postStart"))...) | ||||
| @@ -3457,7 +3457,7 @@ func validateFieldAllowList(value interface{}, allowedFields map[string]bool, er | ||||
| } | ||||
|  | ||||
| // validateInitContainers is called by pod spec and template validation to validate the list of init containers | ||||
| func validateInitContainers(containers []core.Container, regularContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList { | ||||
| func validateInitContainers(containers []core.Container, regularContainers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList { | ||||
| 	var allErrs field.ErrorList | ||||
|  | ||||
| 	allNames := sets.Set[string]{} | ||||
| @@ -3595,7 +3595,7 @@ func validateHostUsers(spec *core.PodSpec, fldPath *field.Path) field.ErrorList | ||||
| } | ||||
|  | ||||
| // validateContainers is called by pod spec and template validation to validate the list of regular containers. | ||||
| func validateContainers(containers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList { | ||||
| func validateContainers(containers []core.Container, volumes map[string]core.VolumeSource, podClaimNames sets.Set[string], gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions, podRestartPolicy *core.RestartPolicy, hostUsers bool) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	if len(containers) == 0 { | ||||
| @@ -4145,11 +4145,10 @@ func validateHostIPs(pod *core.Pod) field.ErrorList { | ||||
| func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { | ||||
| 	allErrs := field.ErrorList{} | ||||
|  | ||||
| 	var gracePeriod int64 | ||||
| 	if spec.TerminationGracePeriodSeconds != nil { | ||||
| 		// this could happen in tests | ||||
| 		gracePeriod = *spec.TerminationGracePeriodSeconds | ||||
| 	if spec.TerminationGracePeriodSeconds == nil { | ||||
| 		allErrs = append(allErrs, field.Required(fldPath.Child("terminationGracePeriodSeconds"), "")) | ||||
| 	} | ||||
| 	gracePeriod := spec.TerminationGracePeriodSeconds | ||||
|  | ||||
| 	// The default for hostUsers is true, so a spec with no SecurityContext or no HostUsers field will be true. | ||||
| 	// If the default ever changes, this condition will need to be changed. | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -29,6 +29,7 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	clientscheme "k8s.io/client-go/kubernetes/scheme" | ||||
| 	"k8s.io/kubernetes/pkg/api/legacyscheme" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/apis/core/validation" | ||||
| 	"k8s.io/kubernetes/pkg/securitycontext" | ||||
| @@ -290,7 +291,7 @@ func TestStaticPodNameGenerate(t *testing.T) { | ||||
| 	} | ||||
| 	for _, c := range testCases { | ||||
| 		assert.Equal(t, c.expected, generatePodName(c.podName, c.nodeName), "wrong pod name generated") | ||||
| 		pod := &core.Pod{} | ||||
| 		pod := podtest.MakePod("") | ||||
| 		pod.Name = c.podName | ||||
| 		if c.overwrite != "" { | ||||
| 			pod.Name = c.overwrite | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/registry/generic" | ||||
| 	genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/apps" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/registry/registrytest" | ||||
| @@ -62,18 +63,7 @@ func newValidDaemonSet() *apps.DaemonSet { | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: map[string]string{"a": "b"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "test", | ||||
| 							Image:                    "test_image", | ||||
| 							ImagePullPolicy:          api.PullIfNotPresent, | ||||
| 							TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 						}, | ||||
| 					}, | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSClusterFirst, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePod("").Spec, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -23,6 +23,7 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/apps" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| ) | ||||
| @@ -138,11 +139,7 @@ func newDaemonSetWithSelectorLabels(selectorLabels map[string]string, templateGe | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: selectorLabels, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSClusterFirst, | ||||
| 					Containers:    []api.Container{{Name: fakeImageName, Image: fakeImage, ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePod("").Spec, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -39,6 +39,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	storeerr "k8s.io/apiserver/pkg/storage/errors" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/apps" | ||||
| 	"k8s.io/kubernetes/pkg/apis/autoscaling" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| @@ -79,18 +80,7 @@ func validNewDeployment() *apps.Deployment { | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: map[string]string{"a": "b"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "test", | ||||
| 							Image:                    "test_image", | ||||
| 							ImagePullPolicy:          api.PullIfNotPresent, | ||||
| 							TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 						}, | ||||
| 					}, | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSClusterFirst, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePod("").Spec, | ||||
| 			}, | ||||
| 			Replicas: 7, | ||||
| 		}, | ||||
|   | ||||
| @@ -26,13 +26,12 @@ import ( | ||||
| 	"k8s.io/apimachinery/pkg/util/intstr" | ||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/apps" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	fakeImageName  = "fake-name" | ||||
| 	fakeImage      = "fakeimage" | ||||
| 	deploymentName = "test-deployment" | ||||
| 	namespace      = "test-namespace" | ||||
| ) | ||||
| @@ -175,11 +174,7 @@ func newDeploymentWithSelectorLabels(selectorLabels map[string]string) *apps.Dep | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: selectorLabels, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers:    []api.Container{{Name: fakeImageName, Image: fakeImage, ImagePullPolicy: api.PullNever, TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePod("").Spec, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| @@ -210,15 +205,9 @@ func newDeploymentWithHugePageValue(resourceName api.ResourceName, value resourc | ||||
| 					Name:      "foo", | ||||
| 					Labels:    map[string]string{"foo": "bar"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{{ | ||||
| 						Name:                     fakeImageName, | ||||
| 						Image:                    fakeImage, | ||||
| 						ImagePullPolicy:          api.PullNever, | ||||
| 						TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 						Resources: api.ResourceRequirements{ | ||||
| 				Spec: podtest.MakePodSpec(api.RestartPolicyAlways, | ||||
| 					podtest.SetContainers(podtest.MakeContainer("ctr", podtest.SetContainerResources( | ||||
| 						api.ResourceRequirements{ | ||||
| 							Requests: api.ResourceList{ | ||||
| 								api.ResourceName(api.ResourceCPU): resource.MustParse("10"), | ||||
| 								api.ResourceName(resourceName):    value, | ||||
| @@ -227,8 +216,8 @@ func newDeploymentWithHugePageValue(resourceName api.ResourceName, value resourc | ||||
| 								api.ResourceName(api.ResourceCPU): resource.MustParse("10"), | ||||
| 								api.ResourceName(resourceName):    value, | ||||
| 							}, | ||||
| 						}}, | ||||
| 					}}, | ||||
| 						}))), | ||||
| 				), | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import ( | ||||
| 	genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/apps" | ||||
| 	"k8s.io/kubernetes/pkg/apis/autoscaling" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| @@ -75,18 +76,7 @@ func validNewReplicaSet() *apps.ReplicaSet { | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: map[string]string{"a": "b"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "test", | ||||
| 							Image:                    "test_image", | ||||
| 							ImagePullPolicy:          api.PullIfNotPresent, | ||||
| 							TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 						}, | ||||
| 					}, | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSClusterFirst, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePod("").Spec, | ||||
| 			}, | ||||
| 			Replicas: 7, | ||||
| 		}, | ||||
|   | ||||
| @@ -23,6 +23,7 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/util/validation/field" | ||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/apps" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| ) | ||||
| @@ -49,11 +50,7 @@ func TestReplicaSetStrategy(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validSelector, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePod("").Spec, | ||||
| 		}, | ||||
| 	} | ||||
| 	rs := &apps.ReplicaSet{ | ||||
| @@ -218,11 +215,7 @@ func newReplicaSetWithSelectorLabels(selectorLabels map[string]string) *apps.Rep | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: selectorLabels, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSClusterFirst, | ||||
| 					Containers:    []api.Container{{Name: fakeImageName, Image: fakeImage, ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePod("").Spec, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/registry/generic" | ||||
| 	genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/batch" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/registry/registrytest" | ||||
| @@ -59,15 +60,7 @@ func validNewCronJob() *batch.CronJob { | ||||
| 			JobTemplate: batch.JobTemplateSpec{ | ||||
| 				Spec: batch.JobSpec{ | ||||
| 					Template: api.PodTemplateSpec{ | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers: []api.Container{{ | ||||
| 								Name: "abc", Image: "image", | ||||
| 								ImagePullPolicy:          api.PullIfNotPresent, | ||||
| 								TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 							}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -85,9 +78,15 @@ func TestCreate(t *testing.T) { | ||||
| 	test.TestCreate( | ||||
| 		// valid | ||||
| 		validCronJob, | ||||
| 		// invalid (empty spec) | ||||
| 		// invalid (no containers) | ||||
| 		&batch.CronJob{ | ||||
| 			Spec: batch.CronJobSpec{}, | ||||
| 			Spec: batch.CronJobSpec{ | ||||
| 				JobTemplate: batch.JobTemplateSpec{ | ||||
| 					Spec: batch.JobSpec{ | ||||
| 						Template: api.PodTemplateSpec{}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,7 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/batch" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/utils/ptr" | ||||
| @@ -29,11 +30,7 @@ import ( | ||||
|  | ||||
| var ( | ||||
| 	validPodTemplateSpec = api.PodTemplateSpec{ | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 			DNSPolicy:     api.DNSClusterFirst, | ||||
| 			Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 		}, | ||||
| 		Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 	} | ||||
| 	validCronjobSpec = batch.CronJobSpec{ | ||||
| 		Schedule:          "5 5 * * ?", | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	"k8s.io/apiserver/pkg/warning" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/batch" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/registry/registrytest" | ||||
| @@ -73,18 +74,7 @@ func validNewJob() *batch.Job { | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: map[string]string{"a": "b"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "test", | ||||
| 							Image:                    "test_image", | ||||
| 							ImagePullPolicy:          api.PullIfNotPresent, | ||||
| 							TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 						}, | ||||
| 					}, | ||||
| 					RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 					DNSPolicy:     api.DNSClusterFirst, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -30,6 +30,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	apitesting "k8s.io/kubernetes/pkg/api/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/batch" | ||||
| 	_ "k8s.io/kubernetes/pkg/apis/batch/install" | ||||
| @@ -1020,11 +1021,7 @@ func TestJobStrategy_ValidateUpdate(t *testing.T) { | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Labels: validSelector.MatchLabels, | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 			DNSPolicy:     api.DNSClusterFirst, | ||||
| 			Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 		}, | ||||
| 		Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 	} | ||||
| 	validPodTemplateSpecNever := *validPodTemplateSpec.DeepCopy() | ||||
| 	validPodTemplateSpecNever.Spec.RestartPolicy = api.RestartPolicyNever | ||||
| @@ -1226,11 +1223,7 @@ func TestJobStrategy_ValidateUpdate(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{batch.LegacyJobNameLabel: "myjob", batch.LegacyControllerUidLabel: "test"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1256,11 +1249,7 @@ func TestJobStrategy_ValidateUpdate(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: map[string]string{batch.LegacyJobNameLabel: "myjob", batch.JobNameLabel: "myjob", batch.LegacyControllerUidLabel: "test", batch.ControllerUidLabel: "test"}, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1326,11 +1315,7 @@ func TestJobStrategy_WarningsOnUpdate(t *testing.T) { | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Labels: validSelector.MatchLabels, | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 			DNSPolicy:     api.DNSClusterFirst, | ||||
| 			Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 		}, | ||||
| 		Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 	} | ||||
| 	cases := map[string]struct { | ||||
| 		oldJob            *batch.Job | ||||
| @@ -1485,11 +1470,7 @@ func TestJobStrategy_WarningsOnCreate(t *testing.T) { | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Labels: validSelector.MatchLabels, | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 			DNSPolicy:     api.DNSClusterFirst, | ||||
| 			Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 		}, | ||||
| 		Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure), | ||||
| 	} | ||||
| 	validSpec := batch.JobSpec{ | ||||
| 		CompletionMode: completionModePtr(batch.NonIndexedCompletion), | ||||
| @@ -1556,13 +1537,8 @@ func TestJobStrategy_Validate(t *testing.T) { | ||||
| 	batchLabels := getValidBatchLabels() | ||||
| 	labelsWithNonBatch := getValidBatchLabelsWithNonBatch() | ||||
| 	defaultSelector := &metav1.LabelSelector{MatchLabels: map[string]string{batch.ControllerUidLabel: string(theUID)}} | ||||
| 	validPodSpec := api.PodSpec{ | ||||
| 		RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 		DNSPolicy:     api.DNSClusterFirst, | ||||
| 		Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 	} | ||||
| 	validPodSpecNever := *validPodSpec.DeepCopy() | ||||
| 	validPodSpecNever.RestartPolicy = api.RestartPolicyNever | ||||
| 	validPodSpec := podtest.MakePodSpec(api.RestartPolicyOnFailure) | ||||
| 	validPodSpecNever := podtest.MakePodSpec(api.RestartPolicyNever) | ||||
| 	validObjectMeta := getValidObjectMeta(0) | ||||
| 	testcases := map[string]struct { | ||||
| 		enableJobPodFailurePolicy     bool | ||||
| @@ -1745,12 +1721,8 @@ func TestJobStrategy_Validate(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: labelsWithNonBatch, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							Volumes:       []api.Volume{{Name: "volume-name"}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure, | ||||
| 							podtest.SetVolumes(api.Volume{Name: "volume-name"})), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| @@ -1763,12 +1735,8 @@ func TestJobStrategy_Validate(t *testing.T) { | ||||
| 						ObjectMeta: metav1.ObjectMeta{ | ||||
| 							Labels: labelsWithNonBatch, | ||||
| 						}, | ||||
| 						Spec: api.PodSpec{ | ||||
| 							RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 							DNSPolicy:     api.DNSClusterFirst, | ||||
| 							Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 							Volumes:       []api.Volume{{Name: "volume-name"}}, | ||||
| 						}, | ||||
| 						Spec: podtest.MakePodSpec(api.RestartPolicyOnFailure, | ||||
| 							podtest.SetVolumes(api.Volume{Name: "volume-name"})), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
|   | ||||
| @@ -42,6 +42,7 @@ import ( | ||||
| 	apiserverstorage "k8s.io/apiserver/pkg/storage" | ||||
| 	storeerr "k8s.io/apiserver/pkg/storage/errors" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/registry/registrytest" | ||||
| 	"k8s.io/kubernetes/pkg/securitycontext" | ||||
| @@ -63,34 +64,18 @@ func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *etcd3testing.E | ||||
| } | ||||
|  | ||||
| func validNewPod() *api.Pod { | ||||
| 	grace := int64(30) | ||||
| 	enableServiceLinks := v1.DefaultEnableServiceLinks | ||||
| 	return &api.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Name:      "foo", | ||||
| 			Namespace: metav1.NamespaceDefault, | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyAlways, | ||||
| 			DNSPolicy:     api.DNSClusterFirst, | ||||
|  | ||||
| 			TerminationGracePeriodSeconds: &grace, | ||||
| 			Containers: []api.Container{ | ||||
| 				{ | ||||
| 					Name:            "foo", | ||||
| 					Image:           "test", | ||||
| 					ImagePullPolicy: api.PullAlways, | ||||
| 	pod := podtest.MakePod("foo", | ||||
| 		podtest.SetContainers(podtest.MakeContainer("foo", | ||||
| 			podtest.SetContainerSecurityContext(*securitycontext.ValidInternalSecurityContextWithContainerDefaults()))), | ||||
| 		podtest.SetSecurityContext(&api.PodSecurityContext{}), | ||||
| 	) | ||||
| 	pod.Spec.SchedulerName = v1.DefaultSchedulerName | ||||
| 	pod.Spec.EnableServiceLinks = &enableServiceLinks | ||||
| 	pod.Spec.Containers[0].TerminationMessagePath = api.TerminationMessagePathDefault | ||||
|  | ||||
| 					TerminationMessagePath:   api.TerminationMessagePathDefault, | ||||
| 					TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 					SecurityContext:          securitycontext.ValidInternalSecurityContextWithContainerDefaults(), | ||||
| 				}, | ||||
| 			}, | ||||
| 			SecurityContext:    &api.PodSecurityContext{}, | ||||
| 			SchedulerName:      v1.DefaultSchedulerName, | ||||
| 			EnableServiceLinks: &enableServiceLinks, | ||||
| 		}, | ||||
| 	} | ||||
| 	return pod | ||||
| } | ||||
|  | ||||
| func validChangedPod() *api.Pod { | ||||
|   | ||||
| @@ -43,6 +43,7 @@ import ( | ||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" | ||||
| 	ptr "k8s.io/utils/ptr" | ||||
|  | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	apitesting "k8s.io/kubernetes/pkg/api/testing" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/features" | ||||
| @@ -827,21 +828,13 @@ func TestPodIndexFunc(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func newPodWithHugePageValue(resourceName api.ResourceName, value resource.Quantity) *api.Pod { | ||||
| 	return &api.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 	return podtest.MakePod("", podtest.SetObjectMeta(metav1.ObjectMeta{ | ||||
| 		Namespace:       "default", | ||||
| 		Name:            "foo", | ||||
| 		ResourceVersion: "1", | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyAlways, | ||||
| 			DNSPolicy:     api.DNSDefault, | ||||
| 			Containers: []api.Container{{ | ||||
| 				Name:                     "foo", | ||||
| 				Image:                    "image", | ||||
| 				ImagePullPolicy:          "IfNotPresent", | ||||
| 				TerminationMessagePolicy: "File", | ||||
| 				Resources: api.ResourceRequirements{ | ||||
| 	}), | ||||
| 		podtest.SetContainers(podtest.MakeContainer("foo", | ||||
| 			podtest.SetContainerResources(api.ResourceRequirements{ | ||||
| 				Requests: api.ResourceList{ | ||||
| 					api.ResourceCPU: resource.MustParse("10"), | ||||
| 					resourceName:    value, | ||||
| @@ -850,10 +843,9 @@ func newPodWithHugePageValue(resourceName api.ResourceName, value resource.Quant | ||||
| 					api.ResourceCPU: resource.MustParse("10"), | ||||
| 					resourceName:    value, | ||||
| 				}, | ||||
| 				}}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 			}), | ||||
| 		)), | ||||
| 	) | ||||
| } | ||||
|  | ||||
| func TestPodStrategyValidate(t *testing.T) { | ||||
| @@ -871,90 +863,48 @@ func TestPodStrategyValidate(t *testing.T) { | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "a new pod setting init-container with indivisible hugepages values", | ||||
| 			pod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Namespace: "default", | ||||
| 					Name:      "foo", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					InitContainers: []api.Container{{ | ||||
| 						Name:                     containerName, | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 						Resources: api.ResourceRequirements{ | ||||
| 			pod: podtest.MakePod("foo", | ||||
| 				podtest.SetInitContainers(podtest.MakeContainer(containerName, podtest.SetContainerResources( | ||||
| 					api.ResourceRequirements{ | ||||
| 						Requests: api.ResourceList{ | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "64Ki"): resource.MustParse("127Ki"), | ||||
| 						}, | ||||
| 						Limits: api.ResourceList{ | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "64Ki"): resource.MustParse("127Ki"), | ||||
| 						}, | ||||
| 						}}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 					}))), | ||||
| 			), | ||||
| 			wantErr: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "a new pod setting init-container with indivisible hugepages values while container with divisible hugepages values", | ||||
| 			pod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Namespace: "default", | ||||
| 					Name:      "foo", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					InitContainers: []api.Container{{ | ||||
| 						Name:                     containerName, | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 						Resources: api.ResourceRequirements{ | ||||
| 			pod: podtest.MakePod("foo", | ||||
| 				podtest.SetInitContainers(podtest.MakeContainer(containerName, podtest.SetContainerResources( | ||||
| 					api.ResourceRequirements{ | ||||
| 						Requests: api.ResourceList{ | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("5.1Mi"), | ||||
| 						}, | ||||
| 						Limits: api.ResourceList{ | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("5.1Mi"), | ||||
| 						}, | ||||
| 						}}, | ||||
| 					}, | ||||
| 					Containers: []api.Container{{ | ||||
| 						Name:                     containerName, | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 						Resources: api.ResourceRequirements{ | ||||
| 					}))), | ||||
| 				podtest.SetContainers(podtest.MakeContainer(containerName, podtest.SetContainerResources( | ||||
| 					api.ResourceRequirements{ | ||||
| 						Requests: api.ResourceList{ | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "1Gi"): resource.MustParse("2Gi"), | ||||
| 						}, | ||||
| 						Limits: api.ResourceList{ | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "1Gi"): resource.MustParse("2Gi"), | ||||
| 						}, | ||||
| 						}}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 					}))), | ||||
| 			), | ||||
| 			wantErr: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "a new pod setting container with divisible hugepages values", | ||||
| 			pod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Namespace: "default", | ||||
| 					Name:      "foo", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{{ | ||||
| 						Name:                     containerName, | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 						Resources: api.ResourceRequirements{ | ||||
| 			pod: podtest.MakePod("foo", | ||||
| 				podtest.SetContainers(podtest.MakeContainer(containerName, podtest.SetContainerResources( | ||||
| 					api.ResourceRequirements{ | ||||
| 						Requests: api.ResourceList{ | ||||
| 							api.ResourceName(api.ResourceCPU):                     resource.MustParse("10"), | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "1Mi"): resource.MustParse("2Mi"), | ||||
| @@ -963,10 +913,8 @@ func TestPodStrategyValidate(t *testing.T) { | ||||
| 							api.ResourceName(api.ResourceCPU):                     resource.MustParse("10"), | ||||
| 							api.ResourceName(api.ResourceHugePagesPrefix + "1Mi"): resource.MustParse("2Mi"), | ||||
| 						}, | ||||
| 						}}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 					}))), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| @@ -992,54 +940,20 @@ func TestEphemeralContainerStrategyValidateUpdate(t *testing.T) { | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "add ephemeral container to regular pod and expect success", | ||||
| 			oldPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			newPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 					EphemeralContainers: []api.EphemeralContainer{ | ||||
| 						{ | ||||
| 			oldPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetResourceVersion("1"), | ||||
| 			), | ||||
| 			newPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetResourceVersion("1"), | ||||
| 				podtest.SetEphemeralContainers(api.EphemeralContainer{ | ||||
| 					EphemeralContainerCommon: api.EphemeralContainerCommon{ | ||||
| 						Name:                     "debugger", | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 					}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 				}), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| @@ -1059,170 +973,64 @@ func TestEphemeralContainerStrategyValidateUpdate(t *testing.T) { | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "add ephemeral container to static pod and expect failure", | ||||
| 			oldPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 					Annotations:     map[string]string{api.MirrorPodAnnotationKey: "someVal"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 					NodeName: "example.com", | ||||
| 				}, | ||||
| 			}, | ||||
| 			newPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 					Annotations:     map[string]string{api.MirrorPodAnnotationKey: "someVal"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 					EphemeralContainers: []api.EphemeralContainer{ | ||||
| 						{ | ||||
| 			oldPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetAnnotations(map[string]string{api.MirrorPodAnnotationKey: "someVal"}), | ||||
| 				podtest.SetNodeName("example.com"), | ||||
| 			), | ||||
| 			newPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetAnnotations(map[string]string{api.MirrorPodAnnotationKey: "someVal"}), | ||||
| 				podtest.SetEphemeralContainers(api.EphemeralContainer{ | ||||
| 					EphemeralContainerCommon: api.EphemeralContainerCommon{ | ||||
| 						Name:                     "debugger", | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 					}, | ||||
| 						}, | ||||
| 					}, | ||||
| 					NodeName: "example.com", | ||||
| 				}, | ||||
| 			}, | ||||
| 				}), | ||||
| 				podtest.SetNodeName("example.com"), | ||||
| 			), | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "remove ephemeral container from regular pod and expect failure", | ||||
| 			newPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			oldPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 					EphemeralContainers: []api.EphemeralContainer{ | ||||
| 						{ | ||||
| 			newPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetResourceVersion("1"), | ||||
| 			), | ||||
| 			oldPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetResourceVersion("1"), | ||||
| 				podtest.SetEphemeralContainers(api.EphemeralContainer{ | ||||
| 					EphemeralContainerCommon: api.EphemeralContainerCommon{ | ||||
| 						Name:                     "debugger", | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 					}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 				}), | ||||
| 			), | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "change ephemeral container from regular pod and expect failure", | ||||
| 			newPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 					EphemeralContainers: []api.EphemeralContainer{ | ||||
| 						{ | ||||
| 			newPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetResourceVersion("1"), | ||||
| 				podtest.SetEphemeralContainers(api.EphemeralContainer{ | ||||
| 					EphemeralContainerCommon: api.EphemeralContainerCommon{ | ||||
| 						Name:                     "debugger", | ||||
| 						Image:                    "image2", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 					}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			oldPod: &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Name:            "test-pod", | ||||
| 					Namespace:       "test-ns", | ||||
| 					ResourceVersion: "1", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 					EphemeralContainers: []api.EphemeralContainer{ | ||||
| 						{ | ||||
| 				}), | ||||
| 			), | ||||
| 			oldPod: podtest.MakePod("test-pod", | ||||
| 				podtest.SetResourceVersion("1"), | ||||
| 				podtest.SetEphemeralContainers(api.EphemeralContainer{ | ||||
| 					EphemeralContainerCommon: api.EphemeralContainerCommon{ | ||||
| 						Name:                     "debugger", | ||||
| 						Image:                    "image", | ||||
| 						ImagePullPolicy:          "IfNotPresent", | ||||
| 						TerminationMessagePolicy: "File", | ||||
| 					}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 				}), | ||||
| 			), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| @@ -1530,24 +1338,7 @@ func TestNodeInclusionPolicyEnablementInCreating(t *testing.T) { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeInclusionPolicyInPodTopologySpread, tc.enableNodeInclusionPolicy) | ||||
|  | ||||
| 			pod := &api.Pod{ | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Namespace: "default", | ||||
| 					Name:      "foo", | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSDefault, | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "container", | ||||
| 							Image:                    "image", | ||||
| 							ImagePullPolicy:          "IfNotPresent", | ||||
| 							TerminationMessagePolicy: "File", | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
| 			pod := podtest.MakePod("foo") | ||||
| 			wantPod := pod.DeepCopy() | ||||
| 			pod.Spec.TopologySpreadConstraints = append(pod.Spec.TopologySpreadConstraints, tc.topologySpreadConstraints...) | ||||
|  | ||||
| @@ -1575,34 +1366,15 @@ func TestNodeInclusionPolicyEnablementInUpdating(t *testing.T) { | ||||
| 	featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeInclusionPolicyInPodTopologySpread, true) | ||||
| 	ctx := genericapirequest.NewDefaultContext() | ||||
|  | ||||
| 	pod := &api.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			Namespace:       "default", | ||||
| 			Name:            "foo", | ||||
| 			ResourceVersion: "1", | ||||
| 		}, | ||||
| 		Spec: api.PodSpec{ | ||||
| 			RestartPolicy: api.RestartPolicyAlways, | ||||
| 			DNSPolicy:     api.DNSDefault, | ||||
| 			Containers: []api.Container{ | ||||
| 				{ | ||||
| 					Name:                     "container", | ||||
| 					Image:                    "image", | ||||
| 					ImagePullPolicy:          "IfNotPresent", | ||||
| 					TerminationMessagePolicy: "File", | ||||
| 				}, | ||||
| 			}, | ||||
| 			TopologySpreadConstraints: []api.TopologySpreadConstraint{ | ||||
| 				{ | ||||
| 	pod := podtest.MakePod("foo", | ||||
| 		podtest.SetTopologySpreadConstraints(api.TopologySpreadConstraint{ | ||||
| 			NodeAffinityPolicy: &ignore, | ||||
| 			NodeTaintsPolicy:   &honor, | ||||
| 			WhenUnsatisfiable:  api.DoNotSchedule, | ||||
| 			TopologyKey:        "kubernetes.io/hostname", | ||||
| 			MaxSkew:            1, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 		}), | ||||
| 	) | ||||
|  | ||||
| 	errs := Strategy.Validate(ctx, pod) | ||||
| 	if len(errs) != 0 { | ||||
|   | ||||
| @@ -26,6 +26,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/registry/generic" | ||||
| 	genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/registry/registrytest" | ||||
| ) | ||||
| @@ -55,20 +56,7 @@ func validNewPodTemplate(name string) *api.PodTemplate { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: map[string]string{"test": "foo"}, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers: []api.Container{ | ||||
| 					{ | ||||
| 						Name:            "foo", | ||||
| 						Image:           "test", | ||||
| 						ImagePullPolicy: api.PullAlways, | ||||
|  | ||||
| 						TerminationMessagePath:   api.TerminationMessagePathDefault, | ||||
| 						TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePod("").Spec, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| ) | ||||
|  | ||||
| @@ -40,11 +41,9 @@ func TestStrategy(t *testing.T) { | ||||
| 			Generation: 999, | ||||
| 		}, | ||||
| 		Template: api.PodTemplateSpec{ | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyOnFailure, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePod("", | ||||
| 				podtest.SetRestartPolicy(api.RestartPolicyOnFailure), | ||||
| 			).Spec, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import ( | ||||
| 	genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing" | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	"k8s.io/kubernetes/pkg/apis/autoscaling" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/registry/registrytest" | ||||
| @@ -82,18 +83,7 @@ func validNewController() *api.ReplicationController { | ||||
| 				ObjectMeta: metav1.ObjectMeta{ | ||||
| 					Labels: map[string]string{"a": "b"}, | ||||
| 				}, | ||||
| 				Spec: api.PodSpec{ | ||||
| 					Containers: []api.Container{ | ||||
| 						{ | ||||
| 							Name:                     "test", | ||||
| 							Image:                    "test_image", | ||||
| 							ImagePullPolicy:          api.PullIfNotPresent, | ||||
| 							TerminationMessagePolicy: api.TerminationMessageReadFile, | ||||
| 						}, | ||||
| 					}, | ||||
| 					RestartPolicy: api.RestartPolicyAlways, | ||||
| 					DNSPolicy:     api.DNSClusterFirst, | ||||
| 				}, | ||||
| 				Spec: podtest.MakePod("").Spec, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|   | ||||
| @@ -22,6 +22,7 @@ import ( | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	podtest "k8s.io/kubernetes/pkg/api/pod/testing" | ||||
| 	apitesting "k8s.io/kubernetes/pkg/api/testing" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
|  | ||||
| @@ -44,11 +45,7 @@ func TestControllerStrategy(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validSelector, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: api.TerminationMessageReadFile}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePod("").Spec, | ||||
| 		}, | ||||
| 	} | ||||
| 	rc := &api.ReplicationController{ | ||||
| @@ -163,11 +160,7 @@ func TestValidateUpdate(t *testing.T) { | ||||
| 			ObjectMeta: metav1.ObjectMeta{ | ||||
| 				Labels: validSelector, | ||||
| 			}, | ||||
| 			Spec: api.PodSpec{ | ||||
| 				RestartPolicy: api.RestartPolicyAlways, | ||||
| 				DNSPolicy:     api.DNSClusterFirst, | ||||
| 				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}}, | ||||
| 			}, | ||||
| 			Spec: podtest.MakePod("").Spec, | ||||
| 		}, | ||||
| 	} | ||||
| 	oldController := &api.ReplicationController{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Michael Fraenkel
					Michael Fraenkel