跳转到主要内容

1 - 文章

关于 Barn 的项目文章与长篇技术记录。

这里收录 Barn 的项目文章与长篇技术记录。当前产品行为请以文档为准。

2 - 设计注记

Barn 的架构决策、方案取舍与实现边界。

Barn 源码仓库曾经把重构指令、实现期 ADR 与真机证据和代码放在一起。它们在产品快速变化时 很有价值,但其中不少早期结论后来已经被推翻。本栏目只保留仍然成立的设计理由,并以当前 源码重新表述,而不是把过时计划原样发布。

建议从产品模型开始,再沿着边界向外阅读:

  1. 为什么 Barn 没有 Project:一份 Inventory、一个 Owner-scope Deployment,不制造第二份事实。
  2. 为什么每个节点都有两张网卡:实验室固定身份与管理出网分离。
  3. 声明式不等于破坏式:逐节点 Drift、显式重建与删除。
  4. PID 不是虚拟机身份:QMP 身份、进程证据、Journal 与有界恢复。
  5. repo.yaml 是意图,catalog.json 是证据:生成元数据必须与 实际 qcow2 字节一致的静态镜像仓库。

当前行为以文档为准,带日期的验证边界见当前状态。 这些设计记录解释契约为何存在;它们不会把设计、构建或本地测试升级成发布证据。

本组文章保留原始写作日期,于 2026-09-26 对照源码校准,并于 2026-09-29 同步 Barn 0.9.0 更名。涉及未发布候选的 变化会单独标记;历史验证结果仍以原有日期和范围为准。

2.1 - 为什么 Barn 没有 Project

为什么 Barn 用一份 Pigsty Inventory 驱动一个 Owner-scope Deployment,取代按目录组织的 Project 状态。
说明

2026-09-29 更名: Barn 0.9.0 尚未发布;本文名称已同步更新。2026-09-26 校准记录: 保留原始写作日期;下文已按当前实现更新。公开版本与未发布候选的 边界见当前状态,不以本文日期代替发布或验收日期。

Barn 最初采用了一套很熟悉的虚拟机管理器抽象:工作目录就是 Project,隐藏 Marker 提供 身份,注册表负责重新发现 Project,宿主全局 Lease 防止它们争用私有网络。这种模型可以承载 多套彼此独立的虚拟机,但它并不适合 Barn 最终要成为的产品。

Barn 不是通用 Hypervisor 前端,而是一套本地、固定 IP 的 Pigsty 实验室。操作者本来就有 一份完整描述:Pigsty Inventory。再加入第二份 VM Manifest 与第二套 Project 身份,只会让 每个普通问题变复杂。

说明

决策状态:当前有效。 本文解释产品模型;当前文件名、字段与命令以 配置参考为准。

旧抽象会把普通问题转化为 Project 管理问题:

  • 节点名称和地址究竟以哪份文件为准?
  • 移动目录代表移动实验室,还是创建新实验室?
  • Marker 还在、注册表丢了怎么办?
  • 目录消失代表废弃 Project,还是移动硬盘暂时没有挂载?
  • 唯一的宿主私有网络归哪个 Project 所有?

这些都是合理的多 Project 问题。Barn 的选择是不再制造它们。

一份 Inventory 已经足够

交给 Pigsty 的 Inventory 同时就是 Barn 的期望状态。Barn 只读取一个很小、明确记录的 边界:Host 地址、少量 Pigsty 原生身份字段,以及 vm_* 命名空间。命名空间内部严格校验, Inventory 的其余部分保持不透明,原样留给 Pigsty。

这种不对称很重要。vm_mem 拼错必须报错,因为它会改变 Barn 创建的机器;新增一项 PostgreSQL 调优参数却不应该因为 VM 层从未见过而失败。于是同一份文件可以继续作为 Pigsty Inventory 演进,而不会暗中变成第二种 Barn 配置格式。

命名遵循同一原则:优先使用 nodename,其次按 Pigsty Cluster/Sequence 稳定派生,最后才 回退到地址尾段。Barn 不再增加一个可能与 Pigsty Hostname 冲突的 vm_name。

一个 Owner-scope 状态根

应用状态位于 BARN_HOME,默认是 ~/.barn。工作目录里没有 Marker,也没有按目录维护 的注册表。只读取应用状态的命令可以从任何目录运行;提出新期望状态的命令才需要发现或显式 接收 Inventory。

这里的“一个 Deployment”是 Owner-scope,而不是 root 强制的整机单例。每个 Unix 用户拥有 独立状态根。Barn 面向可信开发工作站,不承诺共享服务器上的敌对用户仲裁。

这项简化带来直接结果:

  • 移动或重命名源码目录不会改变 Deployment 身份;
  • Inventory 丢失不会擦除已经应用的状态;
  • 清理通过显式生命周期命令完成;删除状态目录不能替代停止 VM 或移除托管集成;
  • 镜像缓存、密钥、节点、磁盘、锁与 Deployment 状态集中在同一个可检查的 Home 中; 短 QMP/PID 路径、SSH 客户端集成与宿主全局网络仍有各自的托管位置,完整清理见 卸载。

配置缺席不是操作意图

单 Deployment 并不意味着 Inventory 可有可无,而是让 Barn 可以区分“期望配置”与“已应用 证据”。需要期望状态时,命令契约允许的场景可以回退到已有 Deployment 的 Applied Spec; 文件缺失永远不会被理解成删除节点的请求。

这条规则贯穿生命周期的每一层:规划与删除必须显式, 恢复流程也会保留有歧义的资源,而不是猜测用户意图。

这是刻意接受的取舍

Barn 不支持同一用户同时运行多套 Deployment。Project、注册表与地址级 Lease 不是藏起来 等待未来开启的功能;它们被明确否决,因为会重新引入产品刚刚删除的抽象。

如果需求变成多租户或多宿主编排,那已经是另一个产品边界。对本地 Pigsty 实验室而言,一份 Inventory 与一个 Deployment 能让地址、属主、Drift、恢复和清理都更容易解释,也更容易证明。

下一篇:为什么每个 Barn 节点都有两张网卡。

2.2 - 为什么每个 Barn 节点都有两张网卡

为什么 Barn 把管理出网与宿主、节点、Ansible 和 Pigsty 使用的固定地址网络分离。
说明

2026-09-29 更名: Barn 0.9.0 尚未发布;本文名称已同步更新。2026-09-26 校准记录: 保留原始写作日期;下文已按当前实现更新。公开版本与未发布候选的 边界见当前状态,不以本文日期代替发布或验收日期。

Pigsty Inventory 用稳定地址标识机器。PostgreSQL 复制、etcd 成员、HAProxy 后端、VIP、 监控目标与 Ansible 都假设 10.10.10.11 始终代表同一个节点。回环端口转发可以把 SSH 或 PostgreSQL 暴露给宿主,却无法把这种网络身份提供给其它节点。

因此 Barn 不让用户在“方便的 NAT 模式”和“高级固定网络模式”之间二选一。每个正常节点 同时获得两种能力,并由两张网卡分别承担。

一张网卡不该承担两项冲突职责

网卡 地址方式 职责
管理网卡 QEMU User-mode NAT、DHCP DNS、默认路由、互联网出站与回环 SSH 备用路径
私网网卡(按 MAC 匹配) Inventory 固定地址 宿主到节点、节点间、Ansible、Pigsty 服务与 VIP 流量

Barn 使用确定的 MAC 地址匹配两张虚拟网卡,不再修改它们的名称。Guest 中看到的名字由镜像 自身的网络栈决定(通常是 eth0 或 enp0s4);网卡角色由 MAC 与地址契约决定,而不是显示名称。

管理网卡刻意保持普通:一张新的 Cloud Image 在应用尚未安装前就能访问软件仓库,宿主无需 安装 NAT 规则或 DHCP 服务。

私有网卡使用一个确定的 RFC1918 地址,没有默认路由,也没有 DNS。客机初始化会检查 这些属性,但从 0.7 起,私网检查属于可选步骤:失败时记录 private-network 警告, 管理 SSH 与客机身份可用时仍可达到就绪。因此操作成功时,固定 IP 连通性仍可能受限。 部署依赖该网卡的服务前,应检查警告并测试相应宿主/节点间连接,修正原因后重复 up。

