go-gitea/cmd/restore.go
2018-05-08 18:08:26 +08:00

154 lines
4.2 KiB
Go

// Copyright 2017 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 cmd
import (
"errors"
"io/ioutil"
"log"
"os"
"path/filepath"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/cae/zip"
"github.com/Unknwon/com"
"github.com/urfave/cli"
)
// CmdRestore represents the available restore sub-command.
var CmdRestore = cli.Command{
Name: "restore",
Usage: "Restore Gitea files and database",
Description: `Restore will restore all data from zip file which dumped from gitea. It will use
the custom config in this dump zip file, this operation will remove all the dest database and repositories.`,
Action: runRestore,
Flags: []cli.Flag{
cli.StringFlag{
Name: "config, c",
Value: "custom/conf/app.ini",
Usage: "Custom configuration file path, if empty will use dumped config file",
},
cli.BoolFlag{
Name: "verbose, v",
Usage: "Show process details",
},
cli.StringFlag{
Name: "tempdir, t",
Value: os.TempDir(),
Usage: "Temporary dir path",
},
},
}
func runRestore(ctx *cli.Context) error {
if len(os.Args) < 3 {
return errors.New("need zip file path")
}
tmpDir := ctx.String("tempdir")
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
log.Fatalf("Path does not exist: %s", tmpDir)
}
tmpWorkDir, err := ioutil.TempDir(tmpDir, "gitea-restore-")
if err != nil {
log.Fatalf("Failed to create tmp work directory: %v", err)
}
log.Printf("Creating tmp work dir: %s", tmpWorkDir)
// work-around #1103
if os.Getenv("TMPDIR") == "" {
os.Setenv("TMPDIR", tmpWorkDir)
}
srcPath := os.Args[2]
zip.Verbose = ctx.Bool("verbose")
log.Printf("Extracting %s to %s", srcPath, tmpWorkDir)
err = zip.ExtractTo(srcPath, tmpWorkDir)
if err != nil {
log.Fatalf("Failed to extract %s to tmp work directory: %v", srcPath, err)
}
verData, err := ioutil.ReadFile(filepath.Join(tmpWorkDir, "VERSION"))
if err != nil {
log.Fatalf("Failed to extract %s to tmp work directory: %v", srcPath, err)
}
if setting.AppVer != string(verData) {
log.Fatalf("Expected gitea version to restore is %s, but get %s", string(verData), setting.AppVer)
}
if ctx.IsSet("config") {
setting.CustomConf = ctx.String("config")
} else {
setting.CustomConf = filepath.Join(tmpWorkDir, "custom", "conf", "app.ini")
}
if !com.IsExist(setting.CustomConf) {
log.Fatalf("Failed to load ini config file from %s", setting.CustomConf)
}
setting.NewContext()
//setting.CustomPath = filepath.Join(tmpWorkDir, "custom")
setting.NewXORMLogService(false)
models.LoadConfigs()
err = models.SetEngine()
if err != nil {
log.Fatalf("Failed to SetEngine: %v", err)
}
err = models.SyncDBStructs()
if err != nil {
log.Fatalf("Failed to SyncDBStructs: %v", err)
}
log.Printf("Restoring repo dir to %s ...", setting.RepoRootPath)
repoPath := filepath.Join(tmpWorkDir, "repositories")
err = os.RemoveAll(setting.RepoRootPath)
if err != nil {
log.Fatalf("Failed to Remove repo root path %s: %v", setting.RepoRootPath, err)
}
err = os.Rename(repoPath, setting.RepoRootPath)
if err != nil {
log.Fatalf("Failed to move %s to %s: %v", repoPath, setting.RepoRootPath, err)
}
log.Printf("Restoring custom dir to %s ...", setting.CustomPath)
customPath := filepath.Join(tmpWorkDir, "custom")
err = os.RemoveAll(setting.CustomPath)
if err != nil {
log.Fatalf("Failed to Remove repo root path %s: %v", setting.CustomPath, err)
}
err = os.Rename(customPath, setting.CustomPath)
if err != nil {
log.Fatalf("Failed to move %s to %s: %v", customPath, setting.CustomPath, err)
}
log.Printf("Restoring data dir to %s ...", setting.AppDataPath)
dataPath := filepath.Join(tmpWorkDir, "data")
err = os.RemoveAll(setting.AppDataPath)
if err != nil {
log.Fatalf("Failed to Remove data root path %s: %v", setting.AppDataPath, err)
}
err = os.Rename(dataPath, setting.AppDataPath)
if err != nil {
log.Fatalf("Failed to move %s to %s: %v", dataPath, setting.AppDataPath, err)
}
dbPath := filepath.Join(tmpWorkDir, "database")
log.Printf("Restoring database from %s ...", dbPath)
err = models.RestoreDatabaseFixtures(dbPath)
if err != nil {
log.Fatalf("Failed to restore database dir %s: %v", dbPath, err)
}
return nil
}