Beispiel #1
0
// TryResetTask resets a task
func TryResetTask(taskId, user, origin string, p *Project, detail *apimodels.TaskEndDetail) (err error) {
	t, err := task.FindOne(task.ById(taskId))
	if err != nil {
		return err
	}
	// if we've reached the max number of executions for this task, mark it as finished and failed
	if t.Execution >= evergreen.MaxTaskExecution {
		// restarting from the UI bypasses the restart cap
		message := fmt.Sprintf("Task '%v' reached max execution (%v):", t.Id, evergreen.MaxTaskExecution)
		if origin == evergreen.UIPackage {
			evergreen.Logger.Logf(slogger.DEBUG, "%v allowing exception for %v", message, user)
		} else {
			evergreen.Logger.Logf(slogger.DEBUG, "%v marking as failed", message)
			if detail != nil {
				return MarkEnd(t.Id, origin, time.Now(), detail, p, false)
			} else {
				panic(fmt.Sprintf("TryResetTask called with nil TaskEndDetail by %v", origin))
			}
		}
	}

	// only allow re-execution for failed or successful tasks
	if !task.IsFinished(*t) {
		// this is to disallow terminating running tasks via the UI
		if origin == evergreen.UIPackage {
			evergreen.Logger.Logf(slogger.DEBUG, "Unsatisfiable '%v' reset request on '%v' (status: '%v')", user, t.Id, t.Status)
			return fmt.Errorf("Task '%v' is currently '%v' - can not reset task in this status", t.Id, t.Status)
		}
	}

	if detail != nil {
		if err = t.MarkEnd(origin, time.Now(), detail); err != nil {
			return fmt.Errorf("Error marking task as ended: %v", err)
		}
	}

	if err = resetTask(t.Id); err == nil {
		if origin == evergreen.UIPackage {
			event.LogTaskRestarted(t.Id, user)
		} else {
			event.LogTaskRestarted(t.Id, origin)
		}
	}
	return err
}
Beispiel #2
0
// ActivatePreviousTask will set the Active state for the first task with a
// revision order number less than the current task's revision order number.
func ActivatePreviousTask(taskId, caller string) error {
	// find the task first
	t, err := task.FindOne(task.ById(taskId))
	if err != nil {
		return err
	}

	// find previous task limiting to just the last one
	prevTask, err := task.FindOne(task.ByBeforeRevision(t.RevisionOrderNumber, t.BuildVariant, t.DisplayName, t.Project, t.Requester))
	if err != nil {
		return fmt.Errorf("Error finding previous task: %v:", err.Error())
	}

	// if this is the first time we're running the task, or it's finished or it is blacklisted
	if prevTask == nil || task.IsFinished(*prevTask) || prevTask.Priority < 0 {
		return nil
	}
	// activate the task
	if err = SetActiveState(prevTask.Id, caller, true); err != nil {
		return err
	}
	return nil
}
Beispiel #3
0
// UpdateBuildStatusForTask finds all the builds for a task and updates the
// status of the build based on the task's status.
func UpdateBuildAndVersionStatusForTask(taskId string) error {
	// retrieve the task by the task id
	t, err := task.FindOne(task.ById(taskId))
	if err != nil {
		return err
	}

	finishTime := time.Now()
	// get all of the tasks in the same build
	b, err := build.FindOne(build.ById(t.BuildId))
	if err != nil {
		return err
	}

	buildTasks, err := task.Find(task.ByBuildId(b.Id))
	if err != nil {
		return err
	}

	pushTaskExists := false
	for _, t := range buildTasks {
		if t.DisplayName == evergreen.PushStage {
			pushTaskExists = true
		}
	}

	failedTask := false
	pushSuccess := true
	pushCompleted := false
	finishedTasks := 0

	// update the build's status based on tasks for this build
	for _, t := range buildTasks {
		if task.IsFinished(t) {
			finishedTasks += 1
			// if it was a compile task, mark the build status accordingly
			if t.DisplayName == evergreen.CompileStage {
				if t.Status != evergreen.TaskSucceeded {
					failedTask = true
					finishedTasks = -1
					err = b.MarkFinished(evergreen.BuildFailed, finishTime)
					if err != nil {
						evergreen.Logger.Errorf(slogger.ERROR, "Error marking build as finished: %v", err)
						return err
					}
					break
				}
			} else if t.DisplayName == evergreen.PushStage {
				pushCompleted = true
				// if it's a finished push, check if it was successful
				if t.Status != evergreen.TaskSucceeded {
					err = b.UpdateStatus(evergreen.BuildFailed)
					if err != nil {
						evergreen.Logger.Errorf(slogger.ERROR, "Error updating build status: %v", err)
						return err
					}
					pushSuccess = false
				}
			} else {
				// update the build's status when a test task isn't successful
				if t.Status != evergreen.TaskSucceeded {
					err = b.UpdateStatus(evergreen.BuildFailed)
					if err != nil {
						evergreen.Logger.Errorf(slogger.ERROR, "Error updating build status: %v", err)
						return err
					}
					failedTask = true
				}
			}
		}
	}

	// if there are no failed tasks, mark the build as started
	if !failedTask {
		err = b.UpdateStatus(evergreen.BuildStarted)
		if err != nil {
			evergreen.Logger.Errorf(slogger.ERROR, "Error updating build status: %v", err)
			return err
		}
	}
	// if a compile task didn't fail, then the
	// build is only finished when both the compile
	// and test tasks are completed or when those are
	// both completed in addition to a push (a push
	// does not occur if there's a failed task)
	if finishedTasks >= len(buildTasks)-1 {
		if !failedTask {
			if pushTaskExists { // this build has a push task associated with it.
				if pushCompleted && pushSuccess { // the push succeeded, so mark the build as succeeded.
					err = b.MarkFinished(evergreen.BuildSucceeded, finishTime)
					if err != nil {
						evergreen.Logger.Errorf(slogger.ERROR, "Error marking build as finished: %v", err)
						return err
					}
				} else if pushCompleted && !pushSuccess { // the push failed, mark build failed.
					err = b.MarkFinished(evergreen.BuildFailed, finishTime)
					if err != nil {
						evergreen.Logger.Errorf(slogger.ERROR, "Error marking build as finished: %v", err)
						return err
					}
				} else {
					//This build does have a "push" task, but it hasn't finished yet
					//So do nothing, since we don't know the status yet.
				}
				if err = MarkVersionCompleted(b.Version, finishTime); err != nil {
					evergreen.Logger.Errorf(slogger.ERROR, "Error marking version as finished: %v", err)
					return err
				}
			} else { // this build has no push task. so go ahead and mark it success/failure.
				if err = b.MarkFinished(evergreen.BuildSucceeded, finishTime); err != nil {
					evergreen.Logger.Errorf(slogger.ERROR, "Error marking build as finished: %v", err)
					return err
				}
				if b.Requester == evergreen.PatchVersionRequester {
					if err = TryMarkPatchBuildFinished(b, finishTime); err != nil {
						evergreen.Logger.Errorf(slogger.ERROR, "Error marking patch as finished: %v", err)
						return err
					}
				}
				if err = MarkVersionCompleted(b.Version, finishTime); err != nil {
					evergreen.Logger.Errorf(slogger.ERROR, "Error marking version as finished: %v", err)
					return err
				}
			}
		} else {
			// some task failed
			if err = b.MarkFinished(evergreen.BuildFailed, finishTime); err != nil {
				evergreen.Logger.Errorf(slogger.ERROR, "Error marking build as finished: %v", err)
				return err
			}
			if b.Requester == evergreen.PatchVersionRequester {
				if err = TryMarkPatchBuildFinished(b, finishTime); err != nil {
					evergreen.Logger.Errorf(slogger.ERROR, "Error marking patch as finished: %v", err)
					return err
				}
			}
			if err = MarkVersionCompleted(b.Version, finishTime); err != nil {
				evergreen.Logger.Errorf(slogger.ERROR, "Error marking version as finished: %v", err)
				return err
			}
		}

		// update the build's makespan information if the task has finished
		err = updateMakespans(b)
		if err != nil {
			evergreen.Logger.Errorf(slogger.ERROR, "Error updating makespan information: %v", err)
			return err
		}
	}

	// this is helpful for when we restart a compile task
	if finishedTasks == 0 {
		err = b.UpdateStatus(evergreen.BuildCreated)
		if err != nil {
			evergreen.Logger.Errorf(slogger.ERROR, "Error updating build status: %v", err)
			return err
		}
	}

	return nil
}