说明

决策状态:当前有效。 这套拓扑属于 Barn 的正常生命周期,并不是可选的 “Private Mode”。当前平台边界见设计参考。

地址规划归 Inventory 所有

所有受管 Host 位于同一个规范 RFC1918 /24:

范围 含义
.1 宿主侧私有网络地址
.2–.8 保留边界,包括有效的二层 VIP 空间
.9–.254 节点固定地址

Guest 私有网卡不请求 DHCP:cloud-init 直接得到 Inventory 已声明的准确地址。macOS vmnet 配置的 DHCP 范围止于 .8,受管节点从 .9 开始;Linux 使用桥接与 Guest 静态地址。 因此 VM 地址契约不依赖租约数据库,Ansible 从第一次连接到后续部署始终使用同一地址。

对于自动生成的配置,如果默认子网被占用,setup 可以从一组有限候选中选择空闲网段;显式 提供的 Inventory 绝不会为了绕过冲突而被静默改写。宿主接口、所有节点、Pigsty 地址与别名 必须对同一个子网达成一致。

后端因平台而异,Guest 契约保持一致

Guest 在所有支持宿主上看到相同拓扑,Barn 则跟随宿主真正的网络管理者:

  • macOS: 固定版本的 socket_vmnet 服务提供私有链路。Host Mode 默认,Shared Mode 必须显式选择;QEMU 仍以普通用户运行。
  • NetworkManager 活跃的 Linux: Barn 通过 nmcli 创建自有 barn0 Bridge, 并与活跃的 firewalld 策略配合。
  • systemd-networkd 管理的 Linux: Barn 安装自有 Unit,并借助发行版 qemu-bridge-helper 保持 QEMU 非特权。
  • networkd 尚未启动: 只有预变更扫描能证明现有 Unit 不会接管真实宿主网卡时,才允许 激活它。

同时支持两种 Linux 管理器不是为了抽象而抽象。如果只因为 Barn 会写 .network 文件,就在 桌面或 RHEL 家族宿主上启动 networkd,可能破坏宿主真实网络;后端必须服从当前已经负责网络 的组件。

宿主网络是一项事务

Bridge 或 vmnet Daemon 会跨越一次 CLI 进程,也会跨越特权边界,因此 Barn 把安装视为 可逆宿主事务:

  1. 检查 Route、Interface、Service、属主与已有状态;
  2. 修改前打印准确计划;
  3. Apply 前立即重新检查前置条件;
  4. 用 root-owned 状态记录 Barn 创建了什么、此前存在什么;
  5. 证明普通用户 QEMU 确实可以接入;
  6. 全部 Readiness 检查通过后才接受安装。

一个碰巧占用相同 .1/24 的外部接口不会被接管;已经变化的自有文件不会被覆盖;Uninstall 会在已记录节点仍运行时拒绝,并且只恢复 Manifest 明确记录的前态。失败意味着停止,而不是 授权程序删除挡路的任何东西。

接受的取舍

Guest 互联网流量经过 QEMU User-mode Network。这不是理论上最快的转发路径,但它让普通出网 保持非特权且跨平台。真正影响 Pigsty 实验室的流量——宿主到 Guest、复制、服务调用,以及从 控制节点分发软件包——都留在私有链路上。

最终形成一个清晰的职责分离:管理网卡让机器容易 Bootstrap,私有网卡让它成为地址稳定的 实验室成员,两者都不需要假装成对方。

下一篇:声明式不等于破坏式。

2.3 - 声明式不等于破坏式

Barn 如何用逐节点哈希与显式操作保证配置缺席永远不能授权删除。
说明

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 返回类型化冲突。

这条保守边界有两个好处:

  1. 所有可能使 Guest 状态失效的变化共享一个可见操作;
  2. 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 不是虚拟机身份。

2.4 - PID 不是虚拟机身份

为什么 Barn 在发送信号或删除任何东西前,必须让 QMP 身份、进程证据、类型化 Invocation 与 Journal 相互吻合。
说明

2026-09-29 更名: Barn 0.9.0 尚未发布;本文名称已同步更新。2026-09-26 校准记录: 保留原始写作日期;下文已按当前实现更新。公开版本与未发布候选的 边界见当前状态,不以本文日期代替发布或验收日期。

Pidfile 只能回答一个问题:写入文件时,某个进程使用了哪个整数。它不能证明进程仍然存活, 不能证明 PID 没有被复用,不能证明可执行文件就是 QEMU,也不能证明这个 QEMU 正是操作者 想停止的节点。

这些证据不足以授权 SIGKILL,更不足以授权删除 Root Disk。

Barn 把身份视为一条由独立证据组成的链。每一环承担不同职责;只有操作所需的证据全部一致, 破坏性动作才可以继续。

QMP 是主要运行时身份

每台 VM 都有生成的 UUID 与预期 QEMU Name。启动后,Barn 连接 QEMU Machine Protocol Socket,并向 QEMU 查询这两个字段。仅仅因为进程启动命令返回,或某条 Socket 路径出现,并不 代表 VM 已经启动;QMP 必须报告预期 Name 与 UUID。

同一检查也保护关机。如果 QMP Endpoint 返回另一个 Name 或 UUID,它不会被解释成“大概就是 旧 VM”,而是明确的身份不匹配;Barn 不会通过它发送任何命令。

QMP 同时提供干净关机路径:请求 Guest Powerdown,等待 Guest;若有界 Graceful Wait 到期,再 要求 QEMU Quit。进程信号只是备用工具,不是主要生命周期 API。

说明

决策状态:当前有效。 本文解释 Fail-closed 生命周期边界。运维恢复应从 故障排查开始,而不是手工删除。

进程身份封住备用路径的缺口

Crash、Runtime Directory 损坏或半完成关机都可能让 QMP 不可用。为此 Barn 会记录一组 进程身份:

  • PID;
  • 可执行文件路径;
  • 进程启动时间;
  • 实际命令行的 SHA-256。

完整的类型化 QEMU Invocation 与它一同保存。发送 SIGTERM 前,Barn 会重新读取活进程, 要求整组身份完全匹配;升级到 SIGKILL 前还会再次捕获,专门封住有界 TERM 等待期间产生的 PID 复用窗口。

如果 QMP 仍然可用但某项 QMP 操作失败,Barn 不会绕开活控制平面直接发信号;如果 QMP 报告另一个身份,它会停止;如果进程元组无法验证,它也会停止。“无法证明”本身就是结果, 不是降低检查强度的理由。

未发布的 0.9 候选更新: QMP 不可用、且记录的 PID 已被明确证明属于无关进程时, Barn 把旧 VM 视为已停止,绝不会向那个无关进程发送信号。这与身份不可读或有歧义不同, 后两种情况仍会阻止操作。

Journal 描述 State 提交前的工作

Committed Node State 无法描述创建的最早阶段:Disk 与 Seed 必须先存在,VM 才能启动;进程 必须先启动,身份才能提交。若 CLI 在这个间隔 Crash,就可能留下没有可信 Owner 的工件。

Barn 会先写一份 0600 Prepare Journal,其中包含:

  • Operation UUID 与 VM UUID;
  • Node Name 与 Resolved-spec Hash;
  • 固定 Kind/Path 白名单中的每个已完成工件;
  • 准备完成后的类型化 QEMU Invocation;
  • Commit 成功后的准确 Node-state Path。

Journal 是严格的版本化 JSON。未知字段、无效 UUID、不安全路径、重复工件、错误 Mode、Symlink, 或逃出 Node Directory 的路径都会使它无效。

于是恢复流程可以回答一个边界明确的问题:这次尚未提交的操作创建了哪些工件? 它不需要 扫描目录后猜测。

Rollback 比 Cleanup 更窄

只有在 Committed Node State 不存在,并且类型化 Invocation 对应的 QMP Socket 与 Pidfile 都不存在时,才允许 Offline Rollback。Node Directory 里只能出现 Journal 与已完成白名单工件; 随后按逆序移除已完成工件,再移除 Journal 与空节点目录。

未发布的 0.9 候选更新: 首次 up 失败后,即使已经修改 Inventory 也可以重试。 安全清理按 Journal 的已完成工件列表执行,不再要求新期望配置与失败时的旧配置一致。

