Skip to content

Commit fce958c

Browse files
committed
feat(system): 支持增量更新及下载大小统计
- 新增 IncrementalUpdate 变量用于控制增量更新逻辑 - QuerySourceDownloadSize 中根据 IncrementalUpdate 选择不同下载大小计算方法 - 实现基于 apt-get dist-upgrade 命令获取包下载大小的新函数 buildAndRunDownloadSizeCmd - 实现基于 deepin-immutable-ctl 接口获取包下载大小的新函数 buildAndRunDownloadSizeCmdViaDIC - 日志中增加对增量更新状态和下载大小结果的详细记录 - 启动时从配置加载并设置 IncrementalUpdate 标志 Change-Id: I844b1e18e7e7dce38e2539853576117520ed1bf4
1 parent 0761a4b commit fce958c

File tree

6 files changed

+108
-81
lines changed

6 files changed

+108
-81
lines changed

src/internal/system/apt/apt.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"bytes"
99
"os"
1010
"os/exec"
11-
"strconv"
1211
"strings"
1312
"syscall"
1413

@@ -288,30 +287,3 @@ func DownloadPackages(packages []string, environ map[string]string, options map[
288287
}
289288
return tmpPath, nil
290289
}
291-
292-
// In incremental update mode, returns true if all packages are cached, otherwise returns false.
293-
func IsIncrementalUpdateCached(sourceArgs string) bool {
294-
cmd := exec.Command("/usr/sbin/deepin-immutable-ctl", "upgrade", "check")
295-
if sourceArgs != "" {
296-
cmd.Env = append(os.Environ(), "DEEPIN_IMMUTABLE_UPGRADE_APT_OPTION="+sourceArgs)
297-
}
298-
// Need download count: xxx
299-
output, err := cmd.Output()
300-
if err == nil {
301-
matchFlag := "Need download count: "
302-
lines := strings.Split(string(output), "\n")
303-
for _, line := range lines {
304-
line = strings.TrimSpace(line)
305-
index := strings.Index(line, matchFlag)
306-
if index >= 0 {
307-
count, err := strconv.Atoi(strings.TrimSpace(line[index+len(matchFlag):]))
308-
if err == nil {
309-
if count == 0 {
310-
return true
311-
}
312-
}
313-
}
314-
}
315-
}
316-
return false
317-
}

src/internal/system/system.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
const VarLibDir = "/var/lib/lastore"
1414

1515
var IntranetUpdate bool
16+
var IncrementalUpdate bool
1617

1718
type Status string
1819

src/internal/system/system_apt.go

Lines changed: 105 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ package system
1010

