From 9fe01b3824b486538181a476a5aaf0989a90f865 Mon Sep 17 00:00:00 2001 From: xml Date: Tue, 17 Mar 2026 13:41:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20lastore=E6=9B=B4=E6=96=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81p2p=E5=8D=8F=E8=AE=AE=E7=9A=84=E6=B5=81=E9=87=8F?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当前http协议的更新走cdn平台,网络开销较大。更新模块新增p2p协议更新,可以从同局域网的机器中下载 lastore-daemon新增以下功能: 1.由P2PUpdateEnable控制控制中心传递优化功能的开关状态,由P2PUpdateSupport表示upgrade服务的可用性,并控制控制中心传递优化功能是否展示 2.由SetP2PUpdateEnable来给控制中心控制P2PUpdateEnable的状态 3.新增dconfig的UpgradeDeliveryEnabled配置记录用户的操作状态 4.每次lastore服务启动时将根据UpgradeDeliveryEnabled来尝试控制upgrade服务的状态。如果upgrade拉起成功,就将/var/lib/lastore/下面的相关源切换称upgradedelivery协议 Task: https://pms.uniontech.com/story-view-40501.html --- src/internal/config/config.go | 27 +++++++ src/internal/system/update_type.go | 75 ++++++++++++++++++ src/internal/updateplatform/message_report.go | 5 ++ src/lastore-daemon/common.go | 3 +- src/lastore-daemon/dbusutil.go | 16 ++-- src/lastore-daemon/exported_methods_auto.go | 4 + src/lastore-daemon/manager.go | 2 + src/lastore-daemon/manager_update.go | 2 + src/lastore-daemon/updater.go | 77 ++++++++++++------- src/lastore-daemon/updater_ifc.go | 32 +++++++- .../interfaces/org.deepin.dde.Lastore1.xml | 1 + .../org.deepin.dde.lastore.json | 13 ++++ .../actions/org.deepin.dde.Lastore1.policy | 18 +++++ 13 files changed, 239 insertions(+), 36 deletions(-) diff --git a/src/internal/config/config.go b/src/internal/config/config.go index 244e12b77..660828170 100644 --- a/src/internal/config/config.go +++ b/src/internal/config/config.go @@ -107,6 +107,7 @@ type Config struct { EnableVersionCheck bool UpdateProcessUpload bool PlatformRepoComponents string // 更新平台仓库组件 + UpgradeDeliveryEnabled bool // 传递优化服务是否开机可用 ClassifiedUpdatablePackages map[string][]string OnlineCache string @@ -200,6 +201,7 @@ const ( dSettingsKeyUpdateProcessUpload = "update-process-upload" dSettingsKeyEnableCoreList = "enable-core-list" dSettingsKeyClientPackageName = "client-package-name" + dSettingsKeyUpgradeDeliveryEnabled = "upgrade-delivery-enabled" dSettingsKeySystemCustomSource = "system-custom-source" dSettingsKeySecurityCustomSource = "security-custom-source" dSettingsKeySystemRepoType = "system-repo-type" @@ -607,6 +609,26 @@ func getConfigFromDSettings() *Config { c.ClientPackageName = v.Value().(string) } + updateUpgradeDeliveryEnabled := func() { + v, err = c.dsLastoreManager.Value(0, dSettingsKeyUpgradeDeliveryEnabled) + if err != nil { + logger.Warning(err) + c.UpgradeDeliveryEnabled = false + } else { + c.UpgradeDeliveryEnabled = v.Value().(bool) + } + } + updateUpgradeDeliveryEnabled() + _, err = c.dsLastoreManager.ConnectValueChanged(func(key string) { + switch key { + case dSettingsKeyUpgradeDeliveryEnabled: + updateUpgradeDeliveryEnabled() + } + }) + if err != nil { + logger.Warning(err) + } + v, err = c.dsLastoreManager.Value(0, dSettingsKeySystemCustomSource) if err != nil { logger.Warning(err) @@ -929,6 +951,11 @@ func (c *Config) SetSystemRepoType(typ RepoType) error { return c.save(dSettingsKeySystemRepoType, typ) } +func (c *Config) SetUpgradeDeliveryEnabled(enable bool) error { + c.UpgradeDeliveryEnabled = enable + return c.save(dSettingsKeyUpgradeDeliveryEnabled, enable) +} + func (c *Config) SetSecurityRepoType(typ RepoType) error { c.SecurityRepoType = typ return c.save(dSettingsKeySecurityRepoType, typ) diff --git a/src/internal/system/update_type.go b/src/internal/system/update_type.go index b4c527801..8a608bf5e 100644 --- a/src/internal/system/update_type.go +++ b/src/internal/system/update_type.go @@ -7,15 +7,20 @@ package system import ( "errors" "fmt" + "io/ioutil" "os" "path/filepath" "strings" "github.com/linuxdeepin/go-lib/strv" + "github.com/linuxdeepin/go-lib/utils" ) type UpdateType uint64 +// org.deepin.upgradedelivery的ServiceStatus返回的服务状态。1为可用,2为不可用,0为未知 +const UpgradeDeliveryEnable int32 = 1 + // 用于设置UpdateMode属性,最大支持64位 const ( SystemUpdate UpdateType = 1 << 0 // 系统仓库更新,检查该仓库,显示更新内容 @@ -168,6 +173,76 @@ func UpdateSystemDefaultSourceDir(sourceList []string) error { return nil } +func UpdateP2pDefaultSourceDir(updateType UpdateType, upgradeDeliveryEnabled bool) { + if !upgradeDeliveryEnabled { + return + } + var sourceDir string + switch updateType { + case SystemUpdate: + sourceDir = SoftLinkSystemSourceDir + case SecurityUpdate: + sourceDir = SecuritySourceDir + } + p2pSource, err := ioutil.TempFile("/tmp", "p2pSource.*.list") + defer os.Remove(p2pSource.Name()) + //从SystemSource.d或SecuritySource.d中读取每个文件内容并将协议替换成delivery协议后存放到/tmp中 + //这么做为了保证替换协议的原子性 + files, err := ioutil.ReadDir(sourceDir) + if err != nil { + logger.Warningf("Error writing dir: %s err:%v", sourceDir, err) + return + } + for _, file := range files { + var content []byte + filePath := filepath.Join(sourceDir, file.Name()) + if utils.IsSymlink(filePath) { + targetPath, err := os.Readlink(filePath) + if err != nil { + logger.Warningf("Error read link: %s err:%v", filePath, err) + continue + } + if !utils.IsFileExist(targetPath) { + logger.Warningf("target file is not exist: %s err:%v", filePath, err) + continue + } + content, err = ioutil.ReadFile(targetPath) + if err != nil { + logger.Warningf("Error reading file: %v\n", err) + return + } + } else { + content, err = ioutil.ReadFile(filePath) + if err != nil { + logger.Warningf("Error reading file: %v\n", err) + return + } + } + var newContent string + newContent = strings.ReplaceAll(string(content), "https://", "delivery://") + _, err = p2pSource.Write([]byte(newContent)) + if err != nil { + logger.Warningf("Error writing file: %v\n", err) + return + } + } + //所有协议均正常替换后重新创建SystemSource.d或SecuritySource.d,再讲/tmp中的文件拷贝过去 + err = os.RemoveAll(sourceDir) + if err != nil { + logger.Warning(err) + return + } + err = os.MkdirAll(sourceDir, 0755) + if err != nil { + logger.Warning(err) + return + } + err = utils.MoveFile(p2pSource.Name(), filepath.Join(sourceDir, filepath.Base(p2pSource.Name()))) + if err != nil { + logger.Warning(err) + } +} + func UpdateSecurityDefaultSourceDir(sourceList []string) error { err := os.RemoveAll(SecuritySourceDir) if err != nil { diff --git a/src/internal/updateplatform/message_report.go b/src/internal/updateplatform/message_report.go index a8c7a0b66..ccb49d1cb 100644 --- a/src/internal/updateplatform/message_report.go +++ b/src/internal/updateplatform/message_report.go @@ -1236,6 +1236,11 @@ func (m *UpdatePlatformManager) updateLogMetaSync() error { func (m *UpdatePlatformManager) genDepositoryFromPlatform() { var repos []string for _, repo := range m.repoInfos { + + if m.config.UpgradeDeliveryEnabled { + repo.Source = strings.ReplaceAll(repo.Source, "https://", "delivery://") + repo.Uri = strings.ReplaceAll(repo.Uri, "https://", "delivery://") + } if strings.HasPrefix(repo.Source, "deb ") { repos = append(repos, repo.Source) } else { diff --git a/src/lastore-daemon/common.go b/src/lastore-daemon/common.go index fe300da16..7cd60799c 100644 --- a/src/lastore-daemon/common.go +++ b/src/lastore-daemon/common.go @@ -36,7 +36,7 @@ import ( "github.com/linuxdeepin/go-lib/strv" ) -var _urlReg = regexp.MustCompile(`^[ ]*deb .*((?:https?|ftp|file|p2p)://[^ ]+)`) +var _urlReg = regexp.MustCompile(`^[ ]*deb .*((?:https?|ftp|file|p2p|delivery)://[^ ]+)`) const lastoreGatherInfo = "lastoreGatherInfo" @@ -597,6 +597,7 @@ func checkSenderNsMntValid(pid uint32) bool { } const polkitActionChangeOwnData = "org.deepin.dde.accounts.user-administration" +const polkitActionChangeUpgradeDelivery = "com.deepin.lastore.doUpgradeDelivery" func checkInvokePermission(service *dbusutil.Service, sender dbus.Sender) error { uid, err := service.GetConnUID(string(sender)) diff --git a/src/lastore-daemon/dbusutil.go b/src/lastore-daemon/dbusutil.go index 27b71eb2a..254a0882c 100644 --- a/src/lastore-daemon/dbusutil.go +++ b/src/lastore-daemon/dbusutil.go @@ -157,8 +157,8 @@ func (v *Updater) emitPropChangedUpdateTarget(value string) error { } func (v *Updater) setPropP2PUpdateEnable(value bool) (changed bool) { - if v.p2PUpdateEnable != value { - v.p2PUpdateEnable = value + if v.P2PUpdateEnable != value { + v.P2PUpdateEnable = value v.emitPropChangedP2PUpdateEnable(value) return true } @@ -166,12 +166,12 @@ func (v *Updater) setPropP2PUpdateEnable(value bool) (changed bool) { } func (v *Updater) emitPropChangedP2PUpdateEnable(value bool) error { - return v.service.EmitPropertyChanged(v, "p2PUpdateEnable", value) + return v.service.EmitPropertyChanged(v, "P2PUpdateEnable", value) } func (v *Updater) setPropP2PUpdateSupport(value bool) (changed bool) { - if v.p2PUpdateSupport != value { - v.p2PUpdateSupport = value + if v.P2PUpdateSupport != value { + v.P2PUpdateSupport = value v.emitPropChangedP2PUpdateSupport(value) return true } @@ -179,7 +179,7 @@ func (v *Updater) setPropP2PUpdateSupport(value bool) (changed bool) { } func (v *Updater) emitPropChangedP2PUpdateSupport(value bool) error { - return v.service.EmitPropertyChanged(v, "p2PUpdateSupport", value) + return v.service.EmitPropertyChanged(v, "P2PUpdateSupport", value) } func (v *Job) setPropId(value string) (changed bool) { @@ -417,6 +417,10 @@ func (v *Manager) setPropHardwareId(value string) (changed bool) { return false } +func (v *Manager) emitPropChangedUpgradeDeliveryEnabled(enable bool) error { + return v.service.EmitPropertyChanged(v, "UpgradeDeliveryEnabled", enable) +} + func (v *Manager) emitPropChangedHardwareId(value string) error { return v.service.EmitPropertyChanged(v, "HardwareId", value) } diff --git a/src/lastore-daemon/exported_methods_auto.go b/src/lastore-daemon/exported_methods_auto.go index 8b231d6dc..3b8c6fff4 100644 --- a/src/lastore-daemon/exported_methods_auto.go +++ b/src/lastore-daemon/exported_methods_auto.go @@ -215,6 +215,10 @@ func (v *Updater) GetExportedMethods() dbusutil.ExportedMethods { Fn: v.SetP2PUpdateEnable, InArgs: []string{"enable"}, }, + { + Name: "CleanTransmissionFiles", + Fn: v.CleanTransmissionFiles, + }, { Name: "SetUpdateNotify", Fn: v.SetUpdateNotify, diff --git a/src/lastore-daemon/manager.go b/src/lastore-daemon/manager.go index 3670d2557..9484e915d 100644 --- a/src/lastore-daemon/manager.go +++ b/src/lastore-daemon/manager.go @@ -109,6 +109,8 @@ type Manager struct { logFds []*os.File logFdsMu sync.Mutex logTmpFile *os.File + + UpgradeDeliveryEnabled bool } /* diff --git a/src/lastore-daemon/manager_update.go b/src/lastore-daemon/manager_update.go index b8aa8f7f9..a9795eca2 100644 --- a/src/lastore-daemon/manager_update.go +++ b/src/lastore-daemon/manager_update.go @@ -158,6 +158,8 @@ 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) m.updatePlatform.Token = updateplatform.UpdateTokenConfigFile(m.config.IncludeDiskInfo, m.config.GetHardwareIdByHelper) m.jobManager.dispatch() // 解决 bug 59351问题(防止CreatJob获取到状态为end但是未被删除的job) var job *Job diff --git a/src/lastore-daemon/updater.go b/src/lastore-daemon/updater.go index 465613994..6e5190151 100644 --- a/src/lastore-daemon/updater.go +++ b/src/lastore-daemon/updater.go @@ -5,6 +5,7 @@ package main import ( + "context" "encoding/json" "errors" "fmt" @@ -78,8 +79,8 @@ type Updater struct { UpdateTarget string - p2PUpdateEnable bool // p2p更新是否开启 - p2PUpdateSupport bool // 是否支持p2p更新 + P2PUpdateEnable bool // p2p更新是否开启 + P2PUpdateSupport bool // 是否支持p2p更新 } func NewUpdater(service *dbusutil.Service, m *Manager, config *Config) *Updater { @@ -106,29 +107,7 @@ func NewUpdater(service *dbusutil.Service, m *Manager, config *Config) *Updater if err != nil { logger.Warning(err) } - state, err := u.systemdManager.GetUnitFileState(0, p2pService) - if err != nil { - logger.Warning("get p2p service state err:", err) - u.p2PUpdateEnable = false - u.p2PUpdateSupport = false - } else { - u.p2PUpdateEnable = false - u.p2PUpdateSupport = true - if state == "enabled" { - unit, err := u.getP2PUnit() - if err != nil { - logger.Warning("get p2p unit err:", err) - } else { - value, err := unit.Unit().ActiveState().Get(0) - if err != nil { - logger.Warning("get p2p SubState err:", err) - } - if value == "active" { - u.p2PUpdateEnable = true - } - } - } - } + u.refreshUpgradeDeliveryService() return u } @@ -138,6 +117,50 @@ func SetAPTSmartMirror(url string) error { 0644) // #nosec G306 } +func (u *Updater) refreshUpgradeDeliveryService() { + // 检查upgrade服务是否被正常安装 + _, err := u.service.NameHasOwner("org.deepin.upgradedelivery") + if err != nil { + logger.Warning(err) + u.setPropP2PUpdateSupport(false) + return + } + object := u.service.Conn().Object("org.deepin.upgradedelivery", "/org/deepin/upgradedelivery") + var ret dbus.Variant + ctx, _ := context.WithTimeout(context.Background(), 1*time.Second) + err = object.CallWithContext(ctx, "org.deepin.upgradedelivery.ServiceStatus", 0).Store(&ret) + if err != nil { + logger.Warning(err) + u.setPropP2PUpdateSupport(false) + return + } + u.setPropP2PUpdateSupport(true) + v := ret.Value() + u.setPropP2PUpdateEnable(u.config.UpgradeDeliveryEnabled) + // 情况一:当upgrade服务开启但P2PUpdateEnable关闭时,尝试关闭服务。若关闭失败则将P2PUpdateEnable恢复为true + if !u.P2PUpdateEnable && v == system.UpgradeDeliveryEnable { + err = object.Call("org.deepin.upgradedelivery.DisableService", 0).Err + if err != nil { + logger.Warning(err) + u.setPropP2PUpdateEnable(true) + } else { + err = object.Call("org.deepin.upgradedelivery.Clear", 0).Err + } + return + } + // 情况二:当upgrade服务开启但P2PUpdateEnable为false时,将P2PUpdateEnable设置为true + if v == system.UpgradeDeliveryEnable { + u.setPropP2PUpdateEnable(true) + return + } + // 情况三:当upgrade服务未开启但P2PUpdateEnable为true时,尝试拉起服务。若拉起失败则将P2PUpdateEnable设置为false + err = object.Call("org.deepin.upgradedelivery.StartService", 0).Err + if err != nil { + logger.Warning(err) + u.setPropP2PUpdateEnable(false) + } +} + type LocaleMirrorSource struct { Id string Url string @@ -451,10 +474,10 @@ func (u *Updater) getP2PUnit() (systemd1.Unit, error) { } func (u *Updater) dealSetP2PUpdateEnable(enable bool) error { - if !u.p2PUpdateSupport { + if !u.P2PUpdateSupport { return fmt.Errorf("unsupport p2p update") } - if u.p2PUpdateEnable == enable { + if u.P2PUpdateEnable == enable { return nil } files := []string{p2pService} diff --git a/src/lastore-daemon/updater_ifc.go b/src/lastore-daemon/updater_ifc.go index 4b6d53ce7..9320eb74e 100644 --- a/src/lastore-daemon/updater_ifc.go +++ b/src/lastore-daemon/updater_ifc.go @@ -9,6 +9,7 @@ import ( "time" "github.com/godbus/dbus/v5" + "github.com/linuxdeepin/dde-api/polkit" "github.com/linuxdeepin/go-lib/dbusutil" ) @@ -161,8 +162,35 @@ func (u *Updater) SetDownloadSpeedLimit(limitConfig string) *dbus.Error { return nil } -func (u *Updater) SetP2PUpdateEnable(enable bool) *dbus.Error { - err := u.dealSetP2PUpdateEnable(enable) +func (u *Updater) SetP2PUpdateEnable(sender dbus.Sender, enable bool) *dbus.Error { + err := polkit.CheckAuth(polkitActionChangeUpgradeDelivery, string(sender), nil) + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + err = u.config.SetUpgradeDeliveryEnabled(enable) + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + + u.setPropP2PUpdateEnable(enable) + return nil +} + +func (u *Updater) CleanTransmissionFiles(sender dbus.Sender) *dbus.Error { + err := polkit.CheckAuth(polkitActionChangeUpgradeDelivery, string(sender), nil) + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + sysBus, err := dbus.SystemBus() + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + object := sysBus.Object("org.deepin.upgradedelivery", "/org/deepin/upgradedelivery") + err = object.Call("org.deepin.upgradedelivery.Clear", 0).Store() if err != nil { logger.Warning(err) return dbusutil.ToError(err) diff --git a/usr/share/dbus-1/interfaces/org.deepin.dde.Lastore1.xml b/usr/share/dbus-1/interfaces/org.deepin.dde.Lastore1.xml index 83393c4ad..ade709f71 100644 --- a/usr/share/dbus-1/interfaces/org.deepin.dde.Lastore1.xml +++ b/usr/share/dbus-1/interfaces/org.deepin.dde.Lastore1.xml @@ -137,6 +137,7 @@ + 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 cfd38a12e..e8da5dbfb 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 @@ -509,6 +509,19 @@ "permissions": "readonly", "visibility": "private" }, + "upgrade-delivery-enabled": { + "value": true, + "serial": 0, + "flags": [ + "global" + ], + "name": "UpgradeDeliveryEnabled", + "description": "upgrade delivery enabled", + "name[zh_CN]": "传递优化服务开机是否可用", + "description[zh_CN]": "传递优化服务开机是否可用", + "permissions": "readwrite", + "visibility": "private" + }, "system-custom-source": { "value": [], "serial": 0, diff --git a/usr/share/polkit-1/actions/org.deepin.dde.Lastore1.policy b/usr/share/polkit-1/actions/org.deepin.dde.Lastore1.policy index 361cb2133..35a0393b3 100644 --- a/usr/share/polkit-1/actions/org.deepin.dde.Lastore1.policy +++ b/usr/share/polkit-1/actions/org.deepin.dde.Lastore1.policy @@ -27,4 +27,22 @@ Check Authentication Tämän toiminnon suorittaminen edellyttää todennusta + + Check Authentication + Operate Delivery Optimization requires permission + + no + no + auth_admin_keep + + Check Authentication + Operate Delivery Optimization requires permission + Check Authentication + 操作优化传递需认证 + Check Authentication + 操作最佳化傳遞需認證 + Check Authentication + 操作優化傳遞需認證 + org.deepin.upgradedelivery.change-status +