已提交节点绝不会因为旧 Prepare Journal 被回滚;已有磁盘不会被补进 Action List;未知文件 会阻止目录删除,而不是作为附带损失被一扫而空。

普通 Destroy 采用同样思路:证明路径包含、文件类型、属主边界、进程已经死亡,以及准确工件 集合。Persistent Disk 有独立保留与 Purge 规则。只有已知文件全部移除后才删除目录,所以任何 未知条目都会变成错误。

原子状态让证据持久

状态更新使用同目录临时文件、fsync、原子 Rename 与父目录 fsync,并拒绝 Symlink Target; Deployment 与 Node Lock 串行化修改。目标不是让 Crash 永不发生,而是保证 Crash 后留下的要么 是旧的完整事实,要么是新的完整事实,再加一份描述两者之间有界阶段的 Journal。

这套设计刻意保守。它有时会要求操作者检查一个更激进工具可能直接删除的歧义资源。对本地 数据库实验室而言,保留证据是更安全的失败方式。

下一篇:repo.yaml 是意图,catalog.json 是证据。

2.5 - repo.yaml 是意图,catalog.json 是证据

为什么 Barn 把人工维护的镜像策略与必须匹配实际 qcow2 工件的生成元数据分离。
说明

2026-09-29 更名: Barn 0.9.0 尚未发布;本文名称已同步更新。2026-09-26 校准记录: 保留原始写作日期;下文已按当前实现更新。公开版本与未发布候选的 边界见当前状态,不以本文日期代替发布或验收日期。

静态镜像仓库看起来只是一些 qcow2 文件加一个 JSON 索引。真正困难的问题是:哪些事实允许 维护者手写,哪些事实必须从即将发布的字节中推导。

如果 Checksum 与 Size 放在手写源文件里,它们很容易被错误复制;如果策略只存在于生成 JSON 中,审查 Channel 变化或弃用决定就要阅读机器输出。Barn 把这两项工作明确分开。

repo.yaml:维护者表达什么意图

源码控制的 repo.yaml 记录作者意图:

  • 仓库 Revision 与默认选择;
  • Image Family 与 Alias;
  • stable 等可移动 Channel;
  • Exact Version 与 Architecture;
  • Boot Mode 与支持状态;
  • Immutable Upstream 与 Provenance 说明。

它刻意不包含生成的 Artifact Size、SHA-256 或 Virtual Size。一条简洁配置可以表达 d13:stable 指向某个准确版本,并提供 amd64/arm64 Variant,而不假装知道只属于文件本身的事实。 下面保留的历史策略片段只演示格式;完整可用示例见镜像仓库, 当前版本以镜像参考为准:

defaults: { image: d13, channel: stable, arch: native, boot: uefi }
images:
  d13:
    aliases: [debian13, debian, trixie]
    channels: { stable: "20260810.2566.0" }
    versions:
      "20260810.2566.0":
        status: supported
        variants:
          amd64: {}
          arm64: {}

这是适合 Review 的层:Pull Request 可以清楚展示 Channel 移动、Version 弃用或 Provenance 描述变化。

说明

决策状态:当前有效。 仓库语法与客户端行为见镜像参考, Candidate 准备属于独立的镜像流水线契约。

catalog.json:仓库能够证明什么

catalog.json 把策略落实到本地仓库。每个 Variant 都包含准确文件名、字节数、SHA-256、 qcow2 Virtual Size、Boot Contract、Source User 与 Immutable Upstream Provenance。

文件名、字节数、摘要与虚拟大小由工具物化并对照工件检查;启动模式、源用户、状态与溯源 则来自 repo.yaml 中经过校验的策略,文件检查本身不能独立证明这些声明。 Build 会强制解析 qcow2,拒绝 Backing File、 External Data、Encryption 与未知 Incompatible Feature,执行结构检查后才原子替换 Catalog。

Artifact 身份是 (image, exact version, architecture) 三元组,而不是选择它的 Channel。 文件保持可读、不可变的名字:

images/d13-20260810.2566.0-arm64.qcow2

可读文件名是一项运维能力:管理员可以用普通文件系统工具检查、镜像或恢复仓库。完整性仍来自 生成元数据与验证,而不是相信名字。

三个操作,三种职责

仓库 CLI 把观察、生成与证明分开:

命令 职责
barn repo scan 只读报告 Tracked、Missing、Untracked 与 Unsafe Artifact
barn repo build 校验 Source 与 Artifact,再原子生成 Catalog
barn repo verify 在内存中重新物化,并要求与已发布 Catalog 逐字节一致

build 永远不修改 repo.yaml 或 qcow2 字节。verify 比“每个 Checksum 都正确”更强:它还能 证明没有任何源策略或工件变化被漏出生成 Catalog。

发布遵循同一方向:先上传不可变镜像字节,最后发布 Catalog 与匹配签名,尽量一起切换 这两个文件。部分上传造成正文与签名不匹配时,客户端会拒绝;先工件后目录则避免声明 仍在传输中的镜像字节。

Selector 可以移动,Artifact 不能

人工配置需要方便的 Selector。随着仓库演进,d13:stable、el9@9 与 [email protected] 可以解析到 更新的准确版本。数字前缀按点分组件的整数比较,因此 9.10 排在 9.9 之后。

解析完成后,客户端保存准确 Version、Architecture、Size 与 Digest。一个已经解析的节点不会 因为 Channel 移动就变成另一台机器。便利只存在于选择阶段,不可变身份存在于执行阶段。

传输与信任是两个问题

官方 Catalog 与普通 HTTP Catalog 必须具有受信 Detached Signature。操作者显式选择本地目录 或 HTTPS Repository 时,可以使用 Unsigned Catalog,因为本地属主或认证传输本身就是显式 信任决策。即使 URL 是 HTTPS,隐式 Compiled Default 仍属于签名信任域。

Accepted Catalog State 按 Repository 独立记录。Barn 会拒绝未知 Key、低于该仓库 High-water Mark 的 Revision,以及同 Revision 不同字节。显式 Downgrade 可见且只影响选定 Repository; 重置到 Embedded Catalog 也不会擦掉防回滚记录。

接受 Catalog 只是前半程。每次 Pull 仍会检查 Byte Count、SHA-256 与 qcow2 结构。通过验证的 Base Image 变为只读,Node Root Disk 使用 Overlay,因此普通 VM 写入永远不会修改受信 Base。

不同信任域保持分离

Image Catalog Key 授权镜像策略;Release Signing 证明 Barn 应用工件与 Checksum Manifest。 两组 Key 刻意独立:有权发布 VM Image 不应自动获得发布 Barn Binary 的权限,反之亦然。

普通 Public Build 默认使用 https://repo.pigsty.io/barn,并通过 --mirror 显式选择 https://repo.pigsty.cc/barn;--repo 仍是自定义覆盖。自 0.7.0 起的更新: 两个 官方仓库在下载镜像时可以互相回退,始终校验同一 Catalog 的尺寸与 SHA-256。自定义仓库 仍是唯一工件源,Catalog 更新仍使用选定来源;Embedded Catalog 的 Upstream URL 只提供溯源,绝不会变成工件回退。源码配置、生成 Catalog、上传 Artifact、签名与公开可用性仍是彼此独立的发布门禁。

更大的设计原则是:策略应当便于人类审查,而关于已发布字节的事实必须可生成、可复现,并能 被独立验证。

3 - 发布注记

当前 Barn 发布与保留的迁名前开发记录。
重要

Barn 仍处于 pre-1.0。带版本号的发布说明与保留的 Farrow 发行与 Piglet 开发记录并列展示; 历史条目不能作为当前 Barn 字节的支持承诺。

3.1 - Farrow 0.8.0:恢复更顺畅,镜像更新

接续宿主准备、隔离失败节点、保留虚拟机身份,并更新九月 Debian 与 Ubuntu 镜像。

Farrow 0.8.0 减少初始化中断和部分节点启动失败后的手工操作,同时更新 Debian 与 Ubuntu 镜像,保留全部旧 Catalog 工件和已有 VM 身份。

