diff --git a/pkg/controller/job/jobcontroller.go b/pkg/controller/job/jobcontroller.go index ade0e584088..9c55e45cbb6 100644 --- a/pkg/controller/job/jobcontroller.go +++ b/pkg/controller/job/jobcontroller.go @@ -46,6 +46,9 @@ import ( "github.com/golang/glog" ) +// controllerKind contains the schema.GroupVersionKind for this controller type. +var controllerKind = batch.SchemeGroupVersion.WithKind("Job") + type JobController struct { kubeClient clientset.Interface podControl controller.PodControlInterface @@ -507,7 +510,7 @@ func (jm *JobController) manageJob(activePods []*v1.Pod, succeeded int32, job *b for i := int32(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.CreatePodsWithControllerRef(job.Namespace, &job.Spec.Template, job, newControllerRef(job)); err != nil { defer utilruntime.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/jobcontroller_test.go b/pkg/controller/job/jobcontroller_test.go index 4d3cb6116ce..e4f1ed358e0 100644 --- a/pkg/controller/job/jobcontroller_test.go +++ b/pkg/controller/job/jobcontroller_test.go @@ -101,9 +101,10 @@ func newPodList(count int32, status v1.PodPhase, job *batch.Job) []v1.Pod { for i := int32(0); i < count; i++ { newPod := v1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("pod-%v", rand.String(10)), - Labels: job.Spec.Selector.MatchLabels, - Namespace: job.Namespace, + Name: fmt.Sprintf("pod-%v", rand.String(10)), + Labels: job.Spec.Selector.MatchLabels, + Namespace: job.Namespace, + OwnerReferences: []metav1.OwnerReference{*newControllerRef(job)}, }, Status: v1.PodStatus{Phase: status}, } @@ -274,6 +275,22 @@ func TestControllerSyncJob(t *testing.T) { if int32(len(fakePodControl.DeletePodName)) != tc.expectedDeletions { t.Errorf("%s: unexpected number of deletes. Expected %d, saw %d\n", name, tc.expectedDeletions, len(fakePodControl.DeletePodName)) } + // Each create should have an accompanying ControllerRef. + if len(fakePodControl.ControllerRefs) != int(tc.expectedCreations) { + t.Errorf("%s: unexpected number of ControllerRefs. Expected %d, saw %d\n", name, tc.expectedCreations, len(fakePodControl.ControllerRefs)) + } + // Make sure the ControllerRefs are correct. + for _, controllerRef := range fakePodControl.ControllerRefs { + if got, want := controllerRef.APIVersion, "batch/v1"; got != want { + t.Errorf("controllerRef.APIVersion = %q, want %q", got, want) + } + if got, want := controllerRef.Kind, "Job"; got != want { + t.Errorf("controllerRef.Kind = %q, want %q", got, want) + } + if controllerRef.Controller == nil || *controllerRef.Controller != true { + t.Errorf("controllerRef.Controller is not set to true") + } + } // validate status if actual.Status.Active != tc.expectedActive { t.Errorf("%s: unexpected number of active pods. Expected %d, saw %d\n", name, tc.expectedActive, actual.Status.Active) diff --git a/pkg/controller/job/utils.go b/pkg/controller/job/utils.go index 5d14f054c60..47f1cc83d0e 100644 --- a/pkg/controller/job/utils.go +++ b/pkg/controller/job/utils.go @@ -17,6 +17,7 @@ limitations under the License. package job import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/api/v1" batch "k8s.io/kubernetes/pkg/apis/batch/v1" ) @@ -29,3 +30,14 @@ func IsJobFinished(j *batch.Job) bool { } return false } + +func newControllerRef(j *batch.Job) *metav1.OwnerReference { + isController := true + return &metav1.OwnerReference{ + APIVersion: controllerKind.GroupVersion().String(), + Kind: controllerKind.Kind, + Name: j.Name, + UID: j.UID, + Controller: &isController, + } +}