1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2024-11-28 09:21:13 -05:00

Add Retry button when creating a mirror-repo fails (#26228)

fixed #26156 
* Added a retry button in the frontend (only displayed when the status
is abnormal)
* After clicking Retry, the backend adds the task back to the task queue


![7UJDNM671RI})EA8~~XPL39](https://github.com/go-gitea/gitea/assets/3371163/e088fd63-5dcc-4bc6-8849-7db3086511b7)

![T83F1WL9)VGHR@MB956$VT9](https://github.com/go-gitea/gitea/assets/3371163/744425bb-dde1-4315-be2e-5c99ac3a44d4)

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Kerwin Bryant 2023-08-04 10:21:32 +08:00 committed by GitHub
parent 907bedaad0
commit 865d2221c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 4 deletions

View file

@ -80,6 +80,7 @@ milestones = Milestones
ok = OK ok = OK
cancel = Cancel cancel = Cancel
retry = Retry
rerun = Re-run rerun = Re-run
rerun_all = Re-run all jobs rerun_all = Re-run all jobs
save = Save save = Save

View file

@ -259,6 +259,15 @@ func setMigrationContextData(ctx *context.Context, serviceType structs.GitServic
ctx.Data["service"] = serviceType ctx.Data["service"] = serviceType
} }
func MigrateRetryPost(ctx *context.Context) {
if err := task.RetryMigrateTask(ctx.Repo.Repository.ID); err != nil {
log.Error("Retry task failed: %v", err)
ctx.ServerError("task.RetryMigrateTask", err)
return
}
ctx.JSONOK()
}
func MigrateCancelPost(ctx *context.Context) { func MigrateCancelPost(ctx *context.Context) {
migratingTask, err := admin_model.GetMigratingTask(ctx.Repo.Repository.ID) migratingTask, err := admin_model.GetMigratingTask(ctx.Repo.Repository.ID)
if err != nil { if err != nil {

View file

@ -953,7 +953,11 @@ func registerRoutes(m *web.Route) {
addSettingsSecretsRoutes() addSettingsSecretsRoutes()
addSettingVariablesRoutes() addSettingVariablesRoutes()
}, actions.MustEnableActions) }, actions.MustEnableActions)
m.Post("/migrate/cancel", repo.MigrateCancelPost) // this handler must be under "settings", otherwise this incomplete repo can't be accessed // the follow handler must be under "settings", otherwise this incomplete repo can't be accessed
m.Group("/migrate", func() {
m.Post("/retry", repo.MigrateRetryPost)
m.Post("/cancel", repo.MigrateCancelPost)
})
}, ctxDataSet("PageIsRepoSettings", true, "LFSStartServer", setting.LFS.StartServer)) }, ctxDataSet("PageIsRepoSettings", true, "LFSStartServer", setting.LFS.StartServer))
}, reqSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoAdmin, context.RepoRef()) }, reqSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoAdmin, context.RepoRef())

View file

@ -126,3 +126,27 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*adm
return task, nil return task, nil
} }
// RetryMigrateTask retry a migrate task
func RetryMigrateTask(repoID int64) error {
migratingTask, err := admin_model.GetMigratingTask(repoID)
if err != nil {
log.Error("GetMigratingTask: %v", err)
return err
}
if migratingTask.Status == structs.TaskStatusQueued || migratingTask.Status == structs.TaskStatusRunning {
return nil
}
// TODO Need to removing the storage/database garbage brought by the failed task
// Reset task status and messages
migratingTask.Status = structs.TaskStatusQueued
migratingTask.Message = ""
if err = migratingTask.UpdateCols("status", "message"); err != nil {
log.Error("task.UpdateCols failed: %v", err)
return err
}
return taskQueue.Push(migratingTask)
}

View file

@ -36,10 +36,11 @@
<div class="divider"></div> <div class="divider"></div>
<div class="item"> <div class="item">
{{if .Failed}} {{if .Failed}}
<button class="ui basic red show-modal button" data-modal="#delete-repo-modal">{{.locale.Tr "repo.settings.delete"}}</button> <button class="ui basic red show-modal button" data-modal="#delete-repo-modal">{{.locale.Tr "repo.settings.delete"}}</button>
{{else}} {{else}}
<button class="ui basic red show-modal button" data-modal="#cancel-repo-modal">{{.locale.Tr "cancel"}}</button> <button class="ui basic red show-modal button" data-modal="#cancel-repo-modal">{{.locale.Tr "cancel"}}</button>
{{end}} {{end}}
<button id="repo_migrating_retry" data-migrating-task-retry-url="{{.Link}}/settings/migrate/retry" class="ui basic button gt-hidden">{{.locale.Tr "retry"}}</button>
</div> </div>
{{end}} {{end}}
</div> </div>

View file

@ -1,12 +1,14 @@
import $ from 'jquery'; import $ from 'jquery';
import {hideElem, showElem} from '../utils/dom.js'; import {hideElem, showElem} from '../utils/dom.js';
const {appSubUrl} = window.config; const {appSubUrl, csrfToken} = window.config;
export function initRepoMigrationStatusChecker() { export function initRepoMigrationStatusChecker() {
const $repoMigrating = $('#repo_migrating'); const $repoMigrating = $('#repo_migrating');
if (!$repoMigrating.length) return; if (!$repoMigrating.length) return;
$('#repo_migrating_retry').on('click', doMigrationRetry);
const task = $repoMigrating.attr('data-migrating-task-id'); const task = $repoMigrating.attr('data-migrating-task-id');
// returns true if the refresh still need to be called after a while // returns true if the refresh still need to be called after a while
@ -31,6 +33,7 @@ export function initRepoMigrationStatusChecker() {
if (data.status === 3) { if (data.status === 3) {
hideElem('#repo_migrating_progress'); hideElem('#repo_migrating_progress');
hideElem('#repo_migrating'); hideElem('#repo_migrating');
showElem('#repo_migrating_retry');
showElem('#repo_migrating_failed'); showElem('#repo_migrating_failed');
showElem('#repo_migrating_failed_image'); showElem('#repo_migrating_failed_image');
$('#repo_migrating_failed_error').text(data.message); $('#repo_migrating_failed_error').text(data.message);
@ -53,3 +56,14 @@ export function initRepoMigrationStatusChecker() {
syncTaskStatus(); // no await syncTaskStatus(); // no await
} }
async function doMigrationRetry(e) {
await fetch($(e.target).attr('data-migrating-task-retry-url'), {
method: 'post',
headers: {
'X-Csrf-Token': csrfToken,
'Content-Type': 'application/json',
},
});
window.location.reload();
}