主要变化

  • 宿主准备接续原命令。 交互式 start、restart、reload 可以补齐宿主工具, 恢复已确认完整的 Farrow 网络。macOS 新网络安装先完成 Homebrew 发现/安装或固定 归档下载、校验,再申请管理员认证,避免 Homebrew 清除过早获取的 sudo 凭据。
  • 单个节点失败不阻断独立节点。 up、start 将宿主共享目录缺失的影响限制在 对应节点;新节点准备失败时,独立的已停止节点仍可启动。错误指出源目录和挂载点, 不创建空目录掩盖问题。restart/reload/recreate 在停止已有 VM 前先检查共享能否访问。
  • 恢复保留身份。 公钥缺失时从原私钥派生;私钥丢失时给出备份恢复指引,不生成 新的登录身份。macOS vmnet 日志目录恢复保留网络归属证据,避免误报自身网段冲突。
  • 失败保留上下文。 重试命令保留配置、仓库和适用参数,start 的重试仍是 start。 setup 与重试使用同一操作编号;还没有部署状态时也能读取有大小上限的事件日志。 查询未缓存镜像信息不再要求 QEMU。
  • 清理准确汇总最终结果。 显式删除持久盘或 purge 不再同时声称保留和删除同一磁盘。 之前删除单个节点留下的受管磁盘,不再阻断其余实验环境的销毁。

九月镜像

内置 Catalog 2026092001 包含九个 Family、37 个工件,保留前一版全部 27 个工件。 以下新 stable 均覆盖 amd64 与 arm64:

Family 系统版本 Catalog 版本
d12 Debian 12.15 20260909.2596.1
d13 Debian 13.7 20260914.2601.1
u22 Ubuntu 22.04.5 20260913.0.0
u24 Ubuntu 24.04.5 20260911.0.0
u26 Ubuntu 26.04.1 20260918.0.0

Debian 延续离线安装的 XFS 工具与已生成的 en_US.UTF-8 locale,默认仍为 C.UTF-8。 Ubuntu 保留 Canonical 原始镜像字节,部署账户和网络由 cloud-init 配置。已有 VM 和显式 锁定的镜像版本继续使用原基础镜像。仓库与更新行为见镜像参考。

安装或升级

curl -fLO https://github.com/pgsty/farrow/releases/download/v0.8.0/install.sh
chmod +x install.sh
FARROW_VERSION=0.8.0 ./install.sh
export PATH="$HOME/.local/bin:$PATH"
farrow version

已有实验环境在配置所在目录先查看 farrow plan,再执行 farrow up。首次使用时, 在终端执行 farrow up,准备宿主并创建默认实验环境。

Farrow 仍处于 1.0 之前,沿用 GitHub pre-release 通道,请保留显式 FARROW_VERSION。 本版包含 macOS/Linux amd64/arm64 归档、Linux DEB/RPM、校验清单、SBOM、安装器和 Homebrew Formula。其他安装方式见快速上手。

start 仍只启动已有节点;up 应用配置并重试未完成的客机初始化,不需要独立 repair 命令。测试数据盘的既有重置策略不变:证实不可用的测试文件系统可以被清空,包括持久 数据盘,并明确报告数据丢弃。设备缺失、探测失败、忙碌挂载或宿主 I/O 故障不构成 格式化依据;根盘和宿主共享目录不属于此恢复范围。

验证与限制

两台 macOS arm64/HVF 和两台 Linux amd64/KVM 完成七系统 pro 验收,每机覆盖 Rocky Linux 9.8/10.2、Debian 12.15/13.7、Ubuntu 22.04.5/24.04.5/26.04.1。 基线候选 6d7870e 使用局域网仓库完成从零初始化;运行时候选 1c054a0 随后原位安装, 通过健康重复 up、stop/start、两轮客机 SSH、数据盘访问、Ansible 配置读取和控制节点 SSH。两台 Mac 还分别通过全部七节点 Ansible ping。VM UUID、镜像身份、健康根盘与 数据盘路径/inode 保持。临时验收 VM 已在之后清理。

以下计时是单次样本,不能视作性能分布;首次 up 包含镜像下载:

宿主 平台 6d 从零首次 up 1c 健康 up 1c 已有磁盘 start
m0 Linux amd64 / KVM 117.915 s 3.924 s 36.944 s
m1 macOS arm64 / HVF 86.309 s 1.745 s 39.639 s
m3 Linux amd64 / KVM 98.443 s 2.169 s 44.068 s
m5 macOS arm64 / HVF 87.946 s 1.467 s 38.162 s

发布 tag 指向 320a32afa8f6fca02592215aa0d5607ca4e852b2,相对已验收运行时只更新 README 和发布说明。完整本地 make check、发布归档/软件包检查通过, 源码 CI、独立 打包 Snapshot 与 Tag 工作流也均通过。 Tag 工作流生成 20 个发布资产,其中 19 项载荷列入校验清单。 Release 已公开,使用 GitHub pre-release 通道。20 个匿名下载均返回 HTTP 200,完整 SHA-256 与 GitHub API 及已检查 草稿一致;19 项载荷全部匹配 checksums.txt。

UX 审计与 镜像更新记录 保留此前回归、原生镜像启动与升级证据。

两个官方镜像入口都提供与发布版一致的签名 Catalog。对每个入口分别执行隔离的 farrow update,均成功验证签名并激活 revision 2026092001。每端十个新增镜像对象 均返回 HTTP 200,内容长度匹配;这不是重新下载全部公开 qcow2 正文后的完整摘要验证。

公开安装器已在 macOS arm64 与 Linux amd64 的隔离用户目录安装成功,两端 CLI 均报告 0.8.0 / 320a32a,安装后的 CLI/helper 字节与各自已校验的公开归档一致。Linux 下载 通过临时 SSH 回环转发访问已有代理,验证后已关闭。默认安装及 VM/网络状态保持不变。 这些检查验证了二进制交付;通过公开安装器重新初始化宿主并启动 VM 仍待验证。

Homebrew Tap 更新 已提供 0.8.0,四平台归档校验和与公开发布一致。本地 Formula 检查、严格在线 audit 和 原生 arm64 brew fetch 通过;Homebrew CI 也在 macOS 和 Linux 上通过元数据、更新器、样式、平台和 audit 检查。本次没有重新执行 Homebrew 安装、升级或 brew test。

这是从零 6d 基线,再用 1c 原位复验生命周期,不是 1c 再次从零初始化。Homebrew 认证 顺序有修复前失败、修复后通过的回归,但修复后的全新 Formula 安装没有再次原生重放; 本轮 macOS 网络首装使用已校验的局域网后端归档。物理宿主重启、完整 Pigsty 安装、 macOS amd64 和 Linux arm64 原生运行不属于本轮覆盖范围。

macOS 目录共享仍受已测 QEMU 目录描述符行为限制。 新前置检查改进诊断,没有实现 共享支持;pro 配置不含宿主共享。控制节点中缺失的 Guest 私钥现在会被发现,即使旧的 ready 标记仍存在,但尚未实现私钥自动重新注入。管理 SSH 可以继续使用,节点间 SSH 则明确报告限制。完整的带日期验证矩阵见当前状态。

3.2 - Farrow 0.7.0:简化测试环境,自动恢复故障

缩短首次启动路径、精简进度输出、独立初始化可选功能,统一通过 up 恢复。

Farrow 0.7.0 简化测试环境的启动与恢复。重复执行 farrow up 即可继续中断的工作、 重试未完成的客机初始化,并原位更新旧的客机脚本,无需重启正在运行的虚拟机。

主要变化

  • 缩短首次使用路径。 交互式 up 可以创建默认配置、准备缺少的宿主工具,并恢复 已正确安装但未运行的 Farrow 网络。短检查保持安静,长任务显示进度,完成后给出简洁结果。
  • 可用的环境继续运行。 数据盘、共享目录、客机主机名、节点间 SSH 和私网分别初始化。 可选功能失败时明确报告限制,保留可用的管理 SSH;后续 up 跳过健康步骤。
  • 自动恢复测试数据盘。 可用文件系统直接复用;无法识别或确认损坏的文件系统会被 清空重建并重新挂载,结果明确提示旧数据已丢弃。探测失败、设备暂缺、挂载占用和底层 I/O 故障不会触发格式化。
  • 减少手工排障。 不可写的共享目录降级为只读,权限修正后重复 up 恢复;已停止 虚拟机的自动 SSH 端口被占用时重新分配。镜像传输支持续传和官方源故障切换,保留摘要校验。
  • 精简输出,分离提示与状态。 成功命令给出短摘要,限制按问题分组,JSON/YAML 保留 结构化结果。客机警告单独缓存,不进入 schema-2 虚拟机状态和节点工件目录,旧版本仍可 读取并管理原有环境。

