loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Redefine the meaning of column is_active to make Actions Registration Token generation easier (#27143)

Partially Fix #25041

This PR redefined the meaning of column `is_active` in table
`action_runner_token`.
Before this PR, `is_active` means whether it has been used by any
runner. If it's true, other runner cannot use it to register again.

In this PR, `is_active` means whether it's validated to be used to
register runner. And if it's true, then it can be used to register
runners until it become false. When creating a new `is_active` register
token, any previous tokens will be set `is_active` to false.

authored by

Lunny Xiao and committed by
GitHub
3b2da7e4 ee27b94b

+26 -16
+18 -8
models/actions/runner_token.go
··· 22 22 Owner *user_model.User `xorm:"-"` 23 23 RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global 24 24 Repo *repo_model.Repository `xorm:"-"` 25 - IsActive bool 25 + IsActive bool // true means it can be used 26 26 27 27 Created timeutil.TimeStamp `xorm:"created"` 28 28 Updated timeutil.TimeStamp `xorm:"updated"` ··· 57 57 return err 58 58 } 59 59 60 - // NewRunnerToken creates a new runner token 60 + // NewRunnerToken creates a new active runner token and invalidate all old tokens 61 61 func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) { 62 62 token, err := util.CryptoRandomString(40) 63 63 if err != nil { ··· 66 66 runnerToken := &ActionRunnerToken{ 67 67 OwnerID: ownerID, 68 68 RepoID: repoID, 69 - IsActive: false, 69 + IsActive: true, 70 70 Token: token, 71 71 } 72 - _, err = db.GetEngine(ctx).Insert(runnerToken) 73 - return runnerToken, err 72 + 73 + return runnerToken, db.WithTx(ctx, func(ctx context.Context) error { 74 + if _, err := db.GetEngine(ctx).Where("owner_id =? AND repo_id = ?", ownerID, repoID).Cols("is_active").Update(&ActionRunnerToken{ 75 + IsActive: false, 76 + }); err != nil { 77 + return err 78 + } 79 + 80 + _, err = db.GetEngine(ctx).Insert(runnerToken) 81 + return err 82 + }) 74 83 } 75 84 76 - // GetUnactivatedRunnerToken returns a unactivated runner token 77 - func GetUnactivatedRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) { 85 + // GetLastestRunnerToken returns the latest runner token 86 + func GetLastestRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) { 78 87 var runnerToken ActionRunnerToken 79 - has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=? AND is_active=?", ownerID, repoID, false).OrderBy("id DESC").Get(&runnerToken) 88 + has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=?", ownerID, repoID). 89 + OrderBy("id DESC").Get(&runnerToken) 80 90 if err != nil { 81 91 return nil, err 82 92 } else if !has {
+3 -3
routers/api/actions/runner/runner.go
··· 47 47 48 48 runnerToken, err := actions_model.GetRunnerToken(ctx, req.Msg.Token) 49 49 if err != nil { 50 - return nil, errors.New("runner token not found") 50 + return nil, errors.New("runner registration token not found") 51 51 } 52 52 53 - if runnerToken.IsActive { 54 - return nil, errors.New("runner token has already been activated") 53 + if !runnerToken.IsActive { 54 + return nil, errors.New("runner registration token has been invalidated, please use the latest one") 55 55 } 56 56 57 57 labels := req.Msg.Labels
+2 -2
routers/private/actions.go
··· 41 41 }) 42 42 } 43 43 44 - token, err := actions_model.GetUnactivatedRunnerToken(ctx, owner, repo) 45 - if errors.Is(err, util.ErrNotExist) { 44 + token, err := actions_model.GetLastestRunnerToken(ctx, owner, repo) 45 + if errors.Is(err, util.ErrNotExist) || (token != nil && !token.IsActive) { 46 46 token, err = actions_model.NewRunnerToken(ctx, owner, repo) 47 47 if err != nil { 48 48 err := fmt.Sprintf("error while creating runner token: %v", err)
+3 -3
routers/web/shared/actions/runners.go
··· 35 35 36 36 // ownid=0,repo_id=0,means this token is used for global 37 37 var token *actions_model.ActionRunnerToken 38 - token, err = actions_model.GetUnactivatedRunnerToken(ctx, opts.OwnerID, opts.RepoID) 39 - if errors.Is(err, util.ErrNotExist) { 38 + token, err = actions_model.GetLastestRunnerToken(ctx, opts.OwnerID, opts.RepoID) 39 + if errors.Is(err, util.ErrNotExist) || (token != nil && !token.IsActive) { 40 40 token, err = actions_model.NewRunnerToken(ctx, opts.OwnerID, opts.RepoID) 41 41 if err != nil { 42 42 ctx.ServerError("CreateRunnerToken", err) 43 43 return 44 44 } 45 45 } else if err != nil { 46 - ctx.ServerError("GetUnactivatedRunnerToken", err) 46 + ctx.ServerError("GetLastestRunnerToken", err) 47 47 return 48 48 } 49 49