1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00
wxiaoguang
2023-05-11 16:25:46 +08:00
committed by GitHub
parent 58dfaf3a75
commit f6e029e6c7
10 changed files with 128 additions and 106 deletions

View File

@@ -7,8 +7,8 @@ import (
"errors"
"fmt"
"strings"
"time"
"code.gitea.io/gitea/models"
admin_model "code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
@@ -28,13 +28,13 @@ import (
func handleCreateError(owner *user_model.User, err error) error {
switch {
case repo_model.IsErrReachLimitOfRepo(err):
return fmt.Errorf("You have already reached your limit of %d repositories", owner.MaxCreationLimit())
return fmt.Errorf("you have already reached your limit of %d repositories", owner.MaxCreationLimit())
case repo_model.IsErrRepoAlreadyExist(err):
return errors.New("The repository name is already used")
return errors.New("the repository name is already used")
case db.IsErrNameReserved(err):
return fmt.Errorf("The repository name '%s' is reserved", err.(db.ErrNameReserved).Name)
return fmt.Errorf("the repository name '%s' is reserved", err.(db.ErrNameReserved).Name)
case db.IsErrNamePatternNotAllowed(err):
return fmt.Errorf("The pattern '%s' is not allowed in a repository name", err.(db.ErrNamePatternNotAllowed).Pattern)
return fmt.Errorf("the pattern '%s' is not allowed in a repository name", err.(db.ErrNamePatternNotAllowed).Pattern)
default:
return err
}
@@ -57,22 +57,17 @@ func runMigrateTask(t *admin_model.Task) (err error) {
log.Error("FinishMigrateTask[%d] by DoerID[%d] to RepoID[%d] for OwnerID[%d] failed: %v", t.ID, t.DoerID, t.RepoID, t.OwnerID, err)
}
log.Error("runMigrateTask[%d] by DoerID[%d] to RepoID[%d] for OwnerID[%d] failed: %v", t.ID, t.DoerID, t.RepoID, t.OwnerID, err)
t.EndTime = timeutil.TimeStampNow()
t.Status = structs.TaskStatusFailed
t.Message = err.Error()
// Ensure that the repo loaded before we zero out the repo ID from the task - thus ensuring that we can delete it
_ = t.LoadRepo()
t.RepoID = 0
if err := t.UpdateCols("status", "errors", "repo_id", "end_time"); err != nil {
if err := t.UpdateCols("status", "message", "end_time"); err != nil {
log.Error("Task UpdateCols failed: %v", err)
}
if t.Repo != nil {
if errDelete := models.DeleteRepository(t.Doer, t.OwnerID, t.Repo.ID); errDelete != nil {
log.Error("DeleteRepository: %v", errDelete)
}
}
// then, do not delete the repository, otherwise the users won't be able to see the last error
}()
if err = t.LoadRepo(); err != nil {
@@ -100,7 +95,7 @@ func runMigrateTask(t *admin_model.Task) (err error) {
opts.MigrateToRepoID = t.RepoID
pm := process.GetManager()
ctx, _, finished := pm.AddContext(graceful.GetManager().ShutdownContext(), fmt.Sprintf("MigrateTask: %s/%s", t.Owner.Name, opts.RepoName))
ctx, cancel, finished := pm.AddContext(graceful.GetManager().ShutdownContext(), fmt.Sprintf("MigrateTask: %s/%s", t.Owner.Name, opts.RepoName))
defer finished()
t.StartTime = timeutil.TimeStampNow()
@@ -109,6 +104,23 @@ func runMigrateTask(t *admin_model.Task) (err error) {
return
}
// check whether the task should be canceled, this goroutine is also managed by process manager
go func() {
for {
select {
case <-time.After(2 * time.Second):
case <-ctx.Done():
return
}
task, _ := admin_model.GetMigratingTask(t.RepoID)
if task != nil && task.Status != structs.TaskStatusRunning {
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)
cancel()
return
}
}
}()
t.Repo, err = migrations.MigrateRepository(ctx, t.Doer, t.Owner.Name, *opts, func(format string, args ...interface{}) {
message := admin_model.TranslatableMessage{
Format: format,
@@ -118,13 +130,14 @@ func runMigrateTask(t *admin_model.Task) (err error) {
t.Message = string(bs)
_ = t.UpdateCols("message")
})
if err == nil {
log.Trace("Repository migrated [%d]: %s/%s", t.Repo.ID, t.Owner.Name, t.Repo.Name)
return
}
if repo_model.IsErrRepoAlreadyExist(err) {
err = errors.New("The repository name is already used")
err = errors.New("the repository name is already used")
return
}
@@ -132,9 +145,9 @@ func runMigrateTask(t *admin_model.Task) (err error) {
err = util.SanitizeErrorCredentialURLs(err)
if strings.Contains(err.Error(), "Authentication failed") ||
strings.Contains(err.Error(), "could not read Username") {
return fmt.Errorf("Authentication failed: %w", err)
return fmt.Errorf("authentication failed: %w", err)
} else if strings.Contains(err.Error(), "fatal:") {
return fmt.Errorf("Migration failed: %w", err)
return fmt.Errorf("migration failed: %w", err)
}
// do not be tempted to coalesce this line with the return

View File

@@ -95,7 +95,7 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*adm
DoerID: doer.ID,
OwnerID: u.ID,
Type: structs.TaskTypeMigrateRepo,
Status: structs.TaskStatusQueue,
Status: structs.TaskStatusQueued,
PayloadContent: string(bs),
}