升级说明

数据盘按可丢弃的测试存储处理。up 可能清空损坏的文件系统,包括 persistent 数据盘。 persistent 表示销毁、重建虚拟机时保留盘,不表示在故障恢复时保留损坏内容。有价值的数据 请存放在这些测试盘之外。此次自动清盘不涉及系统盘和宿主机共享目录。

不增加单独的 repair 命令,恢复工作统一由 up 完成。start 继续只启动已有节点, 不应用配置;--no-wait 跳过就绪检查及客机恢复步骤。

管理 SSH 可用、但可选功能受限时返回 0。要求全部功能可用的脚本应检查 JSON/YAML 的 nodes[].warnings;数据盘重置等自动操作写入 nodes[].repairs。回退 CLI 不会恢复已丢弃 的数据,也不会回退已经安装到客机中的脚本。

旧版 0.6.0 初始化中断时,可能在安装前就删除暂存的控制节点 SSH 私钥。up 能恢复 管理访问并继续独立步骤,但密钥缺失时仍报告 control-ssh 限制;原位重试不会重新注入 私钥。需要节点间 SSH 时,先用 farrow plan 查看磁盘影响,再显式重建受影响的控制节点。

安装或升级

curl -fLO https://github.com/pgsty/farrow/releases/download/v0.7.0/install.sh
chmod +x install.sh
FARROW_VERSION=0.7.0 ./install.sh
farrow version
farrow up

提供 macOS/Linux 的 amd64/arm64 归档、Linux DEB/RPM、安装器、校验和、SBOM 和 Homebrew Formula。沿用 pre-1.0 规则,在 GitHub 标记为 Pre-release,安装时需指定 FARROW_VERSION。

验证范围

发布提交为 9c6d4896d93733d1cb60a7e5d8591e9a06659c9d,通过源码 CI 与独立打包 Snapshot后打 Tag。 Tag 工作流重复门禁并生成 20 个发布资产: 19 个带校验和的载荷及校验清单。检查后,20 个资产均可匿名 HTTP 200 下载,并与检查过的字节一致。

公开 macOS arm64 与 Linux amd64 安装器安装的二进制均与归档一致,并报告版本 0.7.0 与上述提交。 Ubuntu 26.04 amd64、KVM/QEMU 10.2.1、Ubuntu 24.04 Guest 隔离环境实际验证了 ext4/XFS 损坏、持久盘、 探测失败、忙碌挂载、只读共享降级和重复健康 up 保留 VM 进程。公开版 0.6.0 因管理出网探测失败而中断, 0.7.0 在 3.3 秒内接续,探测失败期间已有数据盘和 UUID 保持不变。升级后 0.6.0 二进制仍能执行 status、stop、start 与 destroy。最终 0.7.0 归档新建的 VM 无警告启动;公开安装器还在 3.2 秒内 重置了人为损坏的可丢弃 ext4 数据盘,明确提示数据丢失,同时保留 VM 进程。

特定的 0.6.0 中断现场可能在安装前删除暂存的控制节点 SSH 私钥。此升级路径中管理 SSH 会恢复, 但节点间 SSH 会明确显示 control-ssh 限制,原位重试不会重新注入私钥;需要节点间 SSH 时,先查看 farrow plan 再重建受影响的控制节点。全新 0.7.0 Guest 会正常安装该密钥。

本版本 macOS 验证包括 CLI 冒烟与交叉编译;不宣称新增 HVF Guest 重放、宿主重启、Linux arm64 或完整 Pigsty 安装验收。

3.3 - Farrow 0.6.0:默认 U24,更顺手的本地虚拟机体验

默认 Ubuntu 24.04,准备宿主前即可查看计划,状态更清晰,扩容与重建更可靠。

Farrow 0.6.0 默认使用 Ubuntu 24.04,完善本地 Pigsty 实验环境的计划、启动、扩容和重建体验。

主要变化

  • 默认 Ubuntu 24.04。 新配置与内置镜像目录使用 u24:stable。目录版本 2026090501 同时纳入官方仓库已经发布的 Debian 12/13、Rocky Linux 8/9 镜像更新。
  • 准备宿主前就能查看计划。 Catalog 镜像的 plan 无需先安装 QEMU 或配置网络 (已注册的 local-* 镜像仍需 qemu-img 校验缓存),展示准确镜像版本、 资源总量、待启动节点、变化字段、磁盘影响,并保留自定义 -f 路径。
  • 状态和错误更清晰。 状态表直接显示镜像、CPU 与内存,异常节点不再遮住健康节点。 状态损坏报告具体文件与原因;镜像摘要错误返回 7,SSH 的 255 原样透传; --no-wait 明确说明跳过就绪检查。
  • 先检查,再中断。 局部 recreate 在删除磁盘前发现同伴配置冲突;reload 在停机前 检查启动依赖。停止、销毁和运行时清理沿用现有部署锁,一致地处理状态。
  • 节点名称随环境更新。 启动与删除节点后更新 Guest 内 Farrow 管理的 hosts 和控制节点 SSH 配置;同名节点重建后可以直接连接,无需手动清理 Guest 的 known_hosts。 用户 SSH 内容及全局选项的作用域得到保留。
  • 减少命令行意外。 init 自定义路径给出可用的下一步命令,展示参数不再误读选项值, 整数容量与多文档 YAML 不再被静默截断。ALL_PROXY/all_proxy 提供代理回退, 同时尊重专用代理和 NO_PROXY。

升级说明

升级程序不会自动替换已有磁盘,也不会修改显式选择的镜像。旧配置若依赖隐式 Debian 13 默认值,请先在 all.vars 中加入 vm_image: d13,再使用 0.6.0 应用配置。执行变更前先看 farrow plan;farrow start 继续使用已应用状态。

CPU、内存变化仍通过 recreate 应用:根盘与非持久数据盘会被替换,持久数据盘保留。 --no-wait 跳过就绪检查和 Guest 信息刷新,之后执行 farrow up 即可补齐。 脚本应读取 --json 或 --yaml,避免依赖表格列位置;部分状态失败时仍返回健康节点与 failures 数组,退出码为 5。

安装或升级

curl -fLO https://github.com/pgsty/farrow/releases/download/v0.6.0/install.sh
chmod +x install.sh
FARROW_VERSION=0.6.0 ./install.sh
farrow version
farrow doctor

同一 Release 提供四个平台归档、amd64/arm64 的 DEB/RPM 软件包和 Homebrew Formula。 0.6.0 沿用 pre-1.0 发布规则,在 GitHub 标记为 Pre-release,安装器需要显式指定版本。 完整步骤见快速上手。

验证范围

生命周期与 UX 修改通过了 Claude Code Fable 5.1 / xhigh 两轮对抗性审查和完整本地 make check。隔离的 macOS arm64/HVF 环境验证了 U24 启动、扩容、控制节点到同伴的 SSH、stop/start、reload、recreate、部分状态失败和缩容;最终的 Guest SSH 作用域修复 另经真实 OpenSSH 有效配置测试验证。

Tag 工作流重复源码检查,并验证归档、软件包、SBOM、安装器、Formula、发布元数据和 校验和。这些结果不代表新增 Linux 宿主 VM 重放、宿主重启测试或完整 Pigsty 安装。

3.4 - Farrow 0.4.0:一条命令、能用的数据盘、统一的输出

首次运行只需一条命令,默认数据盘在所有镜像上可用,就绪失败直接给出原因,全部命令统一输出风格。

Farrow 0.4.0 是被 0.5.0 取代的公开 pre-1.0 发布。它把首次运行压缩为一条命令,修复了 Debian 与 Ubuntu 镜像上的默认数据盘,并让全部命令使用同一套输出风格。Pigsty Inventory 格式、 固定 IP Deployment 模型、状态布局与内嵌 Catalog revision 2026082903 均未变化。

