mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-25 19:49:14 +08:00
151 lines
5.0 KiB
Go
151 lines
5.0 KiB
Go
|
package service
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"time"
|
||
|
|
||
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||
|
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||
|
"github.com/jinzhu/copier"
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
type SnapshotService struct{}
|
||
|
|
||
|
type ISnapshotService interface {
|
||
|
SearchWithPage(req dto.PageInfo) (int64, interface{}, error)
|
||
|
Create(req dto.SnapshotCreate) error
|
||
|
}
|
||
|
|
||
|
func NewISnapshotService() ISnapshotService {
|
||
|
return &SnapshotService{}
|
||
|
}
|
||
|
|
||
|
func (u *SnapshotService) SearchWithPage(req dto.PageInfo) (int64, interface{}, error) {
|
||
|
total, snapshots, err := snapshotRepo.Page(req.Page, req.PageSize)
|
||
|
var dtoSnap []dto.SnapshotInfo
|
||
|
for _, snapshot := range snapshots {
|
||
|
var item dto.SnapshotInfo
|
||
|
if err := copier.Copy(&item, &snapshot); err != nil {
|
||
|
return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error())
|
||
|
}
|
||
|
dtoSnap = append(dtoSnap, item)
|
||
|
}
|
||
|
return total, dtoSnap, err
|
||
|
}
|
||
|
|
||
|
func (u *SnapshotService) Create(req dto.SnapshotCreate) error {
|
||
|
localDir, err := loadLocalDir()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
backup, err := backupRepo.Get(commonRepo.WithByType(req.BackupType))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
backupAccont, err := NewIBackupService().NewClient(&backup)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
timeNow := time.Now().Format("20060102150405")
|
||
|
rootDir := fmt.Sprintf("/tmp/songliu/1panel_backup_%s", timeNow)
|
||
|
backupPanelDir := fmt.Sprintf("%s/1panel", rootDir)
|
||
|
_ = os.MkdirAll(backupPanelDir, os.ModePerm)
|
||
|
backupDockerDir := fmt.Sprintf("%s/docker", rootDir)
|
||
|
_ = os.MkdirAll(backupDockerDir, os.ModePerm)
|
||
|
|
||
|
defer func() {
|
||
|
_, _ = cmd.Exec("systemctl start docker")
|
||
|
_ = os.RemoveAll(rootDir)
|
||
|
}()
|
||
|
|
||
|
fileOp := files.NewFileOp()
|
||
|
if err := fileOp.Compress([]string{localDir}, backupPanelDir, "1panel_backup.tar.gz", files.TarGz); err != nil {
|
||
|
global.LOG.Errorf("snapshot backup 1panel backup datas %s failed, err: %v", localDir, err)
|
||
|
return err
|
||
|
}
|
||
|
client, err := docker.NewDockerClient()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
ctx := context.Background()
|
||
|
info, err := client.Info(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
dataDir := info.DockerRootDir
|
||
|
stdout, err := cmd.Exec("systemctl stop docker")
|
||
|
if err != nil {
|
||
|
return errors.New(stdout)
|
||
|
}
|
||
|
|
||
|
if _, err := os.Stat("/etc/systemd/system/1panel.service"); err == nil {
|
||
|
if err := fileOp.Compress([]string{dataDir}, backupDockerDir, "docker_data.tar.gz", files.TarGz); err != nil {
|
||
|
global.LOG.Errorf("snapshot backup docker data dir %s failed, err: %v", dataDir, err)
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
if _, err := os.Stat(constant.DaemonJsonPath); err == nil {
|
||
|
if err := fileOp.CopyFile(constant.DaemonJsonPath, backupDockerDir); err != nil {
|
||
|
global.LOG.Errorf("snapshot backup daemon.json failed, err: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if _, err := os.Stat("/Users/slooop/go/bin/swag"); err == nil {
|
||
|
if err := fileOp.CopyFile("/Users/slooop/go/bin/swag", backupPanelDir); err != nil {
|
||
|
global.LOG.Errorf("snapshot backup 1panel failed, err: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
if _, err := os.Stat("/etc/systemd/system/1panel.service"); err == nil {
|
||
|
if err := fileOp.CopyFile("/etc/systemd/system/1panel.service", backupPanelDir); err != nil {
|
||
|
global.LOG.Errorf("snapshot backup 1panel.service failed, err: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
if _, err := os.Stat("/usr/local/bin/1panelctl"); err == nil {
|
||
|
if err := fileOp.CopyFile("/usr/local/bin/1panelctl", backupPanelDir); err != nil {
|
||
|
global.LOG.Errorf("snapshot backup 1panelctl failed, err: %v", err)
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
if _, err := os.Stat(global.CONF.System.DataDir); err == nil {
|
||
|
if err := fileOp.Compress([]string{global.CONF.System.DataDir}, backupPanelDir, "1panel_data.tar.gz", files.TarGz); err != nil {
|
||
|
global.LOG.Errorf("snapshot backup 1panel data %s failed, err: %v", global.CONF.System.DataDir, err)
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
if err := fileOp.Compress([]string{rootDir}, fmt.Sprintf("%s/system", localDir), fmt.Sprintf("1panel_backup_%s.tar.gz", timeNow), files.TarGz); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
snap := model.Snapshot{
|
||
|
Name: "1panel_backup_" + timeNow,
|
||
|
Description: req.Description,
|
||
|
BackupType: req.BackupType,
|
||
|
Status: constant.StatusWaiting,
|
||
|
}
|
||
|
_ = snapshotRepo.Create(&snap)
|
||
|
go func() {
|
||
|
localPath := fmt.Sprintf("%s/system/1panel_backup_%s.tar.gz", localDir, timeNow)
|
||
|
if ok, err := backupAccont.Upload(localPath, fmt.Sprintf("system_snapshot/1panel_backup_%s.tar.gz", timeNow)); err != nil || !ok {
|
||
|
_ = snapshotRepo.Update(snap.ID, map[string]interface{}{"status": constant.StatusFailed, "message": err.Error()})
|
||
|
global.LOG.Errorf("upload snapshot to %s failed, err: %v", backup.Type, err)
|
||
|
return
|
||
|
}
|
||
|
snap.Status = constant.StatusSuccess
|
||
|
_ = snapshotRepo.Update(snap.ID, map[string]interface{}{"status": constant.StatusSuccess})
|
||
|
global.LOG.Infof("upload snapshot to %s success", backup.Type)
|
||
|
}()
|
||
|
return nil
|
||
|
}
|