]> source.dussan.org Git - gitea.git/commitdiff
Move restore repo to internal router and invoke from command to avoid open the same...
authorLunny Xiao <xiaolunwen@gmail.com>
Mon, 10 May 2021 13:14:59 +0000 (21:14 +0800)
committerGitHub <noreply@github.com>
Mon, 10 May 2021 13:14:59 +0000 (21:14 +0800)
* 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

cmd/restore_repo.go
modules/migrations/dump.go
modules/private/restore_repo.go [new file with mode: 0644]
routers/private/internal.go
routers/private/restore_repo.go [new file with mode: 0644]

index 541995879bf4c4611d3fde70c5dcbd9c007860c8..b832471928f4af122361b255ff46b6f85a5e68f8 100644 (file)
@@ -5,15 +5,12 @@
 package cmd
 
 import (
-       "context"
-       "strings"
+       "errors"
+       "net/http"
 
        "code.gitea.io/gitea/modules/log"
-       "code.gitea.io/gitea/modules/migrations"
-       "code.gitea.io/gitea/modules/migrations/base"
+       "code.gitea.io/gitea/modules/private"
        "code.gitea.io/gitea/modules/setting"
-       "code.gitea.io/gitea/modules/storage"
-       pull_service "code.gitea.io/gitea/services/pull"
 
        "github.com/urfave/cli"
 )
@@ -50,70 +47,18 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
 }
 
 func runRestoreRepository(ctx *cli.Context) error {
-       if err := initDB(); err != nil {
-               return err
-       }
-
-       log.Trace("AppPath: %s", setting.AppPath)
-       log.Trace("AppWorkPath: %s", setting.AppWorkPath)
-       log.Trace("Custom path: %s", setting.CustomPath)
-       log.Trace("Log path: %s", setting.LogRootPath)
-       setting.InitDBConfig()
-
-       if err := storage.Init(); err != nil {
-               return err
-       }
-
-       if err := pull_service.Init(); err != nil {
-               return err
-       }
-
-       var opts = base.MigrateOptions{
-               RepoName: ctx.String("repo_name"),
-       }
-
-       if len(ctx.String("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 {
-               units := strings.Split(ctx.String("units"), ",")
-               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
-                       }
-               }
-       }
+       setting.NewContext()
 
-       if err := migrations.RestoreRepository(
-               context.Background(),
+       statusCode, errStr := private.RestoreRepo(
                ctx.String("repo_dir"),
                ctx.String("owner_name"),
                ctx.String("repo_name"),
-       ); err != nil {
-               log.Fatal("Failed to restore repository: %v", err)
-               return err
+               ctx.StringSlice("units"),
+       )
+       if statusCode == http.StatusOK {
+               return nil
        }
 
-       return nil
+       log.Fatal("Failed to restore repository: %v", errStr)
+       return errors.New(errStr)
 }
index 297095883be4b1d1bc17e50bcef6d2537763f6af..4a18c47ae5bec8d35b2a005e3c2a425dca4fa481 100644 (file)
@@ -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 (file)
index 0000000..6fe2e68
--- /dev/null
@@ -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)
+}
index e541591a3840b474384824c4b2da7a295eac4c0d..15a393c530678960c90cd5ece308f75b92520245 100644 (file)
@@ -69,6 +69,7 @@ func Routes() *web.Route {
        r.Post("/manager/add-logger", bind(private.LoggerOptions{}), AddLogger)
        r.Post("/manager/remove-logger/{group}/{name}", RemoveLogger)
        r.Post("/mail/send", SendEmail)
+       r.Post("/restore_repo", RestoreRepo)
 
        return r
 }
diff --git a/routers/private/restore_repo.go b/routers/private/restore_repo.go
new file mode 100644 (file)
index 0000000..c002de8
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2021 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 (
+       "io/ioutil"
+
+       myCtx "code.gitea.io/gitea/modules/context"
+       "code.gitea.io/gitea/modules/migrations"
+       jsoniter "github.com/json-iterator/go"
+)
+
+// RestoreRepo restore a repository from data
+func RestoreRepo(ctx *myCtx.PrivateContext) {
+       json := jsoniter.ConfigCompatibleWithStandardLibrary
+       bs, err := ioutil.ReadAll(ctx.Req.Body)
+       if err != nil {
+               ctx.JSON(500, map[string]string{
+                       "err": err.Error(),
+               })
+               return
+       }
+       var params = struct {
+               RepoDir   string
+               OwnerName string
+               RepoName  string
+               Units     []string
+       }{}
+       if err = json.Unmarshal(bs, &params); err != nil {
+               ctx.JSON(500, map[string]string{
+                       "err": err.Error(),
+               })
+               return
+       }
+
+       if err := migrations.RestoreRepository(
+               ctx.Req.Context(),
+               params.RepoDir,
+               params.OwnerName,
+               params.RepoName,
+               params.Units,
+       ); err != nil {
+               ctx.JSON(500, map[string]string{
+                       "err": err.Error(),
+               })
+       } else {
+               ctx.Status(200)
+       }
+}