变化

  • 在终端里,固定 IP 网络尚未安装时 farrow up 会自己执行 farrow setup:展示 setup 计划、在特权步骤前确认,然后继续。farrow init 的下一步提示改为 farrow up。
  • vm_disks[].fs 默认值改为 auto:空白磁盘在 Guest 有 mkfs.xfs 时格式化为 XFS, 否则为 ext4,与 Pigsty 的 Vagrant 流程一致。旧的 xfs 默认值在不带 xfsprogs 的 Debian 与 Ubuntu 镜像上会失败。按旧默认值创建的 Deployment 不会被报告为漂移,持久盘 也保持兼容。
  • Guest 的错误标记携带失败命令的最后一行输出,up 会报告 guest bootstrap failed during data-disks: xfs requested but mkfs.xfs is unavailable, 而不是只有退出码。
  • 生命周期命令与 status 打印节点表,up 成功后给出 next: farrow ssh <node>。 没有变化时 plan 与 validate 只打印一行;image list、network status、doctor 与预检错误使用没有机器码的自然语句;spec hash 等内部信息只在 --json 中出现。 未知节点名的错误会列出现有节点。
  • farrow ssh <node> -- 'df -h /data; id' 会把远程命令按 OpenSSH 的方式原样传递。

升级说明

由 0.3.0 或更早版本创建、/data 从未挂载的 d13、d12 或 Ubuntu 节点,运行一次 farrow recreate <node> 即可;这些镜像上磁盘会格式化为 ext4,Enterprise Linux 镜像上 为 XFS。在没有终端的自动化中,对未准备好的宿主机运行 up 之前仍需先执行 farrow setup --yes。

验证边界

源码 Commit 8ecb8476c7dbc934d8cbbee935ac53884d00fcdb 通过完整本地源码门禁:单测与 Race、Vet、Staticcheck、deadcode、errcheck、govulncheck、Shell 与模块检查、四目标 构建、镜像流水线与 Installer 边界、依赖许可证。Tag 工作流在公开 Release 前重复执行了 这些检查,并构建、验证了全部 Archive、原生 Package、SBOM 与 Installer。

新的首次运行路径(up 自动执行 setup)有单元测试覆盖,但本次发布前未在全新宿主机上 重放。带日期的 macOS arm64/HVF 与 Ubuntu amd64/KVM 证据仍列在状态页; 源码、打包、发布与真机证据继续作为独立门禁。

安装或升级

从 Farrow 0.4.0 GitHub Release 下载 Installer 与资产:

curl -fLO https://github.com/pgsty/farrow/releases/download/v0.4.0/install.sh
chmod +x install.sh
FARROW_VERSION=0.4.0 ./install.sh
farrow version
farrow doctor

同一 Pre-release 附带 Homebrew Formula 与 amd64/arm64 DEB/RPM 软件包。现有 Deployment 与 Catalog 状态仍可读取。

3.5 - Farrow 0.5.0:显式处置、显式仓库、可复现镜像

无需确认的整套实验室处置、全球与中国仓库显式选择、无隐藏工件回退,以及八目标官方镜像候选流水线。
说明

本页记录 0.5.0。0.7.0 已增加官方镜像源故障回退,未发布的 0.9 候选移除了 rm 别名。请按安装版本阅读当前命令行说明。

Farrow 0.5.0 是被 0.6.0 取代的公开 pre-1.0 发布。它为一次性实验室加入明确处置命令,让仓库地域 成为操作者的显式选择,并提供可复现的下一代官方 Guest 镜像准备路径。Pigsty Inventory 契约、Deployment 状态格式与内嵌 Catalog revision 2026082903 均未变化。

变化

  • farrow purge(别名 farrow rm)无需确认,删除完整 Deployment、持久数据盘、 Deployment 密钥与状态,以及默认 SSH Fragment;已校验镜像缓存与宿主全局网络仍然保留。 没有 Deployment 时幂等成功,无法证明身份的遗留节点工件仍会 Fail-closed。
  • Release 二进制默认使用 https://repo.pigsty.io/farrow。仅有长参数的 --mirror 选择 https://repo.pigsty.cc/farrow;优先级依次为 --repo、--mirror、FARROW_REPO、 全球默认仓库。两个官方根都保持规范的签名 Catalog 信任。
  • Catalog Upstream URL 只用于溯源,不再作为回退。选定仓库必须包含 Catalog 指定的准确 qcow2,否则拉取会失败,并提示显式选择其他仓库或导入本地镜像。
  • 源码新增 Debian 12/13、Rocky Linux 8/9 在 amd64/arm64 上的摘要锁定离线 Builder。 它记录准确软件包闭包、SBOM、Provenance 与 testing Manifest,并可组装未签名候选仓库, 留待真机 Smoke 与签名审查。
  • 固定的源码/发布工具链升级到 Go 1.27.1、GoReleaser 2.18.0、golangci-lint 2.13.2 与当前选定的 Go 模块版本。

镜像边界

八目标矩阵修复具体 Guest 前置条件:Debian 12/13 加入显式 XFS 数据盘所需的 XFS 用户态 工具;Rocky Linux 8 加入 /usr/bin/python3、有效的 SSH Drop-in Include 与干净网卡命名 状态;Rocky Linux 9 同样清理旧网络状态。

这些是 Candidate 构建输入,不是新发布的 Catalog 工件。每份结果在完成真机启动/就绪 Smoke、双构建比较、生产签名、上传与 Catalog 发布前,始终保持未签名和 testing。

升级与处置

从 0.4.0 升级无需迁移状态、Inventory 或 Catalog,现有缓存镜像仍可使用。新的下载默认走 全球仓库,除非用 --mirror、--repo 或 FARROW_REPO 选择其他根。

purge 刻意设计为无交互操作,会不可逆删除 Deployment 磁盘与密钥。若要保留持久盘或只 删除部分节点,请继续使用带确认的 farrow destroy。

验证边界

Release 源码 Commit fc85b65ff6a24b0933b56ae1179be9ada2ba91b1 已通过完整本地源码 门禁:模块与 Shell 检查、单测与 Race、Vet、Staticcheck、deadcode、errcheck、 govulncheck、四目标构建、模拟镜像流水线边界、Installer 测试与准确依赖许可证校验; GoReleaser 2.18.0 也接受了发布配置。

Tag 工作流会独立重复这些检查,并在公开 Pre-release 前构建、验证全部 Archive、原生 Package、SBOM、Formula、Installer、Release Metadata 与 Checksum。源码门禁不会自动继承 新的真机 VM 生命周期证据,也不代表镜像 Candidate 已发布。

安装或升级

从 Farrow 0.5.0 GitHub Release 下载 Installer 与资产:

curl -fLO https://github.com/pgsty/farrow/releases/download/v0.5.0/install.sh
chmod +x install.sh
FARROW_VERSION=0.5.0 ./install.sh
farrow version
farrow doctor

同一 Pre-release 附带 Homebrew Formula 与 amd64/arm64 DEB/RPM 软件包。

3.6 - Farrow 0.3.0:显式 Catalog 与可操作的就绪诊断

显式镜像 Catalog 更新、逐节点 Bootstrap 诊断、发行版原生 Guest 网卡名与更小的 CLI。

Farrow 0.3.0 是被 0.4.0 取代的公开 pre-1.0 发布。它移除隐式 Catalog 刷新,把 Guest Bootstrap 失败变成可操作的逐节点结果,并在不改变 Pigsty Inventory 与固定 IP Deployment 模型的 前提下简化 CLI。

变化

  • up、plan 与普通 image 命令只使用一份当前本地 Catalog 快照,绝不隐式获取 Catalog 元数据。farrow update 显式获取配置仓库;image sync 激活精确 URL 或文件。
  • Guest Bootstrap 原子写入失败阶段。部分操作报告每个失败节点、阶段与错误;就绪失败 会直接指向 farrow logs <node>。
  • 已运行 Guest 可在不重启 QEMU 的情况下复查。生命周期部分失败后,SSH 客户端配置仍会 根据全部 committed 节点重建。
  • Netplan 按确定性 MAC 匹配且不再重命名接口。vm_disks[].fs: auto 优先 XFS,必要时 回退到 ext4。
  • 删除冗余 ss 命令与含义模糊的根/参数短写;image reset 取代 reset-manifest,旧名称仍是别名。

