func ReaperFor(kind unversioned.GroupKind, c client.Interface) (Reaper, error) { switch kind { case api.Kind("ReplicationController"): return &ReplicationControllerReaper{c, Interval, Timeout}, nil case extensions.Kind("ReplicaSet"): return &ReplicaSetReaper{c, Interval, Timeout}, nil case extensions.Kind("DaemonSet"): return &DaemonSetReaper{c, Interval, Timeout}, nil case api.Kind("Pod"): return &PodReaper{c}, nil case api.Kind("Service"): return &ServiceReaper{c}, nil case extensions.Kind("Job"), batch.Kind("Job"): return &JobReaper{c, Interval, Timeout}, nil case extensions.Kind("Deployment"): return &DeploymentReaper{c, Interval, Timeout}, nil } return nil, &NoSuchReaperError{kind} }
func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error { jobs := reaper.Batch().Jobs(namespace) pods := reaper.Pods(namespace) scaler, err := ScalerFor(batch.Kind("Job"), *reaper) if err != nil { return err } job, err := jobs.Get(name) if err != nil { return err } if timeout == 0 { // we will never have more active pods than job.Spec.Parallelism parallelism := *job.Spec.Parallelism timeout = Timeout + time.Duration(10*parallelism)*time.Second } // TODO: handle overlapping jobs retry := NewRetryParams(reaper.pollInterval, reaper.timeout) waitForJobs := NewRetryParams(reaper.pollInterval, timeout) if err = scaler.Scale(namespace, name, 0, nil, retry, waitForJobs); err != nil { return err } // at this point only dead pods are left, that should be removed selector, _ := unversioned.LabelSelectorAsSelector(job.Spec.Selector) options := api.ListOptions{LabelSelector: selector} podList, err := pods.List(options) if err != nil { return err } errList := []error{} for _, pod := range podList.Items { if err := pods.Delete(pod.Name, gracePeriod); err != nil { // ignores the error when the pod isn't found if !errors.IsNotFound(err) { errList = append(errList, err) } } } if len(errList) > 0 { return utilerrors.NewAggregate(errList) } // once we have all the pods removed we can safely remove the job itself return jobs.Delete(name, nil) }