deepin 是一个开放的操作系统,用户可通过多种方式更新系统。若某一次的更新与系统不兼容或是更新过程被意外中断,可能会导致重启后系统无法正常运行,影响用户使用。
deepin 为了处理此类更新引发的问题,从 v20 开始,设计实现了 AB 双系统分区的方案。即在系统安装时创建两个等大的系统分区,标记为 A 和 B 。 如当前系统是在 A ,系统更新时先将 A 中内容增量同步到 B ,同步完成后,生成对于 B 的引导,然后开始更新 A 。更新完成后重启,若更新存在问题,用户可回退到 B 中的系统。
在实际的使用中,AB 双系统分区的方案面临空间占用多、不支持命令行的问题。
因此需要重新设计一套更新管理程序,实现以下目标:
- 系统状态变更(软件安装、更新、卸载)前备份当前状态,并支持命令行
- 能够回滚到前一个系统状态
- 合并双系统分区为一个系统分区
- 备份的系统存储在数据分区
- golang
- ostree
- mount
make
make install
使用之前需先编写好配置文件,若无特殊要求,配置文件需安装到 /persistent/osroot/config.json
。
- 初始化
sudo deepin-upgrade-manager --action=init
sudo deepin-upgrade-manager --action=list
获取初始化版本号,假定为
v23.0.0.20220218
sudo deepin-upgrade-manager --action=rollback --version=v23.0.0.20220218
- 提交新版本
sudo update-grub
sudo deepin-upgrade-manager --action=commit
- 回滚到指定版本
需先询问用户是否保存当前系统状态,若需要保存则按照 提交新版本 的步骤进行操作。 假定要回滚到
v23.0.0.20220218
,使用命令:sudo deepin-upgrade-manager --action=rollback --version=v23.0.0.20220218
- 解释性语言优先选择 shell
- 编译性语言优先选择 golang , C 次之,后期考虑更换为 rust
当前优先实现功能,所以 golang 优先
- 依赖最小化
因为需要在 initrd 阶段运行,尽可能的不要引入外部依赖
本方案采用 ostree 构建系统文件的本地 repo ,根据配置文件中的订阅目录,将数据提交到此 repo 中。
而系统文件则由每个版本的快照通过 hardlink 生成,以节省空间使用。
每次系统变更前,都对当前系统状态进行提交,生成新版本。版本回滚时,则使用对应版本的快照重新生成系统文件目录。
详细介绍请见概要设计文档。
- [ ] 实现更新程序的单例检测
在执行
init、commit、rollback、snapshot
命令时,需检测当前是否有更新程序正在执行这些操作,若存在则直接退出。 - [ ] 回滚前需检查 fstab 中的分区是否都已经挂载
系统文件并不都是在系统分区中,有一部分在数据分区,因此需要检查相关的分区是否都已经挂载。 特别是在 initrd 中,因为在 initrd 中只会挂载系统分区,所以需要检查并挂载需要的分区。
- [ ] apt/dpkg 执行前的 hook 添加
系统在启动后,在执行 apt/dpkg 安装、更新、卸载软件前,需要使用更新程序提交当前系统状态,需要注意的是在一次系统运行周期内(未重启),更新程序只应执行一次版本提交。
- [ ] 更新结果自检程序
系统状态变更完成重启后,需要对启动阶段每个关键阶段进行检测,记录状态是否正常。若不正常则在用户登录后,提示用户是否回滚。若无法正常进入系统,则标记未失败,重启后自动回滚到上一版本。
- [ ] 版本数据清理功能
默认本地 repo 中只保留 3 个版本,多余的版本需要清理,清理时版本对应的数据也应清理,过程如下:
- 查询版本对应的提交:
ostree --repo=/persistent/osroot/os/repo log <version>
- 删除版本:
ostree --repo=/persistent/osroot/os/repo refs --delete <version>
- 删除数据:
ostree --repo=/persistent/osroot/os/repo prune --delete-commit=<commit>
但需保留初始安装版本。
- 查询版本对应的提交:
- [ ] DBus 接口
添加必要的 DBus 接口,供控制中心等调用者使用。
- [ ] 确定订阅目录列表
- [ ] 更新/回滚前检查空间是否充足
- [ ] 优化提交/回滚效率
- 可在操作之前计算差异,针对差异数据进行操作
- [ ] 支持从
/persistent/osroot/snapshot/<version>
启动系统 - [ ] 配置文件自动生成功能
- 根据不同的分区挂载方式,生成相应的配置文件
- [ ]
/vendor
合并支持
- [ ] 实现版本回滚功能
添加版本获取并回滚。
- [ ] 按照分区要求分区,并创建目录结构
- [ ] 初始化本地 repo ,并提交初始数据
- [ ] 添加版本回滚管理界面
- [ ] AB 分区处理
- [ ] OTA 更新支持
从 snapshot 恢复,若 snapshot 也被损坏,则从 repo 中恢复,repo 也被损坏则放弃。
- [ ] 文件篡改修复
- [ ] 文件丢失修复
- [ ] 确定基础 img
- [ ] 确定模块格式及生成工具
- [ ] 确定模块加载方式