验证边界

源码 Commit da6d02426da93c677c94c67fec4eb4fcecf4766a 通过完整本地源码门禁与 GoReleaser 全量 Snapshot:单测与 Race、Vet、Staticcheck、govulncheck、四目标构建、 镜像流水线与 Installer 边界、Archive/Package 一致性、依赖许可证、SBOM 和 Linux 原生 Package 校验。Tag 工作流在公开 Release 前重复执行了这些检查。

本发布不声称新增真机 VM Replay。带日期的 macOS arm64/HVF 与 Ubuntu amd64/KVM 证据 仍列在状态页;源码、打包、发布与真机证据继续作为独立门禁。

安装或升级

从 Farrow 0.3.0 GitHub Release 下载 Installer 与资产:

curl -fLO https://github.com/pgsty/farrow/releases/download/v0.3.0/install.sh
chmod +x install.sh
FARROW_VERSION=0.3.0 ./install.sh
farrow version
farrow doctor

同一 Pre-release 附带 Homebrew Formula 与 amd64/arm64 DEB/RPM 软件包。现有 0.1/0.2 Deployment 与 Catalog 状态仍可读取;Catalog 刷新从本版本开始始终显式。

3.7 - Farrow 0.2.0:选点收敛与发布完整性

VPN 感知网络预检、真正的选点扩容、基于 committed state 的集成、CI 多平台构件与 0.1.0 升级边界。

Farrow 0.2.0 是被 0.3.0 取代的公开 pre-1.0 发布。它保留 0.1.0 引入的 Pigsty Inventory 与 磁盘 Deployment 格式,同时修复最终真机重放中发现的网络与选点收敛边界。

主要变化

  • 10.0.0.0/8 等较宽 VPN 排除路由不再误拦 Farrow 自有的 10.10.10.0/24;相同或更具体的外部路由、重叠接口、已占用地址与自有路由缺失 仍然 Fail Closed。
  • farrow up <node> 只下载并准备选中的节点。Inventory 中没有 State 的 desired peer 显示为 absent;SSH/hosts/provision、UUID/端口分配、生命周期与持久盘校验 使用 committed 节点集合,同时保留后续扩容意图。
  • 新 Guest 写入 # farrow-deployment-host;添加当前 hosts 行前,会同时清理该标记 与 0.1.0 发布过的 # farrow-project-host。
  • 未发布中间版本中的命令取消、结构化输出、确认、reload、诊断脱敏、Installer 保留策略与依赖图精简,全部直接进入 0.2.0。

真机与发布证据

准确源码 Commit 在 MonoProxy 在线时完成 macOS arm64/HVF 重放:选点创建 u24-1、 SSH、stop/start、增量创建已缓存的 el9-1、两节点 SSH、五个显式 absent peer 与 whole destroy 全部通过。在 Ubuntu 26.04 amd64/KVM 上,当前 Linux 二进制无变更地 审计了一套现存四节点 Deployment,并进入控制 Guest。

本地 make check、源码 CI 与完整 Packaging Workflow 均通过。Tag Workflow 构建 四平台 Archive、amd64/arm64 DEB 与 RPM、SPDX SBOM、Homebrew Formula、Installer、 Checksum 与 Release Metadata。GitHub Actions 将这些已验证 CI 产物上传为草稿,经检查后公开;不附加应用 签名或 Provenance Bundle。

签名镜像 Catalog 仍为 Revision 2026082903,包含 9 个 Family 与 27 个分架构工件。 默认仓库继续使用 https://repo.pigsty.cc/farrow;repo.pgsty.com/farrow 是独立验收 通过的源站/备用入口,不是编译默认值。

安装或升级

从 Farrow 0.2.0 GitHub Release 下载 install.sh 与对应构件:

chmod +x install.sh
FARROW_VERSION=0.2.0 ./install.sh
farrow version
farrow doctor

0.1.0 Deployment State 可直接读取。保留 VM 在线时运行一次 farrow status,可收敛 任何发布前进程出生身份;现有 Guest 在重建时采用新的 /etc/hosts 标记。

Farrow 尚未达到 1.0,因此 GitHub 会把 0.2.0 标为 Pre-release。

3.8 - RC6 开发候选:Owner-scope Tier 1 交付

RC6 准确身份、四个要求的原生产品通过、Durable 网络事务、可复现本地 Archive,以及保持未发布的边界。
注意

Barn 之前的历史记录。本页保留前任候选的准确身份,不证明当前 Barn 二进制或路径。 当前边界见当前状态。

Piglet 1.0.0-rc.6 是单一 Native-QEMU 路径的 Owner-scope 本地开发候选。它在两条 Tier 1 宿主上关闭了要求的 Quick 与准确四节点 full 场景,并加入 Durable 特权网络事务。 它刻意不是公开 Release。

警告

没有执行 Homebrew 操作、公开 Tag、远端 Push、GitHub Release、Package Repo、生产签名、 Attestation 或支持承诺。下面 Hash 只标识保留本地 Artifact,本站不提供下载。

冻结身份

字段 RC6 值
Version 1.0.0-rc.6
Source Commit 7db733184463cc189ffa738335c213fc9a2982de
Go go1.27.0
Source Epoch 1787657920
Build Timestamp 2026-08-25T11:38:40Z
Channel development
Signature / Attestation false / false
准确 full Profile SHA-256 912fea61bf1602c2a437570561a6ab4d0a5a8c152695147ad9e96ae831bc9336

四个要求的产品场景

宿主 场景 结果 Guest 契约
macOS arm64 / HVF Quick PASS Ubuntu 24.04.4、dba UID/GID 88、2 vCPU、64 GiB 根盘、64 GiB /data
Linux amd64 / KVM Quick PASS 相同契约
macOS arm64 / HVF 准确 full PASS .10–.13、UID 88、64 GiB 根盘、128 GiB 数据盘、2/1/1/1 vCPU、四向互通
Linux amd64 / KVM 准确 full PASS 相同契约

最终八台 Full Profile Guest 全部报告 Ubuntu 24.04.4。断言完成后,项目通过 Piglet Destroy; 共享 Image Cache、Project Marker 与 Key 刻意保留。

Durable 原生网络

Network Install/Uninstall 现在使用一套 root-owned Strict-prefix Transaction:

  • Root Plan 返回与 Owner/Host/Prestate 绑定的 Token;
  • Apply 在宿主全局锁内重新规划,只接受该 Token;
  • 第一次修改前发布类型化、Fsync Journal;
  • 每个固定 Action 在验证准确 Postcondition 后 Checkpoint;
  • 中断后普通 Private 修改阻止,直到显式 Forward 或 Rollback Recovery Plan 单独经 Token 批准。

Darwin 完成真实中断 Forward Recovery,最终处于默认 Host Mode 的 Protected/Healthy 状态。 Linux 在最终 Adversarial Patch 前完成真实 Install、Rollback/Retry、四节点运行、Uninstall 与宿主 恢复。最终 Patch 关闭 Socket State 规范化、过宽 Systemd Enable、NetworkManager 顺序与 Field-scoped Recovery Effect 问题,随后通过整合 Source/Race Gate。

按 Owner 最终指令,最后 Patch 后没有再运行 VM 或网络测试。因此 Post-audit Linux Install/Uninstall/Reinstall Replay 明确为未运行;本页不会把 Source/Race Evidence 升格成 原生结果。

macOS Shared Mode 与子网冲突

受支持默认仍是 socket_vmnet Host Mode。Shared Mode 在证明空闲的替代子网上通过双节点契约, 但它是显式 Fallback,不是隔离边界。

历史默认子网失败为 VMNET_SHARING_SERVICE_BUSY (1009)。VirtualBox 是合理污染候选,但未被 证明为该事故 Owner。最终迁移前立即观察到的子网 Interface 是旧 Piglet 创建的 bridge100。 Preflight 现在按身份拒绝外部 Interface,不会因为 .1/24 地址匹配而接管。操作者可以移除已确认 Owner,或把整套实验室迁移到一份带 Warning 的规范 RFC1918 /24;Piglet 永远不会只修改 Guest 地址,也不会随机选择逃生子网。

