// LoadData loads the build data for the given commits.
func LoadData(commits []string) (map[int]*buildbot.Build, map[string]map[string]*buildbot.BuildSummary, map[string][]*buildbot.BuilderComment, error) {
	defer timer.New("build_cache.LoadData()").Stop()
	builds, err := buildbot.GetBuildsForCommits(commits, nil)
	if err != nil {
		return nil, nil, nil, err
	}
	byId := map[int]*buildbot.Build{}
	byCommit := map[string]map[string]*buildbot.BuildSummary{}
	builders := map[string]bool{}
	for hash, buildList := range builds {
		byBuilder := map[string]*buildbot.BuildSummary{}
		for _, b := range buildList {
			byId[b.Id] = b
			if !util.AnyMatch(BOT_BLACKLIST, b.Builder) {
				byBuilder[b.Builder] = b.GetSummary()
				builders[b.Builder] = true
			}
		}
		byCommit[hash] = byBuilder
	}
	builderList := make([]string, 0, len(builders))
	for b, _ := range builders {
		builderList = append(builderList, b)
	}
	builderComments, err := buildbot.GetBuildersComments(builderList)
	if err != nil {
		return nil, nil, nil, err
	}
	return byId, byCommit, builderComments, nil
}
Exemple #2
0
// getFreeBuildslaves returns a slice of names of buildslaves which are free.
func getFreeBuildslaves() ([]*buildslave, error) {
	errMsg := "Failed to get free buildslaves: %v"
	// Get the set of builders for each master.
	builders, err := getBuilders()
	if err != nil {
		return nil, fmt.Errorf(errMsg, err)
	}

	// Get the set of buildslaves for each master.
	buildslaves, err := getBuildslaves()
	if err != nil {
		return nil, fmt.Errorf(errMsg, err)
	}

	// Map the builders to buildslaves.
	for _, b := range builders {
		// Only include builders in the whitelist, and those only if
		// there are no already-pending builds.
		if !util.AnyMatch(BOT_BLACKLIST, b.Name) && b.PendingBuilds == 0 {
			for _, slave := range b.Slaves {
				buildslaves[slave].Builders = append(buildslaves[slave].Builders, b.Name)
			}
		}
	}

	// Return the builders which are connected and idle.
	rv := []*buildslave{}
	for _, s := range buildslaves {
		if len(s.RunningBuilds) == 0 && s.Connected {
			rv = append(rv, s)
		}
	}
	return rv, nil
}
Exemple #3
0
// updateRepo syncs the given repo and returns a set of BuildCandidates for
// each builder which uses it.
func (q *BuildQueue) updateRepo(repoUrl string, now time.Time) (map[string][]*BuildCandidate, error) {
	defer timer.New("BuildQueue.updateRepo()").Stop()
	errMsg := "Failed to update the repo: %v"

	// Sync/update the code.
	repo, err := q.repos.Repo(repoUrl)
	if err != nil {
		return nil, fmt.Errorf(errMsg, err)
	}
	if err := repo.Update(true, true); err != nil {
		return nil, fmt.Errorf(errMsg, err)
	}

	// Get the details for all recent commits.
	from := now.Add(-q.period)
	if q.period == PERIOD_FOREVER {
		from = time.Unix(0, 0)
	}
	recentCommits := util.Reverse(repo.From(from))

	// Pre-load commit details, from a larger window than we actually care about.
	fromPreload := now.Add(time.Duration(int64(-1.5 * float64(q.period))))
	if q.period == PERIOD_FOREVER {
		fromPreload = time.Unix(0, 0)
	}
	recentCommitsPreload := repo.From(fromPreload)
	for _, c := range recentCommitsPreload {
		if _, err := repo.Details(c); err != nil {
			return nil, fmt.Errorf(errMsg, err)
		}
	}

	// Get all builds associated with the recent commits.
	buildsByCommit, err := buildbot.GetBuildsForCommits(recentCommitsPreload, map[int]bool{})
	if err != nil {
		return nil, fmt.Errorf(errMsg, err)
	}

	// Create buildCaches for each builder.
	buildCaches := map[string]*buildCache{}
	for _, buildsForCommit := range buildsByCommit {
		for _, build := range buildsForCommit {
			if util.AnyMatch(q.botBlacklist, build.Builder) {
				glog.Infof("Skipping blacklisted builder %s", build.Builder)
				continue
			}
			if _, ok := buildCaches[build.Builder]; !ok {
				bc, err := newBuildCache(build.Builder, build.Master, build.Repository)
				if err != nil {
					return nil, fmt.Errorf(errMsg, err)
				}
				buildCaches[build.Builder] = bc
			}
			if err := buildCaches[build.Builder].Put(build); err != nil {
				return nil, err
			}
		}
	}

	// Find candidates for each builder.
	candidates := map[string][]*BuildCandidate{}
	errs := map[string]error{}
	mutex := sync.Mutex{}
	var wg sync.WaitGroup
	for builder, finder := range buildCaches {
		wg.Add(1)
		go func(b string, bc *buildCache) {
			defer wg.Done()
			c, err := q.getCandidatesForBuilder(bc, recentCommits, now)
			mutex.Lock()
			defer mutex.Unlock()
			if err != nil {
				errs[b] = err
				return
			}
			candidates[b] = c
		}(builder, finder)
	}
	wg.Wait()
	if len(errs) > 0 {
		msg := "Failed to update the repo:"
		for _, err := range errs {
			msg += fmt.Sprintf("\n%v", err)
		}
		return nil, fmt.Errorf(msg)
	}
	return candidates, nil
}