1111
import (
1212
"bytes"
13+
"encoding/json"
1314
"errors"
1415
"fmt"
1516
"os"
@@ -200,8 +201,101 @@ func QueryPackageDownloadSize(updateType UpdateType, packages ...string) (float6
200201
return *downloadSize, *allPackageSize, nil
201202
}
202203

203-
// QuerySourceDownloadSize 根据更新类型(仓库),获取需要的下载量,return arg0:需要下载的量;arg1:所有包的大小;arg2:error
204+
// queryDownloadSizeViaApt queries the download size information by running apt-get dist-upgrade
205+
// with the given source path. It parses the command output to extract package size data.
206+
// Returns: bytes needed to download, total size of all packages, error.
207+
func queryDownloadSizeViaApt(path string, updateType UpdateType, pkgList []string) (float64, float64, error) {
208+
var cmd *exec.Cmd
209+
if utils2.IsDir(path) {
210+
// #nosec G204
211+
cmd = exec.Command("/usr/bin/apt-get",
212+
append([]string{"dist-upgrade", "-d", "-o", "Debug::NoLocking=1", "-c", LastoreAptV2CommonConfPath, "--assume-no",
213+
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::sourcelist", "/dev/null"),
214+
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::SourceParts", path)}, pkgList...)...)
215+
} else {
216+
// #nosec G204
217+
cmd = exec.Command("/usr/bin/apt-get",
218+
append([]string{"dist-upgrade", "-d", "-o", "Debug::NoLocking=1", "-c", LastoreAptV2CommonConfPath, "--assume-no",
219+
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::sourcelist", path),
220+
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::SourceParts", "/dev/null")}, pkgList...)...)
221+
}
222+
cmd.Env = append(os.Environ(), "LC_ALL=C")
223+
logger.Infof("%v download size cmd: %v", updateType.JobType(), cmd.String())
224+
lines, err := utils.FilterExecOutput(cmd, time.Second*120, func(line string) bool {
225+
_, _, _err := parsePackageSize(line)
226+
return _err == nil
227+
})
228+
if err != nil && len(lines) == 0 {
229+
return 0, 0, fmt.Errorf("run:%v failed-->%v", cmd.Args, err)
230+
}
231+
if len(lines) != 0 {
232+
needDownloadSize, allSize, err := parsePackageSize(lines[0])
233+
if err != nil {
234+
logger.Warning(err)
235+
return 0, 0, err
236+
}
237+
return needDownloadSize, allSize, nil
238+
}
239+
return 0, 0, nil
240+
}
241+
242+
// immutableUpgradeCheckOutput represents the JSON output of deepin-immutable-ctl upgrade check -j.
243+
type immutableUpgradeCheckOutput struct {
244+
Code int `json:"code"`
245+
Message string `json:"message"`
246+
Data struct {
247+
TotalSize int64 `json:"totalSize"`
248+
CachedOstreePkgCount int64 `json:"cachedOstreePkgCount"`
249+
NeedDownload struct {
250+
Size int64 `json:"size"`
251+
} `json:"needDownload"`
252+
} `json:"data"`
253+
}
254+
255+
// queryDownloadSizeForImmutable queries the download size information for immutable systems
256+
// by invoking deepin-immutable-ctl upgrade check. The source path is passed via the
257+
// DEEPIN_IMMUTABLE_UPGRADE_APT_OPTION environment variable.
258+
// Returns: bytes needed to download, total size of all packages, error.
259+
func queryDownloadSizeForImmutable(path string, updateType UpdateType, pkgList []string) (float64, float64, error) {
260+
var sourceArgs string
261+
cmd := exec.Command(DeepinImmutableCtlPath, "upgrade", "check", "-j")
262+
if path != "" {
263+
if utils2.IsDir(path) {
264+
sourceArgs = "-o Dir::Etc::sourcelist=/dev/null -o Dir::Etc::SourceParts=" + path
265+
} else {
266+
sourceArgs = "-o Dir::Etc::sourcelist=" + path + " -o Dir::Etc::SourceParts=/dev/null"
267+
}
268+
}
269+
cmd.Env = append(os.Environ(), "LC_ALL=C",
270+
"DEEPIN_IMMUTABLE_UPGRADE_APT_OPTION="+sourceArgs)
271+
logger.Infof("%v download size cmd (immutable): %v", updateType.JobType(), cmd.String())
272+
out, err := cmd.Output()
273+
logger.Debugf("immutable upgrade check output: %s", out)
274+
if err != nil {
275+
return 0, 0, fmt.Errorf("run %v failed: %v", cmd.Args, err)
276+
}
277+
var result immutableUpgradeCheckOutput
278+
if err := json.Unmarshal(out, &result); err != nil {
279+
return 0, 0, fmt.Errorf("parse immutable upgrade check output failed: %v", err)
280+
}
281+
logger.Debugf("immutable upgrade check result: %+v", result)
282+
if result.Code != 0 {
283+
return 0, 0, fmt.Errorf("immutable upgrade check returned code %d: %s", result.Code, result.Message)
284+
}
285+
needDownload := result.Data.NeedDownload.Size
286+
totalSize := result.Data.TotalSize
287+
if needDownload == 0 && totalSize == 0 && result.Data.CachedOstreePkgCount > 0 {
288+
// TODO 此时如果返回 0, 0, nil 会导致控制中心界面卡住。
289+
return 0, 1, nil
290+
}
291+
return float64(needDownload), float64(totalSize), nil
292+
}
293+
294+
// QuerySourceDownloadSize returns the download size information for the given update type.
295+
// It selects the appropriate backend (apt or immutable-ctl) based on the IncrementalUpdate flag.
296+
// Returns: bytes needed to download, total size of all packages, error.
204297
func QuerySourceDownloadSize(updateType UpdateType, pkgList []string) (float64, float64, error) {
298+
logger.Debugf("QuerySourceDownloadSize updateType: %v, pkgList: %v", updateType, pkgList)
205299
startTime := time.Now()
206300
downloadSize := new(float64)
207301
allPackageSize := new(float64)
@@ -211,46 +305,24 @@ func QuerySourceDownloadSize(updateType UpdateType, pkgList []string) (float64,
211305
unref()
212306
}
213307
}()
214-
var cmd *exec.Cmd
215-
if utils2.IsDir(path) {
216-
// #nosec G204
217-
cmd = exec.Command("/usr/bin/apt-get",
218-
append([]string{"dist-upgrade", "-d", "-o", "Debug::NoLocking=1", "-c", LastoreAptV2CommonConfPath, "--assume-no",
219-
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::sourcelist", "/dev/null"),
220-
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::SourceParts", path)}, pkgList...)...)
221-
} else {
222-
// #nosec G204
223-
cmd = exec.Command("/usr/bin/apt-get",
224-
append([]string{"dist-upgrade", "-d", "-o", "Debug::NoLocking=1", "-c", LastoreAptV2CommonConfPath, "--assume-no",
225-
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::sourcelist", path),
226-
"-o", fmt.Sprintf("%v=%v", "Dir::Etc::SourceParts", "/dev/null")}, pkgList...)...)
227-
}
228-
cmd.Env = append(os.Environ(), "LC_ALL=C")
229-
logger.Infof("%v download size cmd: %v", updateType.JobType(), cmd.String())
230-
lines, err := utils.FilterExecOutput(cmd, time.Second*120, func(line string) bool {
231-
_, _, _err := parsePackageSize(line)
232-
return _err == nil
233-
})
234-
if err != nil && len(lines) == 0 {
235-
return fmt.Errorf("run:%v failed-->%v", cmd.Args, err)
308+
queryFn := queryDownloadSizeViaApt
309+
if IncrementalUpdate {
310+
queryFn = queryDownloadSizeForImmutable
236311
}
237-
238-
if len(lines) != 0 {
239-
needDownloadSize, allSize, err := parsePackageSize(lines[0])
240-
if err != nil {
241-
logger.Warning(err)
242-
return err
243-
}
244-
*downloadSize = needDownloadSize
245-
*allPackageSize = allSize
312+
needDownloadSize, allSize, err := queryFn(path, updateType, pkgList)
313+
if err != nil {
314+
return err
246315
}
316+
*downloadSize = needDownloadSize
317+
*allPackageSize = allSize
247318
return nil
248319
})
249320
if err != nil {
250321
logger.Warning(err)
251322
return SizeDownloaded, SizeDownloaded, err
252323
}
253324
logger.Debug("end QuerySourceDownloadSize duration:", time.Now().Sub(startTime))
325+
logger.Debugf("QuerySourceDownloadSize result, download size: %v, all package size: %v", *downloadSize, *allPackageSize)
254326
return *downloadSize, *allPackageSize, nil
255327
}
256328

@@ -329,7 +401,7 @@ func QuerySourceAddSize(updateType UpdateType) (float64, error) {
329401
logger.Warning(err)
330402
return SizeUnknown, err
331403
}
332-
logger.Debug("end QuerySourceDownloadSize duration:", time.Now().Sub(startTime))
404+
logger.Debug("end QuerySourceAddSize duration:", time.Now().Sub(startTime))
333405
return *addSize, nil
334406
}
335407

src/lastore-daemon/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ func main() {
7676
config := NewConfig(path.Join(system.VarLibDir, "config.json"))
7777
logger.Info("intranet update:", config.IntranetUpdate)
7878
system.IntranetUpdate = config.IntranetUpdate
79+
logger.Info("incremental update:", config.IncrementalUpdate)
80+
system.IncrementalUpdate = config.IncrementalUpdate
7981
if config.IntranetUpdate {
8082
go func() {
8183
out, err := exec.Command("/usr/bin/lastore-tools", "gatherinfo", "-type=post").CombinedOutput()

src/lastore-daemon/manager_ifc.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
utils2 "github.com/linuxdeepin/go-lib/utils"
2727
"github.com/linuxdeepin/lastore-daemon/src/internal/config"
2828
"github.com/linuxdeepin/lastore-daemon/src/internal/system"
29-
"github.com/linuxdeepin/lastore-daemon/src/internal/system/apt"
3029
)
3130

3231
/*
@@ -214,10 +213,6 @@ func (m *Manager) PackagesDownloadSize(packages []string) (int64, *dbus.Error) {
214213
logger.Warningf("PackagesDownloadSize(%q)=%0.2f %v\n", strings.Join(packages, " "), size, err)
215214
}
216215

217-
if m.config.IncrementalUpdate && size > 0 && apt.IsIncrementalUpdateCached("") {
218-
size = 0.0
219-
}
220-
221216
return int64(size), dbusutil.ToError(err)
222217
}
223218

src/lastore-daemon/update_status.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@ import (
99
"strings"
1010
"sync"
1111

12-
"github.com/linuxdeepin/go-lib/utils"
1312
"github.com/linuxdeepin/lastore-daemon/src/internal/config"
1413
"github.com/linuxdeepin/lastore-daemon/src/internal/system"
15-
"github.com/linuxdeepin/lastore-daemon/src/internal/system/apt"
1614
)
1715

1816
type UpdateModeStatusManager struct {
@@ -481,19 +479,6 @@ func (m *UpdateModeStatusManager) updateModeStatusBySize(mode system.UpdateType,
481479
changed = true
482480
}
483481
} else {
484-
sourceList, ok := system.GetCategorySourceMap()[typ]
485-
sourceArgs := ""
486-
if ok && sourceList != "" {
487-
if utils.IsDir(sourceList) {
488-
sourceArgs = "-o Dir::Etc::sourcelist=/dev/null -o Dir::Etc::SourceParts=" + sourceList
489-
} else {
490-
sourceArgs = "-o Dir::Etc::sourcelist=" + sourceList + " -o Dir::Etc::SourceParts=/dev/null"
491-
}
492-
}
493-
if m.lsConfig.IncrementalUpdate && needDownloadSize > 0 && apt.IsIncrementalUpdateCached(sourceArgs) {
494-
needDownloadSize = 0.0
495-
}
496-
497482
m.updateModeDownloadSizeMapLock.Lock()
498483
m.updateModeDownloadSizeMap[currentMode.JobType()] = needDownloadSize
499484
m.updateModeDownloadSizeMapLock.Unlock()

0 commit comments

Comments
 (0)