// DeleteJob creates a Jenkins job with the given name for the given XML job config.
9955
func (client Client) DeleteJob(jobName string) error {
	retry := retry.New(3, retry.DefaultBackoffFunc)
	work := func() error {
		req, err := http.NewRequest("POST", fmt.Sprintf("%s/job/%s/doDelete", client.baseURL.String(), jobName), bytes.NewBuffer([]byte("")))
		if err != nil {
			return err
		}
		req.Header.Set("Content-type", "application/xml")
		req.SetBasicAuth(client.userName, client.password)

		responseCode, data, err := consumeResponse(req)
		if err != nil {
			return err
		}
		if responseCode != http.StatusFound {
			return fmt.Errorf("Error deleting Jenkins job.  Status code: %d, response=%s\n", responseCode, string(data))
		}
		return nil
	}
	return retry.Try(work)
}
1204288
func (c *FakeJobController) RemoveJob(pvName string) (CleanupState, *time.Time, error) {
	c.RemoveCompletedCount++
	status, exists := c.pvCleanupRunning[pvName]
	if !exists {
		return CSNotFound, nil, nil
	}
	if status != CSSucceeded {
		return CSUnknown, nil, fmt.Errorf("cannot remove job that has not yet completed %s status %d", pvName, status)
	}
	return CSSucceeded, nil, nil
}
350972
func (job *QorJob) GetJob() *Job {
	if job.Job != nil {
		return job.Job
	}
	return nil
}
365356
func (c *Cron) AddJob(spec string, cmd Job) error {
	schedule, err := Parse(spec)
	if err != nil {
		return err
	}
	c.Schedule(schedule, cmd)
	return nil
}
436201
func (impl *adminImpl) AbortJob(c context.Context, id *api.JobID) (*empty.Empty, error) {
	_, err := impl.ctl.AbortJob(c, mapper.JobID(id.JobId))
	if err != nil {
		return nil, toStatus(err)
	}
	return &empty.Empty{}, nil
}
1190619
func (s *BatchStopJobRunSuccessfulSubmission) SetJobName(v string) *BatchStopJobRunSuccessfulSubmission {
	s.JobName = &v
	return s
}
343486
func (s *DeleteJobInput) SetJobName(v string) *DeleteJobInput {
	s.JobName = &v
	return s
}
849647
func (s *KeyPhrasesDetectionJobFilter) SetJobName(v string) *KeyPhrasesDetectionJobFilter {
	s.JobName = &v
	return s
}
183283
func (s *GetJobRunsInput) SetJobName(v string) *GetJobRunsInput {
	s.JobName = &v
	return s
}
723764
func removeOldestJobs(sj *batchv1beta1.CronJob, js []batchv1.Job, jc jobControlInterface, maxJobs int32, recorder record.EventRecorder) {
	numToDelete := len(js) - int(maxJobs)
	if numToDelete <= 0 {
		return
	}

	nameForLog := fmt.Sprintf("%s/%s", sj.Namespace, sj.Name)
	klog.V(4).Infof("Cleaning up %d/%d jobs from %s", numToDelete, len(js), nameForLog)

	sort.Sort(byJobStartTime(js))
	for i := 0; i < numToDelete; i++ {
		klog.V(4).Infof("Removing job %s from %s", js[i].Name, nameForLog)
		deleteJob(sj, &js[i], jc, recorder)
	}
}
1281772
func sortJobs(c context.Context, jobs []*engine.Job) sortedJobs {
	out := make(sortedJobs, len(jobs))
	for i, job := range jobs {
		out[i] = makeJob(c, job, nil)
	}
	sort.Sort(out)
	return out
}
394466
func (jm *JobController) manageJob(activePods []*v1.Pod, succeeded int32, job *batch.Job) (int32, error) {
	var activeLock sync.Mutex
	active := int32(len(activePods))
	parallelism := *job.Spec.Parallelism
	jobKey, err := controller.KeyFunc(job)
	if err != nil {
		utilruntime.HandleError(fmt.Errorf("Couldn't get key for job %#v: %v", job, err))
		return 0, nil
	}

	var errCh chan error
	if active > parallelism {
		diff := active - parallelism
		errCh = make(chan error, diff)
		jm.expectations.ExpectDeletions(jobKey, int(diff))
		klog.V(4).Infof("Too many pods running job %q, need %d, deleting %d", jobKey, parallelism, diff)
		// Sort the pods in the order such that not-ready < ready, unscheduled
		// < scheduled, and pending < running. This ensures that we delete pods
		// in the earlier stages whenever possible.
		sort.Sort(controller.ActivePods(activePods))

		active -= diff
		wait := sync.WaitGroup{}
		wait.Add(int(diff))
		for i := int32(0); i < diff; i++ {
			go func(ix int32) {
				defer wait.Done()
				if err := jm.podControl.DeletePod(job.Namespace, activePods[ix].Name, job); err != nil {
					defer utilruntime.HandleError(err)
					// Decrement the expected number of deletes because the informer won't observe this deletion
					klog.V(2).Infof("Failed to delete %v, decrementing expectations for job %q/%q", activePods[ix].Name, job.Namespace, job.Name)
					jm.expectations.DeletionObserved(jobKey)
					activeLock.Lock()
					active++
					activeLock.Unlock()
					errCh <- err
				}
			}(i)
		}
		wait.Wait()

	} else if active < parallelism {
		wantActive := int32(0)
		if job.Spec.Completions == nil {
			// Job does not specify a number of completions.  Therefore, number active
			// should be equal to parallelism, unless the job has seen at least
			// once success, in which leave whatever is running, running.
			if succeeded > 0 {
				wantActive = active
			} else {
				wantActive = parallelism
			}
		} else {
			// Job specifies a specific number of completions.  Therefore, number
			// active should not ever exceed number of remaining completions.
			wantActive = *job.Spec.Completions - succeeded
			if wantActive > parallelism {
				wantActive = parallelism
			}
		}
		diff := wantActive - active
		if diff < 0 {
			utilruntime.HandleError(fmt.Errorf("More active than wanted: job %q, want %d, have %d", jobKey, wantActive, active))
			diff = 0
		}
		jm.expectations.ExpectCreations(jobKey, int(diff))
		errCh = make(chan error, diff)
		klog.V(4).Infof("Too few pods running job %q, need %d, creating %d", jobKey, wantActive, diff)

		active += diff
		wait := sync.WaitGroup{}

		// Batch the pod creates. Batch sizes start at SlowStartInitialBatchSize
		// and double with each successful iteration in a kind of "slow start".
		// This handles attempts to start large numbers of pods that would
		// likely all fail with the same error. For example a project with a
		// low quota that attempts to create a large number of pods will be
		// prevented from spamming the API service with the pod create requests
		// after one of its pods fails.  Conveniently, this also prevents the
		// event spam that those failures would generate.
		for batchSize := int32(integer.IntMin(int(diff), controller.SlowStartInitialBatchSize)); diff > 0; batchSize = integer.Int32Min(2*batchSize, diff) {
			errorCount := len(errCh)
			wait.Add(int(batchSize))
			for i := int32(0); i < batchSize; i++ {
				go func() {
					defer wait.Done()
					err := jm.podControl.CreatePodsWithControllerRef(job.Namespace, &job.Spec.Template, job, metav1.NewControllerRef(job, controllerKind))
					if err != nil && errors.IsTimeout(err) {
						// Pod is created but its initialization has timed out.
						// If the initialization is successful eventually, the
						// controller will observe the creation via the informer.
						// If the initialization fails, or if the pod keeps
						// uninitialized for a long time, the informer will not
						// receive any update, and the controller will create a new
						// pod when the expectation expires.
						return
					}
					if err != nil {
						defer utilruntime.HandleError(err)
						// Decrement the expected number of creates because the informer won't observe this pod
						klog.V(2).Infof("Failed creation, decrementing expectations for job %q/%q", job.Namespace, job.Name)
						jm.expectations.CreationObserved(jobKey)
						activeLock.Lock()
						active--
						activeLock.Unlock()
						errCh <- err
					}
				}()
			}
			wait.Wait()
			// any skipped pods that we never attempted to start shouldn't be expected.
			skippedPods := diff - batchSize
			if errorCount < len(errCh) && skippedPods > 0 {
				klog.V(2).Infof("Slow-start failure. Skipping creation of %d pods, decrementing expectations for job %q/%q", skippedPods, job.Namespace, job.Name)
				active -= skippedPods
				for i := int32(0); i < skippedPods; i++ {
					// Decrement the expected number of creates because the informer won't observe this pod
					jm.expectations.CreationObserved(jobKey)
				}
				// The skipped pods will be retried later. The next controller resync will
				// retry the slow start process.
				break
			}
			diff -= batchSize
		}
	}

	select {
	case err := <-errCh:
		// all errors have been reported before, we only need to inform the controller that there was an error and it should re-try this job once more next time.
		if err != nil {
			return active, err
		}
	default:
	}

	return active, nil
}
1212690
func (e *engineImpl) AbortJob(c context.Context, job *Job) error {
	if err := job.CheckRole(c, acl.Owner); err != nil {
		return err
	}
	jobID := job.JobID

	var invs []int64
	err := e.jobTxn(c, jobID, func(c context.Context, job *Job, isNew bool) (err error) {
		if isNew {
			return errSkipPut // the job was removed, nothing to abort
		}
		// We just abort all active invocations. This should cause them to
		// eventually move to Aborted state, which will kick them out of
		// ActiveInvocations list.
		invs = job.ActiveInvocations
		// AbortJob is sometimes used manually to "reset" the job state if it got
		// stuck for some reason. We initiate a triage for this purpose. This is not
		// strictly necessary (but doesn't hurt either).
		return e.kickTriageLater(c, job.JobID, 0)
	})
	if err != nil {
		return err
	}

	// Now we kill the invocations. We do it separately because it may involve
	// an RPC to remote service (e.g. to cancel a task) that can't be done from
	// the transaction.
	wg := sync.WaitGroup{}
	wg.Add(len(invs))
	errs := errors.NewLazyMultiError(len(invs))
	for i, invID := range invs {
		go func(i int, invID int64) {
			defer wg.Done()
			errs.Assign(i, e.abortInvocation(c, jobID, invID))
		}(i, invID)
	}
	wg.Wait()
	if err := errs.Get(); err != nil {
		return transient.Tag.Apply(err)
	}
	return nil
}
1168952
func (s *TopicsDetectionJobFilter) SetJobName(v string) *TopicsDetectionJobFilter {
	s.JobName = &v
	return s
}
260826
func (j *Jenkins) BuildJob(name string, options ...interface{}) (int64, error) {
	job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + name}
	var params map[string]string
	if len(options) > 0 {
		params, _ = options[0].(map[string]string)
	}
	return job.InvokeSimple(params)
}
1092965
func (client Client) GetJobConfig(jobName string) (JobConfig, error) {
	retry := retry.New(3, retry.DefaultBackoffFunc)

	var data []byte
	work := func() error {
		req, err := http.NewRequest("GET", fmt.Sprintf("%s/job/%s/config.xml", client.baseURL.String(), jobName), nil)
		if err != nil {
			return err
		}
		req.Header.Set("Accept", "application/xml")
		req.SetBasicAuth(client.userName, client.password)

		var responseCode int
		responseCode, data, err = consumeResponse(req)
		if err != nil {
			return err
		}

		if responseCode != http.StatusOK {
			Log.Printf("%s", string(data))
			return fmt.Errorf("%s", string(data))
		}
		return nil
	}
	if err := retry.Try(work); err != nil {
		return JobConfig{}, err
	}

	var config JobConfig
	reader := bytes.NewBuffer(data)
	if err := xml.NewDecoder(reader).Decode(&config); err != nil {
		return JobConfig{}, err
	}
	config.JobName = jobName
	return config, nil
}
832098
func (c *Client) DeleteAllDeadJobs() error {
	conn := c.pool.Get()
	defer conn.Close()
	_, err := conn.Do("DEL", redisKeyDead(c.namespace))
	if err != nil {
		logError("client.delete_all_dead_jobs", err)
		return err
	}

	return nil
}