Aeria
GitHub
改 · 3.29

更新和回滚

最后核对 2026-10-07对应提交 7a2464e依据 layout.py · service.py · safe_mode.py · runtime_commands.py · providers.py

桌面版的更新是一个事务:检查 → 决定 → 下载 → 校验 → 停运行时 → 备份 → 解包 → 用新版本迁移数据 → 自检 → 换指针 → 启动。任何一步失败,数据从备份恢复,指针不动。

本页 6 节
  1. 安装目录
  2. 一次安装
  3. 安全模式
  4. 回到上一个版本
  5. 对应的代码
  6. 没做到的

安装目录

<安装目录>/
  versions/<build>/          解好、校验过的各个版本(并排放,不原地覆盖)
  current.json               指针:现在用哪个(原子替换)
  previous.json              指针:上一个(回滚用)
  staging/<build>.partial/   正在解的(没解完的永远不会被当成一个版本)
  downloads/                 下载中的和下完校验过的包

从源码跑的开发环境没有这个目录,更新也不作用在它上面。

一次安装

  1. 检查:读签名的发布清单(从 GitHub Releases 找,3.28),验签。
  2. 决定:可选更新,用户可以现在装、明天再提醒、跳过这一版;装着的版本低于「最低安全版本」或者被撤回,就是强制更新。
  3. 下载、校验:边复制边算哈希,复制进只有自己能读写的暂存区,解压的是这份副本。
  4. 解包:绝对路径、..、符号链接 / 硬链接、设备文件、超出总量和文件数上限,一律拒绝;包里的构建信息和清单对上了,才改名成 versions/<build>。
  5. 备份、迁移(用新版本自己跑 aeria migrate --root <数据目录>)、自检(aeria self-test --root <数据目录> --json)。
  6. 提交:换 current.json,重启运行时。

整个过程写在一份事务日志里;中途断电,下一次收尾(aeria update recover)按日志处理:指针还没换的,数据从这次的备份恢复,旧版本照旧;指针已经换了的,就是装好了。安装、收尾、回滚拿同一把跨进程的锁。

安全模式

运行时一启动先看本地缓存的、验过签的策略(不联网):这个版本低于最低安全版本、或者被撤回,就不启动人格、插件,退出码告诉桌面版进安全模式(只能更新、备份、导出、诊断)。上一次安装改数据改到一半、还没收尾,也不启动。

拿不到策略(从没检查过、断网、签名不对、缓存被改过)就照常运行;缓存里有一份验过签、说它不安全的,断网也不放行。

回到上一个版本

只换程序、不动数据:把 previous.json 换回来,之后固定用它,直到再装新的。数据也要回去,就恢复更新前自动做的那一份备份。

对应的代码

没做到的