8.4 KiB
更新中心 Spark 更新命令设计
背景
当前 Electron 更新中心对 aptss 来源的更新项仍保留一条旧路径:当任务没有本地下载文件时,直接执行 shell-caller.sh aptss install -y <pkg> --only-upgrade。这条路径会在宿主系统里直接升级软件包,但不会复用 Qt 更新器已经采用的“先下载 deb,再通过 ssinstall 安装”的流程。
仓库里已经存在一个更贴近更新器预期的行为参考:旧 Qt 更新器在安装 aptss 来源更新时,会对下载好的 deb 调用 ssinstall,并带上“不创建桌面快捷方式”和“安装后删除下载文件”等参数。
本次需求是:仅对 Electron 更新中心生效,把 Spark 软件包更新改为走 shell-caller 顶层 ssinstall 路径,同时避免更新时创建新的桌面项。
目标
- Electron 更新中心处理
aptss更新时,统一改为“下载 deb ->shell-caller.sh ssinstall安装”。 - 更新时传入
ssinstall的“不创建桌面项”参数,避免更新流程额外生成桌面快捷方式。 - 变更只作用于 Electron 更新中心,不影响普通安装流、APM 更新流和
extras/shell-caller.sh的白名单行为。 - 继续沿用现有提权方式:若存在
pkexec,仍通过pkexec /opt/spark-store/extras/shell-caller.sh ...执行。
非目标
- 不修改
electron/main/backend/install-manager.ts的普通安装逻辑。 - 不修改
apm来源更新的下载与安装方式。 - 不扩展
extras/shell-caller.sh以支持新的aptss ssinstall子命令形式。 - 不修改旧 Qt 更新器行为;它只作为现有参考实现。
已确认的命令约束
shell-caller 约束
当前仓库内的 extras/shell-caller.sh 只支持 3 个顶层命令类型:
apmaptssssinstall
其中 aptss 仅允许 install 和 remove 两个子命令,不支持 aptss ssinstall ...。因此,本次实现不会尝试新增 shell-caller aptss ssinstall 这种调用形式,而是直接使用已存在的顶层 ssinstall 入口。
ssinstall 参数名
本机 ssinstall --help 显示的真实参数名是:
--no-create-desktop-entry
因此,需求里口头表达的 --no-create-desktop 会在实现中落到 --no-create-desktop-entry,避免引入不存在的参数名。
现状问题
当前更新中心后端只有 APM 更新项会在刷新阶段补齐 downloadUrl、fileName、size 和 sha512 等下载元数据。aptss 更新项只来自 apt list --upgradable 的文本解析结果,因此:
aptss更新项通常没有可下载 deb 的元数据。- 没有 deb 文件时,安装逻辑会退回旧的
aptss install --only-upgrade命令。 - 这使得 Electron 更新中心无法像 Qt 更新器那样稳定走
ssinstall路径。
方案概览
采用“刷新阶段补齐 aptss 下载元数据,执行阶段统一走 ssinstall”的方案。
整体流程如下:
- 刷新更新列表时,继续查询
aptss的可升级包。 - 对每个
aptss更新项额外查询apt download --print-uris元数据。 - 只有拿到
downloadUrl和fileName的aptss更新项才进入最终更新列表。 - 执行更新任务时,先下载对应 deb。
- 下载完成后调用
shell-caller.sh ssinstall <deb> --no-create-desktop-entry --delete-after-install。 - 若存在提权命令,则实际执行
pkexec /opt/spark-store/extras/shell-caller.sh ssinstall ...。
这样可以让 Electron 更新中心的 aptss 更新行为与 Qt 更新器保持一致,同时严格限定在更新中心内部,不影响商店其他安装入口。
模块变更
1. electron/main/backend/update-center/index.ts
新增 aptss 下载元数据补全逻辑,方式与现有 APM 元数据补全保持一致。
建议变更:
- 新增一个
aptss的print-uris命令构造函数,复用当前apt-fast配置与源列表参数。 - 复用现有
parsePrintUrisOutput()解析函数,不新增第二套解析器。 - 为
aptss更新项新增与 APM 相同的元数据补全过程。 - 元数据查询失败的
aptss项从最终可更新列表中剔除,并写入 warning。
这样做的原因是:更新中心一旦展示某个更新项,就应该能够实际完成下载和安装,而不是在任务执行阶段才发现缺少 deb 元数据。
2. electron/main/backend/update-center/install.ts
aptss 更新项的安装路径改为严格依赖已下载的 filePath。
行为调整:
item.source === "aptss"且有filePath时,执行shell-caller.sh ssinstall。- 传参为:
ssinstall <deb-path> --no-create-desktop-entry --delete-after-install
- 若存在
superUserCmd,则通过buildPrivilegedCommand()包装成:
/usr/bin/pkexec /opt/spark-store/extras/shell-caller.sh ssinstall <deb-path> --no-create-desktop-entry --delete-after-install
- 删除
aptss无文件时回退到buildLegacySparkUpgradeCommand()的行为。
这意味着 aptss 更新不再允许悄悄退回旧式 aptss install --only-upgrade 流程。
3. 其他模块
以下模块不应发生行为变化:
electron/main/backend/install-manager.tsextras/shell-caller.shspark-update-tool/中的 Qt 更新器逻辑apm来源更新的下载与安装分支
数据流
刷新阶段
- 读取
aptss和apm的可升级列表。 - 读取已安装来源状态。
- 为
aptss更新项加载 deb 元数据。 - 为
apm更新项加载 deb 元数据。 - 合并来源、迁移标记、图标和其他展示字段。
- 返回只包含“可实际下载并安装”的更新项列表。
执行阶段
- 任务进入
downloading。 - 使用已有 aria2 下载器下载 deb。
- 任务进入
installing。 aptss项执行shell-caller.sh ssinstall。apm项继续执行当前shell-caller.sh apm ssinstall流程。- 成功后标记完成,失败则保留日志与错误信息。
错误处理
刷新失败
如果某个 aptss 包的元数据查询失败:
- 不让该项进入可更新列表。
- 在
warnings中记录具体失败信息,例如aptss metadata query for <pkg> failed ...。 - 不影响其他更新项展示。
安装失败
如果 shell-caller.sh ssinstall ... 返回非 0:
- 保持当前任务失败处理逻辑不变。
- 将 stdout/stderr 继续写入任务日志。
- 由任务队列把该更新项标记为
failed。
取消任务
取消逻辑保持不变。只要下载或安装子进程被中止,任务仍按当前机制进入 cancelled 或 failed 分支,不额外引入新的取消状态。
测试方案
单元测试
先写失败测试,再改实现。至少覆盖以下场景:
-
load-items.test.tsaptss更新项会额外查询print-uris元数据。- 元数据成功时,结果包含
downloadUrl和fileName。 - 元数据失败时,该项被过滤并写入 warning。
-
task-runner.test.tsaptss文件安装走shell-caller.sh ssinstall <deb> --no-create-desktop-entry --delete-after-install。- 不再断言旧的
buildLegacySparkUpgradeCommand()输出。 apm文件安装仍走shell-caller.sh apm ssinstall <deb>,避免回归。
-
如有必要,为安装构造函数补充更细粒度测试,确保带
superUserCmd时参数顺序正确。
验证命令
实现完成后至少执行:
npm run test -- --run src/__tests__/unit/update-center/load-items.test.ts src/__tests__/unit/update-center/task-runner.test.tsnpm run lintnpm run build
风险与约束
aptss元数据查询会为每个更新项新增一次命令调用,刷新成本会增加,但这是换取 updater-onlyssinstall行为所必需的最小代价。- 若某些仓库源对
apt download --print-uris返回格式异常,相关更新项会被过滤并显示 warning;这比静默退回旧命令更符合本次需求。 shell-caller.sh ssinstall会自动补上--native,因此更新中心无需重复传入该参数。
决策总结
- Electron 更新中心的
aptss更新改为“下载 deb 后通过顶层shell-caller.sh ssinstall安装”。 - 实际使用的桌面项参数名为
--no-create-desktop-entry。 - 删除
aptss更新回退到aptss install --only-upgrade的旧行为。 - 该变更只作用于
electron/main/backend/update-center/,不修改其他安装入口。