func newJobInformer(client internalclientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { sharedIndexInformer := cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { var internalOptions api.ListOptions if err := api.Scheme.Convert(&options, &internalOptions, nil); err != nil { return nil, err } return client.Batch().Jobs(api.NamespaceAll).List(internalOptions) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { var internalOptions api.ListOptions if err := api.Scheme.Convert(&options, &internalOptions, nil); err != nil { return nil, err } return client.Batch().Jobs(api.NamespaceAll).Watch(internalOptions) }, }, &batch.Job{}, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, ) return sharedIndexInformer }
func ReaperFor(kind schema.GroupKind, c internalclientset.Interface) (Reaper, error) { switch kind { case api.Kind("ReplicationController"): return &ReplicationControllerReaper{c.Core(), Interval, Timeout}, nil case extensions.Kind("ReplicaSet"): return &ReplicaSetReaper{c.Extensions(), Interval, Timeout}, nil case extensions.Kind("DaemonSet"): return &DaemonSetReaper{c.Extensions(), Interval, Timeout}, nil case api.Kind("Pod"): return &PodReaper{c.Core()}, nil case api.Kind("Service"): return &ServiceReaper{c.Core()}, nil case extensions.Kind("Job"), batch.Kind("Job"): return &JobReaper{c.Batch(), c.Core(), Interval, Timeout}, nil case apps.Kind("StatefulSet"): return &StatefulSetReaper{c.Apps(), c.Core(), Interval, Timeout}, nil case extensions.Kind("Deployment"): return &DeploymentReaper{c.Extensions(), c.Extensions(), Interval, Timeout}, nil } return nil, &NoSuchReaperError{kind} }
// waitForJobsAtLeast waits for at least a number of jobs to appear. func waitForJobsAtLeast(c clientset.Interface, ns string, atLeast int) error { return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { jobs, err := c.Batch().Jobs(ns).List(api.ListOptions{}) if err != nil { return false, err } return len(jobs.Items) >= atLeast, nil }) }
// Wait for job to reach completions. func waitForV1JobFinish(c clientset.Interface, ns, jobName string, completions int32) error { return wait.Poll(framework.Poll, v1JobTimeout, func() (bool, error) { curr, err := c.Batch().Jobs(ns).Get(jobName) if err != nil { return false, err } return curr.Status.Succeeded == completions, nil }) }
// Wait for at least given amount of active jobs. func waitForActiveJobs(c clientset.Interface, ns, cronJobName string, active int) error { return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { curr, err := c.Batch().CronJobs(ns).Get(cronJobName) if err != nil { return false, err } return len(curr.Status.Active) >= active, nil }) }
// Wait for no jobs to appear. func waitForNoJobs(c clientset.Interface, ns, jobName string) error { return wait.Poll(framework.Poll, scheduledJobTimeout, func() (bool, error) { curr, err := c.Batch().ScheduledJobs(ns).Get(jobName) if err != nil { return false, err } return len(curr.Status.Active) != 0, nil }) }
// Wait for job fail. func waitForV1JobFail(c clientset.Interface, ns, jobName string, timeout time.Duration) error { return wait.Poll(framework.Poll, timeout, func() (bool, error) { curr, err := c.Batch().Jobs(ns).Get(jobName) if err != nil { return false, err } for _, c := range curr.Status.Conditions { if c.Type == batch.JobFailed && c.Status == api.ConditionTrue { return true, nil } } return false, nil }) }
// waitForAnyFinishedJob waits for any completed job to appear. func waitForAnyFinishedJob(c clientset.Interface, ns string) error { return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { jobs, err := c.Batch().Jobs(ns).List(api.ListOptions{}) if err != nil { return false, err } for i := range jobs.Items { if job.IsJobFinished(&jobs.Items[i]) { return true, nil } } return false, nil }) }
func ScalerFor(kind schema.GroupKind, c internalclientset.Interface) (Scaler, error) { switch kind { case api.Kind("ReplicationController"): return &ReplicationControllerScaler{c.Core()}, nil case extensions.Kind("ReplicaSet"): return &ReplicaSetScaler{c.Extensions()}, nil case extensions.Kind("Job"), batch.Kind("Job"): return &JobScaler{c.Batch()}, nil // Either kind of job can be scaled with Batch interface. case apps.Kind("StatefulSet"): return &StatefulSetScaler{c.Apps()}, nil case extensions.Kind("Deployment"): return &DeploymentScaler{c.Extensions()}, nil } return nil, fmt.Errorf("no scaler has been implemented for %q", kind) }
// Wait for a job to be replaced with a new one. func waitForJobReplaced(c clientset.Interface, ns, previousJobName string) error { return wait.Poll(framework.Poll, cronJobTimeout, func() (bool, error) { jobs, err := c.Batch().Jobs(ns).List(api.ListOptions{}) if err != nil { return false, err } if len(jobs.Items) > 1 { return false, fmt.Errorf("More than one job is running %+v", jobs.Items) } else if len(jobs.Items) == 0 { framework.Logf("Warning: Found 0 jobs in namespace %v", ns) return false, nil } return jobs.Items[0].Name != previousJobName, nil }) }
// GetJobDetail gets job details. func GetJobDetail(client k8sClient.Interface, heapsterClient client.HeapsterClient, namespace, name string) (*JobDetail, error) { // TODO(floreks): Use channels. jobData, err := client.Batch().Jobs(namespace).Get(name) if err != nil { return nil, err } podList, err := GetJobPods(client, heapsterClient, dataselect.DefaultDataSelectWithMetrics, namespace, name) if err != nil { return nil, err } podInfo, err := getJobPodInfo(client, jobData) if err != nil { return nil, err } eventList, err := GetJobEvents(client, dataselect.DefaultDataSelect, jobData.Namespace, jobData.Name) if err != nil { return nil, err } job := getJobDetail(jobData, heapsterClient, *eventList, *podList, *podInfo) return &job, nil }
// checkNoUnexpectedEvents checks unexpected events didn't happen. // Currently only "UnexpectedJob" is checked. func checkNoUnexpectedEvents(c clientset.Interface, ns, cronJobName string) error { sj, err := c.Batch().CronJobs(ns).Get(cronJobName) if err != nil { return fmt.Errorf("error in getting cronjob %s/%s: %v", ns, cronJobName, err) } events, err := c.Core().Events(ns).Search(sj) if err != nil { return fmt.Errorf("error in listing events: %s", err) } for _, e := range events.Items { if e.Reason == "UnexpectedJob" { return fmt.Errorf("found unexpected event: %#v", e) } } return nil }
// NewJobInformer returns a SharedIndexInformer that lists and watches all jobs func NewJobInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { sharedIndexInformer := cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options api.ListOptions) (runtime.Object, error) { return client.Batch().Jobs(api.NamespaceAll).List(options) }, WatchFunc: func(options api.ListOptions) (watch.Interface, error) { return client.Batch().Jobs(api.NamespaceAll).Watch(options) }, }, &batch.Job{}, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, ) return sharedIndexInformer }
func NewScheduledJobController(kubeClient clientset.Interface) *ScheduledJobController { eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(glog.Infof) // TODO: remove the wrapper when every clients have moved to use the clientset. eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{Interface: kubeClient.Core().Events("")}) if kubeClient != nil && kubeClient.Batch().GetRESTClient().GetRateLimiter() != nil { metrics.RegisterMetricAndTrackRateLimiterUsage("scheduledjob_controller", kubeClient.Batch().GetRESTClient().GetRateLimiter()) } jm := &ScheduledJobController{ kubeClient: kubeClient, jobControl: realJobControl{KubeClient: kubeClient}, sjControl: &realSJControl{KubeClient: kubeClient}, recorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "scheduled-job-controller"}), } return jm }
func toJobPodController(client k8sClient.Interface, reference api.ObjectReference, pods []api.Pod, events []api.Event, heapsterClient client.HeapsterClient) (*Controller, error) { job, err := client.Batch().Jobs(reference.Namespace).Get(reference.Name) if err != nil { return nil, err } jobs := []batch.Job{*job} jobList := joblist.CreateJobList(jobs, pods, events, dataselect.StdMetricsDataSelect, &heapsterClient) return &Controller{ Kind: "Job", JobList: jobList, }, nil }
// testPodNodeConstraintsObjectCreationWithPodTemplate attempts to create different object types that contain pod templates // using the passed in nodeName and nodeSelector. It will use the expectError flag to determine if an error should be returned or not func testPodNodeConstraintsObjectCreationWithPodTemplate(t *testing.T, name string, kclientset kclientset.Interface, client client.Interface, nodeName string, nodeSelector map[string]string, expectError bool) { checkForbiddenErr := func(objType string, err error) { if err == nil && expectError { t.Errorf("%s (%s): expected forbidden error but did not receive one", name, objType) return } if err != nil && !expectError { t.Errorf("%s (%s): got error but did not expect one: %v", name, objType, err) return } if err != nil && expectError && !kapierrors.IsForbidden(err) { t.Errorf("%s (%s): did not get an expected forbidden error: %v", name, objType, err) return } } // Pod pod := testPodNodeConstraintsPod(nodeName, nodeSelector) _, err := kclientset.Core().Pods(testutil.Namespace()).Create(pod) checkForbiddenErr("pod", err) // ReplicationController rc := testPodNodeConstraintsReplicationController(nodeName, nodeSelector) _, err = kclientset.Core().ReplicationControllers(testutil.Namespace()).Create(rc) checkForbiddenErr("rc", err) // TODO: Enable when the deployments endpoint is supported in Origin // Deployment // d := testPodNodeConstraintsDeployment(nodeName, nodeSelector) // _, err = kclientset.Extensions().Deployments(testutil.Namespace()).Create(d) // checkForbiddenErr("deployment", err) // ReplicaSet rs := testPodNodeConstraintsReplicaSet(nodeName, nodeSelector) _, err = kclientset.Extensions().ReplicaSets(testutil.Namespace()).Create(rs) checkForbiddenErr("replicaset", err) // Job job := testPodNodeConstraintsJob(nodeName, nodeSelector) _, err = kclientset.Batch().Jobs(testutil.Namespace()).Create(job) checkForbiddenErr("job", err) // DeploymentConfig dc := testPodNodeConstraintsDeploymentConfig(nodeName, nodeSelector) _, err = client.DeploymentConfigs(testutil.Namespace()).Create(dc) checkForbiddenErr("dc", err) }
// GetJobPodsEvents gets events associated to pods in job. func GetJobPodsEvents(client client.Interface, namespace, jobName string) ( []api.Event, error) { job, err := client.Batch().Jobs(namespace).Get(jobName) if err != nil { return nil, err } podEvents, err := event.GetPodsEvents(client, namespace, job.Spec.Selector.MatchLabels) if err != nil { return nil, err } return podEvents, nil }
// Returns array of api pods targeting job with given name. func getRawJobPods(client k8sClient.Interface, petSetName, namespace string) ([]api.Pod, error) { replicaSet, err := client.Batch().Jobs(namespace).Get(petSetName) if err != nil { return nil, err } labelSelector := labels.SelectorFromSet(replicaSet.Spec.Selector.MatchLabels) channels := &common.ResourceChannels{ PodList: common.GetPodListChannelWithOptions(client, common.NewSameNamespaceQuery(namespace), api.ListOptions{ LabelSelector: labelSelector, FieldSelector: fields.Everything(), }, 1), } podList := <-channels.PodList.List if err := <-channels.PodList.Error; err != nil { return nil, err } return podList.Items, nil }
// GetJobListChannel returns a pair of channels to a Job list and errors that // both must be read numReads times. func GetJobListChannel(client client.Interface, nsQuery *NamespaceQuery, numReads int) JobListChannel { channel := JobListChannel{ List: make(chan *batch.JobList, numReads), Error: make(chan error, numReads), } go func() { list, err := client.Batch().Jobs(nsQuery.ToRequestParam()).List(listEverything) var filteredItems []batch.Job for _, item := range list.Items { if nsQuery.Matches(item.ObjectMeta.Namespace) { filteredItems = append(filteredItems, item) } } list.Items = filteredItems for i := 0; i < numReads; i++ { channel.List <- list channel.Error <- err } }() return channel }
func createJob(c clientset.Interface, ns string, job *batch.Job) (*batch.Job, error) { return c.Batch().Jobs(ns).Create(job) }
func createScheduledJob(c clientset.Interface, ns string, scheduledJob *batch.ScheduledJob) (*batch.ScheduledJob, error) { return c.Batch().ScheduledJobs(ns).Create(scheduledJob) }
func deleteV1Job(c clientset.Interface, ns, name string) error { return c.Batch().Jobs(ns).Delete(name, api.NewDeleteOptions(0)) }
func updateV1Job(c clientset.Interface, ns string, job *batch.Job) (*batch.Job, error) { return c.Batch().Jobs(ns).Update(job) }
func getV1Job(c clientset.Interface, ns, name string) (*batch.Job, error) { return c.Batch().Jobs(ns).Get(name) }
func createCronJob(c clientset.Interface, ns string, cronJob *batch.CronJob) (*batch.CronJob, error) { return c.Batch().CronJobs(ns).Create(cronJob) }
func deleteCronJob(c clientset.Interface, ns, name string) error { return c.Batch().CronJobs(ns).Delete(name, nil) }