From 6d0afb6d309baa384925ff66f45e8cef41a353f3 Mon Sep 17 00:00:00 2001 From: xml Date: Thu, 30 Apr 2026 09:35:32 +0800 Subject: [PATCH] refactor(timer): merge platform policy check into updateSource flow - Remove platform policy check from handleAutoCheckEvent - Move version API call to beginning of updateSource - Add retry limit (max 3) to getUpdateMessage for 416 handling - Fix error handling: return error when unregister fails - Delete unused CheckPolicyChanged and related functions Bug: https://pms.uniontech.com/bug-view-359323.html --- src/internal/updateplatform/message_report.go | 192 ++++++------------ src/lastore-daemon/manager.go | 39 +--- src/lastore-daemon/manager_update.go | 42 ++-- 3 files changed, 89 insertions(+), 184 deletions(-) diff --git a/src/internal/updateplatform/message_report.go b/src/internal/updateplatform/message_report.go index ac502acd2..987844999 100644 --- a/src/internal/updateplatform/message_report.go +++ b/src/internal/updateplatform/message_report.go @@ -801,31 +801,39 @@ func (m *UpdatePlatformManager) genIpfsConfigResponse() (*http.Response, error) return client.Do(request) } -func getResponseData(response *http.Response, reqType requestType) (json.RawMessage, error) { +// getResponseData 解析 HTTP 响应数据,提取响应体中的 JSON 数据 +// response: HTTP 响应对象 +// reqType: 请求类型,用于日志记录 +// 返回值: +// - json.RawMessage: 解析后的 JSON 数据 +// - bool: 请求结果,成功时为 true,失败时为 false +// - int: 错误码,成功时为响应中的 Code 字段,失败时为错误码 +// - error: 错误信息,成功时为 nil +func getResponseData(response *http.Response, reqType requestType) (json.RawMessage, bool, int, error) { if http.StatusOK == response.StatusCode { respData, err := io.ReadAll(response.Body) if err != nil { - return nil, fmt.Errorf("%v failed to read response body: %v ", response.Request.RequestURI, err.Error()) + return nil, false, 0, fmt.Errorf("%v failed to read response body: %v ", response.Request.RequestURI, err.Error()) } logger.Debugf("%v request for %v respData:%s ", reqType.string(), response.Request.URL, string(respData)) msg := &tokenMessage{} err = json.Unmarshal(respData, msg) if err != nil { logger.Warningf("%v request for %v respData:%s ", reqType.string(), response.Request.URL, string(respData)) - return nil, fmt.Errorf("%v failed to Unmarshal respData to tokenMessage: %v ", reqType.string(), err.Error()) + return nil, false, 0, fmt.Errorf("%v failed to Unmarshal respData to tokenMessage: %v ", reqType.string(), err.Error()) } if !msg.Result { logger.Warningf("%v request for %v respData:%s ", reqType.string(), response.Request.URL, string(respData)) errorMsg := &tokenErrorMessage{} err = json.Unmarshal(respData, errorMsg) if err != nil { - return nil, fmt.Errorf("%v request for %s", reqType.string(), response.Request.RequestURI) + return nil, false, 0, fmt.Errorf("%v request for %s", reqType.string(), response.Request.RequestURI) } - return nil, fmt.Errorf("%v request for %s err:%s", reqType.string(), response.Request.RequestURI, errorMsg.Msg) + return nil, false, errorMsg.Code, fmt.Errorf("%v request for %s err:%s", reqType.string(), response.Request.RequestURI, errorMsg.Msg) } - return msg.Data, nil + return msg.Data, msg.Result, msg.Code, nil } else { - return nil, fmt.Errorf("request for %s failed, response code=%d", response.Request.URL, response.StatusCode) + return nil, false, 0, fmt.Errorf("request for %s failed, response code=%d", response.Request.URL, response.StatusCode) } } @@ -919,18 +927,11 @@ func IsForceUpdate(tp UpdateTp) bool { // GenUpdatePolicyByToken 检查更新时将token数据发送给更新平台,获取本次更新信息 func (m *UpdatePlatformManager) genUpdatePolicyByToken() error { - response, err := m.genVersionResponse() - if err != nil { - return fmt.Errorf("failed get version data %v", err) - } - data, err := getResponseData(response, GetVersion) + msg, err := m.getUpdateMessage() if err != nil { - return fmt.Errorf("failed get version data %v", err) - } - msg := getVersionData(data) - if msg == nil { - return errors.New("failed get version data") + return err } + m.targetBaseline = msg.Version.Baseline m.targetVersion = msg.Version.Version m.systemTypeFromPlatform = msg.SystemType @@ -968,6 +969,40 @@ func (m *UpdatePlatformManager) genUpdatePolicyByToken() error { return nil } +func (m *UpdatePlatformManager) getUpdateMessage() (*updateMessage, error) { + return m.getUpdateMessageWithRetry(0) +} + +func (m *UpdatePlatformManager) getUpdateMessageWithRetry(retryCount int) (*updateMessage, error) { + const maxRetry = 3 + if retryCount > maxRetry { + return nil, errors.New("max retry count exceeded for getUpdateMessage") + } + + response, err := m.genVersionResponse() + if err != nil { + return nil, fmt.Errorf("failed get version data %v", err) + } + data, _, code, err := getResponseData(response, GetVersion) + if err != nil { + if code == 416 { + unRegisted, unregErr := m.tryToUnRegisterConsole() + if unRegisted && unregErr == nil { + logger.Infof("unregister console success, will trigger recheck") + time.Sleep(5 * time.Second) + return m.getUpdateMessageWithRetry(retryCount + 1) + } + return nil, fmt.Errorf("unregister console failed: %w", unregErr) + } + return nil, fmt.Errorf("failed get version data %v", err) + } + msg := getVersionData(data) + if msg == nil { + return nil, errors.New("failed get version data") + } + return msg, nil +} + // SyncRepoAndInRelease 从更新平台同步仓库源配置和InRelease到本地 func (m *UpdatePlatformManager) SyncRepoAndInRelease(useP2PUpdate bool) { m.genRepositoryFromPlatform(useP2PUpdate) @@ -1032,7 +1067,7 @@ func (m *UpdatePlatformManager) GenThrottlingByToken() error { if err != nil { return fmt.Errorf("failed get throttling data %v", err) } - data, err := getResponseData(response, GetThrottling) + data, _, _, err := getResponseData(response, GetThrottling) if err != nil { return fmt.Errorf("failed get throttling data %v", err) } @@ -1050,7 +1085,7 @@ func (m *UpdatePlatformManager) GenIpfsConfig() error { if err != nil { return fmt.Errorf("failed to get ipfs config: %w", err) } - data, err := getResponseData(response, GetIPFSConfig) + data, _, _, err := getResponseData(response, GetIPFSConfig) if err != nil { return fmt.Errorf("failed to get ipfs config data: %w", err) } @@ -1115,7 +1150,7 @@ func (m *UpdatePlatformManager) updateTargetPkgMetaSync() error { if err != nil { return fmt.Errorf("failed get target pkg list data %v", err) } - data, err := getResponseData(response, GetTargetPkgLists) + data, _, _, err := getResponseData(response, GetTargetPkgLists) if err != nil { return fmt.Errorf("failed get target pkg list data %v", err) } @@ -1225,7 +1260,7 @@ func (m *UpdatePlatformManager) updateCurrentPreInstalledPkgMetaSync() error { if err != nil { return fmt.Errorf("failed get current pkg list data %v", err) } - data, err := getResponseData(response, GetCurrentPkgLists) + data, _, _, err := getResponseData(response, GetCurrentPkgLists) if err != nil { return fmt.Errorf("failed get current pkg list data %v", err) } @@ -1311,7 +1346,7 @@ func (m *UpdatePlatformManager) updateCVEMetaDataSync() error { if err != nil { return fmt.Errorf("failed get cve meta info %v", err) } - data, err := getResponseData(response, GetPkgCVEs) + data, _, _, err := getResponseData(response, GetPkgCVEs) if err != nil { return fmt.Errorf("failed get cve meta info %v", err) } @@ -1376,7 +1411,7 @@ func (m *UpdatePlatformManager) updateLogMetaSync() error { logger.Warning(err) return nil } - data, err := getResponseData(response, GetUpdateLog) + data, _, _, err := getResponseData(response, GetUpdateLog) if err != nil { logger.Warning(err) return nil @@ -1727,7 +1762,7 @@ func (m *UpdatePlatformManager) PostProcessEventMessage(body ProcessEvent) { logger.Warningf("post process event msg failed:%v", err) return } - _, err = getResponseData(response, PostProcessEvent) + _, _, _, err = getResponseData(response, PostProcessEvent) if err != nil { logger.Warningf("get post process event msg response failed:%v", err) } @@ -1763,7 +1798,7 @@ func (m *UpdatePlatformManager) PostStatusMessage(message StatusMessage, forceUp logger.Warningf("post status message failed:%v", err) return } - data, err := getResponseData(response, PostProcess) + data, _, _, err := getResponseData(response, PostProcess) if err != nil { logger.Warningf("get post status response failed:%v", err) return @@ -1845,7 +1880,7 @@ func (m *UpdatePlatformManager) PostUpdateLogFiles(files []string) { logger.Warningf("post status message failed:%v", err) return } - data, err := getResponseData(response, PostProcess) + data, _, _, err := getResponseData(response, PostProcess) if err != nil { logger.Warningf("get post status response failed:%v", err) return @@ -2400,107 +2435,10 @@ func resetSpeedLimitConfigToDefaults(c *Cfg.Config) { c.DeliveryLocalUploadOffPeakLimit = defaultDeliveryRateLimitConfig } -const checkPolicyCacheFile = "/tmp/checkpolicy.cache" - -func (m *UpdatePlatformManager) CheckPolicyChanged() (bool, error) { - logger.Infof("Check policy changed: requestUrl=%s", m.requestUrl) - response, err := m.genVersionResponse() - if err != nil { - return false, fmt.Errorf("do request failed: %w", err) - } - defer response.Body.Close() - - if response.StatusCode != http.StatusOK { - return false, fmt.Errorf("request failed with status: %d", response.StatusCode) - } - - body, err := io.ReadAll(response.Body) - if err != nil { - return false, fmt.Errorf("read response body failed: %w", err) - } - - unRegisted, err := m.tryToUnRegisterConsole(body) - if unRegisted && err == nil { - // 反注册成功,直接退出,但是需要触发重新检查 - return true, nil - } - if err != nil { - logger.Warning(err) - } - - sum := sha256.Sum256(body) - newSum := hex.EncodeToString(sum[:]) - - oldSum, _ := m.getCheckPolicyCache() - - if oldSum != newSum { - logger.Infof("CheckPolicyChanged: oldSum=%s, newSum=%s", oldSum, newSum) - m.saveCheckPolicyCache(newSum) - return true, nil - } - - return false, nil -} - -func (m *UpdatePlatformManager) getCheckPolicyCache() (string, time.Time) { - readFile, err := os.Open(checkPolicyCacheFile) - if err != nil { - return "", time.Time{} - } - defer readFile.Close() - - reader := bufio.NewReader(readFile) - var sum string - var checkTime time.Time - - data, _, err := reader.ReadLine() - if err == nil { - sum = string(data) - } - data, _, err = reader.ReadLine() - if err == nil { - checkTime, _ = time.Parse(time.RFC3339, string(data)) - } - - return sum, checkTime -} - -func (m *UpdatePlatformManager) saveCheckPolicyCache(sum string) error { - writeFile, err := os.OpenFile(checkPolicyCacheFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return err - } - defer writeFile.Close() - - if _, err := writeFile.WriteString(sum); err != nil { - logger.Warningf("failed to write sum: %v", err) - return err - } - if _, err := writeFile.WriteString("\n"); err != nil { - logger.Warningf("failed to write newline: %v", err) - return err - } - if _, err := writeFile.WriteString(time.Now().Format(time.RFC3339)); err != nil { - logger.Warningf("failed to write time: %v", err) - return err - } - if _, err := writeFile.WriteString("\n"); err != nil { - logger.Warningf("failed to write newline: %v", err) - return err - } - - return nil -} - -func (m *UpdatePlatformManager) tryToUnRegisterConsole(body []byte) (bool, error) { - var response tokenMessage - if err := json.Unmarshal(body, &response); err != nil { - logger.Warningf("failed to parse json %v", string(body)) - return false, err - } - - if response.Code == 416 && utils.IsFileExist("/usr/lib/iup-daemon/uninstall") { - logger.Infof("platform returned code %d, executing uninstall script", response.Code) +// 416 indicates uninstallation is required +func (m *UpdatePlatformManager) tryToUnRegisterConsole() (bool, error) { + if utils.IsFileExist("/usr/lib/iup-daemon/uninstall") { + logger.Infof("executing uninstall script") cmd := exec.Command("/usr/lib/iup-daemon/uninstall") cmd.Env = append(os.Environ(), "IMMUTABLE_DISABLE_REMOUNT=false") output, err := cmd.CombinedOutput() diff --git a/src/lastore-daemon/manager.go b/src/lastore-daemon/manager.go index 6e856b97d..455c656d1 100644 --- a/src/lastore-daemon/manager.go +++ b/src/lastore-daemon/manager.go @@ -279,11 +279,14 @@ func (m *Manager) initDSettingsChangedHandle() { m.config.ConnectConfigChanged(config.DSettingsKeyIntranetUpdate, func(oldValue, newValue interface{}) { intranetUpdate := newValue.(bool) if intranetUpdate { + // 当intranet变化的时候,往往还伴随着checkInerval等配置的变化,此处需要等待几秒钟,等待所有配置均更新完成后,再刷新定时器 + time.Sleep(5 * time.Second) // 当开启内网更新时,将上次检查时间设置为0,并重新触发lastoreAutoCheck定时器 if err := m.config.SetLastCheckTime(time.Unix(0, 0)); err != nil { logger.Warningf("SetLastCheckTime failed: %v", err) } m.isAutoCheckTimerFirstRun = true + logger.Infof("update auto check timer with first run") if err := m.updateAutoCheckSystemUnit(); err != nil { logger.Warningf("updateAutoCheckSystemUnit failed: %v", err) } @@ -799,10 +802,6 @@ func (m *Manager) handleAutoCheckEvent() error { return nil } - if m.config.PlatformUpdate { - return m.handleAutoCheckWithPlatform() - } - _, err := m.updateSource(dbus.Sender(m.service.Conn().Names()[0])) if err != nil { logger.Warning(err) @@ -811,38 +810,6 @@ func (m *Manager) handleAutoCheckEvent() error { return nil } -func (m *Manager) handleAutoCheckWithPlatform() error { - logger.Infof("handle AutoCheck with platform") - needUpdate, err := m.checkPlatformPolicy() - if err != nil { - logger.Warningf("check platform policy failed: %v", err) - if _, err := m.updateSource(dbus.Sender(m.service.Conn().Names()[0])); err != nil { - logger.Warning(err) - } - return err - } - - if needUpdate { - if _, err := m.updateSource(dbus.Sender(m.service.Conn().Names()[0])); err != nil { - logger.Warning(err) - return err - } - } else { - logger.Infof("platform policy no update needed, updating auto check timer") - if err := m.updateAutoCheckSystemUnit(); err != nil { - logger.Warning(err) - } - } - return nil -} - -func (m *Manager) checkPlatformPolicy() (bool, error) { - if !m.config.PlatformUpdate { - return true, nil - } - return m.updatePlatform.CheckPolicyChanged() -} - func (m *Manager) handleAutoCleanEvent() error { const MaxCacheSize = 500.0 // size MB doClean := func() error { diff --git a/src/lastore-daemon/manager_update.go b/src/lastore-daemon/manager_update.go index 89abd0e7e..3e32858b8 100644 --- a/src/lastore-daemon/manager_update.go +++ b/src/lastore-daemon/manager_update.go @@ -143,16 +143,33 @@ func (m *Manager) updateSource(sender dbus.Sender) (*Job, error) { if err1 != nil { logger.Warning(err1) } - err1 = m.updateAutoCheckSystemUnit() - if err1 != nil { - logger.Warning(err1) - } + } + if err := m.updateAutoCheckSystemUnit(); err != nil { + logger.Warning(err) } }() + environ, err = makeEnvironWithSender(m, sender) if err != nil { return nil, err } + + _ = os.Setenv("http_proxy", environ["http_proxy"]) + _ = os.Setenv("https_proxy", environ["https_proxy"]) + // 检查任务开始后,从更新平台获取仓库、更新注记等信息 + // 从更新平台获取数据:系统更新和安全更新流程都包含 + if err := m.updatePlatform.GenUpdatePolicyByToken(); err != nil { + if m.config.PlatformUpdate { + return nil, &system.JobError{ + ErrType: system.ErrorPlatformUnreachable, + ErrDetail: "failed to get update policy by token" + err.Error(), + } + } else { + logger.Warningf("updatePlatform gen token failed: %v", err) + return nil, nil + } + } + prepareUpdateSource() m.reloadOemConfig(true) m.updatePlatform.Token = updateplatform.UpdateTokenConfigFile(m.config.IncludeDiskInfo, m.config.GetHardwareIdByHelper) @@ -353,23 +370,6 @@ func (m *Manager) updateSource(sender dbus.Sender) (*Job, error) { // 独立客户端为了减少更新平台的瞬时负载,采取0-58秒内随机开始检查更新任务 time.Sleep(time.Duration(rand.Intn(59)) * time.Second) } - _ = os.Setenv("http_proxy", environ["http_proxy"]) - _ = os.Setenv("https_proxy", environ["https_proxy"]) - // 检查任务开始后,从更新平台获取仓库、更新注记等信息 - // 从更新平台获取数据:系统更新和安全更新流程都包含 - err = m.updatePlatform.GenUpdatePolicyByToken() - if err != nil { - if m.config.PlatformUpdate { - job.retry = 0 - return &system.JobError{ - ErrType: system.ErrorPlatformUnreachable, - ErrDetail: "failed to get update policy by token" + err.Error(), - } - } else { - logger.Warningf("updatePlatform gen token failed: %v", err) - return nil - } - } if m.updater == nil { return errors.New("Manager.updater is nil") }