可复现本地 Archive

两棵独立本地 RC6 输出均通过严格 Release Verifier,四个 Archive、Checksum、Release Metadata 与 Formula 字节一致:

Archive SHA-256
Darwin amd64 1295288ff198b53fcb761a6e8794087d75a46105fc19980fabcd44f0c70fb9ef
Darwin arm64 308310b0f2d179f98c8be78ea09f89d226167072c936387bc42d717a922ec0c6
Linux amd64 547a61f6cc0768071df349cbf5c17d7ddfe3ab3cea59e6b4026e3e3e616a5550
Linux arm64 afc9ce1043d377cc3b4ef8bdf77826a8139a8c839685025853e8bee8100c6a2e

Formula 只是惰性 Build Artifact。更早候选执行过离线 RPM/DEB Consumption 与临时 Cosign/SLSA Round Trip,但这些只属于机制证据,不能改名为 RC6 Publication/Signing。

公开 GA 仍需完成

  • 两条 Tier 1 的 Literal Reboot 持久性;
  • macOS amd64 与 Linux arm64 的当前原生 Smoke;
  • 刻意延期的 Linux 最终网络 Replay;
  • 剩余 Image Normalization、字节可复现决策、Hosting 与主备 Manifest Key Custody;
  • 生产 Release Identity、Signing/Attestation、公开 Homebrew/Linux Package 渠道与干净宿主消费;
  • 持久 Owner-operated macOS HVF Runner 与明确发布授权。

当前维护边界见教程、设计与 当前状态。

3.9 - 开发快照:Go 1.27 产品能力面

Quick 与四节点 Private 语义、Schema-3 自有 Profile、Pigsty Inventory 集成、持久化、状态迁移与已验证发布机制。
注意

Barn 之前的历史记录。本页名称、命令、路径、Hash 与结论只描述前任快照;当前行为以 Barn 状态和使用指南为准。

Piglet 的 2026-08-24 源码快照已经远不止最初的 QEMU Spike。它现在提供一套连贯本地 VM 产品: 零配置 Quick、固定地址私有实验室、13 份 Piglet 自有 Profile、可审计 Pigsty Inventory 边界、 显式持久化/状态迁移、诊断与可复现 Release Toolchain。

它仍是开发快照,不是稳定 Release。

说明

本页是 2026-08-24 历史快照。后续前任候选另行归档;两者都不是当前 Barn Release 证据。

警告

当前没有公开 v1.0 Tag、生产签名 Artifact、Homebrew Tap 或 DEB/RPM 仓库。所有内置镜像记录 仍为 testing。本地 Package 与签名 Round Trip 证明机制,不证明生产托管。

一套原生 Runtime

Piglet 在 macOS 通过 HVF、Linux 通过 KVM 直接驱动原生 QEMU,并负责严格 Spec Resolution、 镜像/qcow2 校验、纯 Go NoCloud CIDATA、QMP/进程身份、SSH 就绪、原子状态、Journal、Event、 Repair 与有界删除。QEMU 以调用用户运行,也不会静默回退 TCG。

没有第二 Provider/Runtime 路径,也没有任意 QEMU 参数逃生口。

两条 Tier 1 上的 Quick

保留的 Go 1.27 Quick 运行覆盖 macOS arm64 与 Linux amd64 公开无 YAML 路径。契约是 meta/dba、2 vCPU、4 GiB、64 GiB 根盘、稀疏 64 GiB /data、User NAT、SSH 与四条 回环转发约定。

产品支持 Plan、Up、Status、SSH/Exec、Stop/Start/Restart、漂移分类、受保护 Recreate/Destroy、 No-wait、持久盘保留、密钥退役、日志、Repair 与脱敏 Debug Bundle。

这些 Forward 不会安装应用;Pigsty/PostgreSQL Bootstrap 仍是独立集成门槛。

Private Lab 与宿主网络

Private 模式现在在两类 Tier 1 宿主上都有公开 Preflight/Status/Install/Uninstall。macOS 使用固定 socket_vmnet v1.2.2,默认 Host Mode,并有 Shared/FD 路径证据。Linux 使用可逆 systemd-networkd/NetworkManager/bridge-helper 事务。两者都让 QEMU 保持非特权,并在全局租约 活跃时阻止 Uninstall。

默认 10.10.10.0/24 可以被一个显式规范 RFC1918 /24 替代。Profile、宿主 Install、租约、 状态、节点地址与 Pigsty Inventory 必须一起迁移,不会随机选择冲突逃生网段。

保留的四节点 full 与 MinIO 运行在两个 Tier 1 路径验证固定 IP、控制节点独占横向 SSH、管理 互联网、存储身份、Stop/Start 持久与干净 Destroy。更早运行还覆盖 Crash Recovery 与 30/30 Soak。MinIO Profile 运行验证的是 16 块 VM 数据盘,不是 MinIO 应用。

Schema-3 自有 Profile 与 Pigsty Inventory

13 份内置 Profile 共 85 个节点,全部使用 dba。普通节点一块 128 GiB /data;MinIO 节点 四块 32 GiB 磁盘。Catalog Schema 3 自有管理 Scalability、Image Policy 与 Pigsty Inventory Binding,并包含 Direct 与 build_subset Mode。

piglet pigsty inventory 读取真实 Pigsty Source Tree,对 Host/VIP/Admin/Service Address 语义分类 校验,Rebase 协调自定义子网,并可原子发布 0600 Marker-owned 输出。pigsty-vm 通过一组小型 类型化环境变量暴露同一 Profile、网络、生命周期与 Inventory 契约。

Wrapper 没有 Provider Fallback。运维回滚是上一版已验证 Piglet Artifact 与匹配 State Backup。

持久化、升级与自动化

标记 persistent: true 的磁盘会在普通 Destroy 与兼容 Recreate 后保留。当前安全契约要求 独立 TTY Phrase,或 destroy --force --delete-persistent --yes-delete-persistent;项目密钥有独立默认 Dry-run 的 project purge-keys --yes 边界。

Schema 0→1 迁移只允许停止、要求无租约、先备份、原子并显式通过 project upgrade-state --dry-run|--yes 执行。更高 Schema 会拒绝,不会降级。

Private 节点 Selector、--no-wait、稳定 JSON、类型化退出码、Shell Completion、SSH Config、 Marker-owned Hosts Block、逐节点日志与脱敏 Support Bundle 构成当前操作者/自动化界面。

镜像与 Release 机制

内置正式镜像集合是 el9、el10、d12、d13、u22、u24、u26,覆盖两个 Tier 1 原生架构。保留矩阵记录每个架构报告 7/7;EL8 因 arm64 Kernel 无法满足已测试原生 HVF 契约而 退出 v1。生产镜像渠道与托管责任落实前,条目继续保持 testing。

源码可以构建并校验四种原生 Archive、Homebrew Formula、Linux amd64/arm64 RPM 与 DEB、 Checksum、SPDX SBOM、组合 Release Assembly,以及 Cosign Signature/SLSA Provenance 正向与 Tamper 测试。测试快照的隔离 Package Install/Verify/Remove 与两轮可复现通过;已检入 Release Workflow 尚未针对真实 Tag 执行。

证据必须跟随准确字节

在该快照时间点,Catalog Schema 3 与 Inventory 集成晚于已保留 full/MinIO 运行,因此准确 当前 Profile 仍需原生刷新;自定义子网 Hosts 发布、落实 storage.data_root/ ssh.wait_timeout 与通用 Quick User 也仍开放。

RC6 后续关闭了这些实现与准确 Profile 缺口。历史原生运行仍只对自身真实执行过的字节与行为 有效。

v1.0 前仍需完成

该快照中的准确 Profile、Pigsty Bootstrap 与 Rocky 9.8 Private-host Gate 后续已经运行。当前 剩余门槛是生产 Image/Manifest/Release 托管、持久 Runner Ownership、真实 Reboot Recovery、 Tier 2 原生 Smoke、已发布 Package 消费,以及真实签名/证明 Tag-bound Release。

当前维护边界见教程、设计与 当前状态。