77 "errors"
88 "fmt"
99 "strings"
10+ "time"
1011
11- "code.gitea.io/gitea/models"
1212 admin_model "code.gitea.io/gitea/models/admin"
1313 "code.gitea.io/gitea/models/db"
1414 repo_model "code.gitea.io/gitea/models/repo"
@@ -28,13 +28,13 @@ import (
2828func handleCreateError (owner * user_model.User , err error ) error {
2929 switch {
3030 case repo_model .IsErrReachLimitOfRepo (err ):
31- return fmt .Errorf ("You have already reached your limit of %d repositories" , owner .MaxCreationLimit ())
31+ return fmt .Errorf ("you have already reached your limit of %d repositories" , owner .MaxCreationLimit ())
3232 case repo_model .IsErrRepoAlreadyExist (err ):
33- return errors .New ("The repository name is already used" )
33+ return errors .New ("the repository name is already used" )
3434 case db .IsErrNameReserved (err ):
35- return fmt .Errorf ("The repository name '%s' is reserved" , err .(db.ErrNameReserved ).Name )
35+ return fmt .Errorf ("the repository name '%s' is reserved" , err .(db.ErrNameReserved ).Name )
3636 case db .IsErrNamePatternNotAllowed (err ):
37- return fmt .Errorf ("The pattern '%s' is not allowed in a repository name" , err .(db.ErrNamePatternNotAllowed ).Pattern )
37+ return fmt .Errorf ("the pattern '%s' is not allowed in a repository name" , err .(db.ErrNamePatternNotAllowed ).Pattern )
3838 default :
3939 return err
4040 }
@@ -57,22 +57,17 @@ func runMigrateTask(t *admin_model.Task) (err error) {
5757 log .Error ("FinishMigrateTask[%d] by DoerID[%d] to RepoID[%d] for OwnerID[%d] failed: %v" , t .ID , t .DoerID , t .RepoID , t .OwnerID , err )
5858 }
5959
60+ log .Error ("runMigrateTask[%d] by DoerID[%d] to RepoID[%d] for OwnerID[%d] failed: %v" , t .ID , t .DoerID , t .RepoID , t .OwnerID , err )
61+
6062 t .EndTime = timeutil .TimeStampNow ()
6163 t .Status = structs .TaskStatusFailed
6264 t .Message = err .Error ()
63- // Ensure that the repo loaded before we zero out the repo ID from the task - thus ensuring that we can delete it
64- _ = t .LoadRepo ()
6565
66- t .RepoID = 0
67- if err := t .UpdateCols ("status" , "errors" , "repo_id" , "end_time" ); err != nil {
66+ if err := t .UpdateCols ("status" , "message" , "end_time" ); err != nil {
6867 log .Error ("Task UpdateCols failed: %v" , err )
6968 }
7069
71- if t .Repo != nil {
72- if errDelete := models .DeleteRepository (t .Doer , t .OwnerID , t .Repo .ID ); errDelete != nil {
73- log .Error ("DeleteRepository: %v" , errDelete )
74- }
75- }
70+ // then, do not delete the repository, otherwise the users won't be able to see the last error
7671 }()
7772
7873 if err = t .LoadRepo (); err != nil {
@@ -100,7 +95,7 @@ func runMigrateTask(t *admin_model.Task) (err error) {
10095 opts .MigrateToRepoID = t .RepoID
10196
10297 pm := process .GetManager ()
103- ctx , _ , finished := pm .AddContext (graceful .GetManager ().ShutdownContext (), fmt .Sprintf ("MigrateTask: %s/%s" , t .Owner .Name , opts .RepoName ))
98+ ctx , cancel , finished := pm .AddContext (graceful .GetManager ().ShutdownContext (), fmt .Sprintf ("MigrateTask: %s/%s" , t .Owner .Name , opts .RepoName ))
10499 defer finished ()
105100
106101 t .StartTime = timeutil .TimeStampNow ()
@@ -109,6 +104,23 @@ func runMigrateTask(t *admin_model.Task) (err error) {
109104 return
110105 }
111106
107+ // check whether the task should be canceled, this goroutine is also managed by process manager
108+ go func () {
109+ for {
110+ select {
111+ case <- time .After (2 * time .Second ):
112+ case <- ctx .Done ():
113+ return
114+ }
115+ task , _ := admin_model .GetMigratingTask (t .RepoID )
116+ if task != nil && task .Status != structs .TaskStatusRunning {
117+ log .Debug ("MigrateTask[%d] by DoerID[%d] to RepoID[%d] for OwnerID[%d] is canceled due to status is not 'running'" , t .ID , t .DoerID , t .RepoID , t .OwnerID )
118+ cancel ()
119+ return
120+ }
121+ }
122+ }()
123+
112124 t .Repo , err = migrations .MigrateRepository (ctx , t .Doer , t .Owner .Name , * opts , func (format string , args ... interface {}) {
113125 message := admin_model.TranslatableMessage {
114126 Format : format ,
@@ -118,23 +130,24 @@ func runMigrateTask(t *admin_model.Task) (err error) {
118130 t .Message = string (bs )
119131 _ = t .UpdateCols ("message" )
120132 })
133+
121134 if err == nil {
122135 log .Trace ("Repository migrated [%d]: %s/%s" , t .Repo .ID , t .Owner .Name , t .Repo .Name )
123136 return
124137 }
125138
126139 if repo_model .IsErrRepoAlreadyExist (err ) {
127- err = errors .New ("The repository name is already used" )
140+ err = errors .New ("the repository name is already used" )
128141 return
129142 }
130143
131144 // remoteAddr may contain credentials, so we sanitize it
132145 err = util .SanitizeErrorCredentialURLs (err )
133146 if strings .Contains (err .Error (), "Authentication failed" ) ||
134147 strings .Contains (err .Error (), "could not read Username" ) {
135- return fmt .Errorf ("Authentication failed: %w" , err )
148+ return fmt .Errorf ("authentication failed: %w" , err )
136149 } else if strings .Contains (err .Error (), "fatal:" ) {
137- return fmt .Errorf ("Migration failed: %w" , err )
150+ return fmt .Errorf ("migration failed: %w" , err )
138151 }
139152
140153 // do not be tempted to coalesce this line with the return
0 commit comments