13 · 更新、迁移与渠道¶
滚动发行版的更新不是一次 pacman -Syu。Quattro 把快照、系统包事务、用户迁移、AUR、工具链和重启判断组织成一条可观察、可续跑的流程。
总流程¶
omarchy-update 在 script 中运行以留下 /tmp/omarchy-update.log transcript,随后:
flowchart TD
Start[omarchy-update] --> Lock[获取 update flock]
Lock --> Free[检查可用空间]
Free --> Prune[必要时清 package cache]
Prune --> Snapshot[创建系统快照]
Snapshot --> Awake[阻止睡眠]
Awake --> Dev[可选更新 dev checkout/keyring]
Dev --> Pkg[系统包事务]
Pkg --> Mig[顺序运行 migrations]
Mig --> Hook[post-update hook]
Hook --> AUR[AUR 更新]
AUR --> Mise[mise 工具链]
Mise --> Orphan[清理孤儿/状态]
Orphan --> Restart[判断并重启]
Restart --> Done[释放锁/恢复睡眠]
任何会改变系统的大动作之前先检查空间并创建快照。update lock 防止两个 updater 并发,也让登录通知器知道“当前已有更新在进行”。
系统包事务是屏障¶
迁移脚本属于新版本代码,通常假设新包、新路径或新默认值已存在。因此顺序必须是:
如果 pacman 失败,迁移不会在半新半旧的基础上继续。反过来,迁移失败时 package transaction 已完成,所以修复后重跑 update/migrate,而不是假设系统完全回滚。
为什么阻止直接 pacman -Syu¶
libalpm pre-transaction hook 检测完整系统升级,要求走 Omarchy update,除非显式环境变量 override。它保护的不是命令品牌,而是流程前后条件:
- 更新前的快照和磁盘空间检查;
- Hyprland reload pause/resume;
- package 后的 migration;
- AUR/mise 与重启提示;
- transcript 与状态通知。
直接升级会绕过这些控制面,导致包版本已前进但用户状态没迁移。高级用户仍可显式 override,说明这是强 guard 而不是把 pacman 封死。
migration runner¶
迁移文件用时间戳命名并按文件名排序。每用户 marker 位于:
runner 的核心保证:
- 最多等待 pacman lock 900 秒;
- 找出没有 marker 的迁移;
- 按文件名排序;
- 用
bash -euo pipefail执行; - 只有退出 0 才 touch 对应 marker;
- 第一个失败阻止后续迁移。
stateDiagram-v2
[*] --> Pending
Pending --> Running
Running --> Marked: exit 0
Running --> Failed: non-zero
Marked --> Next
Failed --> Pending: 修复后重跑
新迁移按约定无 shebang、不可执行,因为它是由 runner 以受控 Bash 参数 source/执行的片段,而不是独立公共命令。脚本仍应幂等:失败前可能已经完成部分副作用。
登录通知不偷偷迁移¶
omarchy-migrate-notify 在图形会话中检查 pending migration,等待通知服务后提示用户点击打开终端。它在 update lock 存在时抑制自己。
选择“通知而不后台自动跑”有三个原因:迁移可能需要密码/终端、失败需要被看见、用户不应在登录时遭遇不可解释的系统修改。
四个渠道¶
| 渠道 | 包来源/语义 |
|---|---|
stable |
正常稳定包与 mirror config |
rc |
release candidate 包 |
edge |
开发/edge 包 |
dev |
本地 checkout 通过 dev-link 接管 |
omarchy-channel-set 不只改一个字符串;它调整 pacman 配置/包形态或开发链接,最后运行 update 让机器真正收敛到新渠道。channel marker 若与实际包源分离,就不可信。
hooks 的位置¶
迁移成功后运行 post-update hook。用户 hook 入口是:
先执行同名文件,再执行 .d 中可执行项;sample 跳过。单个 hook 失败会报告但 runner 继续,避免一个用户扩展阻断所有后续收尾。这里是有意的 best-effort 边界,不应与 migration 的硬失败语义混淆。
失败后从哪里继续¶
| 失败阶段 | 事实 | 合理动作 |
|---|---|---|
| 空间检查前 | 系统未变 | 释放空间后重跑 |
| snapshot | 包事务未开始 | 修复 snapshot/Snapper 后重跑 |
| pacman | 可能有 transaction 自身状态 | 先处理 pacman 错误/锁 |
| migration N | 新包已装,N 无 marker | 修复 N,重跑从 N 开始 |
| post hook/AUR/mise | 核心包和迁移可能已完成 | 单独重试外围阶段或完整重跑 |
| restart | 状态已更新 | 检查 restart reason 后手动处理 |
关键源码索引¶
bin/omarchy-update— 总编排、锁和 trapbin/omarchy-update-system-pkgs— package transactionbin/omarchy-migrate— 排序、执行与 markerbin/omarchy-migrate-notify— 登录提示default/libalpm/hooks/00-omarchy-update-guard.hook— pacman guardbin/omarchy-channel-set— 渠道收敛bin/omarchy-hook— 用户扩展执行顺序docs/update-process.md— 上游更新说明
更新能在不同机器上成立,依赖下一章的硬件适配策略:14 · 硬件探测与调优。