Skip to content

Commit 05dbf66

Browse files
author
xml
committed
fix: automatic update check timer cycle anomaly
Bug: https://pms.uniontech.com/bug-view-355587.html
1 parent 21953aa commit 05dbf66

6 files changed

Lines changed: 174 additions & 70 deletions

File tree

src/internal/config/config.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ type Config struct {
111111

112112
PlatformUrl string // 更新接口地址
113113
StartCheckRange []int // 开机检查更新区间
114-
CheckPolicyInterval int // 策略检查时间间隔(单位:秒)
115114
GetHardwareIdByHelper bool // machineID是否直接从sync helper获取
116115
IncludeDiskInfo bool // machineID是否包含硬盘信息
117116
PostUpgradeCron string // 更新上报间隔
@@ -224,7 +223,6 @@ const (
224223
DSettingsKeyIncrementalUpdate = "incremental-update"
225224
dSettingsKeyIntranetUpdate = "intranet-update"
226225
dSettingsKeyGetHardwareIdByHelper = "hardware-id-from-helper"
227-
dSettingsKeyCheckPolicyInterval = "check-policy-interval"
228226
dSettingsKeyDeliveryRemoteDownloadGlobalLimit = "delivery-remote-download-global-limit"
229227
dSettingsKeyDeliveryRemoteUploadGlobalLimit = "delivery-remote-upload-global-limit"
230228
dSettingsKeyDeliveryRemoteDownloadPeakLimit = "delivery-remote-download-peak-limit"
@@ -757,17 +755,6 @@ func getConfigFromDSettings() *Config {
757755
c.GetHardwareIdByHelper = v.Value().(bool)
758756
}
759757

760-
v, err = c.dsLastoreManager.Value(0, dSettingsKeyCheckPolicyInterval)
761-
if err != nil {
762-
logger.Warning(err)
763-
} else {
764-
if val, ok := v.Value().(int64); ok {
765-
c.CheckPolicyInterval = int(val)
766-
} else {
767-
logger.Warningf("dSettings key %s: value is not int64", dSettingsKeyCheckPolicyInterval)
768-
}
769-
}
770-
771758
err = c.recoveryAndApplyOemFlag(system.SystemUpdate)
772759
if err != nil {
773760
logger.Warning(err)
@@ -1222,11 +1209,6 @@ func (c *Config) SetSecurityRepoType(typ RepoType) error {
12221209
return c.save(dSettingsKeySecurityRepoType, typ)
12231210
}
12241211

1225-
func (c *Config) SetCheckPolicyInterval(interval int) error {
1226-
c.CheckPolicyInterval = interval
1227-
return c.save(dSettingsKeyCheckPolicyInterval, interval)
1228-
}
1229-
12301212
func (c *Config) SetStartCheckRange(checkRange []int) error {
12311213
c.StartCheckRange = checkRange
12321214

src/internal/updateplatform/message_report.go

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ func getResponseData(response *http.Response, reqType requestType) (json.RawMess
778778
}
779779
return msg.Data, nil
780780
} else {
781-
return nil, fmt.Errorf("request for %s failed, response code=%d", response.Request.RequestURI, response.StatusCode)
781+
return nil, fmt.Errorf("request for %s failed, response code=%d", response.Request.URL, response.StatusCode)
782782
}
783783
}
784784

@@ -897,8 +897,8 @@ func (m *UpdatePlatformManager) genUpdatePolicyByToken(updateInRelease bool) err
897897
m.UpdateTime, _ = time.Parse(time.RFC3339, msg.Policy.Data.UpdateTime)
898898
}
899899
m.TimerHasChanged = false
900-
if !utils.IsElementEqual(m.config.CheckPolicyInterval, msg.ClientPollSetting.CheckPolicyInterval) && msg.ClientPollSetting.CheckPolicyInterval > 0 {
901-
m.config.SetCheckPolicyInterval(msg.ClientPollSetting.CheckPolicyInterval)
900+
if !utils.IsElementEqual(m.config.CheckInterval, msg.ClientPollSetting.CheckPolicyInterval*1000*1000*1000) && msg.ClientPollSetting.CheckPolicyInterval > 0 {
901+
m.config.SetCheckInterval(time.Duration(msg.ClientPollSetting.CheckPolicyInterval) * time.Second)
902902
m.TimerHasChanged = true
903903
}
904904
if !utils.IsElementEqual(m.config.StartCheckRange, msg.ClientPollSetting.StartCheckRange) && msg.ClientPollSetting.StartCheckRange != nil {
@@ -2182,3 +2182,84 @@ func (m *UpdatePlatformManager) UpdateDeliverySpeedLimit() error {
21822182

21832183
return nil
21842184
}
2185+
2186+
const checkPolicyCacheFile = "/tmp/checkpolicy.cache"
2187+
2188+
func (m *UpdatePlatformManager) CheckPolicyChanged() (bool, error) {
2189+
response, err := m.genVersionResponse()
2190+
if err != nil {
2191+
return false, fmt.Errorf("do request failed: %w", err)
2192+
}
2193+
defer response.Body.Close()
2194+
2195+
body, err := io.ReadAll(response.Body)
2196+
if err != nil {
2197+
return false, fmt.Errorf("read response body failed: %w", err)
2198+
}
2199+
2200+
if response.StatusCode != http.StatusOK {
2201+
return false, fmt.Errorf("request failed with status: %d", response.StatusCode)
2202+
}
2203+
2204+
sum := sha256.Sum256(body)
2205+
newSum := hex.EncodeToString(sum[:])
2206+
2207+
oldSum, _ := m.getCheckPolicyCache()
2208+
2209+
if oldSum != newSum {
2210+
m.saveCheckPolicyCache(newSum)
2211+
return true, nil
2212+
}
2213+
2214+
return false, nil
2215+
}
2216+
2217+
func (m *UpdatePlatformManager) getCheckPolicyCache() (string, time.Time) {
2218+
readFile, err := os.Open(checkPolicyCacheFile)
2219+
if err != nil {
2220+
return "", time.Time{}
2221+
}
2222+
defer readFile.Close()
2223+
2224+
reader := bufio.NewReader(readFile)
2225+
var sum string
2226+
var checkTime time.Time
2227+
2228+
data, _, err := reader.ReadLine()
2229+
if err == nil {
2230+
sum = string(data)
2231+
}
2232+
data, _, err = reader.ReadLine()
2233+
if err == nil {
2234+
checkTime, _ = time.Parse(time.RFC3339, string(data))
2235+
}
2236+
2237+
return sum, checkTime
2238+
}
2239+
2240+
func (m *UpdatePlatformManager) saveCheckPolicyCache(sum string) error {
2241+
writeFile, err := os.OpenFile(checkPolicyCacheFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
2242+
if err != nil {
2243+
return err
2244+
}
2245+
defer writeFile.Close()
2246+
2247+
if _, err := writeFile.WriteString(sum); err != nil {
2248+
logger.Warning("failed to write sum:", err)
2249+
return err
2250+
}
2251+
if _, err := writeFile.WriteString("\n"); err != nil {
2252+
logger.Warning("failed to write newline:", err)
2253+
return err
2254+
}
2255+
if _, err := writeFile.WriteString(time.Now().Format(time.RFC3339)); err != nil {
2256+
logger.Warning("failed to write time:", err)
2257+
return err
2258+
}
2259+
if _, err := writeFile.WriteString("\n"); err != nil {
2260+
logger.Warning("failed to write newline:", err)
2261+
return err
2262+
}
2263+
2264+
return nil
2265+
}

src/lastore-daemon/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ func main() {
100100
manager.initAgent()
101101
manager.initPlatformManager()
102102
if config.IntranetUpdate {
103-
//私有化更新的Cron是核心业务场景,不再依赖检查更新或者online定时器触发,而是直接创建
104-
manager.TryToStartCronCheck()
103+
//不再依赖检查更新或者online定时器触发,而是直接创建
104+
manager.TryToStartAutoCheck()
105105
}
106106
err = serverObject.SetWriteCallback(updater, "AutoInstallUpdates", updater.autoInstallUpdatesWriteCallback)
107107
if err != nil {

src/lastore-daemon/manager.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,11 @@ func (m *Manager) initPlatformManager() {
304304
}
305305
}
306306

307-
func (m *Manager) TryToStartCronCheck() {
308-
if isTimerUnitFileExists(lastoreCronCheck) {
307+
func (m *Manager) TryToStartAutoCheck() {
308+
if isTimerUnitFileExists(lastoreAutoCheck) {
309309
return
310310
}
311-
m.startCheckPolicyTask()
311+
m.updateAutoCheckSystemUnit()
312312
}
313313

314314
func (m *Manager) delUpdatePackage(sender dbus.Sender, jobName string, packages string) (*Job, error) {
@@ -728,16 +728,56 @@ func (m *Manager) handleAutoCheckRegularlyEvent() error {
728728
}
729729

730730
func (m *Manager) handleAutoCheckEvent() error {
731-
if m.config.AutoCheckUpdates && !m.ImmutableAutoRecovery {
732-
_, err := m.updateSource(dbus.Sender(m.service.Conn().Names()[0]))
733-
if err != nil {
731+
if m.ImmutableAutoRecovery {
732+
return nil
733+
}
734+
735+
if !m.config.AutoCheckUpdates { // 不再需要自动检查更新
736+
return nil
737+
}
738+
739+
if m.config.PlatformUpdate {
740+
return m.handleAutoCheckWithPlatform()
741+
}
742+
743+
_, err := m.updateSource(dbus.Sender(m.service.Conn().Names()[0]))
744+
if err != nil {
745+
logger.Warning(err)
746+
return err
747+
}
748+
return nil
749+
}
750+
751+
func (m *Manager) handleAutoCheckWithPlatform() error {
752+
needUpdate, err := m.checkPlatformPolicy()
753+
if err != nil {
754+
logger.Warningf("check platform policy failed: %v", err)
755+
if _, err := m.updateSource(dbus.Sender(m.service.Conn().Names()[0])); err != nil {
756+
logger.Warning(err)
757+
}
758+
return err
759+
}
760+
761+
if needUpdate {
762+
if _, err := m.updateSource(dbus.Sender(m.service.Conn().Names()[0])); err != nil {
734763
logger.Warning(err)
735764
return err
736765
}
766+
} else {
767+
if err := m.updateAutoCheckSystemUnit(); err != nil {
768+
logger.Warning(err)
769+
}
737770
}
738771
return nil
739772
}
740773

774+
func (m *Manager) checkPlatformPolicy() (bool, error) {
775+
if !m.config.PlatformUpdate {
776+
return true, nil
777+
}
778+
return m.updatePlatform.CheckPolicyChanged()
779+
}
780+
741781
func (m *Manager) handleAutoCleanEvent() error {
742782
const MaxCacheSize = 500.0 // size MB
743783
doClean := func() error {

src/lastore-daemon/manager_unit.go

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,35 @@ const (
5454

5555
type UnitName string
5656

57+
// lastoreAutoCheck: automatic update check scheduled task unit
58+
//
59+
// Complete workflow:
60+
// 1. System startup phase
61+
// startOfflineTask() -> getLastoreSystemUnitMap()
62+
// -> Create lastoreAutoCheck.timer
63+
// -> Delay time = getNextAutoCheckDelay()
64+
//
65+
// ↓
66+
//
67+
// 2. Timer trigger phase
68+
// systemd-run executes dbus-send
69+
// -> Call Manager.HandleSystemEvent("AutoCheck")
70+
//
71+
// ↓
72+
//
73+
// 3. Event processing phase
74+
// delHandleSystemEvent() -> handleAutoCheckEvent()
75+
// -> Execute actual update check operations (UpdateSource/platform version request)
76+
// -> Update LastCheckTime
77+
// -> Call updateAutoCheckSystemUnit() to reset timer
78+
5779
const (
5880
lastoreAutoClean UnitName = "lastoreAutoClean"
5981
lastoreAutoCheck UnitName = "lastoreAutoCheck"
6082
lastoreAutoUpdateToken UnitName = "lastoreAutoUpdateToken"
6183
watchOsVersion UnitName = "watchOsVersion"
6284
lastoreInitIdleDownload UnitName = "lastoreInitIdleDownload"
63-
lastoreRegularlyUpdate UnitName = "lastoreRegularlyUpdate" // 到触发时间后开始检查更新->下载更新->安装更新
64-
lastoreCronCheck UnitName = "lastoreCronCheck"
85+
lastoreRegularlyUpdate UnitName = "lastoreRegularlyUpdate"
6586
lastorePostUpgrade UnitName = "lastorePostUpgrade"
6687
lastoreRetryPostMsg UnitName = "lastoreRetryPostMsg"
6788
)
@@ -79,8 +100,7 @@ func (m *Manager) getLastoreSystemUnitMap() lastoreUnitMap {
79100
unitMap := make(lastoreUnitMap)
80101
if (m.config.GetLastoreDaemonStatus()&config.DisableUpdate) == 0 && !m.ImmutableAutoRecovery { // 更新禁用未开启且无忧还原未开启时
81102
unitMap[lastoreAutoCheck] = genHandleEventCmdArgs([]string{
82-
// 随机数范围1800-21600,时间为0.5~6小时
83-
fmt.Sprintf("--on-active=%d", int(m.getNextUpdateDelay()/time.Second)+rand.New(rand.NewSource(time.Now().UnixNano())).Intn(m.config.StartCheckRange[1]-m.config.StartCheckRange[0])+m.config.StartCheckRange[0])}, AutoCheck) // 根据上次检查时间,设置下一次自动检查时间
103+
fmt.Sprintf("--on-active=%d", m.getNextAutoCheckDelay())}, AutoCheck)
84104
}
85105
unitMap[lastoreAutoClean] = genHandleEventCmdArgs([]string{
86106
"--on-active=600"}, AutoClean) // 10分钟后自动检查是否需要清理
@@ -260,31 +280,6 @@ func (m *Manager) updateTimerUnit(unitName UnitName) error {
260280
return nil
261281
}
262282

263-
func (m *Manager) startCheckPolicyTask() {
264-
if m.config.CheckPolicyInterval == 0 {
265-
logger.Info("config: not CheckPolicyInterval")
266-
return
267-
}
268-
269-
args := []string{
270-
fmt.Sprintf("--unit=%s", lastoreCronCheck),
271-
fmt.Sprintf("--on-active=%d", m.config.CheckPolicyInterval),
272-
fmt.Sprintf(`--on-unit-active=%d`, m.config.CheckPolicyInterval),
273-
"--uid=root",
274-
"/usr/bin/lastore-tools",
275-
"checkpolicy",
276-
}
277-
cmd := exec.Command(run, args...)
278-
logger.Info(cmd.String())
279-
var errBuffer bytes.Buffer
280-
cmd.Stderr = &errBuffer
281-
err := cmd.Run()
282-
if err != nil {
283-
logger.Warning(err)
284-
logger.Warning(errBuffer.String())
285-
}
286-
}
287-
288283
func (m *Manager) handleAutoDownload() {
289284
if m.ImmutableAutoRecovery {
290285
logger.Debug("Immutable auto recovery is enabled, don't allow to auto download")
@@ -332,6 +327,24 @@ func (m *Manager) getNextUpdateDelay() time.Duration {
332327
return remained + _minDelayTime
333328
}
334329

330+
func (m *Manager) getNextAutoCheckDelay() int {
331+
checkInterval := m.config.CheckInterval
332+
if checkInterval < 0 {
333+
checkInterval = 0
334+
}
335+
336+
elapsed := time.Since(m.config.LastCheckTime)
337+
remained := int((checkInterval - elapsed) / time.Second)
338+
if remained < 0 {
339+
remained = 0
340+
}
341+
342+
randomDelay := rand.New(rand.NewSource(time.Now().UnixNano())).Intn(m.config.StartCheckRange[1]-m.config.StartCheckRange[0]) + m.config.StartCheckRange[0]
343+
autoCheckDelay := remained + randomDelay
344+
logger.Infof("get next auto check delay, StartCheckRange=%v, randomDelay=%d, autoCheckDelay=%d", m.config.StartCheckRange, randomDelay, autoCheckDelay)
345+
return autoCheckDelay
346+
}
347+
335348
// isAllowedToTriggerSystemEvent checks if the uid is allowed to trigger system events
336349
func isAllowedToTriggerSystemEvent(uid uint32, eventType systemdEventType) bool {
337350
// Allow regular users to trigger OsVersionChanged event
@@ -384,7 +397,6 @@ func (m *Manager) delHandleSystemEvent(sender dbus.Sender, eventType string) err
384397
if err != nil {
385398
logger.Warning(err)
386399
}
387-
m.startCheckPolicyTask() // 在第一次自动检查更新后再加任务
388400
}()
389401
case AutoClean:
390402
go func() {

usr/share/dsg/configs/org.deepin.dde.lastore/org.deepin.dde.lastore.json

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -611,17 +611,6 @@
611611
"permissions": "readwrite",
612612
"visibility": "private"
613613
},
614-
"check-policy-interval": {
615-
"value": 0,
616-
"serial": 0,
617-
"flags": [
618-
"global"
619-
],
620-
"name": "CheckPolicyInterval",
621-
"description": "check policy interval (seconds)",
622-
"permissions": "readwrite",
623-
"visibility": "private"
624-
},
625614
"incremental-update": {
626615
"value": true,
627616
"serial": 0,

0 commit comments

Comments
 (0)