这是本节的多页打印视图。 .
Barn 文档
1 - 开始使用
安装 Barn 后,新用户只需按快速上手启动测试环境:
没有配置文件且没有已有部署时,交互式 up 会生成默认配置;它也能准备缺少的宿主依赖与网络。重复执行
barn up 可重试未完成的客机初始化,不会重启已经健康运行的 VM。无人值守时,
先执行 barn setup --yes,再执行 barn up。
公开软件包状态见当前状态;开发者与源码审查者可使用 从源码构建。
其余内容按任务拆开:
1.1 - 快速上手
安装
通过 Homebrew 安装当前的 Barn 0.9.0 开发版:
Homebrew Formula 会从主分支源码构建 CLI 与 hosts 文件 helper。也可以手动从源码构建。
发行包
0.9.0 发行包尚未发布。发布后,用户级安装器支持 macOS/Linux 的 arm64/amd64, 校验归档摘要,安装自身无需 sudo:
默认安装目录为 ~/.local/bin;请把相同 PATH 设置写入 Shell 配置。
发行构建应显示 0.9.0。预发布版本不会出现在 GitHub 的 /releases/latest,
请显式设置 BARN_VERSION=0.9.0。
下载问题见下载与 PATH。
发布时还会提供 DEB 与 RPM 包。以下示例使用 amd64;ARM64 使用对应的 linux_arm64 文件。
下面的宿主要求针对 Linux 客机。macOS 客机使用独立的 barn mac。
宿主要求
| 宿主 | 原生加速 | 最低 QEMU 版本 |
|---|---|---|
| macOS arm64 / amd64 | HVF | 8.2.1 |
| Linux amd64 / arm64 | KVM | 6.2 |
宿主还需要 qemu-img、OpenSSH 与所选客机对应的固件。交互式 up 可以通过 macOS 的
Homebrew,或受支持 Linux 发行版的 apt/dnf 补齐依赖,并安装固定 IP 网络。宿主软件包与
网络变更可能需要 sudo;Barn 本身应以普通用户运行。Linux 需要可用的 KVM,以及
NetworkManager 或 systemd-networkd。带日期的真机验证覆盖 macOS arm64 与 Ubuntu amd64,
其他构建平台的验证范围较窄,详见当前状态。
启动第一个实验环境
首次部署时,在终端中进入一个空目录:
用 exit 从客机返回宿主终端后,再执行后续 Barn 命令。
没有配置文件、也没有已应用部署时,交互式 up 会生成只有一个 meta 节点的
barn.yml,准备缺少的宿主依赖与网络,下载并校验镜像,启动 QEMU,然后等待管理 SSH
就绪。宿主变更会显示出来,sudo 可能要求输入密码。如果希望先查看完整宿主计划,运行
barn setup --dry-run。
换目录不会新建一套实验环境。状态位于 $BARN_HOME,默认是 ~/.barn。
如果已有部署且当前目录没有配置文件,up 会继续该部署;可先用 barn status 查看。
默认模板解析为:
| 配置项 | 默认值 |
|---|---|
| 节点 / 固定 IP | meta / 10.10.10.10 |
| 客机镜像 | Ubuntu 24.04,u24:stable,与宿主相同的架构 |
| 登录用户 | dba,使用 SSH 密钥认证 |
| CPU / 内存 | 每节点 2 vCPU / 4 GiB |
| 根盘 / 数据盘 | 64 GiB 根盘 + 挂载到 /data 的 128 GiB 非持久数据盘 |
磁盘大小是虚拟容量,qcow2 文件随写入增长。四节点环境共配置 8 vCPU、16 GiB 客机内存,
还需为宿主保留资源;启动前可用 barn plan 查看总量。
首次使用、尚未编辑且采用默认网段的内置模板遇到子网冲突时,setup 可以改用可用的私有 /24;若模板文件
已经存在,会备份为 barn.yml.before-network-change。请以生成后的 barn.yml 和
barn status 为准。显式 -f 文件、编辑过的模板与已有部署会保留选定网段。
健康的首次启动会以类似结果结束:
barn ssh 默认连接控制节点,在此模板中就是 meta。也可以显式指定节点,或直接执行命令:
st 是 status 的别名;
其中的 running 表示 VM 进程在运行,不代表刚刚重新检查了客机就绪状态。
继续未完成的初始化
重复 barn up 可以接续中断的操作、重试未完成的客机初始化、更新旧的客机脚本。
健康的运行中 VM 会保留进程与根盘。管理 SSH 可用时,即使共享目录只读、私网不可用等功能
受限,客机仍可完成启动。请查看这些提示;自动化应检查 barn up --json 的
nodes[].warnings 与 nodes[].repairs,因为这些限制仍返回退出码 0。
数据盘是可丢弃的测试存储。up 可能清空重建无法识别或确认损坏的文件系统,
包括持久盘,并报告旧数据已丢弃。persistent 只控制 destroy/recreate 时保留磁盘,
不保证恢复时保留损坏的内容。详见数据盘说明。
--no-wait 会跳过客机就绪、恢复与元数据刷新,后续执行 barn up 补齐。
镜像下载支持重试与断点续传;使用 barn up --mirror 优先访问中国官方仓库。
镜像选择与回退规则见镜像仓库。
启动前选择配置
这是前面自动启动流程的另一种入口。在新的实验目录中,先生成并检查配置,再启动:
对于本文使用的 Catalog 镜像,init、validate、plan 都不要求先安装 QEMU
或配置宿主网络。规划已注册的 local-* 镜像时,则需要 qemu-img 校验缓存字节。默认 meta 配置为:
内置四种模板:
| 模板 | 节点数 | 默认地址 |
|---|---|---|
meta |
1 | 10.10.10.10 |
dual |
2 | 10.10.10.10–10.10.10.11 |
trio |
3 | 10.10.10.10–10.10.10.12 |
full |
4 | 10.10.10.10–10.10.10.13 |
例如 barn init full 生成四节点配置,barn init full -c 10.20.30.0/24 指定另一网段。
现有文件不会被覆盖,除非显式传入 --force。在第一次 up 前调整 vm_cpu、vm_mem、
vm_image 等字段,全部字段见配置参考。
显式准备宿主
setup 只准备依赖与网络,不启动 VM:
与 up 内部的准备流程不同,单独执行 setup 会在应用有变更的计划前请求确认。
它会复用当前目录发现的配置,没有文件时生成 meta。可选的 /etc/hosts helper
仅在 barn hosts install --yes 需要时安装;普通启动与 barn ssh 不依赖这项集成。
下载尊重 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY、NO_PROXY 及其小写形式。
无人值守的首次部署可在空目录执行:
setup --yes 本身就能生成配置,只有需要预先编辑时才必须单独 init。自动化环境仍需为
必要的 sudo 操作准备凭据;--yes 不会提供管理员凭据。
自动化教程说明如何保存命令结果、检查客机限制后再继续。
使用现有 Pigsty 配置
Barn 读取已记录的 VM、命名与登录字段,其余 Pigsty 参数保持原样。以上步骤启动虚拟机; PostgreSQL 与其他 Pigsty 服务仍需通过 Pigsty 单独安装。内置模板只描述 VM 拓扑, 不包含完整的 Pigsty 服务配置。 衔接方式见自动化与客机脚本, 文件传输与服务连接见存储与访问。
扩容与日常操作
扩展默认单节点环境时,保留已有设置,在 barn.yml 中增加三台主机:
此例假定使用默认网段;如果 setup 选择了其他网段,所有地址及 admin_ip 都应沿用该网段。
不要为了扩容而用 init --force 覆盖已经定制的配置。
仅增加这三行时,计划应列出三个待创建节点。up 会创建它们,保留正在运行的 meta
进程,并刷新客机 hosts 与控制节点 SSH 配置。健康的结果为 4 nodes ready。
0.9.0 内置 Catalog 将 u24:stable 解析为 u24@20260926.0.0;手动更新 Catalog 后
可能解析为其他版本,准确版本显示在 plan 和 status 中。
修改 CPU、内存或其他被读取的 VM 字段,需要显式执行 barn recreate <node>;
删除 YAML 条目不会删除 VM。停止并恢复环境,不重建磁盘:
使用完毕后销毁部署:
在终端输入 destroy 确认。根盘与非持久数据盘会被删除,镜像缓存、密钥、声明为持久的
数据盘与宿主网络保留。彻底清理见卸载与清理环境;重启、日志、显式变更与
缩容见日常管理。
barn update 只更新镜像 Catalog。安装 Barn 程序请使用本页开头的 Homebrew 或源码构建方式;
发行包将在 0.9.0 发布后提供。
1.2 - 日常管理
本教程描述 Barn 0.9.0 发布候选。发布与验收边界见当前状态。
检查与访问
应用状态默认位于 ~/.barn(可由 BARN_HOME 覆盖),这些命令可在任意目录执行。
切换工作目录不会创建另一套 deployment。
Status 默认显示镜像和资源;--verbose 显示架构、加速器、SSH 端口和 PID,
TCG 在普通输出中也明确标记。异常节点不会隐藏其他节点的状态。
barn up 会在选中 VM 启动后,根据完整 applied deployment 重建默认 SSH 别名;因此
局部 up 不会删除未选中节点,可直接运行 ssh meta;如需手工重写,使用
barn ssh-config --install。
plan、up、reload、recreate 依次优先使用 -f、当前目录发现的 Inventory,
两者都没有时才回退到已应用规格;validate 始终需要文件。
再次执行 up 会重试未完成的客机初始化、原位更新旧脚本,健康 VM 无需重启。结果会列出
可选功能限制,JSON/YAML 提供 nodes[].warnings 与 nodes[].repairs。不可用的测试
数据文件系统可能被清空重建,包括持久盘,详见数据盘说明。
停止与启动
start 启动已停止的 VM 并复查运行中 VM 的就绪状态;start 与 restart 都使用已应用
状态,并刷新 SSH 别名,包括重新分配的自动端口。reload 先读取 Inventory、检查配置变化与启动依赖,再停止选中节点
并执行完整的 up 路径。
up、start、restart、reload、recreate 还会刷新运行中 guest 的 Barn hosts
和控制节点 SSH 条目。--no-wait 跳过就绪检查、客机恢复与 guest 刷新,后续运行 up 补齐。
变更 deployment
plan 规划 Catalog 镜像时无需先准备宿主,展示镜像、资源总量、变更原因与磁盘影响;
规划导入的 local-* 镜像还会校验缓存,需要 qemu-img。CPU/内存等定义
变化仍通过 recreate 应用,会替换根盘与非持久数据盘,持久盘保留。若多个节点同时
变化,局部重建受未选节点影响时会提前拒绝,并列出所需节点。
recreate 与 destroy 在终端上展示磁盘范围并要求输入确认词;--force 跳过提示,
无终端时必须显式传入。
| 字段 | 含义 | 操作 |
|---|---|---|
create |
配置有、状态无 | barn up |
recreate |
VM 定义改变 | barn recreate <node> |
missing |
状态有、配置无 | 恢复配置,或显式 destroy |
删除 YAML 永远不会删除 VM。未消费的 Pigsty 变更得到 action:none;命名与
node-admin 字段虽然不以 vm_ 开头,仍会被消费。成功的 recreate 也会刷新完整 SSH
fragment。
并发命令(0.9 候选版)
修改 deployment 的命令会等待其他 Barn 操作释放锁,最长十分钟,同时受命令自身
超时限制。等待信息会显示持锁命令、PID 与开始时间。等待超时返回退出码 4,JSON
为 error: conflict、reason: deployment_busy;持锁操作完成后再重试。
持锁进程退出时锁自动释放;不要通过删除锁文件打断仍在运行的操作。
status、ssh、exec、ssh-config,以及 hosts 读取部署状态的步骤不会排队等待
这把锁,而是读取已写入的状态。其他命令持锁时,status 会附带 note,并且不会
收敛该命令正在进行的状态转换。因此尚在启动中的 VM 可能暂时无法 SSH。
销毁
--delete-persistent 与 --purge 只适用于整体销毁,不能和节点选择器一起使用。
--purge 删除持久盘、密钥和 deployment 状态,但保留镜像。节点级 destroy 会刷新
剩余节点的 SSH fragment,整体 destroy 会移除默认 Barn SSH 集成。宿主网络单独卸载,
仍有 VM 挂接时会拒绝。
barn purge 是一次性实验室的简洁路径,等价于
对已有部署执行 destroy --force --purge。它不接受节点选择器,没有 Deployment 时
幂等成功,保留镜像缓存与
宿主网络,同时不会绕过进程身份、属主和路径完整性检查。
**0.9 候选版:**没有 deployment 时,普通 destroy 直接成功。状态已删除但还有
归属明确的持久盘时,使用 purge;destroy --delete-persistent 或 destroy --purge
会提示改用该命令。旧的 rm 别名已移除,必须写出 purge。
1.3 - 故障排查
本页描述 Barn 0.9.0 发布候选。使用版本相关说明前,请先检查 barn version。
先收集诊断信息(status 可能收敛中断的运行时状态):
下载与 PATH 问题
安装器从 GitHub Release 下载程序;--mirror 选择的是 Barn 镜像仓库,不会重定向安装器
下载。如果访问 GitHub 需要代理,在终端将 HTTPS_PROXY 或 ALL_PROXY 设置为已有代理的
地址。macOS 系统代理设置本身不会替命令行工具配置这些环境变量。
用户态安装器默认写入 ~/.local/bin。安装后找不到 barn,或版本仍旧时,检查当前使用的
程序路径:
Homebrew 或系统软件包安装应使用对应渠道的程序。CLI 与配套 barn-hosts-helper 应来自
同一 Release,并保留软件包规定的相对位置。
找不到 Inventory
尚无部署时,交互式 up 可以生成首份默认配置。显式使用配置时,在
barn.yml/pigsty.yml 所在目录运行 plan、up、validate,
传入 -f /path/to/file,或运行 barn init 生成一份。状态存在后,plan、up、
reload、recreate 可回退到已应用规格;status、start、stop、SSH 与 destroy 始终使用
已应用状态。如果 status 报告 no deployment state found,说明所选 BARN_HOME
没有已应用部署,可能是首次使用,也可能已执行过 purge。
setup 需要 sudo
提示前一行会说明具体宿主变更;特权步骤开始时 Barn 会直接把交互终端交给 sudo。
--yes 只接受 setup 计划,不会绕过 sudo 认证。自动化环境需要已有凭据或合适的
NOPASSWD 策略。可以先用 barn setup --dry-run 查看计划。
macOS setup 会在请求管理员认证之前准备固定版本的 socket_vmnet 来源,下载失败不会
要求密码。**0.9 候选版:**setup 计划明确说明 sudo 用途与 socket_vmnet 来源;若首次
确认后自动选择的子网改变,会再次确认,除非已经传入 --yes。
原生加速或兼容运行时不可用
原生路径需要 macOS HVF 或 Linux KVM。只有显式外来 vm_arch 或内置镜像/宿主兼容规则
才会选择 TCG;任意原生失败绝不会静默回退。Homebrew QEMU 包含两个 System Emulator;
Linux setup 只安装宿主原生家族,因此外来 Guest 还需要对应 qemu-system-* 与固件。
plan 解析 Catalog 镜像及目标运行时时无需安装 QEMU;导入的 local-* 镜像仍需要
qemu-img 与有效缓存。up、recreate 在变更 VM 资源前检查
所选模拟器与固件。TCG 性能结果没有参考意义。
网络是 partial 或 invalid
完整但未激活的 Barn 网络可由交互式 up 恢复;对于 partial 或 invalid 安装,
不要手工删宿主文件,先查看受控清理计划:
未加 --yes 的 JSON 输出只展示删除计划;网络计划仍可能需要 sudo 读取受保护的
归属状态。核对计划后,使用 barn network uninstall --yes 执行。0.9 候选版:
普通终端输出会询问 [y/N],确认后立即执行。Linux bridge smoke 失败会自动回滚安装;
只有出现 automatic rollback failed 才表示必须人工检查。
macOS 的 /var/log/barn-vmnet 缺失或权限过紧时可以修复。查看 network status
的诊断,预期为 root:wheel 0755 目录。barn setup 能修复归属可确认的安装;
手工修复时使用诊断给出的准确命令。符号链接、错误属主或组/其他用户可写目录不会自动
修复。不要仅凭桥接接口名称判断路由冲突。
Linux bridge helper 失败
Debian/Ubuntu 使用 root:<调用者可用组> 4750。桌面系统通过 ACL 获得 /dev/kvm
权限时,调用者不必静态加入 kvm 组。
plan 报 recreate 或 missing
recreate 表示节点定义已改变:先用 barn plan 查看,再运行 barn recreate <node>。
终端上该命令会要求输入 recreate 确认,无终端时必须传入 --force。missing 只是报告:
恢复主机条目,或运行 barn destroy <node>。
节点未就绪
就绪要求管理 SSH 可用且客机实例身份一致。节点无法创建、启动或连接时,节点级部分 失败结果会指出节点和阶段,并以 5 退出。缺少宿主能力、Inventory 冲突等全局失败则使用 各自的退出类别。先查看日志:
数据盘、共享目录、主机名、guest hosts、控制节点 SSH 与私网分别初始化,一项失败不会
阻止管理 SSH 或其他步骤。客机可用时返回 0,并列出具体限制;JSON/YAML 通过
nodes[].warnings 暴露这些问题。访问互联网不是就绪的前提。
| 功能限制 | 下一步 |
|---|---|
| 数据盘不可用 | 处理设备暂缺、探测、工具、挂载占用或 I/O 问题,再执行 up |
| 共享目录只读 | 修正宿主权限,再执行 up 重试可写挂载 |
| Guest hosts 或控制节点 SSH 未完成 | 执行 up 刷新托管文件 |
| 私网网卡不可用 | 检查 barn network status 后再次 up;管理 SSH 仍可能可用 |
修正原因后重复 up:它会重试未完成步骤、原位更新旧客机脚本、跳过健康步骤,不重启
运行中的 VM。无法识别或确认损坏的测试数据文件系统会自动清空重建,包括持久盘,
结果会报告旧数据已丢弃。探测失败、忙碌挂载和 I/O 故障不会触发格式化。详见
数据盘说明。
重复 up 也可清理能够确认归属的中断准备残留。--rollback 在同一次运行中清除 prepare
失败的产物,并在 rolled_back 中列出。--no-wait 在 QEMU 运行后即返回,跳过就绪检查、
客机恢复与元数据刷新;后续执行 up 补齐。
SSH 失败
Barn 在启动时会从完好的原私钥恢复缺失的部署公钥。若私钥丢失,需要从备份恢复同一把私钥;Barn 不会为已有 VM 生成替代身份。
这是宿主侧派生公钥的恢复,与控制节点中缺失的 Guest 私钥是两种情况。
up 也会检查当前安装的 Guest key:文件缺失时报告 control-ssh 限制,管理 SSH
仍可使用。恢复原 Guest key 后执行 up 会清除限制;向旧 Guest 自动重新注入私钥
仍是待完成的功能。
检查 barn status、barn ssh-config 与串口日志。Barn 自身 SSH 使用回环管理端口;
Ansible 直连固定 IP。
若已停止 VM 的自动分配管理端口被其他进程占用,下次启动会选择空闲端口并刷新 SSH 别名;
运行中的 VM 保留原端口。SSH 主机密钥信任按 VM 实例 UUID 区分,重建 VM 无需删除无关的
known-host 条目;同一实例的密钥变化仍会校验失败。
doctor 的通用可用性扫描会排除已应用部署保留的固定 IP;up 与 start 仍会拒绝
已经接受 SSH 的新增节点或已停止节点地址。
0.9 候选版:~/.ssh/config 为符号链接或硬链接时不会被改写;Barn 会生成
fragment,并给出需要通过 dotfile 管理器添加的 Include 行。若 barn ssh meta
可用但 ssh meta 不可用,应先检查 Include,不要更换 Guest 密钥。ssh/exec
会在含数字或 - 的参数匹配近似节点名规则时拒绝执行并给出建议;需要明确区分节点
选择器与远程命令时
使用 --。
Catalog 或镜像校验失败
当前二进制已内置 active 与 standby Catalog 公钥。未知签名者、版本回滚/同版本异内容、
工件尺寸/SHA 不符、qcow2 结构不安全属于不同完整性错误。使用正确签名仓库,或通过
barn image import --sha256 ... 导入;不要直接向 ~/.barn/images 复制字节。
命令被中断
先确认是否仍有其他 Barn 命令运行。0.9 候选版的 status 不排队等待,
其他命令持有部署锁时会读取已写入状态并显示 note。应先等待该命令结束,再判断
中间状态是否属于异常中断。
没有操作持锁时,运行 barn status。可证明存活或死亡的运行时会按记录的完整身份
收敛;歧义进程继续阻塞。不要只凭状态文件里的 PID 就杀进程。
0.9 候选版还支持以下恢复:
| 中断场景 | 恢复步骤 |
|---|---|
| 宿主重启或 QEMU PID 被复用 | status 确认 PID 属于无关进程后将原 VM 标记为停止,再用 start 启动 |
stop 中断,QEMU 仍在运行 |
status 恢复运行状态;仍需关机时再次执行 stop |
首次 up 在准备阶段失败 |
修正 Inventory 后再次执行 up -f /path/to/barn.yml,只回滚日志记录的未完成产物 |
destroy 执行到一半中断 |
使用相同的显式销毁范围重试;中间状态与已保留的持久盘都可继续处理 |
如果恢复仍然失败,请保留状态与日志,不要删除节点目录或改写 PID 来模拟恢复成功。
如果记录的 QEMU 进程仍存在,但 QMP Socket 缺失,应先保留证据并查看串口/QEMU 日志,
再决定是否用 stop 收敛。不要手工删除运行时 Socket 或状态文件。
**0.9 候选版:**通用错误信封的 error 字段使用稳定类别,另有可选的 reason、
next 与 command 中的外部程序详情;部分命令返回自身的诊断报告。根据原因与下一步
提示处理,不要把人类可读文本当作
接口解析。退出码与结果处理见自动化。事件与 QEMU 日志按易读记录
展示,需要完整 QEMU 参数时加 --verbose。
提交问题时请包含准确命令与退出码、barn version、上面三份 JSON、宿主系统/架构与
QEMU 版本。
1.4 - 自动化与客机脚本
本文示例以 Barn 0.9.0 发布候选为准。
宿主命令应由拥有部署的普通 Unix 用户运行。每次调用使用同一份 Inventory 和
BARN_HOME;切换工作目录不会创建独立实验环境。
准备可预测的实验环境
第一次部署时,先生成并审查配置,再交给自动化运行:
将选定的配置纳入版本管理。显式设置 vm_image;如果更新 Catalog 后创建的新节点
也必须使用同一镜像,可固定为 vm_image: u24@20260911.0.0。
显式 -f 还会禁止首次 setup 自动把未编辑的默认模板迁移到其他子网。
审查宿主计划后,执行一次宿主准备:
--yes 表示接受 setup 计划,不会提供 sudo 凭据。无人值守执行环境必须提前具备
必要的宿主依赖、网络与权限策略。非交互式 up 不会执行交互式首次宿主准备,
up 也没有 --yes 参数。
使用自定义镜像仓库时,setup 与 up 应传入相同的 --repo;规划前先用
barn update --repo URL 显式激活该仓库的 Catalog,详见镜像仓库。
不只检查退出码
Barn 将结构化结果写到 stdout,诊断写到 stderr。保留两种输出与命令退出码,
避免后续 Shell 命令覆盖需要检查的状态。下面是额外依赖 jq 的 Bash 示例:
此处 jq 要求每个返回节点均已就绪,且没有功能限制或已报告的修复动作。
客机可用但可选数据盘、共享或节点间 SSH 失败时,Barn 仍可能返回退出码 0,
并在 nodes[].warnings 中列出限制。nodes[].repairs 可能报告已丢弃测试数据的
文件系统重置。应根据工作负载选择验收策略,而不是忽略这些字段。顶层 warnings
还可能描述可选 SSH 集成或元数据刷新失败。jq -e 检查失败会向调用方返回非零状态。
下一步依赖客机就绪时,不要使用 --no-wait。status --json 是 VM 状态与缓存警告
的快照,不是新一轮客机就绪测试。用 up 补齐初始化;如果流程依赖某个服务,
还需在客机内执行相应的应用检查。
失败与版本边界
结合命令行退出码与具体命令的结果结构判断。
部分失败可能保留已经成功的节点;重试前查看结果中存在的 nodes 或 failures。
0.9 候选调整了一些错误分类。例如首次缺少配置、未知镜像均为 usage/2;
recreate_required 与 nodes_removed 是 conflict/4 下的 reason。
它还使用有上限的锁等待,超时报 deployment_busy。
不是每个失败命令都返回通用的 error/message 信封:doctor、network status、
provision 与 SSH 执行可能返回各自的报告。ssh/exec 透传远程退出状态,
包括 OpenSSH 的 255。结构化执行结果应检查 success、exit_code、stdout
与 stderr,不要把远程退出状态当成 Barn 错误分类。
执行单条命令或脚本
显式指定节点,用 -- 分隔远程命令:
多个客机需要执行相同检查时,将以下 Bash 脚本保存为 check-lab.sh:
然后在选定节点运行:
不带节点选择器时,provision 面向所有已提交节点;这些节点必须已运行。
它不会创建或启动 VM。宿主脚本必须是非空、非符号链接的普通文件,最大 4 MiB。
Barn 将同一份已验证的脚本快照流式传给客机 Bash,记录 SHA-256,不会在客机留下
脚本文件;宿主脚本无需可执行权限。
默认串行执行,--parallel 可设为 1 到 4。--timeout 默认为一小时,
是整个操作的期限,最大 24 小时。--sudo 在客机使用 sudo -n,无法提示输入密码。
结果包含 results[]、各节点 stdout/stderr 与退出码,以及 successful/failed
计数。部分失败时,已经成功的变更可能保留。脚本应允许安全地重复执行;Barn
不会回滚客机命令,也不会在下一次 up 自动重跑该脚本。
provision 同时有成功与失败目标时退出 5;只有一个失败目标时,透传其大于零且不为
255 的远程状态。其他全部失败的情况退出 1,具体客机/SSH 状态见 results[].exit_code。
与 Pigsty 一起使用
Barn 与 Pigsty 可以读取同一份 pigsty.yml,但 barn init dual 只生成 VM
拓扑,不会配置 PostgreSQL 集群。应从当前 Pigsty 仓库合适的服务配置开始并审查:
Barn 准备客机管理员与控制节点 SSH 访问。检查配置和客机连通性后,再通过 Pigsty 部署服务。验证记录区分了 Ansible 连通性检查与 完整 Pigsty 安装。宿主文件传输与端口隧道见存储与访问。
1.5 - 存储、文件与服务访问
本教程使用 Barn 0.9.0 发布候选的接口。执行客机内检查之前,
先完成快速上手。示例使用 meta 节点与默认子网;调整已有配置时,
请沿用实际节点名称与地址。
创建 VM 前选择磁盘
每个节点默认有 64 GiB 根盘,以及挂载到 /data 的 128 GiB 非持久数据盘。
vm_disk 以 GiB 设置根盘大小,vm_disks 替换整个数据盘列表;
vm_disks: [] 表示不配置额外数据盘。
新建单节点实验环境时,将以下内容保存为 storage.yml:
审查配置,然后创建:
size: 64 表示 64 GiB;数据盘也可写成 size: 64GiB。这些是虚拟容量,
不是立即占用的宿主空间;qcow2 文件增长时仍需关注宿主剩余容量。
fs: auto 在客机具备 mkfs.xfs 时优先使用 XFS,否则使用 ext4。
VM 进程启动成功不代表数据盘已挂载,请检查客机结果与警告。
此例用于首次创建。如果同名节点已经存在且定义不同,up 会报告漂移。
检查 plan 并备份所需数据后,才能显式执行 recreate;它会替换根盘与非持久数据盘。
各种操作会保留什么
| 操作 | 根盘与非持久数据盘 | 持久数据盘 |
|---|---|---|
stop 后 start,或 restart |
保留 | 保留 |
健康状态重复 up |
保留 | 保留 |
规格兼容的 recreate |
替换 | 保留并重新挂载 |
普通 destroy |
删除 | 保留 |
整套部署 destroy --delete-persistent |
删除 | 删除,包括已保留的磁盘 |
整套部署 purge |
删除 | 删除,包括已保留的磁盘 |
保留盘复用依赖磁盘身份和兼容的规格。再次使用时应保持节点、挂载路径、大小和 文件系统定义一致。它不是自动扩容、改名、文件系统转换、备份或快照功能。 Barn 会拒绝不兼容的保留盘,不要通过手改状态文件强行挂载。
持久盘仍然是可丢弃的测试存储。 客机恢复期间,up 可能清空重建无法识别或
确认损坏的文件系统,并报告数据丢弃。持久性只控制 VM 销毁/重建时的保留行为。
缺少设备、探测失败、挂载点忙碌和 I/O 错误不会触发格式化。
测试故障恢复之前,应将有价值的数据另行保存。
新格式化的数据文件系统由 root 拥有。下面的写入检查使用客机 sudo;应用所需的目录权限 应另行明确配置。在已创建的环境中,可以验证普通重启的数据保留:
这只检查 VM stop/start,不是物理宿主重启后的持久性验证。 原生验证范围见当前状态。
使用管理 SSH 连接传输文件
从运行中的部署生成独立 OpenSSH 配置:
生成的片段包含当前回环 SSH 端口、部署密钥路径与实例主机密钥身份。
重建 VM 或管理端口变化后,应重新生成。如果希望普通 SSH 配置也能使用这些别名,
可选用 barn ssh-config --install;上面的 -F 用法无需这项集成。
导出的配置只引用部署密钥,不会内嵌或导出私钥内容。
访问客机内的服务
宿主可以通过客机固定 IP 访问监听在该地址上的服务,前提是客机防火墙与服务配置允许。
例如 10.10.10.10:5432 上的 PostgreSQL 服务需要另外安装;Barn 启动 VM
不会自动安装 PostgreSQL。
如果服务只监听客机回环地址,可以使用刚才生成的 OpenSSH 配置建立隧道:
保持该宿主终端打开,再让本地客户端连接 127.0.0.1:15432。
客机服务必须已经监听 5432。Ctrl-C 关闭隧道;如果宿主 15432 已占用,请换一个本地端口。
显式绑定回环地址,使此示例仅供本机访问。
Inventory 没有 vm_ports 或 vm_forwards 字段,未知 vm_* 会被拒绝。
请使用固定 IP 网络或 OpenSSH 转发。管理 SSH 使用独立的回环连接,固定 IP
网络报告限制时,管理连接仍可能可用。
Linux 宿主目录共享
Linux 宿主可以在首次 up 前配置只读共享:
将其放入目标主机变量或 all.vars,把宿主路径替换为已存在、Barn 用户能够访问的
真实目录,而且目录必须属于当前 Barn 用户,只读共享也不例外。
宿主路径必须为绝对路径,不能穿过符号链接,也不能与 Barn 数据根重叠。
源文件共享可以从显式只读开始;可写共享还取决于客机用户权限,Barn 可能回退到
只读并报告限制,不会修改宿主目录属主。
不要在当前文档所述运行时的 macOS 环境中添加 vm_shares。 已测 macOS/QEMU
路径无法重新打开安全持有的目录描述符,受影响节点无法启动;这里应使用 SSH 文件传输。
宿主源目录或挂载丢失时,恢复原目录/挂载后再重试 up;Barn 不会新建空目录替代。
修改已有节点的共享定义需要显式重建。完整磁盘与共享约束见配置参考。
1.6 - macOS 虚拟机
Barn 0.9.0 发布候选,尚未发布。 当前验证结果与发行前检查见
当前状态。请以实际运行的 barn mac --help 为准。
barn mac 在 Apple 芯片 Mac 上创建并运行 macOS 虚拟机。每台机器都是干净、可随时
丢弃的 macOS:带管理员账号、免密 sudo、固定的 SSH 密钥和固定地址,适合测试、构建与复现
macOS 特有的问题。它直接使用 Apple 的 Virtualization 框架,全程不需要管理员权限。
Mac 机器与 Linux 实验环境相互独立:不读取 barn.yml,不加入 Pigsty Inventory,
所有文件都在 $BARN_HOME/mac(默认 ~/.barn/mac)下。Linux 的 destroy 与
purge 不会触碰它们。
前提条件
- 一台运行 macOS 27 或更高版本的 Apple 芯片 Mac,且已有用户登录桌面。客机同样运行 macOS 27。
- 第一台机器约需 65 GiB 可用空间:从 Apple 下载的约 25 GiB 恢复镜像(清理前一直保留)、 安装后约 27 GiB 的基础镜像,以及启动所需的余量。此后每台机器按自身改动增长, 上限是磁盘容量,默认 100 GiB。
- 在正式发布包含 Mac 组件之前,从源码构建需要 Xcode 27。
- 不需要 sudo:每台机器、它的网络和桌面都以当前用户身份运行。
Apple 规定一台 Mac 上同时最多运行两台 macOS 虚拟机,其他工具的虚拟机和 macOS 安装过程也计算在内。机器可以创建多台,任意两台可以同时运行。
构建 Mac 组件
在包含 barn mac 的 Barn 源码目录中执行:
bin/mac 中包含命令行、Barn Mac.app(运行机器及其桌面的原生组件)和使用说明,
请保持它们放在一起。本地构建使用 ad-hoc 签名。doctor 会检查 macOS 版本、组件与可用空间:
创建第一台机器
这台 Mac 上还没有准备好 macOS 时,up 会先列出需要做的事并请你确认:
确认后,Barn 依次:
- 只从 Apple 官方下载恢复镜像,并用 Apple 公布的 SHA-256 校验;下载中断后从断点继续。
- 一次性安装 macOS,得到一个从未启动过的基础镜像。安装期间会占用两个 macOS 虚拟机名额中的一个。
- 创建
mac1:以写时复制的方式克隆基础镜像,启动、创建你的账号,并等到 SSH 与 sudo 可用。
之后的每台机器都复用这个基础镜像,几十秒即可就绪;在验证主机上,从已准备好的基础镜像 创建一台机器用时 22 秒。
如果手上已有 Apple 的恢复镜像,可以直接使用,不必重新下载。它与数据在同一个 APFS 卷上时,Barn 以克隆方式引入,不占额外空间;否则校验后原地使用:
没有终端时(例如在脚本中),up 需要 --yes 才会下载,否则直接拒绝,绝不会悄悄下载
25 GiB。barn mac setup 可以提前准备基础镜像而不创建机器。
使用机器
终端与命令
账号名与你的 macOS 用户名相同(创建时可用 --user 另选),并拥有免密 sudo。ssh
像普通 ssh 一样把命令行交给客机 shell;exec 保留参数边界。两者都返回客机命令的退出码,
--json 会记录标准输出、标准错误与退出码:
以上 JSON 有删节,完整字段见 Mac 命令参考。
桌面
桌面在一个与屏幕大小相称的原生窗口中打开。调整窗口大小时客机分辨率随之改变,
View → Enter Full Screen 照常可用。关闭窗口后机器继续运行;
再次执行 open 即可找回窗口,机器已停止时会先启动它。窗口获得焦点时,键盘快捷键都交给客机,
所以宿主侧的操作都放在菜单栏:
| 菜单 | 作用 |
|---|---|
| Machine → Share Clipboard | 在本次运行中开关剪贴板共享 |
| Machine → Restart… | 重启客机中的 macOS |
| Machine → Shut Down… | 正常关机,与 barn mac stop 相同 |
| Window → Keep Running in Background | 隐藏窗口,机器继续运行 |
| Barn Mac → Quit Barn Mac… | 选择让机器在后台继续运行,或关机 |
锁屏和桌面中的管理员授权需要登录密码。每台机器的密码随机生成,可以直接复制而不在终端显示:
剪贴板
纯文本随焦点同步:在 Mac 上复制的内容,点进客机窗口后即可粘贴;在客机中复制的内容, 切换到其他应用时同步回 Mac。内容经由这台机器自己的 SSH 连接传输,客机中无需安装任何程序。 被密码管理器标记为敏感的内容不会离开 Mac;图片和文件不会同步。
执行 barn mac configure mac1 --clipboard off 可为某台机器关闭剪贴板共享,
从这台机器下次启动起生效。
共享目录
创建机器时共享 Mac 上的目录,客机把它们挂载在 /Volumes/My Shared Files/<名称>:
名称默认取目录路径的最后一段;:ro 表示只读。共享的必须是已存在的目录,不能是符号链接;
Barn 从不创建或删除共享目录。之后要调整共享,先停机再用 configure:
Mac 修改共享文件后,macOS 客机可能在短时间内仍看到旧内容。需要即时一致的结果时,
请通过 SSH 或 exec 操作。
在其他工具中使用 SSH
第一台机器就绪时,Barn 会在 ~/.ssh/config 中加入一个带标记的 Include。之后
ssh mac1、scp、rsync 以及支持 Remote-SSH 的编辑器都能按名称访问每台机器,
并使用它自己的密钥和固定的主机密钥:
生命周期命令会保持这些条目为最新。若 ~/.ssh/config 是由 dotfile 工具管理的链接,
Barn 不会修改它,而是打印需要你手动添加的 Include 行。
多台机器
为每台机器命名。创建参数只对新机器生效:
名称使用小写字母、数字和中间连字符,以字母开头。不带名称的命令作用于唯一的一台机器或
mac1;无法确定时会请你指定。DISK 显示机器当前占用的空间与容量。容量属于基础镜像:
--disk 与已准备的基础镜像不同时,会先安装另一个基础镜像,这需要再次使用恢复镜像。
每台机器有自己的私有网络:mac1 使用 10.10.20.10,之后的机器依次使用下一个空闲的
/24,并避开局域网、VPN 与 Linux 实验环境。机器可以访问互联网和 Mac,但彼此不通。
已有两台机器在运行时,第三台会在创建任何内容之前被拒绝,并指出可以停止哪一台:
日常管理
stop 执行正常关机;两分钟后仍在运行的机器会被断电,结果中会明确说明。
stop --force 立即断电,相当于长按电源键,客机中未保存的内容会丢失。
start --recovery 启动到 macOS 恢复模式并显示桌面。
up 从不重新配置已有机器。传入与现有配置不同的参数时,它会拒绝执行并给出应使用的命令:
configure 在机器停止时修改 CPU、内存、共享目录与网络,剪贴板共享可随时修改;
变更从下次启动起生效:
recreate 用基础镜像中全新的 macOS 替换机器,保留名称、账号、资源、共享目录与地址;
destroy 删除机器。两者都会先说明将删除的内容,并要求输入命令名确认;
没有终端时用 --force 确认。
| 操作 | 客机磁盘与应用 | 设置、地址与账号 |
|---|---|---|
stop/start、restart、重复 up |
保留 | 保留 |
configure |
保留 | 按要求修改 |
recreate |
换成全新的 macOS | 保留;密码与 SSH 密钥重新生成 |
destroy |
删除 | 删除 |
以上操作都不会修改共享的基础镜像;删除机器时基础镜像也会保留。
macOS 版本与磁盘空间
升级总是显式进行。barn mac image update 向 Apple 查询最新的 macOS 27,确认后下载,
并将其设为新机器的基础镜像。已有机器保持原来的 macOS,直到执行
barn mac recreate NAME --update。up 与 start 从不改变机器的 macOS 版本。
image prune 列出没有机器使用、且不是默认的基础镜像,加 --yes 才会删除;
--installers 会一并处理已下载的恢复镜像。APFS 克隆共享数据块,因此 ON DISK
与各机器的磁盘数字都不是独占空间,不要相加。
故障排查
先执行 barn mac doctor:它检查宿主、组件、基础镜像与每台机器,并为每个失败项给出
next: 命令。barn mac logs [名称] 显示机器的运行日志:启动、网络、关机以及 Apple
Virtualization 的错误。
| 现象 | 处理方法 |
|---|---|
启动时报 network … overlaps route … |
VPN 或其他工具占用了该网段。执行 barn mac configure NAME --subnet auto。 |
macOS allows 2 macOS virtual machines at a time |
停止提示中的某台机器,或退出其他工具的 macOS 虚拟机。 |
第三方 SSH 客户端执行 ssh mac1 报 “No route to host” |
macOS 的“本地网络”隐私控制阻止了该应用访问私有网络。在系统设置 → 隐私与安全性 → 本地网络中允许它,或改用 /usr/bin/ssh。barn mac ssh 与 exec 始终使用 Apple 自带工具,不受影响。 |
the Barn Mac component is not installed 或 speaks protocol … |
同一次构建的 barn 与 Barn Mac.app 需放在一起;用 make mac-build 重新构建。 |
| 通过 SSH 登录 Mac 后启动失败 | 请在 Mac 桌面会话的终端中运行 barn mac:机器需要已登录用户的会话和已解锁的登录钥匙串。 |
在虚拟机中登录 Apple 账户并不可靠;不支持 USB 设备、快照和挂起机器。
清理
删除最后一台机器时,~/.ssh/config 中的相应条目也会一并移除。默认基础镜像会保留,
供之后创建机器使用;如需删除包括它在内的所有 Mac 文件,先删除全部机器,再删除
$BARN_HOME/mac(默认 ~/.barn/mac)。除该目录外,Barn 只会写入
~/.ssh/config 中的条目、保存在 ~/Library/Preferences/io.pgsty.barn.mac-runner.plist
中的桌面窗口位置,以及 /tmp 下的一个短路径运行目录。整个过程都不需要 sudo。
1.7 - 镜像仓库
正常使用不需要先执行镜像命令:barn up 默认按本机架构解析 u24:stable,并拉取
最终对应的不可变版本。
Barn 一直使用已安装构建内置的 Catalog,直到你运行 barn update:它会获取、校验并
激活仓库当前的 Catalog;没有任何自动刷新。恢复时可用 image sync 显式激活精确 URL
或文件。
选择镜像
先查看可用别名:
内置 Family 包括 el7、el8、el9、el10、d12、d13、u22、u24、
u26。裸名称选择 stable,name:channel 选择频道;name@version 优先精确匹配,
较短的数值 Selector 则按点分量边界选择最新匹配版本:
这里 9.7 选择最新 9.7.x Build,9 选择最新 9.x Release。若希望跟随仓库可移动的
Stable Channel,则改用 vm_image: el9:stable 并删除 vm_version。独立的
vm_version 不能与 vm_image 中的 :channel 或 @version 同时使用。
修改配置后先运行 barn plan。已有节点的镜像请求改变时,需要显式执行
barn recreate <node>;up 会报告定义漂移而不会自动重建。仅更新 Catalog 不会改变
已有节点或它保存的基础镜像身份。新增或显式重建的节点才会按照活动 Catalog 解析选择器。
需要可重复的实验环境时,应锁定 image info 显示的完整版本,而不是可移动的 Channel
或数值前缀:
YAML 中的数值 vm_version 建议加引号,以保留完整原文。
除兼容用途的 EOL el7、EL9 9.3/9.6 与 EL10 10.0 为 deprecated 外,
其余内置版本均为 supported。
使用镜像站
Release 构建默认使用 https://repo.pigsty.io/barn。单条命令可通过仅有长参数的
--mirror 选择中国官方仓库,也可以用 --repo 指定自定义根:
或为当前 Shell 设置默认仓库:
选择优先级依次为 --repo、--mirror、BARN_REPO、全球默认仓库。--mirror
解析为 https://repo.pigsty.cc/barn,两个官方根都保持规范的签名 Catalog 信任。
BARN_REPO 也可以是绝对本地目录。显式本地或 HTTPS 仓库可使用未签名 Catalog;HTTP
仓库必须提供可信密钥签名。文件大小、SHA-256 与 qcow2 结构始终校验。
镜像下载会重试临时故障,并接续中断的传输。选定官方端点无法提供镜像时, 两个官方仓库可以互相回退,仍须匹配同一 Catalog 中的尺寸与摘要。自定义仓库不会回退 到其他站点;Catalog Upstream URL 只用于溯源,始终不是备用下载源。
这项回退只针对镜像工件。barn update 获取选定仓库的 Catalog,image sync 读取
明确指定的 URL 或文件;两者都不会升级 Barn 程序。活动 Catalog 按仓库分别记录。
新 --repo 在激活该根的 Catalog 前使用内置 Catalog;只改变下载源不会让自定义别名出现。
构建静态仓库
仓库只是一个可以直接 rsync 或静态 HTTP 托管的目录:
repo.yaml 是唯一人工维护源。上面单个 arm64 镜像的最小完整配置如下:
将独立校验且已具备 cloud-init 的镜像放到
/srv/barn/images/d13-1-arm64.qcow2。若是 x86 Guest,文件名与 Variant 都改用
amd64;source_user 应填写镜像的源身份。仓库根必须是绝对路径、非符号链接,且不能
允许组或其他用户写入。在本机生成 catalog.json:
scan 只读;build 永不修改 repo.yaml 或镜像字节,它运行完整的 qemu-img check,
并物化文件名、SHA-256、工件大小和虚拟大小。build、verify 需要本机
qemu-img,scan 不需要。在安装 QEMU 的机器上构建后,发布时先上传不可变 QCOW,
最后发布 catalog.json 与匹配签名。本地/HTTPS 示例可以不签名;普通 HTTP 与官方仓库
必须具有可信签名。每次修改 Catalog 内容都应增加 revision。
创建 VM 前,先激活并检查这个本地仓库:
plan、up、recreate 都传入相同的 --repo /srv/barn,也可设置
BARN_REPO=/srv/barn。Inventory 中选择 vm_image: d13@1 与
vm_arch: arm64;导入 Catalog 不会改写 Inventory 默认值。
barn image reset --repo /srv/barn 将该根恢复到内置 Catalog,同时保留防回滚记录。
导入与清理
本机原生架构的单个自定义镜像可以直接导入,并提供独立获得的摘要。CLI 中 --sha256
是可选参数;有可信摘要时建议填写:
自定义别名必须以 local- 开头;--name、--boot、--source-user 必须一起提供。
导入只检查 qcow2 并复制到 Barn 缓存,不会准备 Guest 软件;镜像必须已经支持 Barn
使用的 cloud-init 初始化。命名导入记录宿主架构,外来架构镜像应使用静态仓库。
在 Inventory 中设置 vm_image: local-mybase,再运行 barn plan。
Prune 会保护选定活动 Catalog 的全部镜像、已应用节点的镜像,以及全部已注册本地别名, 因此销毁所有 VM 后也不会简单清空缓存。删除前先看候选列表:
签名、回滚保护、缓存布局、架构与 TCG 规则见镜像参考;准备镜像 Candidate 及发布前的独立验证要求见镜像流水线。
1.8 - 从源码构建
Barn 0.9.0 目前是尚未发布的候选版本。本页用于从源码构建与检查; 正式发布后的安装方式见快速上手。
选择源码
克隆 Barn 源码仓库:
尚未发布时不要假定 v0.9.0 Tag 已存在。构建前核对源码身份与工作区变更,
确认 go.mod 的模块为 github.com/pgsty/barn,命令目录为 cmd/barn:
构建
已审核候选源码的 go.mod 与 packaging/toolchain.env 固定 Go 1.27.1;此外需要
Git、Make、Bash 与标准构建工具。运行 VM 才需要 QEMU 与特权网络准备,编译 CLI
本身不需要。进入选定源码工作区执行:
make build 在被 Git 忽略的 bin/ 下生成同一次构建配套的 barn 与
barn-hosts-helper。不要混用来自不同 Commit 或不同 Release 的两个二进制。开发
构建默认显示 dev;Commit 字段显示干净源码的提交,工作区有变更时显示 uncommitted。
不能只凭版本字符串判断是否包含候选功能。
将 Inventory 保存在单独的实验目录。这不会隔离 Barn 状态;已有 deployment 时,
应先检查该部署,再运行 up:
完整检查
完整检查还需要 Python 3、jq、供 Race 测试使用的 C 工具链,以及固定版本的质量工具。
安装已审核候选版 CI 所用版本;换用其他源码版本时,重新核对其 CONTRIBUTING.md
与 packaging/toolchain.env:
确保 Go 工具安装目录(GOBIN,未设置时为 $(go env GOPATH)/bin)位于 PATH。
提交源码改动前运行:
该门禁包含模块验证、Shell 语法、维护脚本归属、单元与 Race 测试、Vet、Staticcheck、 四目标死代码交集、errcheck、漏洞检查、跨平台构建、镜像流水线和安装器测试、依赖许可证 验证。CI 还单独检查格式、空白、工具准确版本与 GoReleaser 配置;修改打包逻辑还需通过 完整的打包 Snapshot 验证。
通过源码检查不等于已经发布软件包,也不等于完成真机生命周期验证;
make image-pipeline-native-test 是独立的真机镜像门禁,需要显式提供
tests/image-pipeline-native-test.sh 开头说明的镜像输入,不会下载测试镜像。
发布工程、依赖许可证与边界说明见工程说明。
1.9 - 卸载与清理环境
本页会删除虚拟机与本地数据。先确认当前状态,不要在仍需保留 Barn VM 时继续:
1. 删除 deployment
彻底删除节点、持久盘、密钥与 deployment 状态:
这条整套处置命令无需确认;镜像缓存与宿主网络仍然保留。若要保留
持久盘或只删除选中节点,继续使用粒度更细且带确认的 barn destroy。
2. 移除可选集成
整体 destroy 已自动移除默认 barn SSH integration。如果使用过自定义 fragment 名称或
/etc/hosts 条目:
未加 --yes 的 --json 命令只展示 Barn 标记范围内的计划。确认目标正确后再执行
带 --yes 的命令。Barn 0.9.0 的普通终端输出会询问 [y/N],同意后立即卸载。
读取 hosts 计划无需 sudo,实际修改仍需要权限。
3. 删除镜像缓存
Prune 删除未引用的缓存镜像与遗留 staging 文件,但会保护已应用 deployment、当前 Catalog 和已注册本地别名引用的镜像,因此不等于清空全部缓存。后面的可选状态目录 清理会一并删除剩余缓存。
4. 卸载宿主网络
第一条 JSON 命令只展示归属明确的删除计划,但可能需要 sudo 读取受保护的网络状态。 只要仍有 VM 接入,网络卸载就会拒绝执行。宿主网络由用户共享;清理自己的部署不代表 其他用户的 VM 也已停止。
5. 清理源码安装残留
宿主网络卸载会保留可独立使用的 hosts helper。仅在确认不再使用 Barn 后,删除下面的准确路径:
若使用默认状态目录,并且前面所有步骤均已完成,可最后删除空余状态:
此段命令在设置了 BARN_HOME 或默认路径为符号链接时停止。自定义状态目录必须
另行核对,不要把目标替换为 $HOME、/、工作区根目录或未经确认的路径。删除后不要
再次运行生命周期命令来验证目录不存在,因为命令可能重新创建锁目录。
QEMU 可能被其他工具共用,默认不要卸载。只有确定没有其他用途时,macOS 才执行:
检查网络与默认状态目录:
卸载后的网络预期报告缺失或未就绪,应检查具体结果,不应要求退出码为零。不要把
bridge100 是否消失当作依据:macOS 决定桥接名称,其他软件也可能使用 vmnet 桥。
Archive、Homebrew、DEB 或 RPM 安装的 Barn 二进制应使用对应安装渠道移除;源码构建生成的
bin/ 只是工作区构件,与上述宿主状态无关。
2 - 参考
本参考描述 Barn 0.9.0 发布候选。编写脚本前先核对 barn version,
发布进度见当前状态。
- 配置:发现顺序、变量、默认值、磁盘、共享、命名与漂移。
- 命令行:命令、关键参数、输出模式与退出码。
- Mac 命令:尚未发布的
barn mac的命令、JSON 结果与失败原因。 - 镜像:签名 Catalog、别名、本地缓存、拉取、导入与清理。
- 镜像流水线:Candidate 校验与离线归一化。
Barn 不提供受支持的 Go Library API;internal/ 下的包都是实现细节。
2.1 - 配置
本参考描述 Barn 0.9.0 发布候选。编写脚本前先核对 barn version,
发布进度见当前状态。
发现顺序
依次查找:显式 -f、当前目录的 barn.yml、barn.yaml、pigsty.yml、
pigsty.yaml。所有文件名都使用同一种 Pigsty 兼容 YAML Inventory。
plan、up、reload、recreate 找不到文件时,如果 deployment 已存在,会回退到
已应用规格;validate 不会回退。配置必须是最大 4 MiB 的普通非符号链接文件。
发现顺序中第一个存在的文件生效;它若无效会直接报错,不会继续尝试下一个文件名。
重命名文件或切换目录不会产生另一套部署,已应用状态保存在 BARN_HOME。
完整配置示例
这里定义了两个托管节点,控制节点为 meta。保存为 barn.yml 后,可以先检查而不启动 VM:
JSON 校验结果包含 valid、source、spec_hash、resolved。0.9 候选版本的
validate 还会解析 Catalog 镜像引用,并接受 --repo;Catalog 无法读取时会报告警告,
不会声称镜像已检查;local-* 镜像字节校验仍由 up 完成。配置校验不能证明宿主资源、
共享访问、网络、镜像字节或客机就绪可用,也不会启动 VM 或下载镜像。
Barn 读取什么
Barn 读取主机 IP、nodename、admin_ip、pg_cluster、pg_seq、
node_admin_username、node_admin_uid 与已记录的 vm_* 变量。admin_ip 只从
all.vars 读取,用于选择控制节点;没有匹配时使用第一台托管主机。所有节点必须解析为
同一个登录用户名;默认用户 dba 的显式 node_admin_uid 必须为 88。
自定义用户名下,node_admin_uid 仍需通过整数校验,但不会设置客机 UID;Barn
没有提供任意定制客机 UID 的配置契约。
其余内容完全不读,也不会产生 drift。这里指 pg_role、pg_version、repo_*、
node_packages 等未消费字段,不能泛化为所有 pg_* 或 node_*。
命名空间内严格校验:未知 vm_*、错类型、Jinja 表达式、非法地址、同级分组冲突都会报错。
继承顺序是 all.vars → 更深层的 children.<group>.vars → 主机变量。
主机上的 vm_disks 等列表整体替换继承列表,不会追加。相同深度的组给出不同值时,
必须在主机层覆盖消除冲突。支持 YAML 锚点与合并键:显式键优先,合并序列中靠前的映射优先。
重复映射键和多个 YAML 文档都会报错。
即使 vm_skip: true,主机键也必须是 IPv4 地址。跳过的主机不计入 20 节点上限、也不参与
托管子网推导,但至少要有一台托管主机。跳过已应用节点只会将它标为从配置移除,不会销毁 VM。
0.9 候选版本改进了错误诊断,在可定位时显示规则、错误值、行号,并提示相近的 vm_*
拼写;这些诊断改进没有增加新的 Inventory 变量。
VM 变量
| 变量 | 默认值 | 含义 |
|---|---|---|
vm_skip |
false |
不虚拟化这台真实/外部主机 |
vm_image |
u24 |
镜像 Family、Channel 引用或 image@version Selector |
vm_version |
未设置 | 匹配 9、9.7 等数值前缀的最新版本 |
vm_arch |
native |
部署级 Guest 架构:native、amd64 或 arm64 |
vm_cpu |
2 |
vCPU 数量 |
vm_mem |
4096 |
MiB 整数,或 8GiB 等尺寸 |
vm_disk |
64 |
根盘:GiB 整数或 64GiB 等显式尺寸 |
vm_disks |
[{path: /data}] |
额外数据盘,默认一块挂载到 /data 的 128 GiB 非持久盘 |
vm_alias |
[] |
Guest /etc/hosts、SSH config 与可选宿主别名 |
vm_shares |
[] |
QEMU 9p 宿主目录共享 |
空主机条目就是一台完整 VM。每套 deployment 支持 1–20 台托管主机;vm_cpu 范围
1–256,内存至少 512 MiB。内存裸整数单位为 MiB,磁盘裸整数单位为 GiB。
显式尺寸字符串支持正整数加 B、KiB、MiB、GiB、TiB、KB、MB、GB、TB
(区分大小写)。8GiB 合法,8G、1.5GiB 和无单位的引号字符串 "8192" 不合法。
根盘与数据盘尺寸必须为正值;up 还会检查根盘不小于所选基础镜像的虚拟尺寸。
省略 vm_image 时默认选择 Ubuntu 24.04。使用 Debian 13 时,在 all.vars 中
写明 vm_image: d13;修改已有 Barn 配置后先查看 barn plan。
vm_version 将简短的版本意图与镜像 Family 分开:
Catalog 中存在完全相同的版本时优先精确匹配;否则只在点分量边界匹配,并选择数值语义上
最新的结果:9.7 选择最新 9.7.* Build,9 选择最新 9.x Release。各分量按整数
比较,因此 9.10 晚于 9.9。vm_version 不能与已经带 :channel 或 @version 的
vm_image 同时使用。
vm_arch 比普通逐主机字段更严格:出现时必须在所有托管主机上解析为同一个值,因此
应只在 all.vars 定义一次。修改它属于 deployment envelope 变化,必须整体重建。
Linux setup 只安装宿主原生模拟器;外来架构还需要对应 qemu-system-* 与固件。
数据盘
path 同时是磁盘身份与挂载点;fs 为 auto(默认)、xfs 或 ext4。空白的
auto 磁盘在 guest 有 mkfs.xfs 时格式化为 XFS,否则为 ext4,与 Vagrant 流程的
行为一致;显式 xfs、ext4 不会降级,健康的已有文件系统直接复用。persistent: true
在普通 destroy 后保留;vm_disks: [] 表示不要额外盘。每项 size 默认 128 GiB,
整数单位为 GiB,也接受显式尺寸字符串。
挂载点需是 /data、/data/pg 等规范绝对路径。磁盘身份由路径去除首尾 /,再把中间的
/ 替换为 -,必须匹配 [a-z][a-z0-9-]{0,31};单个节点内磁盘身份与挂载点均不得重复。
/、/etc、/usr、/root、/var/lib/barn 等系统路径及与它们重叠的父子路径会被拒绝。
修改持久盘身份或声明可能需要显式迁移;persistent 不表示任意新定义都能自动复用旧盘。
数据盘按可丢弃的测试存储处理。 up 会将无法识别或确认损坏的文件系统清空重建为
配置的类型,并报告旧数据已丢弃。这同样适用于 persistent 盘:持久性控制销毁、重建 VM
时是否保留盘,不保证保留损坏内容。探测失败、设备暂缺、挂载占用或底层 I/O 故障不会
触发格式化;系统盘和宿主共享目录不属于此恢复范围。
目录共享
macOS 限制: Barn 的目录身份保护共享方式尚不支持
macOS,配置了 vm_shares 的节点无法启动;候选版本还会在 validate、plan 时发出警告。新建 macOS 实验环境
应先省略共享;完整共享支持仍待完成。修改已有节点的共享配置需要 recreate,会替换
根盘,请先保留所需数据。Barn 不会退回未经身份校验的宿主路径。
readonly 默认为 true,每个节点最多八个共享。宿主与客机路径必须是规范绝对路径,
不会展开 ~ 或相对路径。源目录必须已经存在、属于调用者,路径的任何分量都不能是
符号链接,也不能与 BARN_HOME 重叠。Linux 上请优先使用真实路径(realpath /path/to/source);0.9 候选版本
会在符号链接错误中提示应该填写的真实路径。
同一节点内宿主源目录、客机目标目录均不得相互重叠;不同节点只有全部只读时才允许宿主
源目录重叠。客机目标不能覆盖数据盘挂载点、保留系统路径或登录用户的 .ssh 目录。
9p 只适合可信开发文件,不能放 PostgreSQL 数据。
请求可写共享但客机无法写入时,Barn 尝试只读访问并报告限制;修正权限后再次 up
即可重试。Barn 不会递归修改宿主文件的属主。
Barn 的 up、start 会将源目录缺失的影响限制在对应节点,其余选中节点
继续执行。恢复原目录或宿主挂载后,再重试该节点;Barn 不会创建空目录代替。
restart、reload、recreate 会在停止已有节点前校验源目录。
名称与地址
节点名依次取 nodename、<pg_cluster>-<pg_seq>、node-<IP末段>,且必须唯一。
名称长度为 1–63,只能包含小写字母、数字和连字符,不能以 - 开头或结尾。
非空显式 nodename 优先,此时无需使用其他 pg_cluster、pg_seq 值派生名称。
vm_alias 是小写 DNS 风格名称列表,不能与节点名或部署内任何其他别名重复。
所有托管主机必须位于同一个 RFC1918 /24:.1 属于宿主,.2–.8 保留,节点使用
.9–.254。
Guest 内部,固定 IP 网卡就是承载 Inventory 地址的那块网卡(ip -br addr);其名称不是
Barn 契约。
漂移
Barn 对每个解析后节点计算哈希。新增主机由 up 创建;选中的已停止节点会启动,
运行中同伴保留进程,同时重试未完成的客机初始化。VM 定义变化需要节点级 recreate;删除主机条目只报告、绝不销毁。
deployment 架构、用户或子网变化需要整体重建。plan/up 会把镜像选择器解析为精确镜像身份,
因此 Catalog 更新后即使 Inventory 文本未改动,也应检查计划。修改用于派生节点名的字段会表现为旧节点
missing 加新节点,建议使用稳定、显式的 nodename。
2.2 - 命令行
本参考描述 Barn 0.9.0 发布候选。编写脚本前先核对 barn version,
发布进度见当前状态。
已安装的二进制是当前版本最准确的参考。每一条可见命令都自带操作边界与可复制样例:
直接运行 barn 会显示简短欢迎信息和下一步命令,以 0 退出,
JSON/YAML 输出 actions[]。barn image 这样的裸命名空间仍以 2
退出,文本模式打印帮助,JSON/YAML 模式返回结构化用法错误。显式 --help 始终输出
供人阅读的帮助文本并以 0 退出。用 barn --version 或 barn version 查看构建身份。
命令
| 范围 | 命令 |
|---|---|
| 准备 | setup、init、validate、doctor |
| 生命周期 | plan、up、start、stop、restart、reload、recreate、status、destroy、purge |
| 访问 | ssh、exec、logs、provision、ssh-config、hosts install/uninstall |
| 镜像 | update、image list/info/pull/import/sync/prune/reset、repo scan/build/verify |
| 宿主网络 | network status/install/uninstall |
| macOS 客机(尚未发布) | mac …,见 Mac 命令 |
| 其他 | version、completion |
没有命令会隐式刷新 Catalog。update 获取配置仓库的 Catalog,校验并激活;
image sync 是为精确 URL 或文件准备的显式恢复路径。普通命令只使用当前本地 Catalog。
两者都不更新 Barn 可执行文件。
常用命令提供作用域明确的短别名:
| 命令 | 别名 | 命令 | 别名 |
|---|---|---|---|
setup |
s |
validate |
v |
plan |
pl |
recreate |
rc |
status |
st |
destroy |
de |
ssh-config |
sc |
image |
images、im |
doctor |
dt |
network |
n、net |
exec / logs |
ex / l |
version |
ver |
up、ssh、init、start、stop、restart、reload、provision、hosts、
completion 没有别名。请使用明确的 barn purge 拼写;rm 不是命令别名。
命名空间内部,hosts 与 network 的 install/uninstall 使用
i/u,network status 使用 st;image 使用 list=ls、info=in、pull=p、
prune=pr、sync=sy、import=i。
Barn 在选定的 BARN_HOME(默认 ~/.barn)中管理一套部署,其身份与
Inventory 所在目录无关。使用已应用状态的命令可在任意目录运行。配置来源由命令决定,-f 刻意不做全局参数:
| 命令 | 期望状态来源 |
|---|---|
setup [template] |
显式 -f,否则发现配置,否则生成 meta;模板与 -f 互斥 |
init [template] |
生成新 Inventory,不读取期望状态;--force 显式替换输出文件 |
validate |
显式 -f,再发现配置;绝不回退到已应用状态 |
plan、up、reload、recreate |
显式 -f,再发现配置,最后回退到已应用规格 |
| 其他生命周期/访问命令 | 不读取期望配置;使用已应用状态 |
没有配置文件且没有已应用部署时,交互式 up 可以生成默认配置;它也能准备缺少的宿主
依赖、恢复完整但未激活的 Barn 网络。该内部准备流程接受 setup 计划,sudo 仍可能
请求凭据;可先用 setup --dry-run 查看宿主计划。脚本应显式执行 setup --yes,
没有配置文件时无需另行 init。
关键参数
| 参数 | 含义 |
|---|---|
--json、--yaml |
stdout 机器可读;进度仍写 stderr;刻意不设短参数 |
-v、--verbose |
stderr 有界诊断 |
-c、--cidr |
为 init/setup 生成模板或宿主网络检查/安装选择 RFC1918 /24 |
-f、--file |
为读取期望状态的命令选择 Inventory |
-r、--repo |
在提供此参数的命令上选择仓库;覆盖 --mirror 与 BARN_REPO;validate 在 0.9 候选版本新增此参数 |
--mirror |
为 setup、Catalog 与需要解析镜像的生命周期命令选择中国官方仓库 |
-m、--mode |
在提供该参数的命令中选择 macOS host/shared 网络模式 |
-d、--dry-run |
只展示 setup/image 计划,不改变状态 |
-y、--yes |
应用已展示的宿主/setup/image 计划 |
--force(init、destroy、recreate) |
覆盖生成文件或跳过输入确认词;因为 -f 用于选择 Inventory,所以只保留长参数 |
-n、--no-wait |
QEMU 运行后即返回,跳过 Guest 就绪检查、恢复与元数据刷新 |
--rollback(up、reload) |
清除本次运行中 prepare 失败节点的残留产物 |
--delete-persistent |
整体销毁时也删持久盘;不能与节点选择器一起使用 |
--purge |
整体处置:删除磁盘、密钥与 deployment 状态,保留镜像 |
参数属于各自命令,下表列出容易混淆的作用域:
| 命令 | 专用参数 |
|---|---|
init |
--output/-o(默认 ./barn.yml,- 表示打印)、--cidr/-c、--force |
plan |
--file/-f、--repo/-r;没有 --mirror 或 --dry-run |
start、restart |
--no-wait/-n;没有 --file 或仓库选择参数 |
provision |
必须提供 --script/-s;--sudo 使用客机 sudo -n;--parallel/-p 为 1–4,默认 1;--timeout/-t 为正值、最多 24h,默认 1h |
ssh-config |
--install/-i 与 --remove 互斥;--name 默认为 barn;移除不接受节点,也不要求部署状态存在 |
logs |
--source/-s serial|qemu|events,默认 serial;--follow/-f;events 不接受节点 |
image info、image pull |
可选镜像选择器、--arch/-a amd64|arm64、--repo/-r;只有 pull 接受 --mirror |
image import |
--sha256/-s;指定 --name local-* 还必须提供 --boot/-b bios|uefi 与 --source-user/-u |
image prune |
--dry-run/-d 与 --yes/-y 互斥;--repo/-r |
image sync |
URL 或路径、--repo/-r、显式 --allow-downgrade |
network install |
--cidr/-c 默认 10.10.10.0/24,--mode/-m 默认 host,--yes/-y;--archive/-a、--interface-id/-i 仅限 macOS |
network status |
可选 --cidr/-c;没有 --file |
network uninstall、hosts install/uninstall |
--yes/-y |
setup --dry-run 与 setup --yes 互斥。--cidr 用来调整生成模板的网段,不能重写显式
选择的 Inventory。validate --repo 是 0.9 候选版本新增参数,没有对应的 --mirror;
需要检查中国仓库时使用 --repo https://repo.pigsty.cc/barn。
0.9 候选版本中,network 与 hosts 的 install/uninstall 会在终端展示计划并询问确认
(安装默认同意,卸载默认拒绝);非终端只展示计划,除非传入 --yes。
macOS 首次网络安装使用 setup;候选版本
的 network install 会在 sudo 提示前引导到该命令。--yes 接受 Barn 计划,不能提供 sudo 密码。
--mirror、--force、--rollback、--remove、--allow-downgrade、--sudo、
--delete-persistent、--purge 等低频或扩大风险边界的参数只保留长版本。读取
Inventory 的命令中 -f 始终选择文件;logs -f 保留惯用的 --follow。
-n 始终表示 --no-wait,-d 始终表示 Dry-run。
存在部署时,barn purge 与 barn destroy --force --purge 执行相同的整体处置,
且无需确认。它不接受节点或 Inventory,删除整套 Deployment、
持久盘、密钥、状态和默认 SSH Fragment,保留镜像与宿主网络。没有部署时幂等成功,
也可清除能够证明归属的保留盘;缺少状态文件绝不会授权按路径删除无法证明身份的遗留节点工件。
0.9 候选版本中,没有部署时的普通整体 destroy 也返回成功;但
destroy --force --delete-persistent 和 destroy --force --purge 会报错,提示改用 purge。
结构化失败(0.9 候选版本)
下列统一失败契约描述 Barn 0.9.0 发布候选。
普通失败会在 stderr 输出 error: <消息>;外部工具失败时附上它 stderr 的最后几行;
有明确下一步时再输出一行 next:。SSH 子进程退出失败不会重复打印错误,直接保留子进程输出。
如果命令没有提供更丰富的类型化结果,结构化模式会输出通用失败对象,包含
error、message,以及适用时的稳定 reason、next、operation_id 和外部程序详情
command(name、argv、exit_status、signal、timed_out、stderr),然后返回退出码。
已携带失败状态的结果后面不会追加第二份 JSON/YAML 文档。
通用对象的 error 使用下方表格中的固定类别;recreate_required 和 nodes_removed
改为 error: "conflict" 下的 reason,旧的 resource_conflict 类别改为 resource。
非零退出不保证 stdout 一定是这个通用对象。 doctor、network、provision、
生命周期操作与远端命令可以返回各自的报告结构。SSH 子进程退出在内部归类为 remote_exit,
但公开结果包含 success、exit_code、stdout、stderr 等字段,可选 error 也不服从
通用错误分类契约。自动化应始终保留进程退出码,再按具体命令解释 payload。
生命周期结果
plan 是只读操作,即使 action 为 recreate 或 blocked-removal 也返回成功;自动化必须
检查 action 与 create、start、recreate、missing、blocked 字段。对于 Catalog
镜像,计划只读取本地配置和 Catalog,无需先安装 QEMU 或宿主网络;已注册的 local-*
镜像还会校验缓存,需要 qemu-img。计划不会下载镜像;它显示精确镜像、资源总量、变更原因
和磁盘影响。0.9 候选版本还逐项列出数据盘,包括隐式的 128 GiB /data。
宿主能力与地址可用性由 up 在执行前检查。up 会创建缺失节点、启动已停止
节点、复查运行中节点的就绪状态,并根据完整的 applied deployment 重写 Barn 安装的
SSH 客户端配置;recreate 同样执行全量刷新,节点级 destroy 删除旧条目,整体 destroy
移除该配置。start 启动已停止节点并复查运行中节点的就绪状态,start 与 restart 也会刷新 SSH 别名。
破坏性 drift 返回冲突,并给出下一步命令:先 barn plan,再 barn recreate <node>
或 barn destroy <node>;终端上这两条命令会要求输入确认词,--force 仅用于脚本。
如果 VM 生命周期成功但 SSH 客户端配置无法写入,命令会给出警告并返回成功;
barn ssh 仍然可用。结构化输出通过 warnings[] 报告集成问题。
0.9 候选版本不修改符号链接或硬链接形式的 ~/.ssh/config,会发布独立配置片段,
并提示需手动加入的 Include 行。
就绪边界是管理 SSH 可用。可选初始化问题通过 nodes[].warnings 报告,已完成的恢复
操作(包括数据盘重置)写入 nodes[].repairs。客机可用但有这些限制时返回 0;重复 up
会重试未完成步骤,无需重启运行中的 VM。要求全部配置功能可用的自动化应检查警告字段。
生命周期批处理出现可隔离的节点级失败时,即使所有选中节点都失败也可能返回 5,并报告
N of M node(s) failed: <node> (<stage>: <error>); ...。常见阶段包括 prepare、start、
readiness、bootstrap、guest-setup、stop、status;readiness 或 bootstrap 失败会追加 run \barn logs 。结构化输出携带 failures[](node、stage、error,**0.9 候选版本**还有可选 reason);当 –rollback清除了 从未提交节点的 prepare 产物时,还会带上rolled_back`。参见
节点未就绪。
status 默认展示节点、状态、IP、精确镜像和 CPU/内存;--verbose 展示 SSH 端口、
架构、加速器与 PID。TCG 在普通文本中也有标记。一个节点异常时,仍保留其他节点的
状态,并返回 5;结构化输出包含逐节点 error 和 failures[]。running 表示 VM
正在运行,不代表本次 status 检查了 guest 就绪状态。
启动命令完成后还会刷新运行中 guest 的 Barn hosts 和控制节点 SSH 配置;停止中的
节点在下次启动时更新。--no-wait 会跳过 guest 就绪检查、恢复和刷新,随后执行 up 补齐。
局部 recreate 若仍受未选节点的配置变化影响,会在停机、删盘前拒绝;按提示一次选择
需要重建的节点。
控制节点中由 Barn 管理的 SSH 条目不固定 guest 主机密钥,也不写入 known_hosts, 因此重建实验节点后可以直接连接。用户自行添加的 SSH 配置会保留。
恢复行为
up、start 按节点隔离宿主共享目录
缺失的影响;up 在新节点准备失败后仍会启动独立的已有停止节点。部分成功保留退出码
5 和成功节点。重试提示保留配置文件、镜像仓库及适用参数,start 的重试仍为 start。
setup 与随后生命周期重试使用同一个 operation_id。首次 setup 失败、尚无部署状态时,
也可通过 barn logs --source events --json 读取有大小上限的阶段日志。setup 日志不记录
命令参数和认证信息,详细根因以命令输出为准;setup --dry-run 不写日志。
destroy --delete-persistent 与 purge 成功摘要只描述最终删除、保留的资源;purge
仍保留镜像缓存和宿主网络。
先删除某个节点后留下的受管持久盘,不再阻断其余节点的销毁。普通 destroy 继续保留
这些盘,只有显式删除持久盘或 purge 才会移除它们。
macOS 新网络安装先完成 Homebrew 发现/安装或固定归档下载,再申请管理员认证。 这避免了 Homebrew 清除先前 sudo 凭据导致的安装失败,不扩大特权操作范围; 下载失败时不会提前要求输入密码。
中断操作恢复(0.9 候选版本)
候选版本会把已被无关进程复用的 QEMU PID 识别为节点停止。stop 中断而 VM 仍运行时,
状态会恢复为 running;其他未完成过渡会指出用于完成它的命令。destroy 会自行处理
中断过渡。首次 up 失败后可以编辑 Inventory 再重试,因为未提交产物按照日志记录回滚。
日志与环境变量
logs 默认读取客机串口;--source qemu 读取 QEMU 诊断,--source events 读取有大小
上限的部署事件日志。使用 --follow 时,文本流式输出字节,JSON 输出 NDJSON 记录,
YAML 输出文档流。0.9 候选版本将普通 events/qemu 日志读取显示为可读记录,
只有 --verbose 才显示 QEMU argv。
| 环境变量 | 用途 |
|---|---|
BARN_HOME |
绝对路径的私有状态目录,默认 ~/.barn;不能是符号链接或用户主目录等范围过大的目录 |
BARN_REPO |
默认仓库;被命令提供的 --mirror、--repo 依次覆盖 |
BARN_OUTPUT |
text、json、yaml;展示参数优先 |
BARN_VERBOSE |
布尔诊断默认值;展示参数优先 |
BARN_VMNET_ARCHIVE |
macOS setup 使用的固定 socket_vmnet 归档绝对路径,仍执行摘要检查 |
NO_COLOR |
非空时关闭颜色 |
SSH 透传与命令补全
barn ssh [node] [--] [command ...] 打开会话或运行可选命令;
barn exec [node] [--] <command ...> 必须给出命令并透传退出码。-- 之前的展示参数
属于 Barn。ssh 中 -- 之后的参数会像普通 SSH 一样以空格连接,再交给远端 shell 解释;
exec 保留多个参数的边界,需要 shell 展开或管道时请显式使用 sh -c;
单个命令字符串仍保留 shell 简写行为。
有 -- 时,其前面只能是空或一个已知节点。为方便交互使用,也接受省略 --:已知
首参数选节点,否则把整段当成默认节点上的命令,并显示 warning。0.9 候选版本会检查
包含数字或 - 的首参数是否像节点名误拼:长度不超过四个字符时最多一个编辑距离,
更长时最多两个。符合时会拒绝执行;ls、df、wc 等普通命令仍可运行。脚本中请明确写 --。
加载 barn completion bash|zsh|fish|powershell 可获得命令与作用域准确的参数补全,
同时补全命令别名、模板、镜像别名、枚举参数,以及从期望/已应用规格只读解析出的节点名。
0.9 候选版本还会让 -f 补全只列出 YAML 文件。
退出码
此表列出 Barn 0.9.0 发布候选的退出码契约。缺少配置、未知镜像均为 usage(2); setup/network 失败按原因区分为 runtime(1)或 capability(3)。
| 代码 | error |
含义 |
|---|---|---|
| 0 | 成功,包括客机可用但可选功能受限 | |
| 1 | runtime |
操作已执行但失败(外部工具、下载或客机失败) |
| 2 | usage |
命令行或 Inventory 有误 |
| 3 | capability |
宿主缺少工具、Barn 网络或权限 |
| 4 | conflict |
Deployment 当前状态不允许,或另一个 barn 命令正持有它 |
| 5 | partial |
节点级批处理失败;检查 failures[],已经成功的同伴会保留 |
| 6 | resource |
宿主地址、端口、网段或磁盘被占用 |
| 7 | integrity |
已校验的摘要、签名、身份或属主不一致 |
| 130 | cancelled |
被中断(SIGINT/SIGTERM)或拒绝确认 |
0.9 候选版本中,修改类命令遇到另一个 Barn 命令持有部署锁时,最多等待 10 分钟
并指出对方;超时以 4 退出,reason 为 deployment_busy。status、ssh、exec、
ssh-config、hosts 不等待。status 在显示已记录状态时通过 note 报告并发操作;
这不代表该部署操作已完成。
ssh 与 exec 原样透传 SSH 子进程退出码,包括 255;255 可能是 SSH 连接失败,
也可能是远端命令返回该值。文本、JSON 与进程退出码保持一致。
2.3 - Mac 命令
Barn 0.9.0 发布候选,尚未发布。 当前验证结果与发行前检查见
当前状态。请以实际运行的 barn mac --help 为准。
barn mac 需要 Apple 芯片与 macOS 27 或更高版本,以已登录用户身份运行,拒绝以
root 运行。在其他宿主上该命令默认隐藏,需要 Mac 组件的命令会以
mac_host_unsupported 失败。不带子命令的 barn mac 等同于 barn mac ls。
命令
| 命令 | 用途 |
|---|---|
ls |
列出所有机器的状态、地址、SSH、macOS 版本、资源与共享;别名 list、status、st |
up [name] |
按需创建机器,启动并等待 SSH 与 sudo 可用 |
start [name...] |
启动已有机器 |
stop [name...] |
正常关机,两分钟后仍未停止则断电 |
restart [name] |
先停后启,使配置变更生效 |
open [name] |
显示桌面,机器已停止时先启动 |
ssh [name] |
交互式终端;-- 之后是交给客机 shell 的命令行 |
exec [name] -- cmd |
执行命令并保留参数边界 |
configure name |
修改机器设置 |
recreate name |
用全新的 macOS 替换机器,保留其设置 |
destroy name... |
删除机器 |
password [name] |
显示或复制登录密码 |
ssh-config |
打印、安装或移除 OpenSSH 条目 |
logs [name] |
最近的运行日志 |
setup |
只准备 macOS 基础镜像,不创建机器 |
image ls |
列出恢复镜像与基础镜像及使用它们的机器;别名 list |
image update |
把 Apple 最新的 macOS 27 准备为默认基础镜像 |
image prune |
列出不再使用的镜像,加 --yes 才删除 |
doctor |
检查宿主、组件、基础镜像与每台机器 |
各命令的参数
| 命令 | 参数 |
|---|---|
up |
--cpu --memory --disk --user --share --clipboard --subnet --ipsw -y/--yes -n/--no-wait --open |
start |
--all -n/--no-wait --open --recovery |
stop |
--all --force |
restart |
-n/--no-wait --open |
configure |
--cpu --memory --share --unshare --clipboard --subnet |
recreate |
--update --force -n/--no-wait |
destroy |
--force |
password |
-c/--copy |
ssh-config |
-i/--install --remove |
logs |
-n/--lines(默认 100,最多 10000) |
setup |
--ipsw --disk -y/--yes |
image update |
--ipsw -y/--yes |
image prune |
--installers -y/--yes |
不带机器名称的命令作用于唯一的一台机器或 mac1;有多台机器且没有 mac1 时会要求
指定名称。start 与 stop 可接收多个名称或 --all。destroy 与 recreate 会先说明
将删除的内容,并要求输入命令名确认;没有终端时用 --force 确认。
参数取值
| 参数 | 取值 |
|---|---|
--cpu |
虚拟 CPU 数,至少 2,不超过 Mac 的逻辑 CPU 数;默认 4 |
--memory |
16G、16GiB、16GB 或字节数;至少 4 GiB,不超过物理内存;默认 8 GiB |
--disk |
基础镜像容量,至少 32 GiB;默认沿用已准备的基础镜像,即 100 GiB。其他容量会安装另一个基础镜像 |
--user |
管理员账号;默认你的 macOS 用户名,该名称不合法时为 barn |
--share |
[name=]path[:ro|:rw],可重复,最多 8 个;名称默认取路径最后一段;~/ 展开为主目录 |
--clipboard |
on 或 off;默认 on |
--subnet |
规范的私有 /24,例如 10.10.30.0/24;auto 表示第一个空闲网段 |
up 遇到与已有机器不同的创建参数时直接拒绝而不是忽略,并在 next: 行给出修改方法。
CPU、内存、共享、网段与剪贴板用 configure 修改。账号与磁盘容量在机器的整个生命周期内
固定,recreate 也会保留它们:需要其他取值时请另建机器。更换 macOS 版本需先执行
image update,再执行 recreate --update。
机器
- 名称:1–32 个小写字母、数字或中间连字符,以字母开头,例如
mac1、dev、build-2。 - 运行上限:每台 Mac 同时运行两台 macOS 虚拟机,其他工具与 macOS 安装过程也计算在内。 Barn 从不为腾出名额而停止任何机器。
- 账号:管理员账号,免密 sudo、SSH 密钥登录、桌面自动登录,并开启远程登录;
SSH 密码登录被关闭。登录密码随机生成,保存在机器目录的
password文件中。 - 客机名称:电脑名称即机器名;本地主机名为
barn-<name>,因此客机以barn-<name>.local应答。 - 共享:一个由 macOS 挂载到
/Volumes/My Shared Files/<name>的 VirtioFS 设备。 共享必须是已存在的目录,不能是符号链接,只能在机器停止时修改。 - 剪贴板:纯文本,在窗口获得或失去焦点时经这台机器的 SSH 连接同步;最大 1 MiB; 标记为敏感的内容不会发送。
- 停止:通过客机中的 macOS 正常关机;两分钟后仍在运行则断电,结果中带
"forced": true。--force立即断电。
网络
每台机器的网络由它自己的 runner 进程在启动时创建,停止时随之消失,不涉及任何守护进程或 root 权限。
| 项目 | 取值 |
|---|---|
| 网段 | 在 10.10.20.0/24 到 10.10.59.0/24 之间选择第一个空闲的私有 /24,避开宿主路由和其他机器;也可用 --subnet 指定 |
| 网关 | .1,即 Mac |
| 客机地址 | .10,通过对机器 MAC 地址的 DHCP 保留分配 |
| 可达性 | 经 NAT 访问 Mac 与互联网;不能访问其他机器与局域网 |
宿主路由(例如 VPN)与机器网段重叠时,start 会以 mac_subnet_in_use 拒绝启动。
SSH 主机密钥绑定到机器实例而不是地址,因此 configure --subnet 后信任关系不变。
macOS 的“本地网络”隐私控制会阻止未获授权的第三方程序连接这些网络,报错为
“No route to host”;需要在隐私与安全性 → 本地网络中允许对应应用。Barn 自身通过
Apple 的 /usr/bin/nc 与 /usr/bin/ssh 连接,不受该限制。
JSON 输出
所有命令都支持 --json 与 --yaml,进度信息输出到标准错误。
ls
| 字段 | 取值 |
|---|---|
state |
prepared(尚未完成首次启动)、starting、running、stopping、stopped、unknown |
ready |
仅当本次检查通过 SSH 登录客机并验证 sudo 时为 true |
ssh |
ready、pending(首次启动进行中)、unavailable、offline、unchecked |
observed |
客机报告的 macOS 版本与基础镜像不同时出现 |
window_visible |
桌面窗口显示期间出现 |
error、warnings |
最近一次记录的失败,以及本次检查发现的 SSH 问题 |
生命周期结果
up、restart、open、recreate 与 configure 返回单个结果;start、stop 与
destroy 返回 {"machines": [...]},每台机器一项,只指定一台时也是如此。
| 字段 | 取值 |
|---|---|
action |
created、started、running(已在运行)、restarted、recreated、opened、configured、stopped、powered_off、already_stopped、destroyed、absent |
forced |
正常关机未完成、只能断电时为 true |
window |
显示了桌面时为 true |
warnings |
不影响结果的后续事项,例如下次启动才生效的变更 |
exec --json 返回与 Linux barn exec --json 相同的对象:node 为机器名,
exit_code、stdout 与 stderr 来自客机。交互式 ssh 没有 JSON 形式。
失败
退出码与 Barn 命令行一致;远程命令自身的退出码经 ssh 与
exec 原样返回。JSON 失败结果带有稳定的 reason 与 next 命令:
| Reason | 退出码 | 含义与下一步 |
|---|---|---|
mac_host_unsupported |
3 | 不是 Apple 芯片,或 macOS 低于 27 |
mac_runner_missing |
3 | 命令行旁边没有安装 Mac 组件 |
mac_runner_protocol |
3 | 命令行与组件来自不同构建,请一起安装 |
mac_root |
2 | 请以普通登录用户运行,不要使用 sudo |
mac_download_consent |
2 | 没有终端时下载 macOS 需要 --yes,或改用 --ipsw |
mac_machine_absent |
4 | 没有该名称的机器;执行 barn mac up NAME |
mac_not_initialized |
4 | 机器尚未完成首次启动;执行 barn mac up NAME |
mac_not_running |
4 | ssh/exec 需要机器正在运行;执行 barn mac start NAME |
mac_running |
4 | 该变更需要先停机;执行 barn mac stop NAME |
mac_configuration_conflict |
4 | up 的参数与已有机器不同;按提示执行 configure 或其他命令 |
ssh_config_linked |
4 | ~/.ssh/config 是链接;请手动加入打印出的 Include 行 |
mac_vm_limit |
6 | 已有两台 macOS 虚拟机在运行;停止提示中的那台 |
mac_subnet_in_use |
6 | 宿主路由与机器网段重叠;执行 configure NAME --subnet auto |
disk_full |
6 | 可用空间不足以下载或安装 macOS |
mac_machine_damaged |
7 | 启动过的机器丢失了磁盘或身份文件;其目录原样保留 |
mac_readiness_interrupted |
130 | stop 中断了首次启动时的 SSH 等待 |
文件
运行时 socket 位于 /tmp/barn-mac-<uid>-<hash>/。ssh-config 写入
~/.ssh/barn-mac_config,并在 ~/.ssh/config 中加入一个 # barn-mac:include
区块,与 Linux 的 # barn:include 区块互不影响。桌面窗口位置保存在
~/Library/Preferences/io.pgsty.barn.mac-runner.plist。
Barn 在客机中写入 ~/.ssh/authorized_keys、/private/etc/sudoers.d/80-barn、
/etc/ssh/sshd_config.d/000-barn.conf,设置电脑名称与本地主机名,并用 pmset
关闭睡眠。
2.4 - 镜像
Barn 使用物化的静态 Catalog 与不可变 qcow2 工件。官方与 HTTP Catalog 必须签名; 用户显式选择的本地或 HTTPS 仓库可以不签名。更新 Catalog 不需要发布新的 Barn 二进制,但二进制决定信任哪些签名公钥与镜像安全规则。
EL7、EL9 9.3/9.6 与 EL10 10.0 是 deprecated 兼容镜像;其余内置版本均为
supported。
别名与拉取顺序
Barn 0.9.0 内置 Catalog 2026092902,包含 9 个 Family、39 个工件。el7 只有 amd64,其余 Family 均有 amd64 与 arm64。
EL9 包含 9.3、9.6、9.7、9.8;EL10 包含 10.0、10.1、10.2。
默认请求为本机架构的 u24:stable(Ubuntu 24.04)。
以下 stable 均覆盖 amd64 和 arm64。这是内置 Catalog 快照,不是实时仓库列表。
运行 barn update,再用 barn image list 查看选定仓库当前的目录。带日期的公开
端点检查与 Guest 小版本观测见当前状态。
| Family | 内置 stable | 发行版系列 |
|---|---|---|
d12 |
20260923.2610.1 |
Debian 12 |
d13 |
20260914.2601.2 |
Debian 13 |
el8 |
8.10.20240528.2 |
Rocky Linux 8.10 |
el9 |
9.8.20260525.2 |
Rocky Linux 9.8 |
u22 |
20260926.0.0 |
Ubuntu 22.04 LTS |
u24 |
20260926.0.0 |
Ubuntu 24.04 LTS |
u26 |
20260927.0.0 |
Ubuntu 26.04 LTS |
Debian 保留离线安装的 XFS 工具和已生成的 en_US.UTF-8,默认 locale 仍为
C.UTF-8。Ubuntu 保留 Canonical 原始镜像,账户与网络由启动时的 cloud-init 配置。
Debian 12 的 9 月 23 日上游构建仍缺少 XFS 工具和 en_US.UTF-8,这两项定制仍然
必要。上述 Ubuntu 原版已包含二者,amd64、arm64 均于 9 月 29 日通过 locale 和
XFS 数据盘检查。
更新 Catalog 只改变新解析的 stable;既有 VM 和显式锁定版本继续引用原来的基础镜像。
| 别名 | 发行版 | 架构 | 启动 | 状态 |
|---|---|---|---|---|
el7 |
CentOS Linux 7.9 / 2211 | amd64 | BIOS | deprecated |
el8 |
Rocky Linux 8.10 | amd64、arm64 | UEFI | supported |
el9 |
Rocky Linux 9.7 / 9.8 | amd64、arm64 | UEFI | supported |
el9 |
Rocky Linux 9.3 / 9.6 | amd64、arm64 | UEFI | deprecated |
el10 |
Rocky Linux 10.1 / 10.2 | amd64、arm64 | UEFI | supported |
el10 |
Rocky Linux 10.0 | amd64、arm64 | UEFI | deprecated |
d12、d13 |
Debian | amd64、arm64 | UEFI | supported |
u22、u24、u26 |
Ubuntu | amd64、arm64 | UEFI | supported |
Catalog 状态只表达支持策略,不是启动开关:supported 表示已通过声明的支持门禁;
testing 可在显式测试/风险接受下使用,但不受支持;deprecated 只为 EOL 兼容保留;
unknown 尚无支持分类。非 supported 条目仍可运行,但会打印警告。
拉取时 Barn 会:
- 为整条命令读取一次选定仓库的本地 Catalog:即本次构建内置的 Catalog,或最近一次
为该仓库通过
barn update/image sync激活的 Catalog; - 解析
image[:channel]或image@version-prefix,官方 Catalog 缺省为u24:stable; 独立image pull默认使用本机架构,可通过--arch覆盖;生命周期解析遵循vm_arch; - 只有尺寸、SHA-256、qcow2 结构全部匹配时才复用本地文件;
- 否则下载 Catalog 指定的准确工件,并支持重试和断点续传;两个官方仓库可互相回退, 自定义仓库仍为唯一来源。接受的字节始终须匹配 Catalog;不可变 Upstream URL 只用于溯源。
Release 构建默认使用 https://repo.pigsty.io/barn;仅有长参数的 --mirror 选择
https://repo.pigsty.cc/barn。优先级依次为 --repo、--mirror、BARN_REPO、
全球默认仓库,两个官方根都保持规范的签名 Catalog 信任。仓库选择同时决定本地 Catalog
槽位和下载来源;即使字节已缓存,仍需选择相同的自定义仓库。Barn 不会自动刷新
Catalog,已有激活目录与已校验缓存时,普通镜像解析可以离线进行。
运行 barn update 可获取、校验并激活选定
仓库当前的 Catalog。Catalog 更新使用该指定源,失败时直接报错;镜像下载则在所有
允许的来源均无法提供通过校验的字节时失败。
仅改变 --repo 不会获取或激活该仓库的 Catalog;使用它的自定义别名前,先运行
barn update --repo <root>。
已校验但可写的缓存文件会恢复为只读;损坏且未被引用的缓存会先保留为带
.corrupt-<timestamp> 后缀的文件,再重新下载。仍被 VM 引用的基础镜像保持原位并报错。
运行时策略
匹配架构正常使用原生 HVF/KVM,只有一个 Catalog 已知例外:Stock EL8 arm64 的 64K
Granule Kernel 无法通过 Apple HVF 运行,因此 Apple Silicon 会自动选择可见的同架构
TCG。显式外来 vm_arch 也会使用 TCG;arm64 宿主上的 amd64 Guest 使用单翻译线程,
以保留 x86 内存序。TCG 结果不能作为性能证据。
EL7 刻意仅支持 Linux/amd64 原生运行。Linux setup 只安装宿主原生 QEMU;外来架构必须
先安装对应 System Emulator 与 UEFI 固件,up、recreate 才会继续;plan 无需
这些工具就能解析 Catalog 镜像与运行时;但 local-* 命名导入在解析时会检查缓存字节,
仍然需要 qemu-img。
未签名仓库必须是本地路径或 HTTPS。HTTP 仓库必须提供可信密钥签名;不可变 Upstream 工件 URL 必须使用 HTTPS。
信任与校验
当前普通构建已经内置两把生产校验公钥;私有签名密钥不在源码仓库中。Catalog 激活会拒绝 未知密钥、畸形内容、同 Revision 异内容,以及低于该仓库独立 High-water Mark 的 Revision;只有操作者显式允许时才可降级。
镜像必须是尺寸与 SHA-256 匹配的纯 qcow2,不得有 backing file、外部数据文件、加密或 未知不兼容 Feature。通过校验的 Base Image 变成只读;节点根盘使用 Overlay,永不修改 Base。
image reset 恢复二进制内置的 Catalog,但不会清除防回滚 High-water Mark。
barn update 立即检查仓库并激活更新的 Catalog。Barn 不会自动刷新 Catalog;每个版本
内嵌的 Catalog 会一直使用到你运行 update。image sync 是指定精确 URL 或文件(含降级)的
恢复路径。
按仓库恢复时要显式传入同一个根目录:
--repo 决定独立的活动 Catalog 与 High-water 槽,位置参数中的源不会改变这个选择。
image sync、image reset 接受 --repo,不接受 --mirror;省略 --repo 时使用
BARN_REPO 或编译期默认值。未签名自定义 Catalog 的精确源必须是选定根下的
catalog.json。
静态仓库格式
发布根刻意保持很小:
repo.yaml 保存人工意图:默认值、别名、Channel、精确版本、架构、启动模式、状态和可选、
只用于溯源的 Upstream URL。source_user 记录镜像声明的源登录身份,例如上游镜像的
rocky,或经过 Barn 官方归一化后的 dba。流水线清理候选镜像时另行接收上游账号。
Catalog/导入元数据不会替换 deployment SSH 用户(默认 dba),也不会自行归一化镜像。
该文件不保存任何生成的摘要或大小;catalog.json 保持同一逻辑树,
但为每个 Variant 物化文件名、SHA-256、工件大小和虚拟大小。repo.yaml 是 schema: 1;
生成的 catalog.json 则是 Barn 内嵌并签名的 Schema-3 Catalog。
不显式设置 file 时,两个预期工件分别是 images/u24-1-amd64.qcow2 与
images/u24-1-arm64.qcow2;已有自定义文件可在 Variant 中覆盖为安全 basename。
Channel 与数值前缀都是可移动 Selector。存在精确 Key 时优先精确匹配;否则只在点分量
边界匹配并选择数值语义最新版本(el9@9.7 选择最新 9.7 Build,el9@9 选择最新
9.x Release)。不可变工件身份仍是 (image, exact version, arch):
barn repo scan 只读;build 执行严格 YAML 校验、完整 qcow2 inspect/check,
并原子替换 Catalog,永不修改 repo.yaml 或 QCOW 字节;verify 要求新鲜物化结果与
现有 Catalog 逐字节一致。build、verify 需要本机 qemu-img,scan 不需要。
应在安装 QEMU 的机器上构建,先发布不可变工件,最后发布 Catalog 与匹配签名,尽量
一起切换两者;正文与签名不一致时验签会失败。
修改 Catalog 内容时必须增加 revision。
本地布局与导入
镜像位于 BARN_HOME/images(默认 ~/.barn/images):各 Family 目录保存下载工件,
manifests/ 保存当前激活的 Catalog 与每个仓库独立的 High-water 状态,local/ 与
local-images.json 保存导入镜像。
CLI 中 --sha256 是可选参数;提供独立获得的可信摘要,才能在必做的 qcow2 检查之外加入
显式真实性校验。导入只复制和校验文件,不会清理凭据、安装 cloud-init、识别 Guest CPU
架构或证明镜像可启动。
命名本地别名必须以 local- 开头,避免未来签名 Catalog 遮蔽它们。--name、--boot、
--source-user 必须同时提供。命名导入记录执行导入的宿主原生架构,没有
image import --arch 参数;外来架构镜像应使用声明明确 Variant 的静态仓库。
别名不可变,镜像字节或元数据改变时应使用新名字。在 Inventory 中通过
vm_image: local-mybase 选择命名导入;不指定名字的导入只填充缓存。
清理
不带参数的 prune 与 --dry-run 只报告候选,--yes 才执行删除。保护集合是选定活动
Catalog 中的全部工件、已应用节点的镜像摘要,以及注册的本地别名。因此,即使没有 VM
使用,当前 Catalog 镜像和命名导入仍会保留。未被保护的镜像与识别出的过期 Staging File
才是候选;不安全或损坏的文件会导致报错。检查自定义 Catalog 的缓存策略时,要传入
相同 --repo。执行 destroy、destroy --purge 与 purge 后镜像仍会保留。
使用 go run ./tools/catalogexport /absolute/new/catalog.json 可逐字节导出编译期
Schema-3 Catalog。
公开 Catalog 若使用相同版本,就必须使用完全相同的字节;同版本不同内容会按 equivocation
拒绝。Release 签名与镜像 Catalog 签名仍属于不同信任域。
2.5 - 镜像流水线
底层 packaging/image-pipeline/build.sh 接受一份已下载的不可变 qcow2 与独立获得的
SHA-256。它绝不下载、上传、修改 Barn 运行时/网络状态、读取签名密钥,也不会把镜像
标成 supported。
以下命令从 Barn 源码目录执行。需要 Python 3 与 qemu-img;offline 还需要可用的
libguestfs virt-customize、virt-cat。这是镜像构建宿主的依赖,与 barn setup
为运行 VM 安装的依赖是不同边界。
模式
validate:复制并重哈希,强制 qcow2 检查,校验单元素 Backing Chain,运行qemu-img check,输出明确不可发布的证据 Bundle;不会修改 Guest 凭据。offline:额外在 Staged Copy 上使用 libguestfsvirt-customize --no-network与virt-cat。它拒绝无关 UID/GID 88 占用,归一化锁定的dba/admin身份,关闭密码与 Root SSH,清理密钥/历史/Host Identity/cloud-init Cache,恢复定向 SELinux Label, 并回读确定性 Marker。
官方 Candidate 矩阵
build-official.py 在同一离线边界上封装固定的八目标矩阵:Debian 12/13 与 Rocky Linux
8/9,各自覆盖 amd64、arm64。每份上游 qcow2、RPM/DEB 输入、Release 名称、Digest 与
Source Epoch 都锁定在 official-v1.json。
不加 --fetch 时,全部锁定输入必须已经位于两个 Canonical Cache 目录;加上后,Wrapper
也只下载固定 HTTPS URL,并在调用离线归一化前拒绝任何 Digest 不匹配。Debian 12/13
安装锁定的 XFS 用户态闭包;Rocky Linux 8 安装锁定的 python36 与 python3-pip
RPM,并在 cloud-init 启用 NTP 时使用镜像已有的 RHEL chrony 模板与 chronyd 服务;
Rocky Linux 9 不需要额外软件包输入。SELinux 标签恢复属于归一化步骤,不是另一组软件包输入。
Debian 同时生成 en_US.UTF-8,并保留 C.UTF-8 作为默认 locale;归一化脚本和
宿主端 Marker 校验都会检查这两项。镜像更新也会保留这两项客机要求。Ubuntu 使用固定
日期的官方原始镜像,不经过这套离线定制流程。
每份结果仍是未签名的 testing Candidate。不传 --target 时构建全部八个目标,重复
该参数可以选择多个目标。--list 显示当前源码锁定的精确版本;目前包含 Debian
20260923.2610.1/20260914.2601.2 与 Rocky Linux
8.10.20240528.2/9.8.20260525.2。
组装接收的是包含按名称命名的 Bundle 的父目录,不是各 Bundle 自身目录。若八个 构建都放在同一个输出根下,执行:
构建分散在不同根时,可以重复 --assemble-from。八个目标都必须有且只有一个 Bundle;
组装会创建新的静态仓库,并调用 PATH 中的 barn 执行 repo build 与 verify,
也可用 --barn /absolute/path/to/barn 指定程序。构建模式使用已存在的输出根,
组装模式的目标目录则必须不存在。生成仓库使用 candidate Channel,而不是 stable,
例如应选 d13:candidate。此过程不包含真机 Smoke、签名、上传或 Catalog 发布。
校验一个已下载镜像
Source/Output 必须是绝对路径;Source 必须 Canonical、普通、非符号链接、复制期间稳定, 且不超过 16 GiB;Output 必须不存在。Builder 使用相邻排它锁、0700 Staging 与一次最终 Rename;失败只删除受保护的 Staging。
成功 Bundle 包含只读 qcow2、Recipe、SLSA Provenance、SPDX Boundary SBOM、状态为
testing 的 manifest-candidate.json、Validation Evidence 与 Checksums。候选 Manifest
是流水线证据格式;仓库组装才会生成运行时使用的 Schema-3 catalog.json。SPDX 文件
描述声明的输入/构建边界,并不是 Guest 文件系统的完整软件包清单。签名刻意位于流水线
之外。固定输入/工具下 validate 模式逐字节可复现;offline Mutation 必须构建两次并比较,
才能成为 Release Evidence。
发布仍需要对每条声明的宿主/Guest 路径进行运行时 Smoke,明确审查支持状态与溯源,
增加 Catalog Revision,进行生产签名,并校验公开工件。构建成功不能直接把 Candidate
改成 supported,也不能证明它已经公开可用。
3 - 关于 Barn
3.1 - 设计
一个有用的抽象
Barn 把一份 Pigsty Inventory 启动成一套本地 QEMU deployment。它刻意不再拥有 project marker、项目注册表、租约模型、Provider Layer 或第二种配置格式。
状态位于当前 Unix 用户的 BARN_HOME(默认 ~/.barn)。产品假设每台电脑只有一套运行中的 Pigsty;
这并不是 root 强制的跨用户单例。
节点级收敛
Barn 只提取已记录的 VM 与 Pigsty 原生字段,计算逐节点哈希,并保存应用状态与完整
进程身份。新增节点增量创建;up 也会启动选中的已停止节点,保留运行中同伴的进程,
同时重试未完成的初始化、刷新托管 hosts 与 SSH 配置。无法识别或确认损坏的测试数据
文件系统可能被清空重建,包括持久盘,详见数据盘。
定义变更需要显式节点重建;配置缺席永远不授权删除。
运行时选择
Guest 架构是部署级期望状态。省略或 native 跟随宿主;显式 amd64/arm64 会准确
选择对应 Catalog 工件。HVF/KVM 原生加速仍是默认路径;外来架构或 Catalog 已知的
镜像/宿主不兼容规则才会选择固定 TCG Profile。没有用户可传的 Accelerator 参数,也不会
因任意原生失败静默回退。
实际架构与加速器保存在每个 QEMU Invocation 中,并通过 status 展示。执行破坏性
recreate 前,Barn 会证明所选 QEMU 二进制与版本、网络后端、镜像字节、启动模式与固件。
以后若新二进制改变运行时策略,也不能把新旧节点混跑:Runtime Drift 必须整体重建。
双网卡与一个固定子网
管理网卡负责 DHCP、DNS、出网与回环 SSH;固定 IP 网卡负责宿主、节点间与 Ansible 流量。macOS 使用 socket_vmnet;Linux 优先跟随当前 NetworkManager,否则使用 systemd-networkd,并通过发行版 bridge helper 接入。若 networkd 尚未启动,只有在 Activation-safety 扫描证明现有 Unit 不会接管真实宿主链路后才启动。
Debian helper 会临时、可逆地限制给调用者真实加入的组。setup 必须通过一次非特权 QEMU bridge smoke;失败后自动回滚安装。
存储与配置有不同生命周期
Inventory 保存期望的 VM 定义;应用状态记录已经创建的内容,包括精确基础镜像身份与 运行时 Invocation。Catalog Channel 移动不会改写已有根盘。
通过校验的基础镜像只读共享,每台 VM 写入自己的根盘 Overlay。数据盘遵循独立的保留 契约:普通 Destroy 保留持久盘,显式磁盘删除或 Purge 才清除它们。镜像缓存清理又有 独立边界,还会保护活动 Catalog 与已注册本地别名。详见存储与访问 和镜像参考。
安全边界
QEMU 与所有 Guest 工件都以调用者身份运行。root 仅用于宿主软件包安装、网络与可选 hosts publisher。 销毁必须同时匹配属主、路径包含、节点身份、QMP/进程身份与工件白名单;任何歧义都会停止。
3.2 - 当前状态
Barn 0.9.0 是尚未发布的候选版本。源码检查、本地构建、软件包、CI、发行和线上文档 分别核验。安装方式见快速上手。
文档基线
| 对象 | 当前身份 | 使用方式 |
|---|---|---|
| 程序与当前文档 | Barn 0.9.0 发布候选 | 安装 Homebrew HEAD 或从源码构建;发行包尚未发布。 |
| CLI 与配置 | barn、barn.yml、BARN_* |
使用版本相关说明前先检查 barn version。 |
| 状态与宿主资源 | ~/.barn、Barn 网络与 helper |
每个用户一套 Linux 部署;macOS 客机使用独立状态。 |
| 镜像仓库 | 官方入口的 /barn 前缀 |
已于 2026-09-29 发布签名 Catalog 2026092902 并完成公网核验,见下方镜像记录。 |
最终发布提交、制品摘要与安装渠道将在完成发布和下载核验后记录。
macOS 客机
barn mac 在 Apple 芯片上运行 macOS 27 虚拟机,见教程与
命令参考。组件名称为 Barn Mac.app,签名标识为
io.pgsty.barn.mac-runner,状态独立保存在 $BARN_HOME/mac。
2026-09-29,本地 CLI/hosts-helper 测试、原生 Bridge/镜像/退出提示/菜单测试、runner 编译、
ad-hoc 签名验证与 probe 通过。这些检查没有启动 VM,不代表完整 Mac 实机生命周期验收。
发行前仍需核验
- 最终 Barn 提交的完整源码、归档、DEB/RPM、安装器与跨平台检查;
- 全新宿主准备、Linux/macOS VM 生命周期与清理;
- Mac Developer ID 签名与公证;
- Barn 0.9.0 的发布与下载核验,包括 Homebrew。
Linux 镜像 Catalog:2026-09-29
两个官方 /barn 入口均已发布签名 Catalog 2026092902:9 个系列、39 个工件。
经过规范化的 Debian 与 Rocky Linux 镜像,其内部配置与元数据统一使用 Barn。
| 系列 | 稳定版本 | 架构 |
|---|---|---|
| Debian 12 | 20260923.2610.1 |
amd64、arm64 |
| Debian 13 | 20260914.2601.2 |
amd64、arm64 |
| Rocky Linux 8 | 8.10.20240528.2 |
amd64、arm64 |
| Rocky Linux 9 | 9.8.20260525.2 |
amd64、arm64 |
| Ubuntu 22.04 / 24.04 | 20260926.0.0 |
amd64、arm64 |
| Ubuntu 26.04 | 20260927.0.0 |
amd64、arm64 |
6 个 Debian 13、Rocky Linux 镜像通过 UEFI 启动、SSH、双网卡、UID/GID 88、Python、
cloud-init 与 XFS 数据盘检查。amd64 使用 KVM,Debian 13 和 Rocky Linux 9 arm64 使用
HVF;Rocky Linux 8 arm64 因上游 64 KiB 内核不兼容 Apple HVF,使用 TCG。
Rocky Linux 8 使用自带的 RHEL chrony 模板和 chronyd 服务。
Debian 12 与 Ubuntu 镜像通过原生 KVM/HVF 启动、SSH、双网卡、UID/GID 88、locale
和 XFS 数据盘检查。Debian 镜像包含锁定版本的 XFS 工具与 en_US.UTF-8,默认 locale
保持 C.UTF-8;Ubuntu 保留 Canonical 原始字节。镜像检查采用隔离的 QEMU user 网络,
完整宿主网络及 VM 生命周期仍需独立验收。
内嵌与公开 Catalog 字节一致,两个官方入口均通过签名校验,新镜像通过公网下载检查。 版本选择与更新行为见镜像参考。
3.3 - 工程与发布
本页描述 Barn 0.9.0 发布候选。构建命令使用当前工作区,请同时记录提交与 未提交变更。源码构建和本地检查通过不代表已经正式发布。
仓库边界
Barn 源码仓库包含代码、测试、构建/打包定义、法律声明、README.md、CHANGELOG.md、
CONTRIBUTING.md、SECURITY.md 与双语应用发布说明。本网站提供用户、设计、运维
与发布文档。运行行为和命令参数需要以匹配的源码及二进制核对;未发布源码的行为不能
代表公开软件包。
Review 记录、临时 Inventory、生成二进制与 Release 输出树不是生产源码输入。
以下输出随时可重建:
bin/:开发构建;dist/与.goreleaser-*:Release/Snapshot Staging;- 根目录
barn、barn-hosts-helper、catalogsign二进制; - Hugo 的
public/与resources/。
构建与源码门禁
make check 包含模块与 Shell 检查、维护脚本归属、单元/Race 测试、Vet、Staticcheck、
死代码与 errcheck 检查、漏洞扫描、四目标跨平台构建、安装器/镜像流水线测试及许可证
检查,准确清单以 Makefile 为准。CI 还单独检查固定工具链、Go 格式、空白与 GoReleaser
配置。质量工具安装步骤见从源码构建。
打包逻辑变更还需要独立 Snapshot 门禁:
安装 packaging/toolchain.env 指定的 GoReleaser、nFPM、Syft 等版本;Snapshot 还需要
验证脚本使用的归档与系统软件包检查工具。输出必须是工作区根目录下尚不存在的新目录,
已有目录会被拒绝。Snapshot 仅在本地生成,不上传 Release。
源码检查不等于真机验证。macOS HVF、Linux KVM/网络、软件包消费、Release 发布与
线上网站渲染需要分别验证。make image-pipeline-native-test 是独立真机镜像流水线
门禁,需要 QEMU/libguestfs 与显式镜像输入。必填的
BARN_IMAGE_PIPELINE_NATIVE_* 变量见 tests/image-pipeline-native-test.sh,
该测试不会下载镜像。
Release 与软件包契约
packaging/、.goreleaser.yaml 与 .github/workflows 属于源码;它们生成的目录不是。
Archive 与 Linux Package 携带配套 CLI 和 hosts-helper 二进制、LICENSE、源码
README,以及根据 go.mod 锁定模块版本重建的准确上游许可证字节。Archive 的二进制
位于 bin/、许可证位于 licenses/;Linux Package 安装 /usr/bin/barn、
/opt/barn/libexec/barn-hosts-helper,文档位于 /usr/share/doc/barn/。
Linux Package 包含 BUILD_INFO.json。GoReleaser Archive 的构建身份在二进制中,发布元数据随资产单独提供,不能假定每种 Archive 都包含
该文件。依赖许可证在构建时生成暂存,详细用户文档保留在本网站。
应用 Release 由 GitHub Actions 构建,提供 checksums.txt、发布元数据与 SPDX SBOM
资产。当前工作流不生成单独的应用发布签名或 provenance/attestation 包。用于认证镜像
Catalog 的 Minisign 签名属于另一套信任机制。
Commit、Tag、归档/软件包验证、CI、草稿上传、公开发行与匿名下载验证应分别记录。
Tag 工作流创建草稿,不会直接发布。pre-1.0 版本在 GitHub 标记为预发布,安装器需要
显式指定 BARN_VERSION。
make release-local VERSION=<version> 在本地构建并验证,不执行发布。它要求干净
工作区正好位于对应 v<version> Tag,配置 origin,使用固定工具,并且暂存/输出
目录尚不存在。未打标签的候选版应使用 Snapshot 路径审核。
镜像归一化
底层 packaging/image-pipeline/build.sh 只接受显式本地 qcow2,不下载也不上传。它复制并
哈希源文件,强制 qcow2 解析,拒绝 Backing/External/Encryption/未知 Feature,运行
qemu-img check,并可在显式 QEMU Sandbox 中做无网络 Offline Guest Mutation。
UID/GID 88 冲突会拒绝,不会含糊改写。
build-official.py 为 Debian 12/13、Rocky Linux 8/9 的 amd64/arm64 目标增加固定、
摘要锁定的 Wrapper。它只允许获取锁定的源镜像与离线软件包输入,输出未签名的 testing
Candidate,并可组装独立候选仓库。真机 Smoke、双构建比较、生产签名、上传与 Catalog
激活仍是后续门禁。
Catalog 逐字节导出命令:
导出器原子写入,拒绝已存在的输出路径。make catalog-sign 与 make catalog-verify
使用 Catalog Minisign 密钥对,生产私钥不进入源码或 CI。应用 checksum 不能替代
Catalog 签名。