zhangzengfei
2023-09-05 63645d248c765244488cd34dbc1bb6528ca6b7c7
version-control/service/backup.go
@@ -1,152 +1,152 @@
package service
import (
   "context"
   "fmt"
   "os"
   "os/exec"
   "path/filepath"
   "time"
   "vamicro/extend/util"
   "vamicro/version-control/models"
   "basic.com/valib/logger.git"
)
/*
   系统备份、备份还原、按设置周期性备份
   备份的数据主要包括sqlite数据、config以及exe(按需要)
   按钮可以触发立即备份
   参数:
      1.备份开关
      2.备份目录文件夹(/opt/vasystem/backup_auto)
      3.备份周期(每7天备份一次,备份时间是夜间0点)
      4.备份数据保存时间
*/
func BakSchedule(ctx context.Context) {
   // tk := time.NewTicker(time.Minute)
   tk := time.Tick(24 * time.Hour)
   for {
      select {
      case <-ctx.Done():
         return
      case <-tk:
         removeCheck()
         backupCheck()
      }
   }
}
//自动清理大于保存时间的备份数据
func removeCheck() {
   var ab models.AutoBackupConf
   i, e := ab.Select()
   if e != nil || i <= 0 {
      return
   }
   if ab.Dir == "" {
      logger.Error("备份目录未配置")
      return
   }
   if ab.Period < 1 || ab.SaveDays < 1 {
      logger.Error("周期和保存天数不合法")
      return
   }
   t := time.Now()
   err := filepath.Walk(ab.Dir, func(src string, f os.FileInfo, err error) error {
      if f.IsDir() {
         nt, e := time.ParseInLocation("2006-01-02-15-04-05", f.Name(), time.Local)
         if e != nil {
            return e
         }
         if int(t.Sub(nt).Hours()) > ab.SaveDays*24 {
            os.RemoveAll(ab.Dir + "/" + f.Name())
         }
      }
      return nil
   })
   if err != nil {
      logger.Error(err)
   }
}
func backupCheck() {
   //检查当前时间
   t := time.Now()
   if t.Hour() > 1 {
      return
   }
   var ab models.AutoBackupConf
   i, e := ab.Select()
   if e != nil || i <= 0 {
      return
   }
   if !ab.Enable {
      logger.Info("自动备份开关未打开")
      return
   }
   if ab.Dir == "" {
      logger.Error("备份目录未配置")
      return
   }
   if ab.Period < 1 || ab.SaveDays < 1 {
      logger.Error("周期和保存天数不合法")
      return
   }
   if !util.DirExists(ab.Dir) {
      os.Mkdir(ab.Dir, os.ModePerm)
   }
   lbd, err := exec.Command(fmt.Sprintf("ls %s | sort -r|head -1", ab.Dir)).Output()
   if err != nil {
      logger.Error("get last auto backup day err:", err)
      return
   }
   sbd := string(lbd)
   if sbd == "" { //未备份过,则执行备份
      DoAutoBackup(&ab)
   } else {
      tl, _ := time.ParseInLocation("2006-01-02-15-04-05", sbd, time.Local)
      if int(t.Sub(tl).Hours()) >= ab.Period*24 {
         DoAutoBackup(&ab)
      }
   }
}
func DoAutoBackup(ab *models.AutoBackupConf) error {
   backDirName := time.Now().Format("2006-01-02-15-04-05")
   dir := ab.Dir + "/" + backDirName
   if !util.DirExists(dir) {
      if err := os.Mkdir(dir, os.ModePerm); err != nil {
         return err
      }
   }
   //备份数据库和配置文件
   _, err := util.CopyDirByCmd("/opt/vasystem/config", dir)
   if err != nil {
      return err
   }
   return nil
}
func DoBackupRecover(dir string) error {
   //防止还原失败,做一个还原点备份
   //先停止所有进程
   //还原
   //重启系统
   recoverBakDir := util.GetVamicroPath() + "/recover_backup"
   if util.DirExists(recoverBakDir) {
      os.RemoveAll(recoverBakDir)
   }
   os.Mkdir(recoverBakDir, os.ModePerm)
   util.CopyDirByCmd("/opt/vasystem/config", recoverBakDir)
   _, err := exec.Command("/bin/sh", "-c", fmt.Sprintf(`
      /opt/vasystem/procs/killAllProcs.sh &&
      cp -rf %s/* /opt/vasystem/config/ &&
      /opt/vasystem/daemon.sh`, dir)).Output()
   return err
}
package service
import (
   "context"
   "fmt"
   "os"
   "os/exec"
   "path/filepath"
   "time"
   "vamicro/extend/util"
   "vamicro/version-control/models"
   "basic.com/valib/logger.git"
)
/*
   系统备份、备份还原、按设置周期性备份
   备份的数据主要包括sqlite数据、config以及exe(按需要)
   按钮可以触发立即备份
   参数:
      1.备份开关
      2.备份目录文件夹(/opt/vasystem/backup_auto)
      3.备份周期(每7天备份一次,备份时间是夜间0点)
      4.备份数据保存时间
*/
func BakSchedule(ctx context.Context) {
   // tk := time.NewTicker(time.Minute)
   tk := time.Tick(24 * time.Hour)
   for {
      select {
      case <-ctx.Done():
         return
      case <-tk:
         removeCheck()
         backupCheck()
      }
   }
}
//自动清理大于保存时间的备份数据
func removeCheck() {
   var ab models.AutoBackupConf
   i, e := ab.Select()
   if e != nil || i <= 0 {
      return
   }
   if ab.Dir == "" {
      logger.Error("备份目录未配置")
      return
   }
   if ab.Period < 1 || ab.SaveDays < 1 {
      logger.Error("周期和保存天数不合法")
      return
   }
   t := time.Now()
   err := filepath.Walk(ab.Dir, func(src string, f os.FileInfo, err error) error {
      if f.IsDir() {
         nt, e := time.ParseInLocation("2006-01-02-15-04-05", f.Name(), time.Local)
         if e != nil {
            return e
         }
         if int(t.Sub(nt).Hours()) > ab.SaveDays*24 {
            os.RemoveAll(ab.Dir + "/" + f.Name())
         }
      }
      return nil
   })
   if err != nil {
      logger.Error(err)
   }
}
func backupCheck() {
   //检查当前时间
   t := time.Now()
   if t.Hour() > 1 {
      return
   }
   var ab models.AutoBackupConf
   i, e := ab.Select()
   if e != nil || i <= 0 {
      return
   }
   if !ab.Enable {
      logger.Info("自动备份开关未打开")
      return
   }
   if ab.Dir == "" {
      logger.Error("备份目录未配置")
      return
   }
   if ab.Period < 1 || ab.SaveDays < 1 {
      logger.Error("周期和保存天数不合法")
      return
   }
   if !util.DirExists(ab.Dir) {
      os.Mkdir(ab.Dir, os.ModePerm)
   }
   lbd, err := exec.Command(fmt.Sprintf("ls %s | sort -r|head -1", ab.Dir)).Output()
   if err != nil {
      logger.Error("get last auto backup day err:", err)
      return
   }
   sbd := string(lbd)
   if sbd == "" { //未备份过,则执行备份
      DoAutoBackup(&ab)
   } else {
      tl, _ := time.ParseInLocation("2006-01-02-15-04-05", sbd, time.Local)
      if int(t.Sub(tl).Hours()) >= ab.Period*24 {
         DoAutoBackup(&ab)
      }
   }
}
func DoAutoBackup(ab *models.AutoBackupConf) error {
   backDirName := time.Now().Format("2006-01-02-15-04-05")
   dir := ab.Dir + "/" + backDirName
   if !util.DirExists(dir) {
      if err := os.Mkdir(dir, os.ModePerm); err != nil {
         return err
      }
   }
   //备份数据库和配置文件
   _, err := util.CopyDirByCmd("/opt/vasystem/config", dir)
   if err != nil {
      return err
   }
   return nil
}
func DoBackupRecover(dir string) error {
   //防止还原失败,做一个还原点备份
   //先停止所有进程
   //还原
   //重启系统
   recoverBakDir := util.GetVamicroPath() + "/recover_backup"
   if util.DirExists(recoverBakDir) {
      os.RemoveAll(recoverBakDir)
   }
   os.Mkdir(recoverBakDir, os.ModePerm)
   util.CopyDirByCmd("/opt/vasystem/config", recoverBakDir)
   _, err := exec.Command("/bin/sh", "-c", fmt.Sprintf(`
      /opt/vasystem/procs/killAllProcs.sh &&
      cp -rf %s/* /opt/vasystem/config/ &&
      /opt/vasystem/daemon.sh`, dir)).Output()
   return err
}