aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2020-10-24 00:46:35 +0100
committerGitHub <noreply@github.com>2020-10-23 19:46:35 -0400
commitf40a2a4404e3eabf5e28ae43e1f395bb13176307 (patch)
treee4c0ece7b11704eba0e9e60cb10158dbb5399db8
parent9b11c3e32037a77e53551127d26dbf54139aa2fc (diff)
downloadgitea-f40a2a4404e3eabf5e28ae43e1f395bb13176307.tar.gz
gitea-f40a2a4404e3eabf5e28ae43e1f395bb13176307.zip
Store task errors following migrations and display them (#13246)
* Store task errors following migrations and display them When migrate tasks fail store the error in the task table and ensure that they show on the status page. Fix #13242 Signed-off-by: Andrew Thornton <art27@cantab.net> * Update web_src/js/index.js * Hide the failed first Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
-rw-r--r--models/task.go21
-rw-r--r--modules/task/migrate.go39
-rw-r--r--public/img/failed.pngbin0 -> 11009 bytes
-rw-r--r--routers/repo/repo.go16
-rw-r--r--routers/routes/routes.go3
-rw-r--r--routers/user/task.go30
-rw-r--r--templates/repo/migrate/migrating.tmpl8
-rw-r--r--web_src/js/index.js19
8 files changed, 95 insertions, 41 deletions
diff --git a/models/task.go b/models/task.go
index 43cb2d4d9a..b86314b449 100644
--- a/models/task.go
+++ b/models/task.go
@@ -147,6 +147,27 @@ func GetMigratingTask(repoID int64) (*Task, error) {
return &task, nil
}
+// GetMigratingTaskByID returns the migrating task by repo's id
+func GetMigratingTaskByID(id, doerID int64) (*Task, *migration.MigrateOptions, error) {
+ var task = Task{
+ ID: id,
+ DoerID: doerID,
+ Type: structs.TaskTypeMigrateRepo,
+ }
+ has, err := x.Get(&task)
+ if err != nil {
+ return nil, nil, err
+ } else if !has {
+ return nil, nil, ErrTaskDoesNotExist{id, 0, task.Type}
+ }
+
+ var opts migration.MigrateOptions
+ if err := json.Unmarshal([]byte(task.PayloadContent), &opts); err != nil {
+ return nil, nil, err
+ }
+ return &task, &opts, nil
+}
+
// FindTaskOptions find all tasks
type FindTaskOptions struct {
Status int
diff --git a/modules/task/migrate.go b/modules/task/migrate.go
index d25decaa00..99f0435b28 100644
--- a/modules/task/migrate.go
+++ b/modules/task/migrate.go
@@ -20,7 +20,7 @@ import (
"code.gitea.io/gitea/modules/util"
)
-func handleCreateError(owner *models.User, err error, name string) error {
+func handleCreateError(owner *models.User, err error) error {
switch {
case models.IsErrReachLimitOfRepo(err):
return fmt.Errorf("You have already reached your limit of %d repositories", owner.MaxCreationLimit())
@@ -38,8 +38,8 @@ func handleCreateError(owner *models.User, err error, name string) error {
func runMigrateTask(t *models.Task) (err error) {
defer func() {
if e := recover(); e != nil {
- err = fmt.Errorf("PANIC whilst trying to do migrate task: %v\nStacktrace: %v", err, log.Stack(2))
- log.Critical("PANIC during runMigrateTask[%d] by DoerID[%d] to RepoID[%d] for OwnerID[%d]: %v", t.ID, t.DoerID, t.RepoID, t.OwnerID, err)
+ err = fmt.Errorf("PANIC whilst trying to do migrate task: %v", e)
+ log.Critical("PANIC during runMigrateTask[%d] by DoerID[%d] to RepoID[%d] for OwnerID[%d]: %v\nStacktrace: %v", t.ID, t.DoerID, t.RepoID, t.OwnerID, e, log.Stack(2))
}
if err == nil {
@@ -55,7 +55,8 @@ func runMigrateTask(t *models.Task) (err error) {
t.EndTime = timeutil.TimeStampNow()
t.Status = structs.TaskStatusFailed
t.Errors = err.Error()
- if err := t.UpdateCols("status", "errors", "end_time"); err != nil {
+ t.RepoID = 0
+ if err := t.UpdateCols("status", "errors", "repo_id", "end_time"); err != nil {
log.Error("Task UpdateCols failed: %v", err)
}
@@ -66,8 +67,8 @@ func runMigrateTask(t *models.Task) (err error) {
}
}()
- if err := t.LoadRepo(); err != nil {
- return err
+ if err = t.LoadRepo(); err != nil {
+ return
}
// if repository is ready, then just finsih the task
@@ -75,33 +76,35 @@ func runMigrateTask(t *models.Task) (err error) {
return nil
}
- if err := t.LoadDoer(); err != nil {
- return err
+ if err = t.LoadDoer(); err != nil {
+ return
}
- if err := t.LoadOwner(); err != nil {
- return err
+ if err = t.LoadOwner(); err != nil {
+ return
}
t.StartTime = timeutil.TimeStampNow()
t.Status = structs.TaskStatusRunning
- if err := t.UpdateCols("start_time", "status"); err != nil {
- return err
+ if err = t.UpdateCols("start_time", "status"); err != nil {
+ return
}
var opts *migration.MigrateOptions
opts, err = t.MigrateConfig()
if err != nil {
- return err
+ return
}
opts.MigrateToRepoID = t.RepoID
- repo, err := migrations.MigrateRepository(graceful.GetManager().HammerContext(), t.Doer, t.Owner.Name, *opts)
+ var repo *models.Repository
+ repo, err = migrations.MigrateRepository(graceful.GetManager().HammerContext(), t.Doer, t.Owner.Name, *opts)
if err == nil {
log.Trace("Repository migrated [%d]: %s/%s", repo.ID, t.Owner.Name, repo.Name)
- return nil
+ return
}
if models.IsErrRepoAlreadyExist(err) {
- return errors.New("The repository name is already used")
+ err = errors.New("The repository name is already used")
+ return
}
// remoteAddr may contain credentials, so we sanitize it
@@ -113,5 +116,7 @@ func runMigrateTask(t *models.Task) (err error) {
return fmt.Errorf("Migration failed: %v", err.Error())
}
- return handleCreateError(t.Owner, err, "MigratePost")
+ // do not be tempted to coalesce this line with the return
+ err = handleCreateError(t.Owner, err)
+ return
}
diff --git a/public/img/failed.png b/public/img/failed.png
new file mode 100644
index 0000000000..b37545f90c
--- /dev/null
+++ b/public/img/failed.png
Binary files differ
diff --git a/routers/repo/repo.go b/routers/repo/repo.go
index 742c952f6e..4220750328 100644
--- a/routers/repo/repo.go
+++ b/routers/repo/repo.go
@@ -402,19 +402,3 @@ func Download(ctx *context.Context) {
ctx.ServeFile(archivePath, ctx.Repo.Repository.Name+"-"+refName+ext)
}
-
-// Status returns repository's status
-func Status(ctx *context.Context) {
- task, err := models.GetMigratingTask(ctx.Repo.Repository.ID)
- if err != nil {
- ctx.JSON(500, map[string]interface{}{
- "err": err,
- })
- return
- }
-
- ctx.JSON(200, map[string]interface{}{
- "status": ctx.Repo.Repository.Status,
- "err": task.Errors,
- })
-}
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 7f43b3b2b1..f123613b1f 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -490,6 +490,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/forgot_password", user.ForgotPasswd)
m.Post("/forgot_password", user.ForgotPasswdPost)
m.Post("/logout", user.SignOut)
+ m.Get("/task/:task", user.TaskStatus)
})
// ***** END: User *****
@@ -997,8 +998,6 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/archive/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.Download)
- m.Get("/status", reqRepoCodeReader, repo.Status)
-
m.Group("/branches", func() {
m.Get("", repo.Branches)
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
diff --git a/routers/user/task.go b/routers/user/task.go
new file mode 100644
index 0000000000..a88257ee50
--- /dev/null
+++ b/routers/user/task.go
@@ -0,0 +1,30 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package user
+
+import (
+ "code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/context"
+)
+
+// TaskStatus returns task's status
+func TaskStatus(ctx *context.Context) {
+ task, opts, err := models.GetMigratingTaskByID(ctx.ParamsInt64("task"), ctx.User.ID)
+ if err != nil {
+ ctx.JSON(500, map[string]interface{}{
+ "err": err,
+ })
+ return
+ }
+
+ ctx.JSON(200, map[string]interface{}{
+ "status": task.Status,
+ "err": task.Errors,
+ "repo-id": task.RepoID,
+ "repo-name": opts.RepoName,
+ "start": task.StartTime,
+ "end": task.EndTime,
+ })
+}
diff --git a/templates/repo/migrate/migrating.tmpl b/templates/repo/migrate/migrating.tmpl
index 0057325e91..fdda33a2c7 100644
--- a/templates/repo/migrate/migrating.tmpl
+++ b/templates/repo/migrate/migrating.tmpl
@@ -7,11 +7,16 @@
{{template "base/alert" .}}
<div class="home">
<div class="ui stackable middle very relaxed page grid">
- <div id="repo_migrating" class="sixteen wide center aligned centered column" repo="{{.Repo.Repository.FullName}}">
+ <div id="repo_migrating" class="sixteen wide center aligned centered column" task="{{.MigrateTask.ID}}">
<div>
<img src="{{StaticUrlPrefix}}/img/loading.png"/>
</div>
</div>
+ <div id="repo_migrating_failed_image" class="sixteen wide center aligned centered column" style="display: none;">
+ <div>
+ <img src="{{StaticUrlPrefix}}/img/failed.png"/>
+ </div>
+ </div>
</div>
<div class="ui stackable middle very relaxed page grid">
<div class="sixteen wide center aligned centered column">
@@ -20,6 +25,7 @@
</div>
<div id="repo_migrating_failed">
<p>{{.i18n.Tr "repo.migrate.migrating_failed" .CloneAddr | Safe}}</p>
+ <p id="repo_migrating_failed_error"></p>
</div>
</div>
</div>
diff --git a/web_src/js/index.js b/web_src/js/index.js
index 8636427092..489651e3b1 100644
--- a/web_src/js/index.js
+++ b/web_src/js/index.js
@@ -192,25 +192,32 @@ function updateIssuesMeta(url, action, issueIds, elementId) {
function initRepoStatusChecker() {
const migrating = $('#repo_migrating');
$('#repo_migrating_failed').hide();
+ $('#repo_migrating_failed_image').hide();
if (migrating) {
- const repo_name = migrating.attr('repo');
- if (typeof repo_name === 'undefined') {
+ const task = migrating.attr('task');
+ if (typeof task === 'undefined') {
return;
}
$.ajax({
type: 'GET',
- url: `${AppSubUrl}/${repo_name}/status`,
+ url: `${AppSubUrl}/user/task/${task}`,
data: {
_csrf: csrf,
},
complete(xhr) {
if (xhr.status === 200) {
if (xhr.responseJSON) {
- if (xhr.responseJSON.status === 0) {
+ if (xhr.responseJSON.status === 4) {
window.location.reload();
return;
+ } else if (xhr.responseJSON.status === 3) {
+ $('#repo_migrating_progress').hide();
+ $('#repo_migrating').hide();
+ $('#repo_migrating_failed').show();
+ $('#repo_migrating_failed_image').show();
+ $('#repo_migrating_failed_error').text(xhr.responseJSON.err);
+ return;
}
-
setTimeout(() => {
initRepoStatusChecker();
}, 2000);
@@ -218,7 +225,9 @@ function initRepoStatusChecker() {
}
}
$('#repo_migrating_progress').hide();
+ $('#repo_migrating').hide();
$('#repo_migrating_failed').show();
+ $('#repo_migrating_failed_image').show();
}
});
}