aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-05-10 15:57:45 +0800
committerGitHub <noreply@github.com>2021-05-10 15:57:45 +0800
commite5723d6556d632df08132472066f1bb167753299 (patch)
treeb7254fa85f8348af7375755bd454f59583b1bd25 /modules
parent1e6fa57acbe3c05cb996b789e8c2d381c953826f (diff)
downloadgitea-e5723d6556d632df08132472066f1bb167753299.tar.gz
gitea-e5723d6556d632df08132472066f1bb167753299.zip
Move restore repo to internal router and invoke from command to avoid open the same db file or queues files (#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
Diffstat (limited to 'modules')
-rw-r--r--modules/migrations/dump.go52
-rw-r--r--modules/private/restore_repo.go60
2 files changed, 101 insertions, 11 deletions
diff --git a/modules/migrations/dump.go b/modules/migrations/dump.go
index 297095883b..4a18c47ae5 100644
--- a/modules/migrations/dump.go
+++ b/modules/migrations/dump.go
@@ -13,6 +13,7 @@ import (
"os"
"path/filepath"
"strconv"
+ "strings"
"time"
"code.gitea.io/gitea/models"
@@ -563,8 +564,42 @@ func DumpRepository(ctx context.Context, baseDir, ownerName string, opts base.Mi
return nil
}
+func updateOptionsUnits(opts *base.MigrateOptions, units []string) {
+ if len(units) == 0 {
+ opts.Wiki = true
+ opts.Issues = true
+ opts.Milestones = true
+ opts.Labels = true
+ opts.Releases = true
+ opts.Comments = true
+ opts.PullRequests = true
+ opts.ReleaseAssets = true
+ } else {
+ for _, unit := range units {
+ switch strings.ToLower(unit) {
+ case "wiki":
+ opts.Wiki = true
+ case "issues":
+ opts.Issues = true
+ case "milestones":
+ opts.Milestones = true
+ case "labels":
+ opts.Labels = true
+ case "releases":
+ opts.Releases = true
+ case "release_assets":
+ opts.ReleaseAssets = true
+ case "comments":
+ opts.Comments = true
+ case "pull_requests":
+ opts.PullRequests = true
+ }
+ }
+ }
+}
+
// RestoreRepository restore a repository from the disk directory
-func RestoreRepository(ctx context.Context, baseDir string, ownerName, repoName string) error {
+func RestoreRepository(ctx context.Context, baseDir string, ownerName, repoName string, units []string) error {
doer, err := models.GetAdminUser()
if err != nil {
return err
@@ -580,17 +615,12 @@ func RestoreRepository(ctx context.Context, baseDir string, ownerName, repoName
}
tp, _ := strconv.Atoi(opts["service_type"])
- if err = migrateRepository(downloader, uploader, base.MigrateOptions{
- Wiki: true,
- Issues: true,
- Milestones: true,
- Labels: true,
- Releases: true,
- Comments: true,
- PullRequests: true,
- ReleaseAssets: true,
+ var migrateOpts = base.MigrateOptions{
GitServiceType: structs.GitServiceType(tp),
- }); err != nil {
+ }
+ updateOptionsUnits(&migrateOpts, units)
+
+ if err = migrateRepository(downloader, uploader, migrateOpts); err != nil {
if err1 := uploader.Rollback(); err1 != nil {
log.Error("rollback failed: %v", err1)
}
diff --git a/modules/private/restore_repo.go b/modules/private/restore_repo.go
new file mode 100644
index 0000000000..6fe2e6844b
--- /dev/null
+++ b/modules/private/restore_repo.go
@@ -0,0 +1,60 @@
+// 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 private
+
+import (
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "time"
+
+ "code.gitea.io/gitea/modules/setting"
+ jsoniter "github.com/json-iterator/go"
+)
+
+// RestoreParams structure holds a data for restore repository
+type RestoreParams struct {
+ RepoDir string
+ OwnerName string
+ RepoName string
+ Units []string
+}
+
+// RestoreRepo calls the internal RestoreRepo function
+func RestoreRepo(repoDir, ownerName, repoName string, units []string) (int, string) {
+ reqURL := setting.LocalURL + "api/internal/restore_repo"
+
+ req := newInternalRequest(reqURL, "POST")
+ req.SetTimeout(3*time.Second, 0) // since the request will spend much time, don't timeout
+ req = req.Header("Content-Type", "application/json")
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ jsonBytes, _ := json.Marshal(RestoreParams{
+ RepoDir: repoDir,
+ OwnerName: ownerName,
+ RepoName: repoName,
+ Units: units,
+ })
+ req.Body(jsonBytes)
+ resp, err := req.Response()
+ if err != nil {
+ return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v, could you confirm it's running?", err.Error())
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != 200 {
+ var ret = struct {
+ Err string `json:"err"`
+ }{}
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return http.StatusInternalServerError, fmt.Sprintf("Response body error: %v", err.Error())
+ }
+ if err := json.Unmarshal(body, &ret); err != nil {
+ return http.StatusInternalServerError, fmt.Sprintf("Response body Unmarshal error: %v", err.Error())
+ }
+ }
+
+ return http.StatusOK, fmt.Sprintf("Restore repo %s/%s successfully", ownerName, repoName)
+}