mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 22:18:07 +08:00
127 lines
3.6 KiB
Go
127 lines
3.6 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/backend/global"
|
|
"github.com/1Panel-dev/1Panel/backend/i18n"
|
|
cmdUtils "github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func init() {
|
|
RootCmd.AddCommand(restoreCmd)
|
|
}
|
|
|
|
var restoreCmd = &cobra.Command{
|
|
Use: "restore",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
i18n.UseI18nForCmd(language)
|
|
if !isRoot() {
|
|
fmt.Println(i18n.GetMsgWithMapForCmd("SudoHelper", map[string]interface{}{"cmd": "sudo 1pctl restore"}))
|
|
return nil
|
|
}
|
|
stdout, err := cmdUtils.Exec("grep '^BASE_DIR=' /usr/local/bin/1pctl | cut -d'=' -f2")
|
|
if err != nil {
|
|
return fmt.Errorf("handle load `BASE_DIR` failed, err: %v", err)
|
|
}
|
|
baseDir := strings.ReplaceAll(stdout, "\n", "")
|
|
upgradeDir := path.Join(baseDir, "1panel", "tmp", "upgrade")
|
|
|
|
tmpPath, err := loadRestorePath(upgradeDir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if tmpPath == "no such file" {
|
|
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreNoSuchFile"))
|
|
return nil
|
|
}
|
|
tmpPath = path.Join(upgradeDir, tmpPath, "original")
|
|
fmt.Println(i18n.GetMsgWithMapForCmd("RestoreStep1", map[string]interface{}{"name": tmpPath}))
|
|
|
|
if err := common.CopyFile(path.Join(tmpPath, "1panel"), "/usr/local/bin"); err != nil {
|
|
return err
|
|
}
|
|
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreStep2"))
|
|
if err := common.CopyFile(path.Join(tmpPath, "1pctl"), "/usr/local/bin"); err != nil {
|
|
return err
|
|
}
|
|
_, _ = cmdUtils.Execf("cp -r %s /usr/local/bin", path.Join(tmpPath, "lang"))
|
|
geoPath := path.Join(global.CONF.System.BaseDir, "1panel/geo")
|
|
_, _ = cmdUtils.Execf("mkdir %s && cp %s %s/", geoPath, path.Join(tmpPath, "GeoIP.mmdb"), geoPath)
|
|
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreStep3"))
|
|
if err := common.CopyFile(path.Join(tmpPath, "1panel.service"), "/etc/systemd/system"); err != nil {
|
|
return err
|
|
}
|
|
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreStep4"))
|
|
checkPointOfWal()
|
|
if _, err := os.Stat(path.Join(tmpPath, "1Panel.db")); err == nil {
|
|
if err := common.CopyFile(path.Join(tmpPath, "1Panel.db"), path.Join(baseDir, "1panel/db")); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if _, err := os.Stat(path.Join(tmpPath, "db.tar.gz")); err == nil {
|
|
if err := handleUnTar(path.Join(tmpPath, "db.tar.gz"), path.Join(baseDir, "1panel")); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreStep5"))
|
|
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreSuccessful"))
|
|
return nil
|
|
},
|
|
}
|
|
|
|
func checkPointOfWal() {
|
|
db, err := loadDBConn()
|
|
if err != nil {
|
|
return
|
|
}
|
|
_ = db.Exec("PRAGMA wal_checkpoint(TRUNCATE);").Error
|
|
}
|
|
|
|
func loadRestorePath(upgradeDir string) (string, error) {
|
|
if _, err := os.Stat(upgradeDir); err != nil && os.IsNotExist(err) {
|
|
return "no such file", nil
|
|
}
|
|
files, err := os.ReadDir(upgradeDir)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var folders []string
|
|
for _, file := range files {
|
|
if file.IsDir() {
|
|
folders = append(folders, file.Name())
|
|
}
|
|
}
|
|
if len(folders) == 0 {
|
|
return "no such file", nil
|
|
}
|
|
sort.Slice(folders, func(i, j int) bool {
|
|
return folders[i] > folders[j]
|
|
})
|
|
return folders[0], nil
|
|
}
|
|
|
|
func handleUnTar(sourceFile, targetDir string) error {
|
|
if _, err := os.Stat(targetDir); err != nil && os.IsNotExist(err) {
|
|
if err = os.MkdirAll(targetDir, os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
commands := fmt.Sprintf("tar zxvfC %s %s", sourceFile, targetDir)
|
|
stdout, err := cmdUtils.ExecWithTimeOut(commands, 20*time.Second)
|
|
if err != nil {
|
|
return errors.New(stdout)
|
|
}
|
|
return nil
|
|
}
|