Пример #1
0
func (s jobService) CanBuildBeScheduled(logger lager.Logger, build db.Build, buildPrep db.BuildPreparation, versions *algorithm.VersionsDB) ([]db.BuildInput, bool, string, error) {
	if build.Scheduled {
		return s.updateBuildPrepAndReturn(buildPrep, true, "build-scheduled")
	}

	paused, err := s.DB.IsPaused()
	if err != nil {
		return []db.BuildInput{}, false, "pause-pipeline-db-failed", err
	}

	if paused {
		buildPrep.PausedPipeline = db.BuildPreparationStatusBlocking
		return s.updateBuildPrepAndReturn(buildPrep, false, "pipeline-paused")
	}

	buildPrep.PausedPipeline = db.BuildPreparationStatusNotBlocking
	err = s.DB.UpdateBuildPreparation(buildPrep)
	if err != nil {
		return []db.BuildInput{}, false, "update-build-prep-db-failed-pipeline-not-paused", err
	}

	if s.DBJob.Paused {
		buildPrep.PausedJob = db.BuildPreparationStatusBlocking
		return s.updateBuildPrepAndReturn(buildPrep, false, "job-paused")
	}

	buildPrep.PausedJob = db.BuildPreparationStatusNotBlocking
	err = s.DB.UpdateBuildPreparation(buildPrep)
	if err != nil {
		return []db.BuildInput{}, false, "update-build-prep-db-failed-job-not-paused", err
	}

	if build.Status != db.StatusPending {
		return []db.BuildInput{}, false, "build-not-pending", nil
	}

	buildInputs, buildPrep, message, err := s.getBuildInputs(logger, build, buildPrep, versions)
	if err != nil || message != "" {
		return []db.BuildInput{}, false, message, err
	}

	buildPrep.MaxRunningBuilds = db.BuildPreparationStatusBlocking
	err = s.DB.UpdateBuildPreparation(buildPrep)
	if err != nil {
		return []db.BuildInput{}, false, "update-build-prep-db-failed-pipeline-not-paused", err
	}

	maxInFlight := s.JobConfig.MaxInFlight()

	if maxInFlight > 0 {
		builds, err := s.DB.GetRunningBuildsBySerialGroup(s.DBJob.Name, s.JobConfig.GetSerialGroups())
		if err != nil {
			return []db.BuildInput{}, false, "db-failed", err
		}

		if len(builds) >= maxInFlight {
			buildPrep.MaxRunningBuilds = db.BuildPreparationStatusBlocking
			return s.updateBuildPrepAndReturn(buildPrep, false, "max-in-flight-reached")
		}

		nextMostPendingBuild, found, err := s.DB.GetNextPendingBuildBySerialGroup(s.DBJob.Name, s.JobConfig.GetSerialGroups())
		if err != nil {
			return []db.BuildInput{}, false, "db-failed", err
		}

		if !found {
			return []db.BuildInput{}, false, "no-pending-build", nil
		}

		if nextMostPendingBuild.ID != build.ID {
			return []db.BuildInput{}, false, "not-next-most-pending", nil
		}
	}

	buildPrep.MaxRunningBuilds = db.BuildPreparationStatusNotBlocking
	err = s.DB.UpdateBuildPreparation(buildPrep)
	if err != nil {
		return []db.BuildInput{}, false, "update-build-prep-db-failed-not-max-running-builds", err
	}

	return buildInputs, true, "can-be-scheduled", nil
}