diff --git a/pkg/apis/extensions/deep_copy_generated.go b/pkg/apis/extensions/deep_copy_generated.go index 3d2d5fe70dc..fcd0c810b6b 100644 --- a/pkg/apis/extensions/deep_copy_generated.go +++ b/pkg/apis/extensions/deep_copy_generated.go @@ -1301,13 +1301,8 @@ func deepCopy_extensions_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := deepCopy_api_PodTemplateSpec(*in.Template, out.Template, c); err != nil { - return err - } - } else { - out.Template = nil + if err := deepCopy_api_PodTemplateSpec(in.Template, &out.Template, c); err != nil { + return err } return nil } diff --git a/pkg/apis/extensions/types.go b/pkg/apis/extensions/types.go index 21f3af562f1..ca026525f7c 100644 --- a/pkg/apis/extensions/types.go +++ b/pkg/apis/extensions/types.go @@ -409,7 +409,7 @@ type JobSpec struct { // Template is the object that describes the pod that will be created when // executing a job. - Template *api.PodTemplateSpec `json:"template"` + Template api.PodTemplateSpec `json:"template"` } // JobStatus represents the current state of a Job. diff --git a/pkg/apis/extensions/v1beta1/conversion_generated.go b/pkg/apis/extensions/v1beta1/conversion_generated.go index 9aecfbdaa77..51465c728bb 100644 --- a/pkg/apis/extensions/v1beta1/conversion_generated.go +++ b/pkg/apis/extensions/v1beta1/conversion_generated.go @@ -2792,13 +2792,8 @@ func autoconvert_extensions_JobSpec_To_v1beta1_JobSpec(in *extensions.JobSpec, o } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil + if err := convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err } return nil } @@ -3714,13 +3709,8 @@ func autoconvert_v1beta1_JobSpec_To_extensions_JobSpec(in *JobSpec, out *extensi } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(api.PodTemplateSpec) - if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil { - return err - } - } else { - out.Template = nil + if err := convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err } return nil } diff --git a/pkg/apis/extensions/v1beta1/deep_copy_generated.go b/pkg/apis/extensions/v1beta1/deep_copy_generated.go index 90e7cec003a..a573e9b8ac4 100644 --- a/pkg/apis/extensions/v1beta1/deep_copy_generated.go +++ b/pkg/apis/extensions/v1beta1/deep_copy_generated.go @@ -1313,13 +1313,8 @@ func deepCopy_v1beta1_JobSpec(in JobSpec, out *JobSpec, c *conversion.Cloner) er } else { out.Selector = nil } - if in.Template != nil { - out.Template = new(v1.PodTemplateSpec) - if err := deepCopy_v1_PodTemplateSpec(*in.Template, out.Template, c); err != nil { - return err - } - } else { - out.Template = nil + if err := deepCopy_v1_PodTemplateSpec(in.Template, &out.Template, c); err != nil { + return err } return nil } diff --git a/pkg/apis/extensions/v1beta1/defaults.go b/pkg/apis/extensions/v1beta1/defaults.go index 2d6efb04845..07c69158075 100644 --- a/pkg/apis/extensions/v1beta1/defaults.go +++ b/pkg/apis/extensions/v1beta1/defaults.go @@ -89,10 +89,7 @@ func addDefaultingFuncs() { } }, func(obj *Job) { - var labels map[string]string - if obj.Spec.Template != nil { - labels = obj.Spec.Template.Labels - } + labels := obj.Spec.Template.Labels // TODO: support templates defined elsewhere when we support them in the API if labels != nil { if len(obj.Spec.Selector) == 0 { diff --git a/pkg/apis/extensions/v1beta1/defaults_test.go b/pkg/apis/extensions/v1beta1/defaults_test.go index 3800fabc2f5..4eb9069b321 100644 --- a/pkg/apis/extensions/v1beta1/defaults_test.go +++ b/pkg/apis/extensions/v1beta1/defaults_test.go @@ -207,7 +207,7 @@ func TestSetDefaultJob(t *testing.T) { // selector from template labels, completions and parallelism - default { Spec: JobSpec{ - Template: &v1.PodTemplateSpec{ + Template: v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{"job": "selector"}, }, @@ -218,7 +218,7 @@ func TestSetDefaultJob(t *testing.T) { { Spec: JobSpec{ Completions: newInt(1), - Template: &v1.PodTemplateSpec{ + Template: v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{"job": "selector"}, }, @@ -229,7 +229,7 @@ func TestSetDefaultJob(t *testing.T) { { Spec: JobSpec{ Parallelism: newInt(1), - Template: &v1.PodTemplateSpec{ + Template: v1.PodTemplateSpec{ ObjectMeta: v1.ObjectMeta{ Labels: map[string]string{"job": "selector"}, }, diff --git a/pkg/apis/extensions/v1beta1/types.go b/pkg/apis/extensions/v1beta1/types.go index 2cdee797e55..f57a968e236 100644 --- a/pkg/apis/extensions/v1beta1/types.go +++ b/pkg/apis/extensions/v1beta1/types.go @@ -417,7 +417,7 @@ type JobSpec struct { // Template is the object that describes the pod that will be created when // executing a job. // More info: http://releases.k8s.io/HEAD/docs/user-guide/jobs.md - Template *v1.PodTemplateSpec `json:"template"` + Template v1.PodTemplateSpec `json:"template"` } // JobStatus represents the current state of a Job. diff --git a/pkg/apis/extensions/validation/validation.go b/pkg/apis/extensions/validation/validation.go index 7cede8a9b87..33a38d24792 100644 --- a/pkg/apis/extensions/validation/validation.go +++ b/pkg/apis/extensions/validation/validation.go @@ -351,19 +351,15 @@ func ValidateJobSpec(spec *extensions.JobSpec) errs.ValidationErrorList { allErrs = append(allErrs, errs.NewFieldRequired("selector")) } - if spec.Template == nil { - allErrs = append(allErrs, errs.NewFieldRequired("template")) - } else { - labels := labels.Set(spec.Template.Labels) - if !selector.Matches(labels) { - allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) - } - allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(spec.Template).Prefix("template")...) - if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure && - spec.Template.Spec.RestartPolicy != api.RestartPolicyNever { - allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", - spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)})) - } + labels := labels.Set(spec.Template.Labels) + if !selector.Matches(labels) { + allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) + } + allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template).Prefix("template")...) + if spec.Template.Spec.RestartPolicy != api.RestartPolicyOnFailure && + spec.Template.Spec.RestartPolicy != api.RestartPolicyNever { + allErrs = append(allErrs, errs.NewFieldValueNotSupported("template.spec.restartPolicy", + spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyOnFailure), string(api.RestartPolicyNever)})) } return allErrs } diff --git a/pkg/apis/extensions/validation/validation_test.go b/pkg/apis/extensions/validation/validation_test.go index 51ef586d0e9..1f9b7f31c9f 100644 --- a/pkg/apis/extensions/validation/validation_test.go +++ b/pkg/apis/extensions/validation/validation_test.go @@ -744,7 +744,7 @@ func TestValidateJob(t *testing.T) { }, Spec: extensions.JobSpec{ Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, }, }, } @@ -763,7 +763,7 @@ func TestValidateJob(t *testing.T) { Spec: extensions.JobSpec{ Parallelism: &negative, Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, }, }, "spec.completions:must be non-negative": { @@ -774,7 +774,7 @@ func TestValidateJob(t *testing.T) { Spec: extensions.JobSpec{ Completions: &negative, Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, }, }, "spec.selector:required value": { @@ -784,16 +784,7 @@ func TestValidateJob(t *testing.T) { }, Spec: extensions.JobSpec{ Selector: map[string]string{}, - Template: &validPodTemplateSpec, - }, - }, - "spec.template:required value": { - ObjectMeta: api.ObjectMeta{ - Name: "myjob", - Namespace: api.NamespaceDefault, - }, - Spec: extensions.JobSpec{ - Selector: validSelector, + Template: validPodTemplateSpec, }, }, "spec.template.labels:selector does not match template": { @@ -803,7 +794,7 @@ func TestValidateJob(t *testing.T) { }, Spec: extensions.JobSpec{ Selector: validSelector, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{"y": "z"}, }, @@ -822,7 +813,7 @@ func TestValidateJob(t *testing.T) { }, Spec: extensions.JobSpec{ Selector: validSelector, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: validSelector, }, diff --git a/pkg/client/unversioned/jobs_test.go b/pkg/client/unversioned/jobs_test.go index 2677e6525d1..856dfaf1971 100644 --- a/pkg/client/unversioned/jobs_test.go +++ b/pkg/client/unversioned/jobs_test.go @@ -49,7 +49,7 @@ func TestListJobs(t *testing.T) { }, }, Spec: extensions.JobSpec{ - Template: &api.PodTemplateSpec{}, + Template: api.PodTemplateSpec{}, }, }, }, @@ -79,7 +79,7 @@ func TestGetJob(t *testing.T) { }, }, Spec: extensions.JobSpec{ - Template: &api.PodTemplateSpec{}, + Template: api.PodTemplateSpec{}, }, }, }, @@ -125,7 +125,7 @@ func TestUpdateJob(t *testing.T) { }, }, Spec: extensions.JobSpec{ - Template: &api.PodTemplateSpec{}, + Template: api.PodTemplateSpec{}, }, }, }, @@ -160,7 +160,7 @@ func TestUpdateJobStatus(t *testing.T) { }, }, Spec: extensions.JobSpec{ - Template: &api.PodTemplateSpec{}, + Template: api.PodTemplateSpec{}, }, Status: extensions.JobStatus{ Active: 1, @@ -212,7 +212,7 @@ func TestCreateJob(t *testing.T) { }, }, Spec: extensions.JobSpec{ - Template: &api.PodTemplateSpec{}, + Template: api.PodTemplateSpec{}, }, }, }, diff --git a/pkg/controller/job/controller.go b/pkg/controller/job/controller.go index ca997b64d82..f2f702c3085 100644 --- a/pkg/controller/job/controller.go +++ b/pkg/controller/job/controller.go @@ -414,7 +414,7 @@ func (jm *JobController) manageJob(activePods []*api.Pod, succeeded int, job *ex for i := 0; i < diff; i++ { go func() { defer wait.Done() - if err := jm.podControl.CreatePods(job.Namespace, job.Spec.Template, job); err != nil { + if err := jm.podControl.CreatePods(job.Namespace, &job.Spec.Template, job); err != nil { defer util.HandleError(err) // Decrement the expected number of creates because the informer won't observe this pod jm.expectations.CreationObserved(jobKey) diff --git a/pkg/controller/job/controller_test.go b/pkg/controller/job/controller_test.go index d73b61603bf..21f1f177518 100644 --- a/pkg/controller/job/controller_test.go +++ b/pkg/controller/job/controller_test.go @@ -44,7 +44,7 @@ func newJob(parallelism, completions int) *extensions.Job { Parallelism: ¶llelism, Completions: &completions, Selector: map[string]string{"foo": "bar"}, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ "foo": "bar", diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index 8fc9b3dca02..8b27ac58b5a 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -884,19 +884,13 @@ func describeJob(job *extensions.Job, events *api.EventList) (string, error) { return tabbedString(func(out io.Writer) error { fmt.Fprintf(out, "Name:\t%s\n", job.Name) fmt.Fprintf(out, "Namespace:\t%s\n", job.Namespace) - if job.Spec.Template != nil { - fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&job.Spec.Template.Spec)) - } else { - fmt.Fprintf(out, "Image(s):\t%s\n", "") - } + fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(&job.Spec.Template.Spec)) fmt.Fprintf(out, "Selector:\t%s\n", labels.FormatLabels(job.Spec.Selector)) fmt.Fprintf(out, "Parallelism:\t%d\n", *job.Spec.Parallelism) fmt.Fprintf(out, "Completions:\t%d\n", *job.Spec.Completions) fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(job.Labels)) fmt.Fprintf(out, "Pods Statuses:\t%d Running / %d Succeeded / %d Failed\n", job.Status.Active, job.Status.Succeeded, job.Status.Failed) - if job.Spec.Template != nil { - describeVolumes(job.Spec.Template.Spec.Volumes, out) - } + describeVolumes(job.Spec.Template.Spec.Volumes, out) if events != nil { DescribeEvents(events, out) } diff --git a/pkg/registry/job/etcd/etcd_test.go b/pkg/registry/job/etcd/etcd_test.go index 51119695ce4..399e2547952 100644 --- a/pkg/registry/job/etcd/etcd_test.go +++ b/pkg/registry/job/etcd/etcd_test.go @@ -48,7 +48,7 @@ func validNewJob() *extensions.Job { Completions: &completions, Parallelism: ¶llelism, Selector: map[string]string{"a": "b"}, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{"a": "b"}, }, diff --git a/pkg/registry/job/strategy_test.go b/pkg/registry/job/strategy_test.go index e5ca69bc5e3..6b90786128e 100644 --- a/pkg/registry/job/strategy_test.go +++ b/pkg/registry/job/strategy_test.go @@ -50,7 +50,7 @@ func TestJobStrategy(t *testing.T) { }, Spec: extensions.JobSpec{ Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, }, Status: extensions.JobStatus{ Active: 11, @@ -116,7 +116,7 @@ func TestJobStatusStrategy(t *testing.T) { }, Spec: extensions.JobSpec{ Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, Parallelism: &oldParallelism, }, Status: extensions.JobStatus{ @@ -131,7 +131,7 @@ func TestJobStatusStrategy(t *testing.T) { }, Spec: extensions.JobSpec{ Selector: validSelector, - Template: &validPodTemplateSpec, + Template: validPodTemplateSpec, Parallelism: &newParallelism, }, Status: extensions.JobStatus{ diff --git a/test/e2e/job.go b/test/e2e/job.go index cc7578547b1..9554121436b 100644 --- a/test/e2e/job.go +++ b/test/e2e/job.go @@ -191,7 +191,7 @@ func newTestJob(behavior, name string, rPol api.RestartPolicy, parallelism, comp Spec: extensions.JobSpec{ Parallelism: ¶llelism, Completions: &completions, - Template: &api.PodTemplateSpec{ + Template: api.PodTemplateSpec{ ObjectMeta: api.ObjectMeta{ Labels: map[string]string{jobSelectorKey: name}, },