diff --git a/cmd/agent/main.go b/cmd/agent/main.go index b45e422..9e1421d 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -374,28 +374,12 @@ func updateAgent(cmd *cobra.Command, args []string) { log.Println("🔍 检查更新...") - // 检查更新 - versionInfo, err := updater.CheckUpdate(cfg.GetUpdateURL(), service.GetVersion()) + up, err := updater.New(cfg, service.GetVersion()) if err != nil { - log.Fatalf("❌ 检查更新失败: %v", err) + log.Fatalf("❌ 创建更新器失败: %v", err) } - // 比较版本 - if versionInfo.Version == service.GetVersion() { - log.Printf("✅ 当前已是最新版本: %s", service.GetVersion()) - return - } - - log.Printf("🆕 发现新版本: %s (当前版本: %s)", versionInfo.Version, service.GetVersion()) - - // 下载并更新 - downloadURL := cfg.GetDownloadURL() - if err := updater.Update(downloadURL); err != nil { - log.Fatalf("❌ 更新失败: %v", err) - } - - log.Println("✅ 更新成功") - log.Println(" 请重启服务以使用新版本") + up.CheckAndUpdate() } // registerAgent 注册探针 diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index b6e84c4..45b67b8 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -230,8 +230,8 @@ func (c *Config) GetWebSocketURL() string { return fmt.Sprintf("%s://%s/ws/agent", scheme, u.Host) } -// GetUpdateURL 获取更新检查地址 -func (c *Config) GetUpdateURL() string { +// GetLatestVersionURL 获取更新检查地址 +func (c *Config) GetLatestVersionURL() string { return c.Endpoint() + "/api/agent/version" } diff --git a/pkg/agent/service/agent.go b/pkg/agent/service/agent.go index 05108c2..2d70f43 100644 --- a/pkg/agent/service/agent.go +++ b/pkg/agent/service/agent.go @@ -292,7 +292,7 @@ func (a *Agent) registerAgent(conn *safeConn) error { Hostname: hostname, OS: runtime.GOOS, Arch: runtime.GOARCH, - Version: version.GetVersion(), + Version: GetVersion(), }, ApiKey: a.cfg.Server.APIKey, } diff --git a/pkg/agent/updater/updater.go b/pkg/agent/updater/updater.go index 225779c..16c7cc6 100644 --- a/pkg/agent/updater/updater.go +++ b/pkg/agent/updater/updater.go @@ -8,7 +8,6 @@ import ( "log" "net/http" "os" - "runtime" "time" "github.com/dushixiang/pika/pkg/agent/config" @@ -65,7 +64,7 @@ func (u *Updater) Start(ctx context.Context) { log.Printf("自动更新已启用,检查间隔: %v", u.cfg.GetUpdateCheckInterval()) // 立即检查一次 - u.checkAndUpdate() + u.CheckAndUpdate() // 定时检查 ticker := time.NewTicker(u.cfg.GetUpdateCheckInterval()) @@ -74,7 +73,7 @@ func (u *Updater) Start(ctx context.Context) { for { select { case <-ticker.C: - u.checkAndUpdate() + u.CheckAndUpdate() case <-ctx.Done(): log.Println("停止自动更新检查") return @@ -82,8 +81,8 @@ func (u *Updater) Start(ctx context.Context) { } } -// checkAndUpdate 检查并更新 -func (u *Updater) checkAndUpdate() { +// CheckAndUpdate 检查并更新 +func (u *Updater) CheckAndUpdate() { log.Println("🔍 检查更新...") // 获取最新版本信息 @@ -112,15 +111,13 @@ func (u *Updater) checkAndUpdate() { // fetchLatestVersion 获取最新版本信息 func (u *Updater) fetchLatestVersion() (*VersionInfo, error) { - updateURL := u.cfg.GetUpdateURL() - return u.checkUpdateWithClient(updateURL, u.currentVer) + latestVersionURL := u.cfg.GetLatestVersionURL() + return u.checkUpdateWithClient(latestVersionURL) } // checkUpdateWithClient 使用实例的 httpClient 检查更新 -func (u *Updater) checkUpdateWithClient(updateURL, currentVer string) (*VersionInfo, error) { - url := fmt.Sprintf("%s?os=%s&arch=%s", updateURL, runtime.GOOS, runtime.GOARCH) - - resp, err := u.httpClient.Get(url) +func (u *Updater) checkUpdateWithClient(latestVersionURL string) (*VersionInfo, error) { + resp, err := u.httpClient.Get(latestVersionURL) if err != nil { return nil, fmt.Errorf("请求失败: %w", err) } @@ -168,60 +165,3 @@ func (u *Updater) downloadAndUpdate(versionInfo *VersionInfo) error { return nil } - -// CheckUpdate 手动检查更新(用于命令行) -func CheckUpdate(updateURL, currentVer string) (*VersionInfo, error) { - client := &http.Client{ - Timeout: 30 * time.Second, - } - - url := fmt.Sprintf("%s?os=%s&arch=%s", updateURL, runtime.GOOS, runtime.GOARCH) - - resp, err := client.Get(url) - if err != nil { - return nil, fmt.Errorf("请求失败: %w", err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("HTTP 状态码: %d", resp.StatusCode) - } - - var versionInfo VersionInfo - if err := json.NewDecoder(resp.Body).Decode(&versionInfo); err != nil { - return nil, fmt.Errorf("解析响应失败: %w", err) - } - - return &versionInfo, nil -} - -// Update 手动更新(用于命令行) -func Update(downloadURL string) error { - client := &http.Client{ - Timeout: 300 * time.Second, - } - - // 下载文件 - resp, err := client.Get(downloadURL) - if err != nil { - return fmt.Errorf("下载失败: %w", err) - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("HTTP 状态码: %d", resp.StatusCode) - } - - // 使用 selfupdate 应用更新 - if err := selfupdate.Apply(resp.Body, selfupdate.Options{}); err != nil { - return fmt.Errorf("应用更新失败: %w", err) - } - - log.Printf("✅ 更新成功,进程即将退出,等待系统服务重启...") - - // 退出当前进程,让系统服务管理器(systemd/supervisor等)自动重启 - // 注意:这要求服务配置了自动重启(如 systemd 的 Restart=always) - os.Exit(0) - - return nil -}