Skip to content

Commit 5d27a8c

Browse files
kasbahAbdulrhmnGhanem
authored andcommitted
Improve migration API
1 parent 576b2d7 commit 5d27a8c

File tree

4 files changed

+67
-64
lines changed

4 files changed

+67
-64
lines changed

routers/api/v1/api.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,10 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route {
772772

773773
m.Get("/issues/search", repo.SearchIssues)
774774

775-
m.Post("/migrate", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate)
775+
m.Group("/migrate", func() {
776+
m.Post("", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate)
777+
m.Get("/status", repo.GetMigratingTask)
778+
})
776779

777780
m.Group("/{username}/{reponame}", func() {
778781
m.Combo("").Get(reqAnyRepoReader(), repo.Get).

routers/api/v1/repo/migrate.go

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
package repo
66

77
import (
8-
"bytes"
9-
"errors"
108
"fmt"
119
"net/http"
1210
"strings"
@@ -19,18 +17,16 @@ import (
1917
user_model "code.gitea.io/gitea/models/user"
2018
"code.gitea.io/gitea/modules/context"
2119
"code.gitea.io/gitea/modules/convert"
22-
"code.gitea.io/gitea/modules/graceful"
2320
"code.gitea.io/gitea/modules/lfs"
2421
"code.gitea.io/gitea/modules/log"
2522
base "code.gitea.io/gitea/modules/migration"
26-
"code.gitea.io/gitea/modules/notification"
27-
repo_module "code.gitea.io/gitea/modules/repository"
2823
"code.gitea.io/gitea/modules/setting"
2924
api "code.gitea.io/gitea/modules/structs"
3025
"code.gitea.io/gitea/modules/util"
3126
"code.gitea.io/gitea/modules/web"
3227
"code.gitea.io/gitea/services/forms"
3328
"code.gitea.io/gitea/services/migrations"
29+
"code.gitea.io/gitea/services/task"
3430
)
3531

3632
// Migrate migrate remote git repository to gitea
@@ -142,6 +138,7 @@ func Migrate(ctx *context.APIContext) {
142138
CloneAddr: remoteAddr,
143139
RepoName: form.RepoName,
144140
Description: form.Description,
141+
OriginalURL: form.CloneAddr,
145142
Private: form.Private || setting.Repository.ForcePrivate,
146143
Mirror: form.Mirror,
147144
LFS: form.LFS,
@@ -150,7 +147,7 @@ func Migrate(ctx *context.APIContext) {
150147
AuthPassword: form.AuthPassword,
151148
AuthToken: form.AuthToken,
152149
Wiki: form.Wiki,
153-
Issues: form.Issues,
150+
Issues: form.Issues || form.PullRequests,
154151
Milestones: form.Milestones,
155152
Labels: form.Labels,
156153
Comments: true,
@@ -168,63 +165,33 @@ func Migrate(ctx *context.APIContext) {
168165
opts.Releases = false
169166
}
170167

171-
repo, err := repo_module.CreateRepository(ctx.Doer, repoOwner, models.CreateRepoOptions{
172-
Name: opts.RepoName,
173-
Description: opts.Description,
174-
OriginalURL: form.CloneAddr,
175-
GitServiceType: gitServiceType,
176-
IsPrivate: opts.Private,
177-
IsMirror: opts.Mirror,
178-
Status: repo_model.RepositoryBeingMigrated,
179-
})
180-
if err != nil {
181-
handleMigrateError(ctx, repoOwner, remoteAddr, err)
168+
if err = repo_model.CheckCreateRepository(ctx.Doer, repoOwner, opts.RepoName, false); err != nil {
169+
handleMigrateError(ctx, repoOwner, &opts, err)
182170
return
183171
}
184172

185-
opts.MigrateToRepoID = repo.ID
186-
187-
defer func() {
188-
if e := recover(); e != nil {
189-
var buf bytes.Buffer
190-
fmt.Fprintf(&buf, "Handler crashed with error: %v", log.Stack(2))
191-
192-
err = errors.New(buf.String())
193-
}
194-
195-
if err == nil {
196-
notification.NotifyMigrateRepository(ctx.Doer, repoOwner, repo)
197-
return
198-
}
199-
200-
if repo != nil {
201-
if errDelete := models.DeleteRepository(ctx.Doer, repoOwner.ID, repo.ID); errDelete != nil {
202-
log.Error("DeleteRepository: %v", errDelete)
203-
}
204-
}
205-
}()
206-
207-
if repo, err = migrations.MigrateRepository(graceful.GetManager().HammerContext(), ctx.Doer, repoOwner.Name, opts, nil); err != nil {
208-
handleMigrateError(ctx, repoOwner, remoteAddr, err)
173+
repo, err := task.MigrateRepository(ctx.Doer, repoOwner, opts)
174+
if err == nil {
175+
log.Trace("Repository migrated: %s/%s", repoOwner.Name, form.RepoName)
176+
ctx.JSON(http.StatusCreated, convert.ToRepo(repo, perm.AccessModeAdmin))
209177
return
210178
}
211179

212-
log.Trace("Repository migrated: %s/%s", repoOwner.Name, form.RepoName)
213-
ctx.JSON(http.StatusCreated, convert.ToRepo(repo, perm.AccessModeAdmin))
180+
handleMigrateError(ctx, repoOwner, &opts, err)
214181
}
215182

216-
func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, remoteAddr string, err error) {
183+
func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, migrationOpts *migrations.MigrateOptions, err error) {
217184
switch {
218-
case repo_model.IsErrRepoAlreadyExist(err):
219-
ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.")
220-
case repo_model.IsErrRepoFilesAlreadyExist(err):
221-
ctx.Error(http.StatusConflict, "", "Files already exist for this repository. Adopt them or delete them.")
222185
case migrations.IsRateLimitError(err):
223186
ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit addressed rate limitation.")
224187
case migrations.IsTwoFactorAuthError(err):
225188
ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit required two factors authentication.")
226189
case repo_model.IsErrReachLimitOfRepo(err):
227190
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit()))
191+
case repo_model.IsErrRepoAlreadyExist(err):
192+
ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.")
193+
case repo_model.IsErrRepoFilesAlreadyExist(err):
194+
ctx.Error(http.StatusConflict, "", "Files already exist for this repository. Adopt them or delete them.")
228195
case db.IsErrNameReserved(err):
229196
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The username '%s' is reserved.", err.(db.ErrNameReserved).Name))
230197
case db.IsErrNameCharsNotAllowed(err):
@@ -270,3 +237,36 @@ func handleRemoteAddrError(ctx *context.APIContext, err error) {
270237
ctx.Error(http.StatusInternalServerError, "ParseRemoteAddr", err)
271238
}
272239
}
240+
241+
// GetMigratingTask returns the migrating task by repo's id
242+
func GetMigratingTask(ctx *context.APIContext) {
243+
// swagger:operation GET /repos/migrate/status task
244+
// ---
245+
// summary: Get the migration status of a repository by its id
246+
// produces:
247+
// - application/json
248+
// parameters:
249+
// - name: repo_id
250+
// in: query
251+
// description: repository id
252+
// type: int64
253+
// responses:
254+
// "200":
255+
// "$ref": "#/responses/"
256+
// "404":
257+
// "$ref": "#/response/"
258+
t, err := models.GetMigratingTask(ctx.FormInt64("repo_id"))
259+
260+
if err != nil {
261+
ctx.JSON(http.StatusNotFound, err)
262+
return
263+
}
264+
265+
ctx.JSON(200, map[string]interface{}{
266+
"status": t.Status,
267+
"err": t.Message,
268+
"repo-id": t.RepoID,
269+
"start": t.StartTime,
270+
"end": t.EndTime,
271+
})
272+
}

routers/web/repo/migrate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ func MigratePost(ctx *context.Context) {
238238
return
239239
}
240240

241-
err = task.MigrateRepository(ctx.Doer, ctxUser, opts)
241+
_, err = task.MigrateRepository(ctx.Doer, ctxUser, opts)
242242
if err == nil {
243243
ctx.Redirect(ctxUser.HomeLink() + "/" + url.PathEscape(opts.RepoName))
244244
return

services/task/task.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,37 +60,37 @@ func handle(data ...queue.Data) []queue.Data {
6060
}
6161

6262
// MigrateRepository add migration repository to task
63-
func MigrateRepository(doer, u *user_model.User, opts base.MigrateOptions) error {
64-
task, err := CreateMigrateTask(doer, u, opts)
63+
func MigrateRepository(doer, u *user_model.User, opts base.MigrateOptions) (*repo_model.Repository, error) {
64+
task, repo, err := createMigrationTask(doer, u, opts)
6565
if err != nil {
66-
return err
66+
return repo, err
6767
}
6868

69-
return taskQueue.Push(task)
69+
return repo, taskQueue.Push(task)
7070
}
7171

72-
// CreateMigrateTask creates a migrate task
73-
func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*models.Task, error) {
72+
// createMigrationTask creates a migrate task
73+
func createMigrationTask(doer, u *user_model.User, opts base.MigrateOptions) (*models.Task, *repo_model.Repository, error) {
7474
// encrypt credentials for persistence
7575
var err error
7676
opts.CloneAddrEncrypted, err = secret.EncryptSecret(setting.SecretKey, opts.CloneAddr)
7777
if err != nil {
78-
return nil, err
78+
return nil, nil, err
7979
}
8080
opts.CloneAddr = util.SanitizeCredentialURLs(opts.CloneAddr)
8181
opts.AuthPasswordEncrypted, err = secret.EncryptSecret(setting.SecretKey, opts.AuthPassword)
8282
if err != nil {
83-
return nil, err
83+
return nil, nil, err
8484
}
8585
opts.AuthPassword = ""
8686
opts.AuthTokenEncrypted, err = secret.EncryptSecret(setting.SecretKey, opts.AuthToken)
8787
if err != nil {
88-
return nil, err
88+
return nil, nil, err
8989
}
9090
opts.AuthToken = ""
9191
bs, err := json.Marshal(&opts)
9292
if err != nil {
93-
return nil, err
93+
return nil, nil, err
9494
}
9595

9696
task := &models.Task{
@@ -102,7 +102,7 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*mod
102102
}
103103

104104
if err := models.CreateTask(task); err != nil {
105-
return nil, err
105+
return nil, nil, err
106106
}
107107

108108
repo, err := repo_module.CreateRepository(doer, u, models.CreateRepoOptions{
@@ -121,13 +121,13 @@ func CreateMigrateTask(doer, u *user_model.User, opts base.MigrateOptions) (*mod
121121
if err2 != nil {
122122
log.Error("UpdateCols Failed: %v", err2.Error())
123123
}
124-
return nil, err
124+
return nil, nil, err
125125
}
126126

127127
task.RepoID = repo.ID
128128
if err = task.UpdateCols("repo_id"); err != nil {
129-
return nil, err
129+
return nil, repo, err
130130
}
131131

132-
return task, nil
132+
return task, repo, nil
133133
}

0 commit comments

Comments
 (0)