146 lines
3.9 KiB
Go
146 lines
3.9 KiB
Go
package service
|
||
|
||
import (
|
||
"bash_go_service/shared/pkg/constants"
|
||
"bash_go_service/shared/pkg/logger"
|
||
"bash_go_service/version/pkg/handler"
|
||
"context"
|
||
"os"
|
||
"path/filepath"
|
||
"time"
|
||
|
||
"github.com/spf13/viper"
|
||
)
|
||
|
||
// VersionCheckTask represents a task that checks for version updates.
|
||
type VersionCheckTask struct {
|
||
interval time.Duration
|
||
}
|
||
|
||
// NewVersionCheckTask creates a new VersionCheckTask.
|
||
func NewVersionCheckTask() *VersionCheckTask {
|
||
interval := viper.GetDuration("update_checker.interval")
|
||
if interval < 1*time.Hour {
|
||
interval = 1 * time.Hour // 默认值为1小时
|
||
}
|
||
logger.Debug("VersionCheckTask interval: %v", interval)
|
||
|
||
return &VersionCheckTask{
|
||
interval: interval,
|
||
}
|
||
}
|
||
|
||
// Execute runs the version check task periodically.
|
||
func (t *VersionCheckTask) Execute(ctx context.Context) {
|
||
ticker := time.NewTicker(t.interval)
|
||
defer ticker.Stop()
|
||
|
||
for {
|
||
select {
|
||
case <-ticker.C:
|
||
t.CheckUpdate(ctx)
|
||
case <-ctx.Done():
|
||
logger.Info("VersionCheckTask stopped")
|
||
return
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查更新,将文件下载到本地,在下次启动程序时执行更新
|
||
func (t *VersionCheckTask) CheckUpdate(ctx context.Context) {
|
||
logger.Info("Executing version update check at %v", time.Now())
|
||
|
||
res, err := handler.CheckVersionUpdate()
|
||
needUpdate, newVersion, md5sum, soMd5 := res.NeedUpdate, res.Version, res.ExeMd5, res.SoMd5
|
||
if err != nil {
|
||
logger.Error("Failed to check for updates: %v", err)
|
||
return
|
||
}
|
||
|
||
if !needUpdate {
|
||
logger.Info("No update needed.")
|
||
return
|
||
}
|
||
|
||
currentExePath, err := os.Executable()
|
||
if err != nil {
|
||
logger.Error("Failed to get executable path: %v", err)
|
||
return
|
||
}
|
||
currentExeDir := filepath.Dir(currentExePath)
|
||
currentExeBase := filepath.Base(currentExePath)
|
||
|
||
backupPath, err := handler.BackupCurrentExecutable(currentExePath, currentExeBase, currentExeDir)
|
||
if err != nil {
|
||
logger.Error("Failed to backup current executable: %v", err)
|
||
return
|
||
}
|
||
logger.Info("Backup current executable to: %s", backupPath)
|
||
|
||
currentSoPath := filepath.Join(constants.SoPath, constants.SoName)
|
||
soBackupPath, err := handler.BackupCurrentExecutable(
|
||
currentSoPath,
|
||
constants.SoName, currentExeDir)
|
||
if err != nil {
|
||
logger.Error("Failed to backup so-lib: %v", err)
|
||
return
|
||
}
|
||
logger.Info("Backup current so-lib to: %s", soBackupPath)
|
||
|
||
// 下载最新的exe,并且校验md5
|
||
newExePath, err := handler.DownloadNewExecutable(constants.SoPath, currentExeBase, newVersion, "exe")
|
||
if err != nil {
|
||
logger.Error("Failed to download new executable: %v", err)
|
||
_ = os.Remove(backupPath)
|
||
return
|
||
}
|
||
|
||
if err := handler.VerifyMD5(newExePath, md5sum); err != nil {
|
||
logger.Error("MD5 verification failed: %v", err)
|
||
// Attempt rollback
|
||
_ = os.Remove(newExePath)
|
||
return
|
||
}
|
||
|
||
// 下载最新的so,并且校验md5
|
||
newSoPath, err := handler.DownloadNewExecutable(constants.SoPath, constants.SoName, newVersion, "so")
|
||
if err != nil {
|
||
logger.Error("Failed to download new so-lib: %v", err)
|
||
// Attempt rollback
|
||
_ = os.Remove(soBackupPath)
|
||
return
|
||
}
|
||
if err := handler.VerifyMD5(newSoPath, soMd5); err != nil {
|
||
logger.Error("MD5 verification failed: %v", err)
|
||
// Attempt rollback
|
||
_ = os.Remove(newSoPath)
|
||
return
|
||
}
|
||
|
||
info := handler.CreateUpdateInfo(backupPath, newExePath, currentExePath, soBackupPath, newSoPath, currentSoPath)
|
||
err = handler.SaveUpdateInfo(currentExePath, *info)
|
||
if err != nil {
|
||
logger.Error("Failed to save update info: %v", err)
|
||
return
|
||
}
|
||
logger.Info("The update will be initiated on the next application start.")
|
||
|
||
// 下次启动的时候检查更新
|
||
|
||
// if err := handler.ExecuteUpdate(currentExeDir, backupPath, newExePath, currentExePath); err != nil {
|
||
// logger.Error("Failed to execute update: %v", err)
|
||
// // Attempt rollback
|
||
// _ = os.Rename(backupPath, currentExePath)
|
||
// _ = os.Remove(newExePath)
|
||
// return
|
||
// }
|
||
|
||
// logger.Info("Update process initiated, current process exiting.")
|
||
//
|
||
}
|
||
|
||
// Name returns the name of the task.
|
||
func (t *VersionCheckTask) Name() string {
|
||
return "VersionCheckTask"
|
||
}
|