Add pool balancing strategy

This change adds the ability to specify the pool balancing strategy to
use when processing queued jobs. Before this change, GARM would round-robin
through all pools that matched the set of tags requested by queued jobs.

When round-robin (default) is used for an entity (repo, org or enterprise)
and you have 2 pools defined for that entity with a common set of tags that
match 10 jobs (for example), then those jobs would trigger the creation of
a new runner in each of the two pools in turn. Job 1 would go to pool 1,
job 2 would go to pool 2, job 3 to pool 1, job 4 to pool 2 and so on.

When "stack" is used, those same 10 jobs would trigger the creation of a
new runner in the pool with the highest priority, every time.

In both cases, if a pool is full, the next one would be tried automatically.

For the stack case, this would mean that if pool 2 had a priority of 10 and
pool 1 would have a priority of 5, pool 2 would be saturated first, then
pool 1.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2024-03-14 20:04:34 +00:00
parent 569d512819
commit ce3c917ae5
34 changed files with 362 additions and 137 deletions

View file

@ -13,7 +13,7 @@ import (
"github.com/cloudbase/garm/params"
)
func (s *sqlDatabase) CreateEnterprise(_ context.Context, name, credentialsName, webhookSecret string) (params.Enterprise, error) {
func (s *sqlDatabase) CreateEnterprise(_ context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error) {
if webhookSecret == "" {
return params.Enterprise{}, errors.New("creating enterprise: missing secret")
}
@ -22,9 +22,10 @@ func (s *sqlDatabase) CreateEnterprise(_ context.Context, name, credentialsName,
return params.Enterprise{}, errors.Wrap(err, "encoding secret")
}
newEnterprise := Enterprise{
Name: name,
WebhookSecret: secret,
CredentialsName: credentialsName,
Name: name,
WebhookSecret: secret,
CredentialsName: credentialsName,
PoolBalancerType: poolBalancerType,
}
q := s.conn.Create(&newEnterprise)
@ -117,6 +118,10 @@ func (s *sqlDatabase) UpdateEnterprise(ctx context.Context, enterpriseID string,
enterprise.WebhookSecret = secret
}
if param.PoolBalancerType != "" {
enterprise.PoolBalancerType = param.PoolBalancerType
}
q := s.conn.Save(&enterprise)
if q.Error != nil {
return params.Enterprise{}, errors.Wrap(q.Error, "saving enterprise")
@ -152,6 +157,7 @@ func (s *sqlDatabase) CreateEnterprisePool(ctx context.Context, enterpriseID str
Enabled: param.Enabled,
RunnerBootstrapTimeout: param.RunnerBootstrapTimeout,
GitHubRunnerGroup: param.GitHubRunnerGroup,
Priority: param.Priority,
}
if len(param.ExtraSpecs) > 0 {