mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2026-10-30 17:51:44 +08:00
@@ -190,6 +190,13 @@ func (w *WafSysInfoApi) UpdateApi(c *gin.Context) {
|
||||
},
|
||||
}
|
||||
go func() {
|
||||
// 备份当前可执行文件
|
||||
err := wafupdate.BackupExecutable()
|
||||
if err != nil {
|
||||
zlog.Error("备份可执行文件失败:", err)
|
||||
// 备份失败不影响升级流程,继续执行
|
||||
}
|
||||
|
||||
// try to update
|
||||
if channel != "" {
|
||||
err := updater.BackgroundRunWithChannel(channel)
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"SamWaf/common/zlog"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BackupFile 备份文件到指定目录
|
||||
// srcFilePath: 源文件路径
|
||||
// backupDir: 备份目录
|
||||
// backupFilePrefix: 备份文件名前缀
|
||||
// keepCount: 保留的备份文件数量
|
||||
func BackupFile(srcFilePath, backupDir, backupFilePrefix string, keepCount int) (string, error) {
|
||||
// 判断源文件是否存在
|
||||
if _, err := os.Stat(srcFilePath); os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("源文件不存在: %s", srcFilePath)
|
||||
}
|
||||
|
||||
// 判断备份目录是否存在,不存在则创建
|
||||
if _, err := os.Stat(backupDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(backupDir, os.ModePerm); err != nil {
|
||||
zlog.Error("创建备份目录失败:", err)
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// 获取文件扩展名
|
||||
fileExt := filepath.Ext(srcFilePath)
|
||||
|
||||
// 创建备份文件名
|
||||
backupFileName := fmt.Sprintf("%s_%s%s", backupFilePrefix, time.Now().Format("20060102150405"), fileExt)
|
||||
backupFilePath := filepath.Join(backupDir, backupFileName)
|
||||
|
||||
// 创建备份文件
|
||||
backupFile, err := os.Create(backupFilePath)
|
||||
if err != nil {
|
||||
zlog.Error("创建备份文件失败:", err)
|
||||
return "", err
|
||||
}
|
||||
defer backupFile.Close()
|
||||
|
||||
// 打开原始文件
|
||||
originalFile, err := os.Open(srcFilePath)
|
||||
if err != nil {
|
||||
zlog.Error("打开原始文件失败:", err)
|
||||
return "", err
|
||||
}
|
||||
defer originalFile.Close()
|
||||
|
||||
// 复制文件内容到备份文件
|
||||
_, err = io.Copy(backupFile, originalFile)
|
||||
if err != nil {
|
||||
zlog.Error("文件复制失败:", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
zlog.Info("文件备份成功,备份文件路径:", backupFilePath)
|
||||
|
||||
// 清理旧的备份文件,只保留最新的keepCount个
|
||||
CleanupOldBackups(backupDir, backupFilePrefix, keepCount)
|
||||
|
||||
return backupFilePath, nil
|
||||
}
|
||||
|
||||
// CleanupOldBackups 清理旧的备份文件,只保留最新的n个
|
||||
func CleanupOldBackups(backupDir, filePrefix string, keepCount int) {
|
||||
// 获取备份目录中的所有文件
|
||||
files, err := os.ReadDir(backupDir)
|
||||
if err != nil {
|
||||
zlog.Error("读取备份目录失败:", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 筛选出指定前缀的备份文件
|
||||
var backupFiles []os.DirEntry
|
||||
for _, file := range files {
|
||||
if !file.IsDir() && strings.HasPrefix(file.Name(), filePrefix) {
|
||||
backupFiles = append(backupFiles, file)
|
||||
}
|
||||
}
|
||||
|
||||
// 如果备份文件数量不超过保留数量,则不需要删除
|
||||
if len(backupFiles) <= keepCount {
|
||||
return
|
||||
}
|
||||
|
||||
// 按文件修改时间排序(从旧到新)
|
||||
sort.Slice(backupFiles, func(i, j int) bool {
|
||||
infoI, err := backupFiles[i].Info()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
infoJ, err := backupFiles[j].Info()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return infoI.ModTime().Before(infoJ.ModTime())
|
||||
})
|
||||
|
||||
// 删除多余的旧文件
|
||||
for i := 0; i < len(backupFiles)-keepCount; i++ {
|
||||
filePath := filepath.Join(backupDir, backupFiles[i].Name())
|
||||
err := os.Remove(filePath)
|
||||
if err != nil {
|
||||
zlog.Error("删除旧备份文件失败:", err, filePath)
|
||||
} else {
|
||||
zlog.Info("已删除旧备份文件:", filePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-35
@@ -13,7 +13,6 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"gorm.io/gorm/logger"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -42,44 +41,14 @@ func InitCoreDb(currentDir string) {
|
||||
path := currentDir + "/data/local.db"
|
||||
// 检查文件是否存在
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
// 文件存在的逻辑
|
||||
// 文件存在的逻辑,使用工具函数进行备份
|
||||
backupDir := currentDir + "/data/backups"
|
||||
// 判断备份目录是否存在,不存在则创建
|
||||
if _, err := os.Stat(backupDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(backupDir, os.ModePerm); err != nil {
|
||||
zlog.Error("创建备份目录失败:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
// 创建备份文件
|
||||
backupFilePath := filepath.Join(backupDir, fmt.Sprintf("local_backup_%s.db", time.Now().Format("20060102150405")))
|
||||
backupFile, err := os.Create(backupFilePath)
|
||||
_, err := utils.BackupFile(path, backupDir, "local_backup", 10)
|
||||
if err != nil {
|
||||
zlog.Error("创建备份文件失败:", err)
|
||||
return
|
||||
zlog.Error("备份数据库文件失败:", err)
|
||||
}
|
||||
defer backupFile.Close()
|
||||
|
||||
// 打开原始文件
|
||||
originalFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
zlog.Error("打开原始文件失败:", err)
|
||||
return
|
||||
}
|
||||
defer originalFile.Close()
|
||||
|
||||
// 复制文件内容到备份文件
|
||||
_, err = io.Copy(backupFile, originalFile)
|
||||
if err != nil {
|
||||
zlog.Error("文件复制失败:", err)
|
||||
return
|
||||
}
|
||||
|
||||
zlog.Info("文件备份成功,备份文件路径:", backupFilePath)
|
||||
|
||||
// 检查并清理旧的备份文件,保留最新的10个
|
||||
cleanupOldBackups(backupDir, 10)
|
||||
}
|
||||
|
||||
key := url.QueryEscape(global.GWAF_PWD_COREDB)
|
||||
dns := fmt.Sprintf("%s?_db_key=%s", path, key)
|
||||
db, err := gorm.Open(sqlite.Open(dns), &gorm.Config{})
|
||||
|
||||
@@ -675,3 +675,31 @@ func verifySha(bin []byte, sha []byte) bool {
|
||||
func writeTime(path string, t time.Time) bool {
|
||||
return ioutil.WriteFile(path, []byte(t.Format(time.RFC3339)), 0644) == nil
|
||||
}
|
||||
|
||||
// BackupExecutable 备份当前可执行文件
|
||||
func BackupExecutable() error {
|
||||
// 获取当前可执行文件路径
|
||||
execPath, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 如果是符号链接,获取实际路径
|
||||
if resolvedPath, err := filepath.EvalSymlinks(execPath); err == nil {
|
||||
execPath = resolvedPath
|
||||
}
|
||||
|
||||
// 获取当前目录
|
||||
currentDir := utils.GetCurrentDir()
|
||||
|
||||
// 创建备份目录
|
||||
backupDir := filepath.Join(currentDir, "data", "backups_bin")
|
||||
|
||||
// 获取文件名(不带路径)
|
||||
fileName := filepath.Base(execPath)
|
||||
fileNameWithoutExt := strings.TrimSuffix(fileName, filepath.Ext(fileName))
|
||||
|
||||
// 备份文件
|
||||
_, err = utils.BackupFile(execPath, backupDir, fileNameWithoutExt, 5)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user