diff options
Diffstat (limited to 'models/actions/runner.go')
-rw-r--r-- | models/actions/runner.go | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/models/actions/runner.go b/models/actions/runner.go index 0d5464a5be..81d4249ae0 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -5,6 +5,7 @@ package actions import ( "context" + "errors" "fmt" "strings" "time" @@ -14,6 +15,7 @@ import ( "code.gitea.io/gitea/models/shared/types" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/optional" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/util" @@ -57,6 +59,8 @@ type ActionRunner struct { // Store labels defined in state file (default: .runner file) of `act_runner` AgentLabels []string `xorm:"TEXT"` + // Store if this is a runner that only ever get one single job assigned + Ephemeral bool `xorm:"ephemeral NOT NULL DEFAULT false"` Created timeutil.TimeStamp `xorm:"created"` Updated timeutil.TimeStamp `xorm:"updated"` @@ -84,9 +88,10 @@ func (r *ActionRunner) BelongsToOwnerType() types.OwnerType { return types.OwnerTypeRepository } if r.OwnerID != 0 { - if r.Owner.Type == user_model.UserTypeOrganization { + switch r.Owner.Type { + case user_model.UserTypeOrganization: return types.OwnerTypeOrganization - } else if r.Owner.Type == user_model.UserTypeIndividual { + case user_model.UserTypeIndividual: return types.OwnerTypeIndividual } } @@ -120,8 +125,15 @@ func (r *ActionRunner) IsOnline() bool { return false } -// Editable checks if the runner is editable by the user -func (r *ActionRunner) Editable(ownerID, repoID int64) bool { +// EditableInContext checks if the runner is editable by the "context" owner/repo +// ownerID == 0 and repoID == 0 means "admin" context, any runner including global runners could be edited +// ownerID == 0 and repoID != 0 means "repo" context, any runner belonging to the given repo could be edited +// ownerID != 0 and repoID == 0 means "owner(org/user)" context, any runner belonging to the given user/org could be edited +// ownerID != 0 and repoID != 0 means "owner" OR "repo" context, legacy behavior, but we should forbid using it +func (r *ActionRunner) EditableInContext(ownerID, repoID int64) bool { + if ownerID != 0 && repoID != 0 { + setting.PanicInDevOrTesting("ownerID and repoID should not be both set") + } if ownerID == 0 && repoID == 0 { return true } @@ -165,8 +177,15 @@ func init() { db.RegisterModel(&ActionRunner{}) } +// FindRunnerOptions +// ownerID == 0 and repoID == 0 means any runner including global runners +// repoID != 0 and WithAvailable == false means any runner for the given repo +// repoID != 0 and WithAvailable == true means any runner for the given repo, parent user/org, and global runners +// ownerID != 0 and repoID == 0 and WithAvailable == false means any runner for the given user/org +// ownerID != 0 and repoID == 0 and WithAvailable == true means any runner for the given user/org and global runners type FindRunnerOptions struct { db.ListOptions + IDs []int64 RepoID int64 OwnerID int64 // it will be ignored if RepoID is set Sort string @@ -178,6 +197,14 @@ type FindRunnerOptions struct { func (opts FindRunnerOptions) ToConds() builder.Cond { cond := builder.NewCond() + if len(opts.IDs) > 0 { + if len(opts.IDs) == 1 { + cond = cond.And(builder.Eq{"id": opts.IDs[0]}) + } else { + cond = cond.And(builder.In("id", opts.IDs)) + } + } + if opts.RepoID > 0 { c := builder.NewCond().And(builder.Eq{"repo_id": opts.RepoID}) if opts.WithAvailable { @@ -272,6 +299,23 @@ func DeleteRunner(ctx context.Context, id int64) error { return err } +// DeleteEphemeralRunner deletes a ephemeral runner by given ID. +func DeleteEphemeralRunner(ctx context.Context, id int64) error { + runner, err := GetRunnerByID(ctx, id) + if err != nil { + if errors.Is(err, util.ErrNotExist) { + return nil + } + return err + } + if !runner.Ephemeral { + return nil + } + + _, err = db.DeleteByID[ActionRunner](ctx, id) + return err +} + // CreateRunner creates new runner. func CreateRunner(ctx context.Context, t *ActionRunner) error { if t.OwnerID != 0 && t.RepoID != 0 { @@ -328,3 +372,17 @@ func FixRunnersWithoutBelongingRepo(ctx context.Context) (int64, error) { } return res.RowsAffected() } + +func CountWrongRepoLevelRunners(ctx context.Context) (int64, error) { + var result int64 + _, err := db.GetEngine(ctx).SQL("SELECT count(`id`) FROM `action_runner` WHERE `repo_id` > 0 AND `owner_id` > 0").Get(&result) + return result, err +} + +func UpdateWrongRepoLevelRunners(ctx context.Context) (int64, error) { + result, err := db.GetEngine(ctx).Exec("UPDATE `action_runner` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0") + if err != nil { + return 0, err + } + return result.RowsAffected() +} |