声明式不等于破坏式
2026-09-29 更名: Barn 0.9.0 尚未发布;本文名称已同步更新。2026-09-26 校准记录: 保留原始写作日期;下文已按当前实现更新。公开版本与未发布候选的 边界见当前状态,不以本文日期代替发布或验收日期。
“声明式”常被简化成“让现实等于文件”。在文件完整、分支正确时,这是一句好口号;但当配置 暂时不完整、检出了错误分支,或某个 YAML Group 被误删时,把“缺席”理解成“删除”就会让普通 编辑错误直接变成破坏操作。
Barn 采用一条更窄的规则:
期望状态可以授权创建,也可以描述 Drift;它永远不能通过省略来授权销毁。
这对 VM Runtime 尤其重要。Root Disk、Data Disk、SSH Key 与本地证据并不是无状态副本。 重建可能是正确选择,但必须是操作者能看见并明确作出的决定。
从 Inventory 得到节点身份
Barn 不会对整份 Pigsty Inventory 做哈希。它先提取自己拥有的字段、填入默认值, 规范化镜像选择器与架构,再构造 Canonical Resolved Spec。精确 Catalog 工件另行解析, 因此 Channel 更新本身不会改变节点的 Spec Hash。每个节点的哈希只包含:
- 所有节点共享的 Deployment Envelope,例如子网、登录用户、架构策略与部署级默认镜像请求;
- 该节点自己的完整 Resolved Definition。
因此,增加一个同伴不会改变已有节点的哈希;修改 Barn 不消费的 Pigsty 字段——例如 PostgreSQL 版本、软件包或服务策略——也不会产生 VM Drift。VM 层只响应自己真正理解的契约。
这也避免了一项危险的半承诺:Barn 不假装实现完整 Ansible 变量系统。自有命名空间里的未知
vm_* 字段与冲突值会失败;记录边界之外的内容保持不透明,而不是只解释一半。
决策状态:当前有效。 Barn 自动收敛新增节点,但定义变更与删除都需要显式命令。 命令流程见日常管理。
Plan 只有五种结果
barn plan 对比期望状态、Applied Deployment State 与已提交的 Node State,结果刻意保持精简:
| 结果 | 含义 | 应用路径 |
|---|---|---|
| create | 期望节点没有已提交状态 | barn up 创建 |
| unchanged | 定义与运行时仍一致 | 运行中同伴不动;已停止节点可以启动 |
| recreate | 节点定义发生变化 | 显式 barn recreate --force <node> |
| missing | Applied Node 在 Inventory 中缺席或被跳过 | 显式 barn destroy <node> --force,或恢复配置 |
| envelope drift | 子网、登录身份、架构或运行时策略改变 | 整套 Deployment 重建 |
Plan 完全只读。它列出准确节点集合,并在文本模式中给出应用显式转换的命令。
为什么 up 遇到 Drift 会停下
Barn 可以把 CPU/内存变化认定为“足够安全”并自动应用,也可以在镜像变化时静默重建根盘。
Pre-1.0 刻意不这样做:任何 VM 定义变化都归类为 Recreate,up 返回类型化冲突。
这条保守边界有两个好处:
- 所有可能使 Guest 状态失效的变化共享一个可见操作;
- Barn 可以在触碰当前节点前完成全部前置检查。
Recreate 会先解析 Emulator、加速策略、Firmware、镜像字节、网络后端、Share 与 Persistent Disk 契约,再开始销毁。若外来架构 Emulator 缺失,或一个 Share 不安全,已有 VM 会保持原样。
为什么 Missing Node 会阻止收敛
节点从期望状态中消失,可能来自许多并不代表删除意图的原因:
- 调试时打开了一份缩减 Inventory;
- Group 被重命名或过滤;
vm_skip暂时标记一台真机或外部节点;- Merge Conflict 丢掉一段 YAML;
- 配置文件本身暂时不可用。
Applied State 仍包含这种节点时,up 会停止并点名报告。操作者必须恢复定义,或运行显式
Destroy 命令。这比自动垃圾回收多一点摩擦,却比恢复被意外删除的磁盘少得多。
Persistent Data Disk 还有独立边界:普通 Destroy 会保留它们;
整套部署的 destroy --delete-persistent 显式包含受管持久盘和已保留的磁盘,
不接受节点选择器;同时删除 Deployment Key
则需要整部署的 destroy --purge 或 purge。保留不是备份保证:Guest 初始化可能重置
无法识别或确认损坏的测试文件系统,包括持久盘,详见
数据盘。一次确认不能静默扩张成更宽的授权。
收敛仍然是增量的
安全并不意味着全部重建。新增节点创建时不会停止已有同伴;选中的已停止节点可以直接启动, 不会重建运行中节点;逐节点 Recreate 保留其它节点,并按磁盘契约保留 Persistent Data。
最终,Barn 在期望状态足以构成强证据的地方——创建与比较——保持声明式;在代价不可逆的 地方保持显式。它不会让操作者手工计算 Drift,也不会把 Diff 错当成权限。
下一篇:PID 不是虚拟机身份。