diff --git a/internal/data/backup.go b/internal/data/backup.go index 6e8fea6f..715bcdd2 100644 --- a/internal/data/backup.go +++ b/internal/data/backup.go @@ -332,14 +332,28 @@ func (r *backupRepo) createPanel(to string) error { } start := time.Now() - if err := io.Compress(filepath.Dir(filepath.Join(app.Root, "panel")), []string{ - ".", - "/usr/local/sbin/panel-cli", - "/usr/local/etc/panel/config.yml", - }, backup); err != nil { + + temp, err := io.TempDir("panel-backup") + if err != nil { return err } - if err := io.Chmod(backup, 0600); err != nil { + defer io.Remove(temp) + + if err = io.Cp(filepath.Join(app.Root, "panel"), temp); err != nil { + return err + } + if err = io.Cp("/usr/local/sbin/panel-cli", temp); err != nil { + return err + } + if err = io.Cp("/usr/local/etc/panel/config.yml", temp); err != nil { + return err + } + + _ = io.Chmod(temp, 0600) + if err = io.Compress(temp, nil, backup); err != nil { + return err + } + if err = io.Chmod(backup, 0600); err != nil { return err } diff --git a/internal/data/setting.go b/internal/data/setting.go index 2a4edb29..60e3f0b4 100644 --- a/internal/data/setting.go +++ b/internal/data/setting.go @@ -327,7 +327,7 @@ func (r *settingRepo) UpdatePanel(version, url, checksum string) error { if app.IsCli { fmt.Println("|-恢复面板数据...") } - if err := io.UnCompress("/tmp/panel-storage.zip", filepath.Join(app.Root, "panel")); err != nil { + if err := io.UnCompress("/tmp/panel-storage.zip", filepath.Join(app.Root, "panel", "storage")); err != nil { return fmt.Errorf("恢复面板数据失败:%w", err) } if !io.Exists(filepath.Join(app.Root, "panel/storage/app.db")) { @@ -455,7 +455,7 @@ func (r *settingRepo) FixPanel() error { } } - // tmp目录下如果有storage备份,则解压回去 + // tmp 目录下如果有 storage 备份,则解压回去 if app.IsCli { fmt.Println("|-恢复面板数据...") } diff --git a/internal/service/cli.go b/internal/service/cli.go index d391426a..06a8745c 100644 --- a/internal/service/cli.go +++ b/internal/service/cli.go @@ -464,7 +464,7 @@ func (s *CliService) BackupWebsite(ctx context.Context, cmd *cli.Command) error fmt.Println("|-备份类型:网站") fmt.Printf("|-备份目标:%s\n", cmd.String("name")) if err := s.backupRepo.Create(biz.BackupTypeWebsite, cmd.String("name"), cmd.String("path")); err != nil { - return fmt.Errorf("|-备份失败:%v", err) + return fmt.Errorf("备份失败:%v", err) } fmt.Println(s.hr) fmt.Printf("☆ 备份成功 [%s]\n", time.Now().Format(time.DateTime)) @@ -480,7 +480,7 @@ func (s *CliService) BackupDatabase(ctx context.Context, cmd *cli.Command) error fmt.Printf("|-数据库:%s\n", cmd.String("type")) fmt.Printf("|-备份目标:%s\n", cmd.String("name")) if err := s.backupRepo.Create(biz.BackupType(cmd.String("type")), cmd.String("name"), cmd.String("path")); err != nil { - return fmt.Errorf("|-备份失败:%v", err) + return fmt.Errorf("备份失败:%v", err) } fmt.Println(s.hr) fmt.Printf("☆ 备份成功 [%s]\n", time.Now().Format(time.DateTime)) @@ -494,7 +494,7 @@ func (s *CliService) BackupPanel(ctx context.Context, cmd *cli.Command) error { fmt.Println(s.hr) fmt.Println("|-备份类型:面板") if err := s.backupRepo.Create(biz.BackupTypePanel, "", cmd.String("path")); err != nil { - return fmt.Errorf("|-备份失败:%v", err) + return fmt.Errorf("备份失败:%v", err) } fmt.Println(s.hr) fmt.Printf("☆ 备份成功 [%s]\n", time.Now().Format(time.DateTime)) @@ -518,7 +518,7 @@ func (s *CliService) BackupClear(ctx context.Context, cmd *cli.Command) error { fmt.Printf("|-清理目标:%s\n", cmd.String("file")) fmt.Printf("|-保留份数:%d\n", cmd.Int("save")) if err = s.backupRepo.ClearExpired(path, cmd.String("file"), int(cmd.Int("save"))); err != nil { - return fmt.Errorf("|-清理失败:%v", err) + return fmt.Errorf("清理失败:%v", err) } fmt.Println(s.hr) fmt.Printf("☆ 清理成功 [%s]\n", time.Now().Format(time.DateTime)) diff --git a/pkg/io/compress.go b/pkg/io/compress.go index 80ac4361..75a83e6a 100644 --- a/pkg/io/compress.go +++ b/pkg/io/compress.go @@ -30,21 +30,18 @@ func Compress(dir string, src []string, dst string) error { for i, s := range src { if strings.HasPrefix(s, dir) { s = strings.TrimPrefix(s, dir) - src[i] = strings.TrimPrefix(s, "/") - } - if src[i] == "" { - src[i] = "." + if s != "" && s[0] == '/' { + src[i] = strings.TrimPrefix(s, "/") + } } } - cmd := new(exec.Cmd) - cmd.Dir = dir - format, err := formatArchiveByPath(dst) if err != nil { return err } + cmd := new(exec.Cmd) switch format { case Zip: cmd = exec.Command("zip", append([]string{"-qr", "-o", dst}, src...)...) @@ -62,6 +59,7 @@ func Compress(dir string, src []string, dst string) error { return errors.New("unsupported format") } + cmd.Dir = dir return cmd.Run() } diff --git a/pkg/io/path.go b/pkg/io/path.go index d92a2855..7c58d6aa 100644 --- a/pkg/io/path.go +++ b/pkg/io/path.go @@ -3,7 +3,6 @@ package io import ( "bytes" "fmt" - "io" "os" "os/exec" "path/filepath" @@ -52,81 +51,16 @@ func Empty(path string) bool { } func Mv(src, dst string) error { - if err := os.Rename(src, dst); err != nil { - // 在不同的文件系统中无法使用 os.Rename - if _, err = shell.Execf(`mv -f '%s' '%s'`, src, dst); err != nil { - return err - } - } - - return nil + _, err := shell.Execf(`mv -f '%s' '%s'`, src, dst) + return err } // Cp 复制文件或目录 func Cp(src, dst string) error { - srcInfo, err := os.Stat(src) - if err != nil { - return err - } - - if srcInfo.IsDir() { - return copyDir(src, dst) - } - return copyFile(src, dst) -} - -func copyFile(src, dst string) error { - srcFile, err := os.Open(src) - if err != nil { - return err - } - defer srcFile.Close() - - dstFile, err := os.Create(dst) - if err != nil { - return err - } - defer dstFile.Close() - - _, err = io.Copy(dstFile, srcFile) + _, err := shell.Execf(`cp -rf '%s' '%s'`, src, dst) return err } -func copyDir(src, dst string) error { - srcInfo, err := os.Stat(src) - if err != nil { - return err - } - - err = os.MkdirAll(dst, srcInfo.Mode()) - if err != nil { - return err - } - - entries, err := os.ReadDir(src) - if err != nil { - return err - } - - for _, entry := range entries { - srcPath := filepath.Join(src, entry.Name()) - dstPath := filepath.Join(dst, entry.Name()) - - if entry.IsDir() { - err = copyDir(srcPath, dstPath) - if err != nil { - return err - } - } else { - err = copyFile(srcPath, dstPath) - if err != nil { - return err - } - } - } - return nil -} - // Size 获取路径大小 func Size(path string) (int64, error) { var size int64