13 · 安装、更新与供应链
Mole 的安装链明确区分“下载不到”和“下载到了但验证失败”。只有前者可以寻找替代来源。
安装源解析
install.sh 可从本地 checkout、指定来源目录或 GitHub 下载源码。默认解析最新 release tag;API 与 git 都失败时会明确警告并退到 main,将其标为 nightly source,而不是声称安装了稳定版。
架构由 uname -m 选择 amd64/arm64。Go helper 先写入同目录临时文件,设置可执行与清理 xattr 后再原子移动到目标,避免目标出现半写入二进制。
校验链
Release binary
│
├─ 下载 SHA256SUMS
│ └─ gh 可用时验证 GitHub Actions provenance
│ owner=tw93 + deny self-hosted runners
├─ 从已证明的清单取该 asset 哈希
└─ 本地 SHA-256 比较
├─ 成功:staged install
└─ 失败:立即中止,禁止自动 source-build 降级若 gh 不可用,默认仍可做 checksum-only;设置 MOLE_REQUIRE_ATTESTATION=1 可要求 provenance 必须验证。关键点在验证失败处理:asset 已到达却无法匹配哈希,可能是损坏或篡改,不应通过“改为源码构建”剥离验证要求。
只有下载本身失败,才会尝试另一 release tag 或明确的本地构建。源码构建也可由 MOLE_VERSION=main / edge 模式显式选择。
安装后验证
安装器运行目标 mole --version 并与刚安装的源码版本比较。仅凭复制命令退出或输出“success”不够,因为 sudo 失败或部分覆盖可能留下 Shell/Go 混合版本。安装 channel(stable/nightly/dev)和 nightly commit hash写入配置供更新判断。
更新先锁定当前安装
更新器先解析“正在执行的这个 Mole”路径,避免 PATH 中另一个 mole 抢走安装目标。Homebrew 安装交给 brew;手工安装才执行脚本更新。稳定版比较版本号,nightly 比较 commit hash。
网络探测有短超时与多来源重试,空结果表示未知;返回内容还必须匹配版本格式。用户拒绝 sudo 后在下载/修改之前安全退出。
自愈为什么直接流式执行 main 安装器
普通更新先把对应 tag 的 install.sh 下载到临时文件并执行。如果旧版本的 staging/registry/exec 代码本身损坏,重复使用它无法修复。最后手段 _update_self_heal_reinstall 从 main 流式获取最新安装器;pipefail 保证截断脚本不会运行到末尾 dispatch。
自愈结束仍实际调用安装后的 --version 与目标 tag 比较,不能相信安装器文本。这是“控制面损坏时用更新的控制面修复”,但最终状态仍由目标程序证明。
关键源码索引
install.sh#L331-L444:checksum 与 provenance 验证。install.sh#L706-L827:二进制下载、staging 与禁止降级。install.sh#L956-L979:安装后版本核验。lib/manage/update.sh#L48-L86:直接自愈。lib/manage/update.sh#L480-L766:更新主流程。
下一章检查这些安全断言如何进入测试与 CI,而不让测试真的操作开发者的 Mac。