# 把 Pigsty 控制节点引导设计成可恢复事务

> 为什么 pig sty boot 在提权前解析来源、分离硬失败与收尾告警，并在软件源准备失败时恢复仓库定义。

---

LLMS 索引： [llms.txt](/zh/llms.txt)

---

> **决策日期：** 2026-08-14<br>
> **状态：** 已实现并随 [pig v1.8.0](/zh/release/pig-1.8.0/) 发布。<br>
> **当前参考：** [`pig sty boot`](/zh/sty/#sty-boot)<br>
> **范围：** 准备 Pigsty 控制节点及其软件来源，不包括部署数据库集群。

## 决策 {#decision}

`pig sty boot` 应当是一套原生、能够处理失败的控制节点引导工作流。
它在提权前解析显式来源，准备在线或离线仓库，只安装必要的控制节点软件包，证明 Ansible 真正可用，
并执行有边界的收尾检查。

仓库替换具有事务语义：软件包准备失败时恢复原有仓库定义。
可选便利功能可以告警，但无效的显式输入、软件包失败和最终不可用的 Ansible 环境属于硬失败。

## 背景 {#context}

旧命令把工作委托给 Shell bootstrap 脚本，来源选择、下载、sudo 边界、仓库回滚、错误分类与结构化自动化都难以观察。
仅仅存在 `ansible-playbook` 二进制也可能产生假就绪，因为它使用的 Python 环境可能缺少必要模块。

离线安装还带来另一种歧义：控制节点已经可用时，仍可能需要为后续节点准备本地仓库。

## 考虑过的方案 {#alternatives}

- **继续调用旧脚本。** PIG 无法拥有事务，也无法可靠解释部分失败。
- **要求整个命令一开始就以 root 运行。** 显式下载与来源校验不需要权限，应在一次有边界的提权前完成。
- **把 Ansible 二进制存在视为就绪。** 可执行文件使用的 Python 环境可能缺少必要模块。
- **Ansible 已就绪时跳过仓库工作。** 显式离线来源的 staging 是独立的请求效果。
- **把所有收尾检查设为硬失败。** locale 便利、本机 SSH 修复或目录初始化失败，不一定让控制节点不可用。

## 契约 {#contract}

- 显式本地路径和 URL 必须校验，失败时不能悄悄回退到在线模式；
- 自动发现的离线来源必须通过所有者与权限检查；
- 已提交的本地仓库可以优先于选定的软件包；
- 下载与受限归档解压使用原生有边界实现；
- 离线包必须包含 `pigsty/repo_complete` 哨兵；附加根目录先预检并在 `pigsty` 前 rename，
  冲突与中断残留都失败关闭，由操作员清理；
- 来源解析完成后只进行一次提权，并可禁止或要求非交互提权；
- 软件包准备失败时，被替换的仓库定义可以恢复；
- 就绪检查实际执行 Ansible，并验证它会使用的 Python 模块；
- 结果区分 ready、offline、online 与 existing 模式；
- 硬失败和收尾告警使用不同结构化字段；
- bootstrap 不声称 Pigsty 部署已经成功。

## 影响 {#impact}

原生工作流比脚本启动器更大，但副作用与回滚状态可见。
它能够在已经可用的控制节点上继续 staging 离线内容，也能为自动化提供稳定结果而不隐藏可选问题。

该命令仍不能证明 Pigsty 已经部署。控制节点就绪、Inventory 生成、部署和真实服务验证是不同门槛。

## 验证与演进 {#verification}

原生实现落地于 [`222616e`](https://github.com/pgsty/pig/commit/222616e)，
并在 [`74e084e`](https://github.com/pgsty/pig/commit/74e084e) 中继续收敛。
测试覆盖来源优先级、权限检查、受限解压、sudo 自重启、仓库回滚、locale 修复、Ansible/Python 就绪、
本机 SSH、初始化、告警分类与结构化结果。v1.8.0 发布页记录了交付状态。

一项尚未发布的 v1.8 后续改进把离线包路径扩展为保留多个安全顶层仓库。它继续使用既有哨兵
契约，明确不增加 manifest 或恢复 journal。该改进已经实现并通过本地测试，但不属于上面的
v1.8.0 发布声明。

## 当前状态 {#status}

`pig sty boot` 负责准备控制节点，不运行 `deploy.yml`，也不证明数据库服务已经就绪。
来源模式、环境控制和后续步骤以当前 [`pig sty` 文档](/zh/sty/)为准。
