|
|
@@ -18,8 +18,10 @@ import (
|
|
|
)
|
|
|
|
|
|
type serviceUpgradeConfig struct {
|
|
|
- Name string `json:"name"` // 去掉"yfkj-"前缀和".service"后缀的
|
|
|
- // 服务名, 也是升级包中可执行程序的名称
|
|
|
+ Name string `json:"name"` /// 去掉"yfkj-"前缀和".service"后缀的
|
|
|
+ // 服务名称, 默认也是升级包中可执行程序的名称
|
|
|
+ Program string `json:"program"` /// 选填可执行程序名, 当与服务名
|
|
|
+ // 不相同时, 通过该字段可指明可执行程序的名称
|
|
|
Enable bool `json:"enable"` /// 是否启用自动升级/
|
|
|
CheckVerURL string `json:"checkVerURL"` /// 版本检查的 URL /
|
|
|
ClonePkgURL string `json:"clonePkgURL"` /// 升级包克隆 URL /
|
|
|
@@ -190,14 +192,19 @@ func (p *program) upgradeService(service serviceUpgradeConfig) (string, string,
|
|
|
baseapp.Logger.Infof("[%s] yfkj-%s.service 发现新版本: %s, 开始升级...",
|
|
|
p.name, service.Name, info.Version)
|
|
|
|
|
|
- currentDir, err := getCurrentVersionDir(service.InstallPath, service.Name)
|
|
|
+ programName := service.Program
|
|
|
+ if programName == "" {
|
|
|
+ programName = service.Name
|
|
|
+ }
|
|
|
+
|
|
|
+ currentDir, err := getCurrentVersionDir(service.InstallPath, programName)
|
|
|
if err != nil {
|
|
|
return "", "", false, fmt.Errorf("获取当前版本目录失败: %w", err)
|
|
|
}
|
|
|
|
|
|
targetVersion := nextVersionDir(currentDir)
|
|
|
targetDir := filepath.Join(service.InstallPath, targetVersion)
|
|
|
- targetName := filepath.Join(targetVersion, service.Name)
|
|
|
+ targetName := filepath.Join(targetVersion, programName)
|
|
|
|
|
|
pkg := filepath.Join(os.TempDir(), service.Name+".tar.gz")
|
|
|
defer os.Remove(pkg)
|
|
|
@@ -214,7 +221,7 @@ func (p *program) upgradeService(service serviceUpgradeConfig) (string, string,
|
|
|
return currentVersion, "", false, fmt.Errorf("安装服务升级包失败: %w", err)
|
|
|
}
|
|
|
|
|
|
- if err := switchServiceVersion(service.Name, service.InstallPath, targetName); err != nil {
|
|
|
+ if err := switchServiceVersion(service.Name, programName, service.InstallPath, targetName); err != nil {
|
|
|
return currentVersion, "", false, fmt.Errorf("切换服务版本失败: %w", err)
|
|
|
}
|
|
|
|
|
|
@@ -257,8 +264,8 @@ func downloadUpgradePackage(ctx context.Context, rawURL string, localFile string
|
|
|
}
|
|
|
|
|
|
// 获取当前软链接指向的版本目录,返回: a、b、c 之一
|
|
|
-func getCurrentVersionDir(installPath string, serviceName string) (string, error) {
|
|
|
- currentLink := filepath.Join(installPath, serviceName)
|
|
|
+func getCurrentVersionDir(installPath string, programName string) (string, error) {
|
|
|
+ currentLink := filepath.Join(installPath, programName)
|
|
|
|
|
|
target, err := os.Readlink(currentLink)
|
|
|
if err != nil {
|
|
|
@@ -294,9 +301,9 @@ func nextVersionDir(currentDir string) string {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 升级包默认包含与服务同名的可执行程序,之后再解压
|
|
|
+// 解压升级包并安装可执行程序及附加目录,升级的核心
|
|
|
func installPackage(pkg string, targetDir string, service serviceUpgradeConfig) error {
|
|
|
- tempDir, err := os.MkdirTemp(service.InstallPath, ".upgrade-")
|
|
|
+ tempDir, err := os.MkdirTemp(service.InstallPath, ".upgrade-*")
|
|
|
if err != nil {
|
|
|
return fmt.Errorf("创建临时目录失败: %w", err)
|
|
|
}
|
|
|
@@ -308,9 +315,13 @@ func installPackage(pkg string, targetDir string, service serviceUpgradeConfig)
|
|
|
return fmt.Errorf("解压%s升级包时出错: %w: %s", service.Name, err, strings.TrimSpace(string(output)))
|
|
|
}
|
|
|
|
|
|
- program := filepath.Join(tempDir, service.Name)
|
|
|
+ programName := service.Program
|
|
|
+ if programName == "" {
|
|
|
+ programName = service.Name
|
|
|
+ }
|
|
|
+ tempProgram := filepath.Join(tempDir, programName)
|
|
|
|
|
|
- info, err := os.Stat(program)
|
|
|
+ info, err := os.Stat(tempProgram)
|
|
|
if err != nil {
|
|
|
return fmt.Errorf("检查%s服务程序失败: %w", service.Name, err)
|
|
|
}
|
|
|
@@ -326,7 +337,7 @@ func installPackage(pkg string, targetDir string, service serviceUpgradeConfig)
|
|
|
return fmt.Errorf("创建%s版本目录失败: %w", service.Name, err)
|
|
|
}
|
|
|
|
|
|
- if err := os.Rename(program, filepath.Join(targetDir, service.Name)); err != nil {
|
|
|
+ if err := os.Rename(tempProgram, filepath.Join(targetDir, programName)); err != nil {
|
|
|
return fmt.Errorf("安装%s服务程序失败: %w", service.Name, err)
|
|
|
}
|
|
|
|
|
|
@@ -341,12 +352,16 @@ func installPackage(pkg string, targetDir string, service serviceUpgradeConfig)
|
|
|
func replacePackageDirs(tempDir string, targetBaseDir string, dirs []string) error {
|
|
|
for _, name := range dirs {
|
|
|
srcDir := filepath.Join(tempDir, name)
|
|
|
- if _, err := os.Stat(srcDir); err != nil {
|
|
|
+ info, err := os.Stat(srcDir)
|
|
|
+ if err != nil {
|
|
|
if os.IsNotExist(err) { //// 如果升级包中没有该目录
|
|
|
continue
|
|
|
}
|
|
|
return fmt.Errorf("检查%s目录失败: %w", name, err)
|
|
|
}
|
|
|
+ if !info.IsDir() {
|
|
|
+ return fmt.Errorf("%s不是目录", name)
|
|
|
+ }
|
|
|
|
|
|
targetDir := filepath.Join(targetBaseDir, name)
|
|
|
newDir := filepath.Join(targetBaseDir, "."+name+"-new")
|
|
|
@@ -386,10 +401,10 @@ func replacePackageDirs(tempDir string, targetBaseDir string, dirs []string) err
|
|
|
}
|
|
|
|
|
|
// 切换服务版本,新版本启动失败时自动回滚并重启服务
|
|
|
-func switchServiceVersion(serviceName string, installPath string, targetName string) error {
|
|
|
+func switchServiceVersion(serviceName string, programName string, installPath string, targetName string) error {
|
|
|
service := "yfkj-" + serviceName + ".service"
|
|
|
- currentLink := filepath.Join(installPath, serviceName)
|
|
|
- tempLink := filepath.Join(installPath, serviceName+".tmp")
|
|
|
+ currentLink := filepath.Join(installPath, programName)
|
|
|
+ tempLink := currentLink + ".tmp"
|
|
|
|
|
|
currentTarget, err := os.Readlink(currentLink)
|
|
|
if err != nil {
|