diff --git a/src/internal/system/update_type.go b/src/internal/system/update_type.go index 8a608bf5e..c46de5ddb 100644 --- a/src/internal/system/update_type.go +++ b/src/internal/system/update_type.go @@ -173,7 +173,7 @@ func UpdateSystemDefaultSourceDir(sourceList []string) error { return nil } -func UpdateP2pDefaultSourceDir(updateType UpdateType, upgradeDeliveryEnabled bool) { +func UpdateP2pDefaultSourceDir(updateType UpdateType, upgradeDeliveryEnabled bool, platformRepos []string) { if !upgradeDeliveryEnabled { return } @@ -218,8 +218,7 @@ func UpdateP2pDefaultSourceDir(updateType UpdateType, upgradeDeliveryEnabled boo return } } - var newContent string - newContent = strings.ReplaceAll(string(content), "https://", "delivery://") + newContent := replaceMatchedReposWithDelivery(string(content), platformRepos) _, err = p2pSource.Write([]byte(newContent)) if err != nil { logger.Warningf("Error writing file: %v\n", err) @@ -243,6 +242,53 @@ func UpdateP2pDefaultSourceDir(updateType UpdateType, upgradeDeliveryEnabled boo } } +func replaceMatchedReposWithDelivery(content string, platformRepos []string) string { + matchedRepoSet := make(map[string]struct{}) + for _, repo := range platformRepos { + repo = strings.TrimSpace(repo) + if repo == "" { + continue + } + matchedRepoSet[repo] = struct{}{} + } + if len(matchedRepoSet) == 0 { + return content + } + + var lines []string + for _, line := range strings.Split(content, "\n") { + if _, ok := matchedRepoSet[strings.TrimSpace(line)]; ok { + lines = append(lines, replaceRepoSchemeWithDelivery(line)) + continue + } + lines = append(lines, line) + } + return strings.Join(lines, "\n") +} + +func replaceRepoSchemeWithDelivery(line string) string { + fields := strings.Fields(line) + if len(fields) < 2 || fields[0] != "deb" { + return line + } + for i := 1; i < len(fields); i++ { + if strings.HasPrefix(fields[i], "[") { + continue + } + switch { + case strings.HasPrefix(fields[i], "https://"): + fields[i] = "delivery://" + strings.TrimPrefix(fields[i], "https://") + return strings.Join(fields, " ") + case strings.HasPrefix(fields[i], "http://"): + fields[i] = "delivery://" + strings.TrimPrefix(fields[i], "http://") + return strings.Join(fields, " ") + case strings.HasPrefix(fields[i], "delivery://"): + return line + } + } + return line +} + func UpdateSecurityDefaultSourceDir(sourceList []string) error { err := os.RemoveAll(SecuritySourceDir) if err != nil { diff --git a/src/internal/system/update_type_delivery_test.go b/src/internal/system/update_type_delivery_test.go new file mode 100644 index 000000000..efcbd5031 --- /dev/null +++ b/src/internal/system/update_type_delivery_test.go @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +package system + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestReplaceMatchedReposWithDelivery(t *testing.T) { + localContent := strings.Join([]string{ + "deb https://packages.example.com/desktop beige main", + "deb https://packages.example.com/custom beige main", + "# keep comments untouched", + "deb https://security.example.com beige-security main", + }, "\n") + + platformRepos := []string{ + "deb https://packages.example.com/desktop beige main", + } + + got := replaceMatchedReposWithDelivery(localContent, platformRepos) + lines := strings.Split(got, "\n") + + assert.Equal(t, "deb delivery://packages.example.com/desktop beige main", lines[0]) + assert.Equal(t, "deb https://packages.example.com/custom beige main", lines[1]) + assert.Equal(t, "# keep comments untouched", lines[2]) + assert.Equal(t, "deb https://security.example.com beige-security main", lines[3]) +} + +func TestReplaceMatchedReposWithDeliveryRequiresExactMatch(t *testing.T) { + localContent := "deb https://packages.example.com/desktop beige main" + platformRepos := []string{ + "deb http://packages.example.com/desktop beige main", + } + + got := replaceMatchedReposWithDelivery(localContent, platformRepos) + + assert.Equal(t, localContent, got) +} + +func TestReplaceMatchedReposWithDeliveryWithoutPlatformReposKeepsOriginal(t *testing.T) { + localContent := "deb https://packages.example.com/desktop beige main" + + got := replaceMatchedReposWithDelivery(localContent, nil) + + assert.Equal(t, localContent, got) +} diff --git a/src/internal/updateplatform/message_report.go b/src/internal/updateplatform/message_report.go index e3c8afc69..6ba556964 100644 --- a/src/internal/updateplatform/message_report.go +++ b/src/internal/updateplatform/message_report.go @@ -242,6 +242,32 @@ func (m *UpdatePlatformManager) GetCVEUpdateLogs(pkgs []string) map[string]CEVIn return cveInfos } +func (m *UpdatePlatformManager) HasDeliveryRepo() bool { + for _, repo := range m.repoInfos { + if strings.HasPrefix(repo.Source, "deb delivery://") { + return true + } + } + return false +} + +func (m *UpdatePlatformManager) GetPlatformRepoSources() []string { + var repos []string + for _, repo := range m.repoInfos { + if strings.HasPrefix(repo.Source, "deb ") { + repos = append(repos, repo.Source) + continue + } + + suffix := "main community commercial" + if m.config != nil && m.config.PlatformRepoComponents != "" { + suffix = m.config.PlatformRepoComponents + } + repos = append(repos, fmt.Sprintf("deb %s %s %s", repo.Uri, repo.CodeName, suffix)) + } + return repos +} + func genPreBuild() string { var preBuild string infoMap, err := GetOSVersionInfo(CacheVersion) @@ -920,6 +946,11 @@ func (m *UpdatePlatformManager) genUpdatePolicyByToken(updateInRelease bool) err if updateInRelease { m.genDepositoryFromPlatform() m.checkInReleaseFromPlatform() + if m.config.UpgradeDeliveryEnabled && !m.config.IntranetUpdate { + repos := m.GetPlatformRepoSources() + system.UpdateP2pDefaultSourceDir(system.SystemUpdate, true, repos) + system.UpdateP2pDefaultSourceDir(system.SecurityUpdate, true, repos) + } } return nil diff --git a/src/internal/updateplatform/message_report_test.go b/src/internal/updateplatform/message_report_test.go new file mode 100644 index 000000000..d080fd441 --- /dev/null +++ b/src/internal/updateplatform/message_report_test.go @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +package updateplatform + +import "testing" + +func TestHasDeliveryRepo(t *testing.T) { + manager := &UpdatePlatformManager{ + repoInfos: []repoInfo{ + {Source: "deb https://packages.example.com/desktop beige main"}, + {Source: "deb delivery://packages.example.com/apps beige main"}, + }, + } + + if !manager.HasDeliveryRepo() { + t.Fatal("expected delivery repo to be detected") + } +} diff --git a/src/lastore-daemon/manager_update.go b/src/lastore-daemon/manager_update.go index acc537f65..3f5344aec 100644 --- a/src/lastore-daemon/manager_update.go +++ b/src/lastore-daemon/manager_update.go @@ -155,8 +155,9 @@ func (m *Manager) updateSource(sender dbus.Sender) (*Job, error) { } prepareUpdateSource() m.reloadOemConfig(true) - system.UpdateP2pDefaultSourceDir(system.SystemUpdate, m.updater.P2PUpdateEnable) - system.UpdateP2pDefaultSourceDir(system.SecurityUpdate, m.updater.P2PUpdateEnable) + repos := m.updatePlatform.GetPlatformRepoSources() + system.UpdateP2pDefaultSourceDir(system.SystemUpdate, m.updater.P2PUpdateEnable, repos) + system.UpdateP2pDefaultSourceDir(system.SecurityUpdate, m.updater.P2PUpdateEnable, repos) m.updatePlatform.Token = updateplatform.UpdateTokenConfigFile(m.config.IncludeDiskInfo, m.config.GetHardwareIdByHelper) m.jobManager.dispatch() // 解决 bug 59351问题(防止CreatJob获取到状态为end但是未被删除的job) var job *Job @@ -372,6 +373,7 @@ func (m *Manager) updateSource(sender dbus.Sender) (*Job, error) { return nil } } + m.updater.refreshUpgradeDeliveryService() if updateplatform.IsForceUpdate(m.updatePlatform.Tp) && m.updatePlatform.Tp != updateplatform.UpdateRegularly { m.stopTimerUnit(lastoreRegularlyUpdate) } diff --git a/src/lastore-daemon/updater.go b/src/lastore-daemon/updater.go index e13cfee2b..0a7beb561 100644 --- a/src/lastore-daemon/updater.go +++ b/src/lastore-daemon/updater.go @@ -144,9 +144,14 @@ func (u *Updater) refreshUpgradeDeliveryService() { } u.setPropP2PUpdateSupport(true) v := ret.Value() + platformHasDelivery := false + if u.manager != nil && u.manager.updatePlatform != nil { + platformHasDelivery = u.manager.updatePlatform.HasDeliveryRepo() + } + shouldEnableService := shouldEnableUpgradeDeliveryService(u.config, platformHasDelivery) u.setPropP2PUpdateEnable(u.config.UpgradeDeliveryEnabled) // 情况一:当upgrade服务开启但P2PUpdateEnable关闭时,尝试关闭服务。若关闭失败则将P2PUpdateEnable恢复为true - if !u.P2PUpdateEnable && v == system.UpgradeDeliveryEnable { + if !shouldEnableService && v == system.UpgradeDeliveryEnable { err = object.Call("org.deepin.upgradedelivery.DisableService", 0).Err if err != nil { logger.Warning(err) @@ -165,8 +170,18 @@ func (u *Updater) refreshUpgradeDeliveryService() { err = object.Call("org.deepin.upgradedelivery.StartService", 0).Err if err != nil { logger.Warning(err) - u.setPropP2PUpdateEnable(false) + u.setPropP2PUpdateEnable(u.config.UpgradeDeliveryEnabled) + } +} + +func shouldEnableUpgradeDeliveryService(cfg *Config, platformHasDelivery bool) bool { + if cfg == nil { + return false + } + if cfg.UpgradeDeliveryEnabled { + return true } + return cfg.IntranetUpdate && cfg.PlatformUpdate && platformHasDelivery } type LocaleMirrorSource struct { diff --git a/src/lastore-daemon/updater_delivery_test.go b/src/lastore-daemon/updater_delivery_test.go new file mode 100644 index 000000000..60cb1b59e --- /dev/null +++ b/src/lastore-daemon/updater_delivery_test.go @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +package main + +import ( + "testing" + + "github.com/linuxdeepin/lastore-daemon/src/internal/config" +) + +func TestShouldEnableUpgradeDeliveryService(t *testing.T) { + tests := []struct { + name string + cfg *config.Config + platformHasDelivery bool + want bool + }{ + { + name: "public network follows user switch", + cfg: &config.Config{ + UpgradeDeliveryEnabled: false, + IntranetUpdate: false, + PlatformUpdate: false, + }, + platformHasDelivery: true, + want: false, + }, + { + name: "intranet platform delivery repo keeps service available", + cfg: &config.Config{ + UpgradeDeliveryEnabled: false, + IntranetUpdate: true, + PlatformUpdate: true, + }, + platformHasDelivery: true, + want: true, + }, + { + name: "intranet non delivery repo keeps service closed", + cfg: &config.Config{ + UpgradeDeliveryEnabled: false, + IntranetUpdate: true, + PlatformUpdate: true, + }, + platformHasDelivery: false, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := shouldEnableUpgradeDeliveryService(tt.cfg, tt.platformHasDelivery); got != tt.want { + t.Fatalf("shouldEnableUpgradeDeliveryService() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/usr/share/dsg/configs/org.deepin.dde.lastore/org.deepin.dde.lastore.json b/usr/share/dsg/configs/org.deepin.dde.lastore/org.deepin.dde.lastore.json index 06c7658b6..f1a657844 100644 --- a/usr/share/dsg/configs/org.deepin.dde.lastore/org.deepin.dde.lastore.json +++ b/usr/share/dsg/configs/org.deepin.dde.lastore/org.deepin.dde.lastore.json @@ -521,7 +521,7 @@ "visibility": "private" }, "upgrade-delivery-enabled": { - "value": false, + "value": true, "serial": 0, "flags": [ "global"