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