Skip to content

Commit 53eda62

Browse files
lunnyAbdulrhmnGhanem
authored andcommitted
Move restore repo to internal router and invoke from command to avoid open the same db file or queues files (go-gitea#15790)
* Move restore repo to internal router and invoke from command to avoid open the same db file or queues files * Follow @zeripath's review * set no timeout for resotre repo private request * make restore repo cancelable
1 parent c625381 commit 53eda62

File tree

5 files changed

+164
-77
lines changed

5 files changed

+164
-77
lines changed

cmd/restore_repo.go

Lines changed: 11 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
package cmd
66

77
import (
8-
"context"
9-
"strings"
8+
"errors"
9+
"net/http"
1010

1111
"code.gitea.io/gitea/modules/log"
12-
"code.gitea.io/gitea/modules/migrations"
13-
"code.gitea.io/gitea/modules/migrations/base"
12+
"code.gitea.io/gitea/modules/private"
1413
"code.gitea.io/gitea/modules/setting"
15-
"code.gitea.io/gitea/modules/storage"
16-
pull_service "code.gitea.io/gitea/services/pull"
1714

1815
"github.com/urfave/cli"
1916
)
@@ -50,70 +47,18 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
5047
}
5148

5249
func runRestoreRepository(ctx *cli.Context) error {
53-
if err := initDB(); err != nil {
54-
return err
55-
}
56-
57-
log.Trace("AppPath: %s", setting.AppPath)
58-
log.Trace("AppWorkPath: %s", setting.AppWorkPath)
59-
log.Trace("Custom path: %s", setting.CustomPath)
60-
log.Trace("Log path: %s", setting.LogRootPath)
61-
setting.InitDBConfig()
62-
63-
if err := storage.Init(); err != nil {
64-
return err
65-
}
66-
67-
if err := pull_service.Init(); err != nil {
68-
return err
69-
}
70-
71-
var opts = base.MigrateOptions{
72-
RepoName: ctx.String("repo_name"),
73-
}
74-
75-
if len(ctx.String("units")) == 0 {
76-
opts.Wiki = true
77-
opts.Issues = true
78-
opts.Milestones = true
79-
opts.Labels = true
80-
opts.Releases = true
81-
opts.Comments = true
82-
opts.PullRequests = true
83-
opts.ReleaseAssets = true
84-
} else {
85-
units := strings.Split(ctx.String("units"), ",")
86-
for _, unit := range units {
87-
switch strings.ToLower(unit) {
88-
case "wiki":
89-
opts.Wiki = true
90-
case "issues":
91-
opts.Issues = true
92-
case "milestones":
93-
opts.Milestones = true
94-
case "labels":
95-
opts.Labels = true
96-
case "releases":
97-
opts.Releases = true
98-
case "release_assets":
99-
opts.ReleaseAssets = true
100-
case "comments":
101-
opts.Comments = true
102-
case "pull_requests":
103-
opts.PullRequests = true
104-
}
105-
}
106-
}
50+
setting.NewContext()
10751

108-
if err := migrations.RestoreRepository(
109-
context.Background(),
52+
statusCode, errStr := private.RestoreRepo(
11053
ctx.String("repo_dir"),
11154
ctx.String("owner_name"),
11255
ctx.String("repo_name"),
113-
); err != nil {
114-
log.Fatal("Failed to restore repository: %v", err)
115-
return err
56+
ctx.StringSlice("units"),
57+
)
58+
if statusCode == http.StatusOK {
59+
return nil
11660
}
11761

118-
return nil
62+
log.Fatal("Failed to restore repository: %v", errStr)
63+
return errors.New(errStr)
11964
}

modules/migrations/dump.go

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"os"
1414
"path/filepath"
1515
"strconv"
16+
"strings"
1617
"time"
1718

1819
"code.gitea.io/gitea/models"
@@ -563,8 +564,42 @@ func DumpRepository(ctx context.Context, baseDir, ownerName string, opts base.Mi
563564
return nil
564565
}
565566

567+
func updateOptionsUnits(opts *base.MigrateOptions, units []string) {
568+
if len(units) == 0 {
569+
opts.Wiki = true
570+
opts.Issues = true
571+
opts.Milestones = true
572+
opts.Labels = true
573+
opts.Releases = true
574+
opts.Comments = true
575+
opts.PullRequests = true
576+
opts.ReleaseAssets = true
577+
} else {
578+
for _, unit := range units {
579+
switch strings.ToLower(unit) {
580+
case "wiki":
581+
opts.Wiki = true
582+
case "issues":
583+
opts.Issues = true
584+
case "milestones":
585+
opts.Milestones = true
586+
case "labels":
587+
opts.Labels = true
588+
case "releases":
589+
opts.Releases = true
590+
case "release_assets":
591+
opts.ReleaseAssets = true
592+
case "comments":
593+
opts.Comments = true
594+
case "pull_requests":
595+
opts.PullRequests = true
596+
}
597+
}
598+
}
599+
}
600+
566601
// RestoreRepository restore a repository from the disk directory
567-
func RestoreRepository(ctx context.Context, baseDir string, ownerName, repoName string) error {
602+
func RestoreRepository(ctx context.Context, baseDir string, ownerName, repoName string, units []string) error {
568603
doer, err := models.GetAdminUser()
569604
if err != nil {
570605
return err
@@ -580,17 +615,12 @@ func RestoreRepository(ctx context.Context, baseDir string, ownerName, repoName
580615
}
581616
tp, _ := strconv.Atoi(opts["service_type"])
582617

583-
if err = migrateRepository(downloader, uploader, base.MigrateOptions{
584-
Wiki: true,
585-
Issues: true,
586-
Milestones: true,
587-
Labels: true,
588-
Releases: true,
589-
Comments: true,
590-
PullRequests: true,
591-
ReleaseAssets: true,
618+
var migrateOpts = base.MigrateOptions{
592619
GitServiceType: structs.GitServiceType(tp),
593-
}); err != nil {
620+
}
621+
updateOptionsUnits(&migrateOpts, units)
622+
623+
if err = migrateRepository(downloader, uploader, migrateOpts); err != nil {
594624
if err1 := uploader.Rollback(); err1 != nil {
595625
log.Error("rollback failed: %v", err1)
596626
}

modules/private/restore_repo.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2020 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package private
6+
7+
import (
8+
"fmt"
9+
"io/ioutil"
10+
"net/http"
11+
"time"
12+
13+
"code.gitea.io/gitea/modules/setting"
14+
jsoniter "github.com/json-iterator/go"
15+
)
16+
17+
// RestoreParams structure holds a data for restore repository
18+
type RestoreParams struct {
19+
RepoDir string
20+
OwnerName string
21+
RepoName string
22+
Units []string
23+
}
24+
25+
// RestoreRepo calls the internal RestoreRepo function
26+
func RestoreRepo(repoDir, ownerName, repoName string, units []string) (int, string) {
27+
reqURL := setting.LocalURL + "api/internal/restore_repo"
28+
29+
req := newInternalRequest(reqURL, "POST")
30+
req.SetTimeout(3*time.Second, 0) // since the request will spend much time, don't timeout
31+
req = req.Header("Content-Type", "application/json")
32+
json := jsoniter.ConfigCompatibleWithStandardLibrary
33+
jsonBytes, _ := json.Marshal(RestoreParams{
34+
RepoDir: repoDir,
35+
OwnerName: ownerName,
36+
RepoName: repoName,
37+
Units: units,
38+
})
39+
req.Body(jsonBytes)
40+
resp, err := req.Response()
41+
if err != nil {
42+
return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v, could you confirm it's running?", err.Error())
43+
}
44+
defer resp.Body.Close()
45+
46+
if resp.StatusCode != 200 {
47+
var ret = struct {
48+
Err string `json:"err"`
49+
}{}
50+
body, err := ioutil.ReadAll(resp.Body)
51+
if err != nil {
52+
return http.StatusInternalServerError, fmt.Sprintf("Response body error: %v", err.Error())
53+
}
54+
if err := json.Unmarshal(body, &ret); err != nil {
55+
return http.StatusInternalServerError, fmt.Sprintf("Response body Unmarshal error: %v", err.Error())
56+
}
57+
}
58+
59+
return http.StatusOK, fmt.Sprintf("Restore repo %s/%s successfully", ownerName, repoName)
60+
}

routers/private/internal.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func Routes() *web.Route {
6969
r.Post("/manager/add-logger", bind(private.LoggerOptions{}), AddLogger)
7070
r.Post("/manager/remove-logger/{group}/{name}", RemoveLogger)
7171
r.Post("/mail/send", SendEmail)
72+
r.Post("/restore_repo", RestoreRepo)
7273

7374
return r
7475
}

routers/private/restore_repo.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2021 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package private
6+
7+
import (
8+
"io/ioutil"
9+
10+
myCtx "code.gitea.io/gitea/modules/context"
11+
"code.gitea.io/gitea/modules/migrations"
12+
jsoniter "github.com/json-iterator/go"
13+
)
14+
15+
// RestoreRepo restore a repository from data
16+
func RestoreRepo(ctx *myCtx.PrivateContext) {
17+
json := jsoniter.ConfigCompatibleWithStandardLibrary
18+
bs, err := ioutil.ReadAll(ctx.Req.Body)
19+
if err != nil {
20+
ctx.JSON(500, map[string]string{
21+
"err": err.Error(),
22+
})
23+
return
24+
}
25+
var params = struct {
26+
RepoDir string
27+
OwnerName string
28+
RepoName string
29+
Units []string
30+
}{}
31+
if err = json.Unmarshal(bs, &params); err != nil {
32+
ctx.JSON(500, map[string]string{
33+
"err": err.Error(),
34+
})
35+
return
36+
}
37+
38+
if err := migrations.RestoreRepository(
39+
ctx.Req.Context(),
40+
params.RepoDir,
41+
params.OwnerName,
42+
params.RepoName,
43+
params.Units,
44+
); err != nil {
45+
ctx.JSON(500, map[string]string{
46+
"err": err.Error(),
47+
})
48+
} else {
49+
ctx.Status(200)
50+
}
51+
}

0 commit comments

Comments
 (0)