跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

使用指南

安装 Barn,启动 Linux 或 macOS 虚拟机,再按需管理机器、文件、镜像与自动化。

本章节指南面向 Barn 1.2.0;变更内容与从 1.1.0 升级的步骤见 Barn 1.2.0 发布说明。你可以在同一台 Apple Silicon Mac 上同时使用 Linux 实验环境与 macOS 虚拟机,两套流程在 ~/.barn 下各自独立管理虚拟机。

快速上手

  • 安装 Barn — 在 macOS 或 Linux 上安装稳定版 CLI,核对宿主软硬件要求并了解版本升级方式。
  • Linux 快速上手 — 启动单节点 Ubuntu 24.04 虚拟机,通过 SSH 登录,并用一份 barn.yml 扩展为多节点固定 IP 实验环境。
  • macOS 虚拟机 — 在 Apple Silicon 上创建和管理 macOS 27 虚拟机,使用原生桌面、SSH、共享目录与剪贴板同步。

Linux 实验环境日常运维

  • 日常管理 — 查看状态、启停节点、用 plan 预览清单差异,以及按需执行 recreate 或 destroy。
  • 存储与访问 — 配置持久测试数据盘、通过 SSH 传输文件与转发端口,或挂载 Virtio-9p 宿主共享目录。
  • 镜像仓库 — 选择 9 大发行版家族镜像、切换中国镜像站、构建静态镜像仓库或导入本地 qcow2 镜像。
  • 自动化 — 执行无人值守宿主初始化、用 jq 校验 --json 结果、通过 barn provision 批量运行脚本并配合 Pigsty 使用。

故障排查、源码构建与清理

  • 故障排查 — 针对宿主依赖、私网修复、客机阶段警告、SSH 密钥与中断恢复的排查手册。
  • 从源码构建 — 从 v1.2.0 标签编译 CLI、barn-hosts-helper 与原生应用包 Barn.app,并运行贡献者检查。
  • 卸载与清理 — 按序销毁 Linux 与 macOS 虚拟机、清理镜像缓存、卸载宿主网络并移除 Barn 程序。

1 - 下载与安装 Barn

在 macOS 或 Linux 上安装 Barn 1.2.0,检查系统要求,并了解升级方式。

Barn 1.2.0 提供 macOS 与 Linux 的 arm64 和 amd64 归档包,以及 Linux DEB 和 RPM 软件包。请始终以普通 Unix 用户身份运行 barn;安装完成后,可继续阅读 Linux 快速上手或 macOS 虚拟机教程。

说明

Barn 1.2.0 是当前稳定版,通过 GitHub 正式发布频道发布:releases/latest、不带 BARN_VERSION 的安装脚本与 Homebrew 配方都会选择此版本;需要固定版本时设置 BARN_VERSION=1.2.0。Apple Silicon 归档包含配套的 barn、barn-hosts-helper 与 macOS 原生应用包 Barn.app,均经过 Developer ID 签名与 Apple 公证。只有从源码构建时才需要 Go 和 Xcode。

组件 用途 1.2.0 发行包是否包含
barn 管理 Linux 实验环境与 macOS 虚拟机生命周期的 Go CLI 四种平台归档及 Linux 软件包均包含
barn-hosts-helper 负责 /etc/hosts 主机名集成的受限辅助程序 与同版本 CLI 配套打包
Barn.app 基于 Virtualization.framework 的原生运行器与 macOS 客机桌面 Darwin arm64 归档与 Apple Silicon Homebrew 安装包含;仅 macOS 客机需要

安装发行版本

运行 Barn 的电脑称为 宿主。请按宿主操作系统选择安装方式:macOS 推荐使用 Homebrew,Linux 推荐使用安装脚本。

在普通用户终端中使用 Homebrew 安装 Barn 及 QEMU 依赖:

brew install pgsty/infra/barn
barn version

在 Apple Silicon 上,Homebrew Formula 还会将 Barn.app 安装至 libexec,CLI 会自动找到它。macOS 27+ 用户可运行 barn mac doctor,随后按 Mac 指南创建客机。Intel Mac 使用 CLI 与 helper 运行 Linux 客机。

下载并运行 install.sh。未设置 BARN_VERSION 时,脚本安装最新稳定版;设置 BARN_VERSION=1.2.0 可固定为本版本。脚本会自动识别 amd64 或 arm64 架构,校验归档 SHA-256,并将 CLI 与配套的 barn-hosts-helper 安装到 ~/.local/bin(无需 sudo):

curl -fLO https://github.com/pgsty/barn/releases/latest/download/install.sh
bash install.sh
export PATH="$HOME/.local/bin:$PATH"
barn version

请将 export PATH="$HOME/.local/bin:$PATH" 加入 ~/.bashrc 或 ~/.zshrc 等 Shell 启动文件,并保留 .barn-releases/ 下的版本化目录结构。如果你在 macOS 上不想使用 Homebrew,也可以直接运行这段安装命令,后续再通过 barn setup 配置 QEMU 与宿主网络依赖。

首次交互式执行 barn up 时,Barn 会检查 Linux 客机所需的宿主依赖与私有网络,展示宿主准备计划,并在安装任何内容前询问一次;只有具体步骤需要时才请求管理员权限(sudo)。没有终端时,barn up 只报告缺少的条件,无人值守准备请执行 barn setup --yes。你也可以先运行 barn setup --dry-run 预览宿主准备计划。

系统要求

客机 宿主 运行时依赖
Linux macOS(Apple Silicon 或 Intel) QEMU 8.2.1+、HVF
Linux Linux(arm64 或 amd64) QEMU 6.2+、可用的 KVM、NetworkManager 或 systemd-networkd
macOS 27 Apple Silicon、macOS 27+、已登录图形桌面会话 原生应用包 Barn.app(无需 QEMU)

一台默认规格的 Linux 虚拟机分配 1 vCPU 与 2 GiB 内存,搭配按需增长的 qcow2 稀疏磁盘(64 GiB 根盘与 128 GiB 测试数据盘)。

首次创建 macOS 虚拟机约需 65 GiB 可用磁盘空间,用于存放 Apple 恢复镜像(约 25 GiB)、已安装的基础镜像(约 27 GiB)以及初始写入数据。Mac 虚拟机默认分配 4 vCPU、8 GiB 内存和 100 GiB APFS 克隆磁盘;后续新建虚拟机除非通过 --disk 另行指定,否则默认沿用已有基础镜像的磁盘容量。各客机的具体约束见平台与限制。

下载 Barn 1.2.0

正式版发布于 2026-11-12,请按宿主系统与处理器架构选择文件:

宿主系统 架构 归档 Debian / Ubuntu RHEL / Fedora
macOS Apple Silicon (arm64) tar.gz — —
macOS Intel (amd64) tar.gz — —
Linux x86-64 (amd64) tar.gz DEB RPM
Linux ARM64 (arm64) tar.gz DEB RPM

SHA-256 校验表 · 发行元数据 · 安装脚本

每个归档和软件包均提供同名的 .spdx.json 依赖清单,见 GitHub Release。Darwin arm64 归档包含签名并公证的 Barn.app。

其他安装方式

Linux 软件包

DEB 与 RPM 软件包已声明 QEMU、UEFI 固件和 OpenSSH 依赖。ARM64 宿主请将文件名中的 amd64 替换为 arm64:

Debian / Ubuntu
barn_release=https://github.com/pgsty/barn/releases/download/v1.2.0
curl -fLO "$barn_release/barn_1.2.0_linux_amd64.deb"
curl -fLO "$barn_release/checksums.txt"
sha256sum --check --ignore-missing checksums.txt
sudo apt install ./barn_1.2.0_linux_amd64.deb
barn version
RHEL / Fedora
barn_release=https://github.com/pgsty/barn/releases/download/v1.2.0
curl -fLO "$barn_release/barn_1.2.0_linux_amd64.rpm"
curl -fLO "$barn_release/checksums.txt"
sha256sum --check --ignore-missing checksums.txt
sudo dnf install ./barn_1.2.0_linux_amd64.rpm
barn version

手动安装归档

从 GitHub Barn 1.2.0 发布页下载对应宿主系统的 barn_1.2.0_<os>_<arch>.tar.gz(darwin 或 linux,arm64 或 amd64)与 checksums.txt,解压前先校验 SHA-256:

barn_release=https://github.com/pgsty/barn/releases/download/v1.2.0
curl -fLO "$barn_release/barn_1.2.0_darwin_arm64.tar.gz"
curl -fLO "$barn_release/checksums.txt"
shasum -a 256 -c checksums.txt --ignore-missing

校验通过后解压归档,将其中的 bin/ 目录加入 PATH。请保持发行包目录结构完整:barn 与 barn-hosts-helper 必须配套,Darwin arm64 归档还包含 bin/Barn.app。CLI 调用 helper 前会核对其内嵌的 SHA-256 摘要,并自动发现旁边的 App。

从源码构建

如需参与开发或自行编译 macOS 原生应用包 Barn.app,请参阅从源码构建。

升级 Barn

从 1.1.0 升级到 1.2.0 会保留 ~/.barn 下的虚拟机磁盘、SSH 密钥、状态和配置。先停止正在运行的 Mac 虚拟机,再通过原安装渠道一起替换 CLI、barn-hosts-helper 与 Barn.app。未指定 CPU/内存的 Linux 清单现在默认使用 1 vCPU / 2 GiB;如需保留旧默认值,请显式设置 vm_cpu: 2、vm_mem: 4GiB 并检查 barn plan。已应用 VM 的资源会保留到显式执行资源变更操作为止。详见 1.2.0 发布说明。

请沿用最初的安装方式执行升级。macOS Homebrew 用户可直接运行:

brew update
brew upgrade pgsty/infra/barn
command -v barn
barn version

Linux 用户可重新运行 install.sh(未设置 BARN_VERSION 时选择最新稳定版),或安装新版 .deb / .rpm 软件包,随后通过 command -v barn 和 barn version 确认当前生效的二进制路径。 若用户目录和系统包/Homebrew 中都安装了 Barn,请更新当前 PATH 选中的安装,或调整 PATH 后再次核验版本。

Barn 将程序升级与客机镜像更新解耦,避免升级工具时意外改动现有虚拟机的系统版本:

更新对象 命令 对现有虚拟机的影响
Barn CLI、helper 与随包 App 重新安装或 brew upgrade 保留所有现有虚拟机磁盘与状态
Linux 镜像目录 barn update(或 barn update --mirror) 仅对新建或显式 recreate 的节点生效
macOS 基础镜像 barn mac image update 准备新基础镜像;已有虚拟机需执行 barn mac recreate NAME --update 才会切换

如遇下载代理或 PATH 问题,请参阅故障排查;如需移除程序与宿主状态,请参阅卸载与清理。

2 - Linux 快速上手

启动 Ubuntu 虚拟机,通过 SSH 连接,再用同一份主机清单扩展为固定 IP 的 Linux 实验环境。

在 Mac 或 Linux 宿主上创建一台 Ubuntu 24.04 虚拟机,通过 SSH 登录,再用同一份 YAML 清单扩展为多节点固定 IP 实验环境。如需在 Apple Silicon 上运行 macOS 客机,请阅读 macOS 虚拟机教程。

本教程使用 Barn 1.2.0,默认每节点 1 vCPU、2 GiB;可在清单中显式设置资源,详见配置默认值。

开始之前

安装 Barn,并确保宿主至少预留 2 GiB 可用内存供客机使用。请在交互式终端中以普通用户执行下面的命令:Barn 改动宿主前会询问一次,只有需要管理员权限的步骤才会提示输入 sudo 密码。CI 等无人值守场景请参阅自动化指南。在中国大陆,可以在首次 barn up 时加上 --mirror,从中国官方仓库 repo.pigsty.cc 下载镜像。

首次启动前定制配置

默认实验环境只有一个 Ubuntu 节点,架构跟随宿主:Apple Silicon 为 arm64,Intel/AMD 为 amd64。日常使用无需指定架构;跨架构选择与覆盖优先级见镜像与架构配置。保持默认即可直接跳到启动并连接。如果希望先自定义拓扑、网段或操作系统镜像,请在首次 barn up 之前生成并编辑清单:

  1. 生成初始配置文件(dual、trio、full 分别生成 2、3、4 节点模板,-c 10.20.30.0/24 指定网段,-I el9 为所有节点写入同一个镜像,-A amd64 设置 vm_arch):

    mkdir -p ~/barn-lab && cd ~/barn-lab
    barn init
  2. 编辑 barn.yml,调整镜像或硬件资源:

    barn.yml
    all:
      vars:
        admin_ip: 10.10.10.10
        vm_image: u24
        vm_cpu: 1
        vm_mem: 2GiB
      children:
        nodes:
          hosts:
            10.10.10.10: { nodename: meta }
  3. 校验 YAML 并预览变更计划:

    barn validate
    barn plan

barn validate 和 barn plan 无需安装 QEMU 或配置宿主网络即可运行,下一节的 barn up 会直接使用这份 barn.yml。完整配置字段见配置参考。

启动并连接

mkdir -p ~/barn-lab && cd ~/barn-lab
barn up

首次运行且既没有配置文件也没有已有部署时,barn up 会在改动任何东西之前打印一份简短的准备计划,只列出适用的行:dependencies 列出缺少的软件包(QEMU、UEFI 固件、OpenSSH)及所用的包管理器,network 给出要准备的固定 IP 网段,config 给出将要写入的单节点 barn.yml,sudo 说明哪些步骤需要 root 权限。在已经装有 QEMU 的宿主上,计划如下:

ITEM     STATE    MESSAGE
network  planned  prepare 10.10.10.0/24
config   planned  create /home/alice/barn-lab/barn.yml
sudo: network (root-owned barn0 bridge)
Continue with this setup? [Y/n]

确认一次后,sudo 可能会要求输入密码。随后 Barn 会下载并校验基础镜像,在终端中实时刷新进度表,等待 SSH 就绪:

NAME  ADDRESS      STATE  MESSAGE
meta  10.10.10.10  ready  SSH ready: barn ssh meta
boot 1/1 nodes: 39s [DONE]

如果 barn up 报错退出,先运行 barn doctor 检查宿主,再用 barn logs meta 查看客机控制台输出,修复问题后重新运行 barn up。常见故障见故障排查。

登录客机:

barn ssh

barn ssh 会使用部署密钥以管理员用户 dba 登录客机,支持免密 sudo。barn up 同时会安装 SSH 别名,所以直接运行 ssh meta 也能登录。输入 exit 退回宿主终端,后面的命令都在宿主上执行。

默认配置 值
节点与地址 meta(10.10.10.10)
镜像 Ubuntu 24.04(u24:stable,与宿主架构一致)
CPU 与内存 1 vCPU、2 GiB
磁盘 64 GiB 根盘写时复制层,以及挂载到 /data 的 128 GiB 测试数据盘

两块磁盘均为按需增长的 qcow2 稀疏文件。如果默认网段 10.10.10.0/24 与本机现有路由冲突,首次 setup 会为未修改过的默认模板自动选择另一个空闲的私有 /24 网段——实际分配的地址以生成的 barn.yml 和 barn status 为准。

说明

每个 BARN_HOME 对应唯一一套 Linux 部署:Barn 默认将 Linux 实验环境的状态保存在 BARN_HOME(即 ~/.barn)下。切换工作目录不会创建第二套实验环境;在没有清单文件的目录中运行 barn up 会直接恢复现有部署。设计背景详见一套部署,没有项目概念。

查看并使用虚拟机

barn status
NAME  ADDRESS      STATE    IMAGE             SPEC  ROOT
meta  10.10.10.10  running  u24@20261017.0.1  1c2g  64 GiB

barn status 列出每个节点的固定地址、记录的状态、镜像版本与规格。在宿主上执行客机命令时,用 -- 隔开远程命令:

barn exec meta -- hostname
barn exec meta -- df -h / /data

barn up 会确认管理 SSH 可用,并报告数据盘、私网等客机阶段是否存在功能限制。修复问题或初始化被中断后,重新运行 barn up 即可继续收敛,已处于健康状态的虚拟机不会重启。

警告

数据盘属于可丢弃的测试存储。在客机恢复期间,若文件系统检查工具报告 ext4 或 XFS 数据盘存在可识别的损坏,barn up 会将其重置(持久数据盘同样如此)。重要数据请保存在宿主上,磁盘保留与恢复边界详见存储与访问。

扩容为多节点环境

要把实验环境扩展为四个节点(按默认每节点 2 GiB 计算共需 8 GiB 客机内存),在现有 barn.yml 的 all.children.nodes.hosts 下追加三个节点。新地址需要与 meta 位于同一个 /24;如果首次运行时 Barn 改选了其他网段,请使用那个网段:

barn.yml
all:
  vars:
    admin_ip: 10.10.10.10
  children:
    nodes:
      hosts:
        10.10.10.10: { nodename: meta }
        10.10.10.11: { nodename: node-1 }   # 新增
        10.10.10.12: { nodename: node-2 }   # 新增
        10.10.10.13: { nodename: node-3 }   # 新增

预览差异并拉起新增节点:

barn plan
barn up

barn plan 会输出 create: node-1, node-2, node-3,随后 barn up 会在不重启 meta 的前提下创建这三个节点。

如果修改了已有节点的 CPU 或内存,执行 barn resize <node> 即可应用,并保留虚拟机身份与磁盘;镜像变更仍需执行 barn recreate <node>,这会替换该节点的根盘。从 barn.yml 中删除节点条目不会自动销毁虚拟机,需显式运行 barn destroy <node>。

停止、恢复与清理

barn stop
barn start

stop 与 start 都会保留虚拟机磁盘。不再需要实验环境时,运行 barn destroy 并输入 destroy 确认。Barn 会删除虚拟机及其根盘与非持久数据盘,移除部署状态和它安装的 SSH 别名,同时保留持久数据盘、部署密钥、基础镜像缓存与宿主网络。之后在 ~/barn-lab 中再次运行 barn up,就会根据 barn.yml 重建一套新的实验环境。如需彻底移除所有残留文件,请参阅卸载与清理。

接下来

  • 日常管理 — 查看日志、重启节点、应用配置变更与销毁虚拟机。
  • 存储与访问 — 配置持久数据盘、通过 OpenSSH 传输文件并访问客机端口。
  • 镜像仓库 — 选择 Debian、Rocky Linux、Ubuntu 或导入本地 qcow2 镜像。
  • 自动化 — 无人值守 setup --yes、解析 --json 输出、执行客机脚本,以及与 Pigsty 共用 pigsty.yml。

3 - macOS 虚拟机

用 barn mac 在 Apple 芯片 Mac 上运行 macOS 27 虚拟机:创建、连接、共享文件与剪贴板,以及清理。

barn mac 用于在 Apple Silicon Mac 上创建和管理可随时重建的 macOS 虚拟机,适合编译构建、自动化测试以及复现 macOS 专属问题。每台虚拟机自带管理员账号、免密 sudo、固定绑定的 SSH 密钥与独立私网地址,基于 Apple Virtualization 框架直接以当前用户身份运行,全程无需 sudo。

Mac 虚拟机与 Linux 实验环境完全独立:它不读取 barn.yml,所有数据保存在 $BARN_HOME/mac(默认 ~/.barn/mac)下,执行 Linux 的 barn destroy 或 barn purge 不会影响任何 Mac 虚拟机。

前提条件

  • 一台运行 macOS 27 或更高版本 的 Apple Silicon Mac,且当前用户已登录图形桌面会话(客机同样运行 macOS 27)。
  • 首次创建约需 65 GiB 可用磁盘空间,用于存放从 Apple 下载的恢复镜像(.ipsw,约 25 GiB)、安装后的基础镜像(约 27 GiB)以及启动写入空间。后续每台虚拟机通过 APFS 写时复制克隆基础镜像,按实际改动增长(默认容量上限为 100 GiB)。
  • 与同一版本 CLI 配套的原生应用包 Barn.app,Apple Silicon 发行包与 Homebrew 安装均已包含。
  • 无需 sudo 权限。

受 Apple Virtualization 框架限制,单台 Mac 最多同时运行两台 macOS 虚拟机(其他虚拟化工具启动的实例及正在执行的 macOS 基础镜像安装均计入配额)。你可以创建更多已停止的虚拟机并按需启动其中任意两台(须遵守适用的 Apple 软件许可协议)。

安装

通过 Homebrew 安装预编译发行版:

brew install pgsty/infra/barn
barn version
barn mac doctor

Homebrew 会一并安装经过签名、公证的 Barn.app 及配套 CLI/helper,无需安装 Go 或 Xcode。Apple Silicon 的安装脚本与手动归档同样包含原生 App。升级或替换 App 前请先停止运行中的 Mac 虚拟机。

如需开发 Barn 本身,请参阅构建 Mac 原生组件。

创建第一台机器

barn mac up

如果本机尚未准备 macOS 基础镜像,barn mac up 会先列出下载体积与磁盘空间并请求确认:

info: macOS 27.0 (26A428) is not prepared on this Mac yet.
download:  24.8 GiB from Apple (updates.cdn-apple.com)
then:      install macOS once into a reusable base (about 20 minutes)
free:      551.2 GiB
Download macOS from Apple now? [Y/n]

确认后,Barn 会依次完成以下三步:

  1. 从 Apple 官方(updates.cdn-apple.com)下载恢复镜像,支持断点续传并自动核对 Apple 公布的 SHA-256 校验值。
  2. 一次性安装 macOS 基础镜像,生成一份未启动过的干净母盘(安装期间会临时占用两个运行配额之一)。
  3. 通过 APFS 写时复制克隆出 mac1,启动客机并自动配置同名管理员账号,等待 SSH 与免密 sudo 就绪。
NAME  ADDRESS      STATE    MESSAGE
mac1  10.10.20.10  running  created and ready; macOS 27.0 (26A428), user alice
ready: barn mac ssh mac1
desktop: barn mac open mac1

后续新建虚拟机都会直接克隆这份基础镜像,几秒内即可完成创建,无需重复执行漫长的系统恢复安装。Barn 首次下载默认固定为 macOS 27.0 (26A428);如需跟进更新的 macOS 27 版本,可显式运行 barn mac image update。

如果本机已下载好 Apple 恢复镜像,可通过 --ipsw 直接传入(位于同一 APFS 卷时将直接克隆数据块而无需复制):

barn mac up --ipsw ~/Downloads/UniversalMac_27.0_26A428_Restore.ipsw

在无终端脚本中,需传入 --yes 才会自动下载 25 GiB 镜像;也可使用 barn mac setup 提前准备基础镜像而不创建虚拟机。如果创建新虚拟机时传入了 --no-wait(虚拟机进程启动即返回),在使用 ssh 或 exec 前请再执行一次不带 --no-wait 的 barn mac up NAME 以完成密钥与 sudo 初始化。

使用机器

终端与命令

barn mac ssh                                  # 进入交互式终端
barn mac exec -- sw_vers                      # 直接执行单个程序
barn mac ssh -- 'id; sudo -n true && echo sudo works'
ProductName:		macOS
ProductVersion:		27.0
BuildVersion:		26A428

客机管理员账号默认与宿主 macOS 用户名一致(创建时可通过 --user 自定义),并具备免密 sudo。请在远端命令前加上 --:ssh 会将命令行交给客机 Shell 执行,exec 则直接按参数列表调用目标程序(需要管道或重定向时请显式调用 sh -c,详见 SSH/exec 契约)。两者都会透传客机命令的退出码,配合 --json 可结构化捕获 stdout、stderr 与 exit_code:

barn --json mac exec -- sh -c 'echo out; exit 3'
{
  "command": "exec",
  "node": "mac1",
  "host": "10.10.20.10",
  "arguments": ["sh", "-c", "echo out; exit 3"],
  "success": false,
  "exit_code": 3,
  "stdout": "out\n"
}

完整 JSON 字段说明见 Mac 命令参考。

桌面

barn mac open

barn mac open 会在原生窗口中打开客机桌面,缩放窗口即可动态调整客机分辨率(可通过 View → Enter Full Screen 切换全屏)。直接关闭窗口不会停止虚拟机;再次运行 barn mac open 可重新唤出窗口,若虚拟机已停止则会先启动它。

当客机窗口处于焦点状态时,键盘快捷键会直接发送给客机,宿主侧操作请通过顶部菜单栏执行:

菜单项 作用
Machine → Share Clipboard 在当前会话中开关纯文本剪贴板共享
Machine → Restart… 重启客机内的 macOS 系统
Machine → Shut Down… 正常关闭客机(等同于 barn mac stop)
Window → Keep Running in Background 隐藏桌面窗口,让虚拟机继续在后台运行
Barn → Quit Barn… 选择让虚拟机在后台保持运行,或直接关机

宿主注销或关机时,Barn 会先请求客机正常关机,若超时仍未停止则强制断电。

每台虚拟机还会随机生成一组用于锁屏解锁和桌面管理员弹窗的登录密码。如需复制到剪贴板而不在终端明文回显,可执行:

barn mac password --copy

剪贴板

剪贴板共享会在窗口焦点切换时通过虚拟机自身的 SSH 通道自动同步纯文本,无需在客机内安装额外代理:点击进入客机窗口时可使用在宿主 Mac 上复制的文本,切回宿主应用时则会同步客机内复制的文本。密码管理器标记为敏感的条目、图片和文件不会跨机同步。

如需为某台虚拟机长期关闭剪贴板同步,可执行 barn mac configure mac1 --clipboard off(下次启动时生效)。

共享目录

创建虚拟机时可通过 --share 将宿主目录共享给客机,客机会将其自动挂载到 /Volumes/My Shared Files/<名称>:

barn mac up dev --cpu 8 --memory 16G --share ~/src --share docs=~/Documents:ro
barn mac exec dev -- ls "/Volumes/My Shared Files"

共享名称默认取目录路径的最后一段,末尾追加 :ro 表示只读挂载。共享路径须解析为已存在的目录(支持符号链接),且 Barn 绝不会自动创建或删除宿主共享目录。若需修改已有虚拟机的共享目录,请先停机再运行 barn mac configure:

barn mac stop dev
barn mac configure dev --share data=/Volumes/Work/data --unshare docs
barn mac start dev

由于 macOS 客机的 VirtioFS 在宿主修改文件后可能短暂缓存旧内容,若构建任务需要立即读取最新字节,建议使用 scp 或 rsync 将文件同步到客机本地磁盘。

在其他工具中使用 SSH

当第一台 Mac 虚拟机就绪时,Barn 会在 ~/.ssh/config 中添加一行带标记的 Include,使 ssh mac1、scp、rsync 以及支持 Remote-SSH 的编辑器能够直接按名称连接每台虚拟机,并自动使用该虚拟机的专属密钥与固定主机密钥:

ssh mac1 'uptime'
rsync -a ./project/ mac1:project/
barn mac ssh-config              # 查看生成的 SSH 配置条目
barn mac ssh-config --remove     # 移除 Barn 添加的 Include 并关闭自动写入

如果 ~/.ssh/config 是由 dotfile 工具管理的符号链接,Barn 不会直接修改它,而是打印出需要手动添加的 Include 行。执行 --remove 后如需恢复自动集成,可运行 barn mac ssh-config --install。若你的个人 SSH 配置已占用某个虚拟机同名别名,Barn 会保留你的原有别名,仅按 IP 地址发布该虚拟机的配置。

多台机器

每台虚拟机使用以字母开头的小写字母、数字或内部连字符命名。创建参数(--cpu、--memory、--disk、--user、--share)仅在首次创建该虚拟机时生效:

barn mac up dev --cpu 8 --memory 16G
barn mac ls
NAME  ADDRESS      STATE    SSH    USER   OS          CPU  MEMORY  DISK                 SHARED
dev   10.10.21.10  running  ready  alice  macOS 27.0  8    16 GiB  504.0 MiB / 100 GiB  src,data
mac1  10.10.20.10  running  ready  alice  macOS 27.0  4    8 GiB   4.7 GiB / 100 GiB
limit: 2 of 2 macOS VMs are running; stop one before starting another

省略机器名称时,命令默认作用于当前唯一存在的虚拟机或 mac1(存在多台机器且目标不唯一时会提示显式指定名称)。如果 --disk 指定的容量与现有基础镜像不同,Barn 会先用恢复镜像安装一份对应容量的基础镜像。

每台虚拟机拥有独立的 /24 私有子网(默认从 10.10.20.0/24 起分配,客机地址为 .10),并自动避开局域网、VPN、Linux 实验环境及其他 Mac 虚拟机占用的网段。当同一数据目录下已有两台 Mac 虚拟机在运行时,启动第三台会立即报错并提示可停止的机器:

barn mac up build --user ci
error: dev and mac1 are running; macOS allows 2 macOS virtual machines at a time
next: barn mac stop mac1

日常管理

barn mac stop dev               # 请求客机正常关机(超时 2 分钟后断电)
barn mac start dev              # 启动并等待 SSH 就绪
barn mac restart dev            # 重启以应用待生效的 configure 变更
barn mac stop --all             # 停止所有运行中的 Mac 虚拟机

传入 barn mac stop --force 可立即断电,传入 barn mac start --recovery 则会启动至 macOS 恢复模式并打开桌面窗口。

barn mac up 不会修改已有虚拟机的硬件配置;若对已存在的虚拟机传入不同的创建参数,命令会拒绝执行并提示改用 barn mac configure:

error: dev already exists, so --cpu would not apply; its configuration and data were preserved
next: barn mac configure dev --cpu 4

修改 CPU、内存、共享目录或网段前请先停止虚拟机(剪贴板开关可随时修改),变更将在下次启动时生效:

barn mac stop dev
barn mac configure dev --cpu 6 --memory 12G --subnet auto
barn mac start dev

barn mac recreate 会基于基础镜像用全新 macOS 替换虚拟机磁盘,同时保留机器名称、账号、资源规格、共享目录与 IP 地址;barn mac destroy 则会彻底删除虚拟机。两条命令在终端中都需要输入确认词,非交互脚本请传入 --yes:

barn mac recreate dev
barn mac destroy dev
操作 客机磁盘与已安装应用 规格设置、IP 地址与账号
stop / start、restart、重复 up 保留 保留
configure 保留 按指定参数更新
recreate 替换为全新的 macOS 克隆盘 保留(重新生成登录密码与 SSH 密钥)
destroy 删除 删除(共享基础镜像仍会保留)

macOS 版本与磁盘空间

barn mac image ls
KIND  OS          BUILD   STATE  ON DISK   CAPACITY  USED BY
base  macOS 27.0  26A428  ready  26.7 GiB  100 GiB   mac1,default

运行 barn mac image update 可向 Apple 查询最新的受支持 macOS 27 版本,确认后下载恢复镜像并为后续新建虚拟机准备新的默认基础镜像。已有虚拟机会保持原有系统版本,直到你显式执行 barn mac recreate NAME --update(若该虚拟机使用了如 200G 的自定义磁盘容量,请先按提示执行 barn mac setup --disk 200G 准备同容量的新基础镜像)。

使用 barn mac image prune 可查看未被任何虚拟机引用的非默认基础镜像,加上 --installers 会一并纳入已下载的 .ipsw 恢复镜像与未完成下载,加上 --yes 执行删除:

barn mac image prune --installers         # 预览可清理的镜像文件
barn mac image prune --installers --yes   # 确认删除

由于 APFS 克隆与基础镜像共享底层物理数据块,ON DISK 与各虚拟机的磁盘占用统计存在重叠,请勿直接相加计算总占用。

故障排查

遇到问题时先运行 barn mac doctor,它会依次检查宿主环境、Barn.app 原生组件、基础镜像和每台虚拟机的状态并给出修复命令;barn mac logs [名称] 则用于查看启动、网络、关机及 Apple Virtualization 运行时日志。

常见现象 处理方法
启动时报 network … overlaps route … VPN 或新路由占用了当前网段,执行 barn mac configure NAME --subnet auto 重新分配子网。
macOS allows 2 macOS virtual machines at a time 停止提示中的某台虚拟机(barn mac stop NAME),或退出其他工具运行的 macOS 虚拟机。
第三方客户端执行 ssh mac1 报 No route to host 在 系统设置 → 隐私与安全性 → 本地网络 中为该终端或 IDE 开启本地网络权限,或改用系统自带的 /usr/bin/ssh(barn mac ssh 与 exec 默认调用系统自带客户端)。
mac_runner_missing 或 mac_runner_protocol 确保 barn、barn-hosts-helper、barn-mac-runner 与 Barn.app 来自同一次 make mac-build 输出目录且保持相对路径不变。
通过远端 SSH 登录宿主 Mac 后启动失败 请在 Mac 本机已登录图形桌面会话的终端中运行 barn mac,并确保登录钥匙串处于解锁状态。

Apple Virtualization 框架尚不支持在虚拟机中稳定登录 Apple 账户,也不支持 USB 设备直通、快照与挂起恢复。

清理

barn mac ls                                 # 查看现有 Mac 虚拟机名称
barn mac destroy mac1 dev                   # 确认删除指定虚拟机
barn mac image prune --installers --yes     # 删除已缓存的恢复镜像与闲置基础镜像

销毁最后一台 Mac 虚拟机时,Barn 会自动清理 ~/.ssh/config 中的对应条目,并保留默认基础镜像供日后复用。如需彻底移除所有 Mac 虚拟机文件:

  1. 销毁所有 Mac 虚拟机(barn mac destroy ...),并执行 barn mac ssh-config --remove。
  2. 删除 $BARN_HOME/mac(默认 ~/.barn/mac)。
  3. 按需删除保存桌面窗口位置的 ~/Library/Preferences/com.pgsty.barn.plist(0.9.0 版本为 io.pgsty.barn.mac-runner.plist)。

4 - 日常管理

唯一部署的正常生命周期:检查、访问、扩容、变更、停止与销毁。

本页介绍 Linux 实验环境的日常运维操作。macOS 虚拟机请参阅 macOS 日常管理。

检查与访问

barn status
barn ssh meta
barn exec node-1 -- hostname
barn logs meta --source serial

以上命令直接读取 BARN_HOME(默认 ~/.barn)中记录的已应用状态,只要该路径指向同一位置,就可在任意工作目录下执行。自行设置 BARN_HOME 时,跨目录操作请使用绝对路径。barn status 默认展示各节点的镜像与资源规格(并在使用软件模拟时标注 tcg);加上 --verbose 还会列出客机架构、虚拟化加速器、回环 SSH 端口和 QEMU PID。

每次执行 barn up(包括只针对部分节点的局部 up)后,Barn 都会根据整套已应用部署刷新 ~/.ssh/barn_config 中的 SSH 别名,确保 ssh meta 等连接始终可用;你也可以随时通过 barn ssh-config --install 手动刷新别名。

涉及配置收敛的命令(plan、up、reload、resize 和 recreate)按以下优先级查找清单:

  1. 显式传入的 -f /path/to/inventory.yml 参数(当同一目录下同时存在 barn.yml 和 pigsty.yml 且希望使用后者时必须指定)。
  2. 当前工作目录下按顺序匹配到的第一个文件:barn.yml、barn.yaml、pigsty.yml、pigsty.yaml(不会向上搜索父目录)。
  3. BARN_HOME 中记录的已应用规格(barn validate 除外,它始终要求提供配置文件)。

重复运行 barn up 会自动重试未完成的客机初始化阶段并原位更新旧版客机辅助脚本,已健康的虚拟机无需重启。任何可选功能限制或自动执行的测试盘修复都会显示在终端摘要及 JSON/YAML 的 nodes[].warnings 与 nodes[].repairs 字段中(详见数据盘说明)。

停止与启动

barn stop
barn start
barn restart node-1
barn reload -f barn.yml       # 校验清单、停止目标节点并重新收敛

barn start 会启动已停止的虚拟机并复查运行中节点的就绪状态,同时刷新因端口占用而重新分配的回环 SSH 端口与别名。barn reload 在停止目标节点前会先校验清单语法、配置漂移与启动依赖,随后对这些节点执行 barn up 流程。

reload 是受控的“停止后重新启动”流程,可以新增节点或启动已停止节点;但对于已有节点的 CPU、内存、镜像、磁盘、共享目录、地址等虚拟机规格变更,它会在停止任何节点前拒绝执行。修改 CPU 或内存时,请编辑 vm_cpu 或 vm_mem 后执行 barn resize。支持的增加操作可以热插拔;减少资源或后端不支持时会自动停机再启动,同时保留虚拟机身份与磁盘。Barn 1.2.0 还支持使用 resize -D 原地扩容根盘。镜像、数据盘、网络和共享目录变更使用 recreate。

在线 resize 在热插拔后中断时,barn status 会提示实际 CPU 和内存可能与已应用配置不一致(reason: resize_incomplete)。再次运行 barn resize NODE 可继续调整,或执行 barn restart NODE 恢复已提交的资源配置。离线 resize 在停止节点和更新状态期间持续持有部署锁。

启动命令传入 --no-wait 时会在 QEMU 进程拉起后立即返回,跳过就绪检查、客机恢复以及客机 /etc/hosts 和控制节点 SSH 刷新;后续运行一次 barn up 即可补齐这些步骤。

变更部署

barn plan
barn up                         # 创建或启动目标节点并刷新 SSH 别名
barn resize node-1              # 应用 CPU/内存变更,不重建虚拟机
barn recreate node-1            # 重建规格发生变更的节点

barn plan 会对比清单文件与已应用状态,展示目标镜像版本、资源总量、漂移原因及磁盘影响:

检测到的变化 含义 应用方式
create 清单中新增了尚未创建的节点 barn up
resize 节点 CPU 或内存发生变化 barn resize <node>
recreate 节点镜像、磁盘、共享目录或其他虚拟机规格发生变化 barn recreate <node>
missing 已创建的节点从 YAML 清单中被移除 恢复 YAML 条目,或执行 barn destroy <node>

JSON 输出中的 start、create、resize、recreate 与 missing 是节点列表,顶层 action 概括整次计划,取值为 create、start、converge、resize、recreate、blocked-removal、repair 或 none;可选字段 blocked 是说明原因的字符串。whole_deployment: true 表示需要重建整个部署;按提示执行命令,确保新节点也一并纳入。

删改 YAML 条目绝不会自动销毁虚拟机;修改 Barn 不消费的 Pigsty 服务级变量则会显示 action: none。在交互式终端中执行 recreate 和 destroy 需输入命令名确认,非交互脚本中则需传入 --yes(或 --force)。

recreate 是显式的替换路径。Barn 会先校验新镜像、网络、共享目录以及持久数据盘的挂载契约,然后销毁选定节点的虚拟机产物,再按目标清单启动全新的虚拟机。根盘和非持久数据盘会被替换;兼容的持久数据盘继续保留并重新挂载。替换后的虚拟机会获得新的身份,同时刷新 SSH 主机密钥状态。

不带节点名的 recreate 会替换部署中的全部节点,并在确认提示中逐一列出。如果清单缺少某个已有节点,它会在停止任何虚拟机前拒绝执行(退出码 4,reason: nodes_removed):请用 barn destroy <node> 显式删除该节点,或把它加回清单。Barn 会在销毁锁内再次核对范围,预检期间已应用状态发生变化时报告 deployment_changed。

分批应用节点变更

可以一次编辑多个节点,再分批应用:

barn plan node-1 -f barn.yml
barn recreate node-1 -f barn.yml
barn plan node-2 -f barn.yml

显式选择节点执行 plan、up、reload、recreate 或 resize 时,未选中节点保留已应用定义,即使 YAML 已修改或暂时省略它们。未创建且未选中的节点会在选中时才解析镜像。整份清单仍须通过语法解析,所选变更也不能与已应用节点的地址、别名、控制节点角色或部署公共设置发生冲突。

不传节点名时,Barn 会检查整份清单:CPU 与内存变更使用 resize,其他已有节点规格变更需要 recreate,清单中缺失的节点需要恢复定义或显式销毁。

并发命令

单条命令内部的节点并行操作,在 Barn 1.2.0 中可通过 --parallel/-p 调整,默认值根据 CPU 数计算;支持的命令与 Barn 1.1.0 的差异见生命周期并发。

修改部署状态的命令(up、start、stop、restart、reload、resize、recreate、destroy、purge 和 provision)会获取 BARN_HOME 下的部署锁。若其他操作正在运行,命令最长等待 10 分钟(provision --timeout 可指定更短的期限),并打印持锁命令、PID 与启动时间;等待超时将返回退出码 4(error: conflict、reason: deployment_busy)。持锁进程退出后锁会自动释放,切勿手动删除锁文件。

只读与连接类命令(status、ssh、exec、ssh-config 以及 hosts 的状态读取)无需等待锁,直接读取最新已发布的状态。若后台正有变更命令持锁运行,barn status 会附带一条 note 说明当前正在执行的操作。异常中断后的恢复步骤见故障排查。

销毁

请根据需要清理的范围选择对应的销毁命令:

销毁单个节点
barn destroy node-3
销毁环境(保留持久盘)
barn destroy
连同持久盘一并删除
barn destroy --delete-persistent
快速清空整套实验环境
barn purge
  • barn destroy <node> 仅删除指定节点,并为剩余节点刷新 SSH 配置片段。删除控制节点时,剩余的第一个节点接任控制节点,ssh-config、hosts、exec 与 provision 可继续使用;请将清单中的 admin_ip 改为该节点的地址(除非希望 up 重新创建已删除的节点,否则一并删除其条目),再执行 barn up 安装其控制 SSH 访问。
  • barn destroy 删除整套部署的虚拟机、根盘、非持久数据盘、部署状态以及 Barn 安装的 SSH 别名,同时保留持久数据盘、部署密钥、镜像缓存和宿主网络。之后再次运行 barn up 即可根据清单重建实验环境。
  • barn destroy --delete-persistent 与 barn destroy --purge 仅适用于整套部署(不支持与节点名称同用),其中 --purge 会一并删除持久数据盘、密钥和部署状态。
  • barn purge 默认立即清空整套 Linux 实验环境,并删除归属明确的遗留持久盘、密钥与部署状态,保留镜像缓存与宿主网络。需要查看节点列表和清理范围后再确认时,运行 barn purge --ask,输入 y/yes 确认或 n/no 取消;空行和 EOF 也会取消。它不接受 --yes、-y 或 --force。

所有虚拟机移除后,如需卸载多用户共享的 Linux 宿主网络:

barn network uninstall --yes

镜像缓存管理请参阅镜像仓库,完整卸载宿主文件请参阅卸载与清理。

5 - 存储、文件与服务访问

配置测试数据盘,理解保留规则,传输文件,并通过 OpenSSH 访问客机服务。

本指南介绍 Linux 实验环境的数据盘配置、文件传输与服务访问,示例沿用 Linux 快速上手中的 meta 节点(10.10.10.10)。

创建虚拟机前配置磁盘

默认情况下,每个 Linux 节点配有一块 64 GiB 根盘写时复制层,以及一块挂载在 /data 的 128 GiB 非持久数据盘。vm_disk 用于以 GiB 为单位设置根盘大小(可填整数 64 或带单位的 64GiB);vm_disks 则会替换整个数据盘列表(设为 vm_disks: [] 即不挂载额外数据盘)。

新建单节点实验环境时,可将以下配置保存为 storage.yml:

storage.yml
all:
  vars:
    admin_ip: 10.10.10.10
    vm_image: u24@20261017.0.1
  children:
    nodes:
      hosts:
        10.10.10.10:
          nodename: meta
          vm_cpu: 2
          vm_mem: 4096
          vm_disk: 64
          vm_disks:
            - {path: /data, size: 64, fs: auto, persistent: true}
            - {path: /scratch, size: 32, fs: ext4, persistent: false}

若同名节点已存在且磁盘配置不同,barn up 会提示配置漂移;请先查看 barn plan 并备份所需数据,再显式执行 barn recreate meta(重建会替换根盘与非持久数据盘)。

校验配置文件、创建虚拟机并验证挂载结果:

barn validate -f storage.yml
barn plan -f storage.yml
barn up -f storage.yml
barn exec meta -- findmnt /data
barn exec meta -- findmnt /scratch
barn exec meta -- df -h / /data /scratch

磁盘容量(size: 64 或 size: 64GiB)均为按需分配的稀疏虚拟容量,随实际写入增长。当 fs: auto 时,若客机安装了 mkfs.xfs 则优先格式化为 XFS,否则使用 ext4。启动后请结合 barn up 输出警告与 findmnt 确认数据盘已正常挂载。

各类操作的磁盘保留规则

操作 根盘与非持久数据盘 持久数据盘(persistent: true)
stop 后 start,或 restart 保留 保留
健康状态下重复执行 up 保留 保留
规格兼容的 recreate 替换 保留并重新挂载
普通 destroy 删除 保留
整套部署 destroy --delete-persistent 或 purge 删除 删除(含已保留的持久盘)

Barn 依据磁盘身份与规格参数复用持久数据盘:在 recreate 或 destroy 后重新挂载保留盘时,节点名称、挂载路径 path、容量 size 和文件系统 fs 必须保持一致。规格不匹配时 Barn 会拒绝挂载,而不会自动执行扩容、改名或文件系统转换。

警告

持久数据盘依然属于可丢弃的测试存储。 persistent: true 仅控制虚拟机销毁或重建时是否保留磁盘文件;但在客机恢复期间,若文件系统检查工具报告 ext4 或 XFS 数据盘存在可识别的损坏,barn up 仍会将其重置(并在 nodes[].repairs 中记录)。带分区表、签名缺少 UUID、使用不支持的文件系统特性或检查工具未知失败的磁盘会保留数据并给出警告;设备暂缺、探测失败、挂载点繁忙或宿主 I/O 错误也绝不会触发格式化。重要数据请务必备份在宿主上。

新格式化的数据盘默认归 root 所有。你可以用以下命令验证写入 /data 的数据在普通停机重启后依然保留:

barn exec meta -- sudo -n sh -c \
  'printf "retention check\n" > /data/barn-retention.txt'
barn stop meta
barn start meta
barn exec meta -- cat /data/barn-retention.txt

macOS 客机的目录共享用法请参阅 macOS 虚拟机教程。

通过管理 SSH 传输文件

从运行中的部署导出独立的 OpenSSH 配置文件,即可直接使用 ssh、scp 或 rsync:

barn ssh-config > barn-ssh.conf
ssh -F ./barn-ssh.conf meta hostname
scp -F ./barn-ssh.conf ./storage.yml meta:/tmp/storage.yml
scp -F ./barn-ssh.conf meta:/data/barn-retention.txt ./barn-retention.txt

生成的配置片段引用当前回环 SSH 端口、部署密钥路径以及按实例隔离的 known_hosts 文件,不会内嵌私钥原文。重建节点或管理端口变动后请重新导出,或执行 barn ssh-config --install 将别名写入 ~/.ssh/config,从而免去 -F 参数。

访问客机内的服务

只要客机内的服务监听在节点的固定私网 IP 上(例如监听在 10.10.10.10:5432 的 PostgreSQL)且客机防火墙放行,宿主与其他节点即可直接通过该 IP 访问。

如果服务仅监听在客机回环地址 127.0.0.1 上,可通过 OpenSSH 建立本地端口转发隧道:

ssh -F ./barn-ssh.conf -N \
  -L 127.0.0.1:15432:127.0.0.1:5432 meta

保持该终端运行,宿主本地客户端即可连接 127.0.0.1:15432(按 Ctrl-C 关闭隧道)。

SSH 别名(如 ssh meta)仅对 OpenSSH 工具生效。如果希望浏览器、psql 等常规宿主程序也能直接解析节点名与 vm_alias,可预览并启用 /etc/hosts 集成:

barn hosts install --json
barn hosts install --yes

barn hosts install --yes 会更新当前宿主的 /etc/hosts(必要时请求 sudo);增删节点或修改 IP 后重新执行即可刷新。

Barn 清单不提供 vm_ports 或 vm_forwards 字段,请直接使用固定私网 IP 或 OpenSSH 端口转发。由于管理 SSH 走独立的宿主回环端口,即便固定 IP 私网受限,barn ssh 与 -L 隧道依然可用。

宿主目录共享

Linux 与 macOS 宿主均可通过 QEMU Virtio-9p 向 Linux 客机共享目录。首次 barn up 前在 all.vars 或节点变量下设置:

barn.yml
vm_shares:
  - host: ./src
    guest: /workspace
    readonly: true

host 支持相对清单真实文件目录的路径、~/ 与目录符号链接。目录须已存在、当前用户可访问且不与 BARN_HOME 重叠,无须归当前用户所有;多个客机可以读写同一目录,由用户协调写入。

宿主 QEMU 与客机内核须支持 9p。可写共享还受客机用户权限约束;无法写入时会降级只读并报告警告,不会修改宿主属主。修改已有节点共享后执行 barn recreate <node>。原生 macOS 客机通过 barn mac up --share 或 barn mac configure --share 使用 VirtioFS。

完整的磁盘与共享字段约束请参阅配置参考。

6 - 镜像仓库

选择客机镜像、使用镜像站、导入本地 qcow2,并清理缓存。

本指南介绍 Linux 客机镜像的选择、镜像站切换、静态仓库构建与本地缓存清理。

使用默认配置时,barn up 会自动按宿主架构解析 u24:stable 并按需下载经过校验的不可变 qcow2 镜像,无需提前手动拉取。Barn 初始使用二进制内置的签名镜像目录(revision 2026110502,覆盖 9 个发行版家族的 17 个镜像产物);执行 barn update 可从远端仓库获取、校验并激活最新镜像目录(或用 barn image sync 从指定 URL 或本地文件加载目录)。

选择镜像

查看当前镜像目录中的发行版家族与版本详情:

barn image list
barn image info u24
barn image info u24:stable

Barn 内置 9 个发行版家族:el7、el8、el9、el10、d12、d13、u22、u24 和 u26。直接填写家族名(如 el9)默认使用 stable 通道,name:channel 指定通道,而 name@version 则精确锁定某个不可变构建版本。你也可以在 vm_version 中填写数字前缀,按点号分隔的版本段自动匹配最新的小版本:

barn.yml
all:
  vars:
    vm_image: el9
    vm_version: "9.8"

上例中 "9.8" 会匹配活动镜像目录中最新的 9.8.x 构建,"9" 则匹配最新的 9.x 构建(YAML 中的纯数字 vm_version 请加双引号以保持字符串类型)。独立设置的 vm_version 不能与 vm_image 中的 :channel 或 @version 后缀同时使用。

若需要跨镜像目录更新保持严格可复现,请直接锁定 barn image info 显示的完整版本号:

barn.yml
all:
  vars:
    vm_image: d13@20261103.2651.1

修改 vm_image 或 vm_version 后,先运行 barn plan 查看变更。已有节点会保留当前根盘,直到显式执行 barn recreate <node>;运行 barn update 仅影响后续新建或重建的节点。

临时覆盖与架构选择

使用 -I(--image)与 -A(--arch)可在单次命令执行中临时覆盖镜像与架构设置。

默认使用宿主架构;只有显式配置 vm_arch 或传入 --arch/-A 时才覆盖。优先级为 -A → vm_arch → 宿主架构;-A native 表示忽略清单中的固定架构,恢复跟随宿主。amd64 接受 x86_64、x64 别名,arm64 接受 aarch64、a64 别名。

barn plan -I u24 -A amd64
barn up -I u24 -A amd64

-I u24 替代所选节点的 vm_image 与 vm_version,不改变架构。这些覆盖不会改写清单;要长期保留,请设置 vm_image 与 all.vars.vm_arch,移除被替代的 vm_version,或用 barn init -I u24 -A amd64 生成新清单。已有节点改镜像或架构仍需 recreate,架构变更必须覆盖全部已有节点。完整规则见配置参考。

barn image list 会列出所有架构;独立的 info 和 pull 默认按宿主架构查询,不读取清单的 vm_arch,可用 --arch/-A 指定(旧 -a 仍兼容)。镜像缺少目标架构变体时会报错,不会改选其他架构。当前 Barn 接受的客机架构只有 amd64 与 arm64:

  • el7 仅支持在原生 linux/amd64 宿主上运行。
  • Apple Silicon 上的 el8(arm64) 会自动启用 QEMU TCG 软件模拟,因为上游 RHEL/Rocky 8 arm64 内核要求 64 KiB 页粒度,而 macOS HVF 硬件加速不支持该页大小。跨架构模拟器与固件要求见运行时排查。
说明

内置镜像目录中,除仅供兼容旧环境使用的 EOL el7 标记为 deprecated 外,其余全部版本均为 supported。

使用镜像站

发行版默认使用全球镜像源 https://repo.pigsty.io/barn。单次命令可通过 --mirror 切换至中国官方镜像站(https://repo.pigsty.cc/barn),或通过 --repo 指定自定义仓库 URL 或本地目录路径:

barn image pull u24 --mirror
barn up --mirror
barn update --repo https://mirror.example/barn
barn image pull u24 --repo https://mirror.example/barn
barn up --repo https://mirror.example/barn

也可以通过环境变量 BARN_REPO 为当前 Shell 会话设置默认仓库:

export BARN_REPO=https://mirror.example/barn
barn update
barn up

仓库选择优先级依次为 --repo → --mirror → BARN_REPO → 全球默认源(https://repo.pigsty.io/barn)。两个官方仓库以及任何明文 http:// 仓库都强制要求可信 Minisign 签名(catalog.json.minisig);显式指定的本地目录和自定义 https:// 仓库则允许使用未签名的 catalog.json。所有下载的镜像文件都会严格校验字节大小、SHA-256 摘要与 qemu-img 结构完整性。

使用官方仓库下载镜像时,Barn 会自动重试临时网络故障并支持断点续传;若所选官方站点不可达,还会自动回退到另一个官方镜像站。自定义 --repo 仓库则不会向外部站点回退。

每个仓库根路径在 BARN_HOME 下各自维护独立的活动镜像目录状态。首次将 --repo 指向包含自定义镜像的仓库时,请先执行 barn update --repo <root> 激活其镜像目录,再运行 plan 或 up。

构建静态仓库

Barn 镜像仓库是一个普通的静态目录,可直接通过本地路径读取、用 rsync 同步或由任意静态 HTTP/HTTPS 服务托管:

/srv/barn

  • barn/
    • repo.yaml人工维护的镜像版本与通道定义
    • catalog.json自动生成的镜像目录(含 SHA-256 与文件尺寸)
    • catalog.json.minisigMinisign 签名(官方仓库与 HTTP 仓库必需)
    • images/
      • d13-1-arm64.qcow2经校验且支持 cloud-init 的 qcow2 基础镜像

repo.yaml 是唯一需要人工编辑的源文件。对应上方单个 arm64 镜像的最小配置如下:

/srv/barn/repo.yaml
schema: 1
revision: 1
defaults: { image: d13, channel: stable, arch: native, boot: uefi }
images:
  d13:
    channels: { stable: "1" }
    versions:
      "1":
        status: testing
        variants:
          arm64:
            source_user: debian

将准备好的 qcow2 镜像放入 /srv/barn/images/d13-1-arm64.qcow2(支持相对仓库路径、目录符号链接与共享可写目录),随后在安装了 qemu-img 的宿主上生成并校验 catalog.json:

barn repo scan /srv/barn
barn repo build /srv/barn
barn repo verify /srv/barn

barn repo scan 以只读方式检查目录结构,barn repo build 则会运行完整的 qemu-img check,将文件名、SHA-256、文件大小和虚拟容量写入 catalog.json。每次更新镜像目录内容时都请递增 revision;发布到远端服务器时,先上传不可变的 .qcow2 镜像文件,最后再更新 catalog.json 及其签名。

激活并验证该本地仓库:

barn update --repo /srv/barn
barn image info d13 --arch arm64 --repo /srv/barn
barn image pull d13 --arch arm64 --repo /srv/barn

后续运行 plan、up 和 recreate 时传入 --repo /srv/barn(或设置 export BARN_REPO=/srv/barn),并在清单中配置 vm_image: d13@1。如需将该仓库恢复为二进制内置目录(同时保留防回滚版本号记录),可执行 barn image reset --repo /srv/barn。

导入本地镜像与清理缓存

如果只需使用单个自定义 qcow2 镜像,无需搭建静态仓库,可直接将其作为 local-* 别名导入本地缓存,默认记录宿主架构:

barn image import --name local-mybase --boot uefi \
  --source-user ubuntu --sha256 <digest> /path/to/base.qcow2

注册别名时需同时指定 --name(必须以 local- 开头)、--boot(uefi 或 bios)和 --source-user;省略这组参数则仅校验镜像并按内容摘要缓存。导入的镜像必须已预装并启用 cloud-init。命名别名一旦注册即不可变——重新制作镜像后请注册新的 local-* 名称,并在 barn.yml 中通过 vm_image: local-mybase 引用。

命名导入支持 -A,例如 barn image import /path/to/arm64.qcow2 --name local-arm64 --boot uefi --source-user ubuntu -A arm64。它记录你声明的架构,不会转换镜像或检测客机 CPU;使用该镜像时,也要让清单的 vm_arch 或生命周期命令的 -A 与之匹配。不带 --name 时不能传入 -A。

清理未被使用的缓存镜像与中断下载暂存文件:

barn image prune --dry-run
barn image prune --yes

barn image prune(依赖本机 qemu-img)会自动保护当前所选仓库活动镜像目录中的全部镜像、已有节点正在使用的基础镜像以及所有已注册的 local-* 别名。

签名信任链、防回滚机制、缓存目录结构及架构兼容规则详见镜像参考;从上游云镜像制作候选镜像并执行发布前验收的完整流程详见镜像流水线。

7 - 自动化与客机脚本

准备无人值守实验环境,检查 JSON 结果,并在选定客机内运行可重复执行的脚本。

本指南介绍如何在无人值守脚本与 CI 流水线中调用 Barn。请始终以拥有该部署的普通 Unix 用户身份执行命令,并在每次调用时传入相同的 -f <清单> 与 BARN_HOME。

准备可预测的实验环境

建议将主机清单纳入版本控制,并将 vm_image 锁定为完整版本号(如 vm_image: u24@20261017.0.1),确保后续更新镜像目录不会意外改变流水线所使用的基础镜像。显式传入 -f 还能防止首次 setup 在遇到网段冲突时自动改写默认模板的子网。若使用自定义镜像仓库,请先执行 barn update --repo URL 激活其镜像目录,再向 setup 和 up 传入相同的 --repo。

在启动自动化流程前,先生成并校验配置文件:

mkdir -p ~/barn-lab
cd ~/barn-lab
barn init dual
# 编辑 barn.yml,锁定 vm_image 与节点规格。
barn version
barn validate -f barn.yml
barn plan -f barn.yml
barn setup -f barn.yml --dry-run

核对宿主变更计划并配置好免交互 sudo 凭据(或 NOPASSWD 策略)后,执行宿主准备并拉起环境:

barn setup -f barn.yml --yes
barn up -f barn.yml --json > up.json

生成新清单时,barn init [模板] --image <引用> 将镜像引用写入 all.vars.vm_image,让所有生成节点继承同一个镜像。引用可以是目录别名(el9)、频道(u24:stable)或版本选择器(u24@20261017.0.1)。barn setup [模板] --image <引用> 也支持生成时选镜像,但遇到已有清单时会拒绝该生成参数。

--image/-I、--arch/-A 在各命令中采用相同的用法:barn init full -I u24 -A amd64 将两项选择保存到新清单;validate、plan、up、reload、recreate 和 resize 的同名参数则只覆盖本次期望配置。例如 barn plan -f barn.yml -I u24 -A arm64 --json,执行时传入相同的覆盖参数。setup 的 -I/-A 仍只适用于生成模板。

这些命令还支持 --cpu/-C、--mem/-M、--scale/-S、--disk/-D。各项规格的优先级为命令行参数 → 非空 BARN_* 环境变量 → 清单 → 默认值;validate、plan 与实际应用计划的命令应使用相同的参数和环境。

未指定架构参数时依次读取 BARN_ARCH、清单的 vm_arch,都未设置时跟随宿主;-A native 可以覆盖环境变量和清单,恢复宿主架构。已有 VM 改镜像或架构需要 recreate。长期使用的 CI 配置宜保存 vm_image、vm_arch 与精确镜像版本,详见配置参考。

barn setup --yes 会直接接受宿主准备计划,不再询问。在终端中,up、start、restart 与 reload 安装软件包或 Barn 网络前会展示同样的计划并询问一次;没有终端时它们只报告缺少的条件,因此请先执行 barn setup --yes。

结合退出码校验 JSON 结果

Barn 将结构化 JSON/YAML 结果输出到 stdout,将诊断信息输出到 stderr。需要注意的是,只要管理 SSH 就绪,barn up 就会返回 退出码 0——即使附加数据盘、Virtio-9p 共享或节点间 SSH 存在功能限制(记录于 nodes[].warnings),或者自动重置了损坏的测试数据盘(记录于 nodes[].repairs)。因此自动化脚本应当同时校验退出码与 JSON 字段:

up-check.sh
#!/usr/bin/env bash
set -euo pipefail

if barn up -f barn.yml --json > up.json 2> up.stderr; then
  jq -e '
    (.nodes | type == "array" and length > 0) and
    all(.nodes[];
      .state == "running" and .ready == true and
      ((.warnings // []) | length == 0) and
      ((.repairs // []) | length == 0)) and
    ((.warnings // []) | length == 0)
  ' up.json || exit 1
else
  barn_exit=$?
  cat up.stderr >&2
  cat up.json
  exit "$barn_exit"
fi

当后续步骤要求客机完全就绪时,请勿在 barn up 中使用 --no-wait(barn status --json 仅读取已缓存的状态与警告,不会重新探测客机 SSH)。

错误退出码与专用报告结构

请结合命令行退出码与各命令的 JSON 结构判断执行结果:

  • 退出码 2(usage):首次运行缺少配置文件、参数非法、镜像别名未知,或标准输入不是终端时执行 destroy/recreate 却未传 --yes(purge 则直接执行,不会询问)。
  • 退出码 4(conflict):清单发生需要显式处理的漂移(reason: recreate_required 或 nodes_removed),recreate 预检期间已应用状态发生变化(reason: deployment_changed),或等待部署锁超过 10 分钟(reason: deployment_busy)。
  • 退出码 5(partial):多节点 up 或 provision 部分成功、部分失败——重试前请先检查 nodes[] 或 results[]。
  • 退出码 7(integrity):摘要、签名或身份校验失败,包括目录签名或签名 revision 校验失败(reason: catalog_signature 或 catalog_equivocation)。
  • 专用报告格式:
    • barn doctor --json 在宿主计算能力检查通过时即退出 0,即使 class: network 检查报错;若工作流依赖私网通信,请同时检查 checks[] 与 barn network status --json。
    • barn ssh 和 barn exec 直接透传远端命令的退出码(含 OpenSSH 连接失败的 255),并在 --json 模式下通过 success、exit_code、stdout 和 stderr 返回结果。
    • 未传 --yes 时,如果标准输入不是终端或输出为 --json/--yaml,network 与 hosts 的 install/uninstall 只输出计划并退出 0;请检查结果中的 applied,或传入 --yes。

执行单条命令或批量脚本

在节点名称与远端命令之间始终使用 -- 分隔,并将 Barn 自身的参数(如 --json、--verbose)放在 -- 之前:

barn exec meta -- hostname
barn exec node-1 -- sh -c 'id; df -h /data'
barn exec meta --json -- uname -a > uname.json

调用 barn exec 时请将程序名与参数分开传递;若需使用管道、重定向或环境变量展开,请显式调用 sh -c(详见 SSH 透传与命令补全)。

如需在多台运行中的 Linux 客机上批量执行巡检或初始化脚本,可先在宿主保存一份 Bash 脚本(普通文件或指向普通文件的符号链接,不超过 4 MiB):

check-lab.sh
#!/usr/bin/env bash
set -euo pipefail
hostname
id
findmnt /data
test -d /data

通过 barn provision 在目标节点上运行:

barn provision --script ./check-lab.sh meta node-1
barn provision --script ./check-lab.sh --parallel 2 --timeout 5m --json > provision.json

省略节点选择器时,provision 会作用于部署中的全部节点(所有目标节点必须已处于运行状态)。Barn 会将校验后的脚本字节流直接通过 SSH 传给客机 Bash 执行,并记录脚本的 SHA-256 摘要,不在客机磁盘上落盘保存脚本文件。

  • 并发与超时:默认串行执行;--parallel 接受正整数,工作线程数不超过所选节点数。--timeout 限制整次操作时长,默认 1h,接受任意正时长。--sudo 通过客机免交互 sudo -n 执行。
  • 输出截断与幂等性:每个节点最多捕获 1 MiB stdout 与 1 MiB stderr(超出时标记 stdout_truncated / stderr_truncated)。由于部分失败不会回滚已执行成功的客机操作,请确保编写的脚本可安全重跑。
  • 退出码规则:目标节点部分成功、部分失败时退出 5;仅针对单个节点且远端返回大于 0 且非 255 的状态码时直接透传该状态码;其余全失败情况退出 1。

与 Pigsty 配合使用

Barn 与 Pigsty 原生共用同一套 Ansible YAML 清单格式。barn init 生成的模板仅定义虚拟机硬件拓扑,而 Pigsty 仓库中的 pigsty.yml 则包含完整的 PostgreSQL 集群与监控服务配置。先用 Barn 根据 pigsty.yml 拉起虚拟机:

barn validate -f pigsty.yml
barn plan -f pigsty.yml
barn up -f pigsty.yml
barn ssh

在 barn up 期间,Barn 会初始化客机管理员账号,并将部署私钥复制到 admin_ip 指定的控制节点上,使其能够直接通过固定私网 IP 免密连接集群内的其他节点(详见安全与信任)。待 barn up 就绪后,登录控制节点即可按照 Pigsty 文档部署数据库服务。

8 - 故障排查

面向 setup、网络、镜像、漂移、中断状态与 SSH 的简短安全手册。

本手册提供 Linux 实验环境的常见问题排查步骤。macOS 客机请运行 barn mac doctor 并参阅 Mac 故障排查章节。

排查问题时,建议先采集以下三份 JSON 诊断报告(当没有其他命令持有部署锁时,barn status 还会自动收敛中断的虚拟机状态):

barn doctor --json
barn network status --json
barn status --json

只要宿主计算能力检查通过,即使 class: network 检查报错,barn doctor 也会返回退出码 0——因此判断 barn up 能否正常接入私网前,请同时查看 checks[] 与 barn network status --json。

下载与 PATH 问题

安装脚本从 GitHub Releases 下载发行归档(--mirror 仅用于切换客机镜像仓库,不会重定向安装脚本下载)。若访问 GitHub 需要代理,请在终端中设置 HTTPS_PROXY 或 ALL_PROXY 环境变量(macOS 系统设置中的图形代理不会自动注入命令行环境)。

用户态安装脚本默认将程序安装到 ~/.local/bin。若安装后提示找不到 barn 或仍显示旧版本,请检查当前 PATH:

export PATH="$HOME/.local/bin:$PATH"
command -v barn
barn version

请始终保持同一版本打包的 barn 与 barn-hosts-helper 处于原有的相对目录结构中。

找不到主机清单

当既没有配置文件也没有已应用部署时,交互式运行 barn up 会自动生成初始 barn.yml。如需使用现有清单,请在 barn.yml / pigsty.yml 所在目录运行 plan、up 或 validate,或显式传入 -f /path/to/file(也可先运行 barn init 生成模板)。

未指定 -f 时,plan、up、reload、resize 和 recreate 会按 barn.yml、barn.yaml、pigsty.yml、pigsty.yaml 的顺序查找当前工作目录,仅在四个文件都不存在时回退到 BARN_HOME 中的已应用规格。若匹配到的第一个文件存在语法错误,命令会立即报错退出;当旧的 barn.yml 与目标 pigsty.yml 同处一个目录时,请显式传入 -f pigsty.yml。

若 barn status 提示 no deployment state found,说明当前 BARN_HOME 下尚无已应用部署(全新环境或刚执行过 purge)。

init 输出路径与符号链接

barn init 与 barn setup 可以经由目录符号链接写入,barn init -o ./lab/config/barn.yml 也会自动创建缺失的父目录。覆盖已有文件需要 --force。Barn 不会经由输出文件本身的符号链接写入:传入 --force 时会报告 will not overwrite …: it is a symlink,此时请改为传入链接指向的目标路径:

barn init -o "$(readlink -f barn.yml)" --force

setup 需要 sudo

barn setup 在请求密码前会先打印即将执行的宿主变更明细,并在特权步骤开始时将当前终端直接交给 sudo。--yes 仅用于自动确认 Barn 的变更计划,不会绕过 sudo 本身的身份认证;无人值守环境需预先配置免密 sudo(NOPASSWD)或有效凭据缓存。你可以随时运行 barn setup --dry-run 预览计划。

在 macOS 上,barn setup 会先完成固定版本 socket_vmnet 软件包的下载与校验,随后才请求管理员权限,因此下载失败不会触发密码提示。

原生加速或兼容运行时不可用

Barn 依赖 macOS HVF 或 Linux KVM 提供原生硬件虚拟化加速,仅在显式配置跨架构 vm_arch 或命中内置兼容规则(如在 Apple Silicon 上运行 el8 arm64)时启用 QEMU TCG 软件模拟;原生 HVF/KVM 异常绝不会自动降级为 TCG。

Homebrew 的 qemu 配方已同时包含 arm64 与 amd64 系统模拟器,而 Linux 宿主的 barn setup 仅安装宿主原生架构的模拟器——在 Linux 上运行跨架构客机前,请先安装对应的 qemu-system-* 二进制与 UEFI 固件。

网络状态为 partial 或 invalid

若宿主网络配置完整但处于未激活状态,交互式运行 barn up 会把重新启动网络列入宿主准备计划,询问一次后执行;没有终端时请运行 barn setup --yes。若 barn network status 报告 partial 或 invalid,请通过内置卸载命令预览并清理受管资源,切勿手动删除系统网络配置文件:

barn network status --json --verbose
barn network uninstall --json
barn network uninstall --yes

若 Linux 网桥冒烟测试在 setup 期间失败,Barn 会自动回滚网络配置;仅当输出明确的 automatic rollback failed 时才需人工介入。

在 macOS 上,barn setup 可自动修复缺失或权限过严的 /var/log/barn-vmnet 目录(标准权限为 root:wheel 0755),但若该路径被替换为符号链接、属主异常或对同组/其他用户可写,Barn 会拒绝自动修改——请按 barn network status 给出的诊断命令手动修复。

Linux bridge helper 失败

在 Debian / Ubuntu 宿主上,请检查 /usr/lib/qemu/qemu-bridge-helper 的属主、属组与 setuid 权限位(应为 root:<当前用户所属组> 4750):

id
stat -c '%U:%G %a %n' /usr/lib/qemu/qemu-bridge-helper
dpkg-statoverride --list /usr/lib/qemu/qemu-bridge-helper

plan 报告 recreate 或 missing

  • recreate:节点的虚拟机规格定义已变更。请先查看 barn plan 并备份根盘或非持久数据盘上的文件,再运行 barn recreate <node>(非交互环境需加 --yes)。
  • missing:已创建的节点从 YAML 清单中被移除。可恢复该节点的 YAML 条目,或执行 barn destroy <node> 将其销毁。存在缺失节点时,不带节点名的 barn recreate 会在停止任何虚拟机前拒绝执行(退出码 4,reason: nodes_removed)。

使用节点选择时,barn plan node-1 与 barn recreate node-1 会保留未选中节点的已应用定义,无关节点的编辑不必一起重建。地址、别名、控制节点角色及部署公共设置的真实冲突仍需处理。

节点未就绪

节点就绪要求管理 SSH 可连通且客机实例 UUID 校验一致。若某个节点无法创建、启动或建立管理 SSH 连接,barn up 会指出故障节点与所处阶段,并以退出码 5 结束。请先查看对应日志:

barn logs <node>                  # 客机串口控制台日志
barn logs <node> --source qemu    # QEMU 进程标准错误与诊断日志
barn logs --source events         # 宿主准备与部署事件日志
barn status

附加数据盘、Virtio-9p 共享目录、主机名、客机 /etc/hosts、控制节点 SSH 与固定 IP 私网网卡均在管理 SSH 就绪后独立初始化。单一步骤失败不会阻断管理 SSH,barn up 仍会返回退出码 0 并在 nodes[].warnings 中列出受限项:

报告的功能限制 处理方法
数据盘不可用 排查设备缺失、文件系统工具、挂载繁忙或宿主 I/O 错误后,重新运行 barn up。带分区表、签名缺少 UUID 或使用不支持的文件系统特性的磁盘会保留数据且不挂载
共享目录只读 核对宿主与客机的实际写权限后,重新运行 barn up
客机 hosts 或控制节点 SSH 未完成 重新运行 barn up 刷新客机内的托管文件
私网网卡不可用 检查 barn network status,修复宿主网桥或 vmnet 后重新运行 barn up

排除故障后再次运行 barn up,Barn 会仅重试未完成的阶段而不重启健康节点。空白数据盘会被初始化;ext4 或 XFS 数据盘只有在文件系统检查工具报告可识别的损坏时才会重置(详见数据盘说明)。若希望在首次准备失败时当场清理未完成产物,可在运行 barn up 时加上 --rollback。

Linux 目录共享要求 QEMU 与客机内核均支持 9p;如果客机内核不支持,修正宿主路径也无法挂载,可改用 SSH/SCP/rsync 或支持 9p 的内核。该要求同样适用于 macOS 宿主;原生 macOS 客机使用独立的 VirtioFS。

SSH 失败

请依次检查 barn status、barn ssh-config 与 barn logs <node>:

  • 部署密钥恢复:若宿主侧公钥文件缺失,Barn 会在启动时根据完好的私钥自动重新派生;若私钥本身丢失,请从备份恢复原私钥——Barn 不会为已存在的虚拟机重新生成新身份。若控制节点内的私钥副本丢失,barn up 会报告 control-ssh 限制,此时宿主到客机的管理 SSH 依然可用。
  • 端口重分配与主机密钥隔离:若已停止虚拟机的回环管理端口被其他进程占用,下次启动时会自动改用空闲端口并刷新 ~/.ssh/barn_config。SSH 主机密钥按虚拟机实例 UUID 独立记录,因此重建节点不会引发 known_hosts 冲突。
  • 由 dotfile 工具管理的 ~/.ssh/config:当 ~/.ssh/config 是符号链接或硬链接时,Barn 只会生成 ~/.ssh/barn_config 并提示你手动添加 Include 行。若 barn ssh meta 正常而直接执行 ssh meta 失败,请先核对该 Include 配置。
  • 远端命令分隔符:在节点名与远端命令之间请使用 -- 分隔(如 barn exec meta -- hostname),详见 SSH 透传与命令补全。

镜像目录或镜像校验失败

Barn 二进制内置了 active 与 standby Minisign 公钥,会严格拦截未知签名者、目录版本回滚、文件尺寸或 SHA-256 不匹配以及存在安全隐患的 qcow2 结构。目录签名或签名 revision 校验失败时退出码为 7(error: integrity,reason: catalog_signature 或 catalog_equivocation);读取缓存签名时出现权限或 I/O 错误仍属于运行时错误(退出码 1)。请始终使用正确签名的镜像仓库,或通过 barn image import --sha256 ... 导入本地镜像,切勿直接将文件手动拷入 ~/.barn/images。

命令被中断

按下 Ctrl-C 或发送 SIGTERM 会取消命令,退出码为 130(cancelled)。Barn 会向它启动的进程发送 SIGTERM,sudo 会将其转发给特权命令;Barn 最多等待 10 秒,忽略 SIGTERM 的后代进程会继续运行,需要你自行停止。

命令中断后,请先运行 barn status:若后台仍有其他 Barn 命令持有部署锁,输出会附带 note 提示——请等待该命令自然结束,切勿将其视为异常中断。

当没有进程持锁时,barn status 会比对记录的 QEMU PID 与进程启动时间戳,确认进程真实身份后自动收敛状态:

中断场景 自动恢复与后续操作
宿主重启,或原 QEMU PID 被其他无关进程复用 barn status 识别出进程身份不匹配后将节点标记为 stopped,随后执行 barn start 即可
barn stop 中断,但 QEMU 仍在运行 barn status 将状态恢复为 running;仍需关机时再次执行 barn stop
在线 barn resize 在修改运行中客机后中断 barn status 报告 resize_incomplete;重新运行 barn resize <node> 或执行 barn restart <node>
首次 barn up 在准备阶段中断 修正清单后重新执行 barn up -f barn.yml,Barn 会自动回滚事务日志中未完成的产物
barn destroy 执行中途中断 按相同的销毁范围重新运行 barn destroy 或 barn purge 即可完成清理

如果 Barn 无法确认记录的进程身份(或者 QEMU 进程仍在运行但 QMP 套接字丢失),它会拒绝后续变更操作以防误杀无关进程。请保留现场状态目录并通过 barn logs <node> --source qemu --verbose 排查原因,切勿手动删除节点目录、套接字或篡改状态文件中的 PID。

在 GitHub 提交问题报告时,请附上完整命令与退出码、barn version、宿主操作系统与架构、QEMU 版本,以及开头三份 --json 诊断输出。

9 - 从源码构建

构建 Barn 1.2.0 或开发分支,准备 Mac 原生组件,并运行贡献者检查。

开发新功能或审阅发行版本时,可从源码构建 Barn。预编译 CLI 与 Apple Silicon 发行包内的原生应用包 Barn.app 均可直接安装,详见安装指南。

检出源码

克隆 v1.2.0 标签以复现本文档对应的发行版(开发主分支时可省略 --branch v1.2.0),并在提交构建记录时附上 git log -1 --oneline 与 git status --short:

git clone --branch v1.2.0 https://github.com/pgsty/barn.git
cd barn

v1.2.0 标签用于复现 Barn 1.2.0 发布说明所描述的已发布版本。开发构建不要设置 BARN_VERSION,避免将开发构建标记为正式的 1.2.0。

构建 CLI

Barn 1.2.0 在 go.mod 与 packaging/toolchain.env 中固定使用 Go 1.27.4,并依赖 Git、Make、Bash 与标准编译工具(仅编译 CLI 无需安装 QEMU 或配置宿主网络):

BARN_VERSION=1.2.0 make build
export PATH="$PWD/bin:$PATH"
barn version

make build 会在 bin/.barn-releases/ 下编译配套的 barn 与 barn-hosts-helper,将 helper 的 SHA-256 摘要嵌入 CLI,并在 bin/ 下创建入口符号链接。请始终使用 make build 而非裸跑 go build ./cmd/barn;移动构建产物时请一并保留 bin/.barn-releases/ 目录与 bin/ 下的两个链接。

未指定 BARN_VERSION 时,开发构建默认将版本号标记为 dev,工作区存在未提交改动时 commit 字段会显示为 uncommitted。

执行 make cross 可在 bin/darwin_amd64、bin/darwin_arm64、bin/linux_amd64 与 bin/linux_arm64 下交叉编译四个目标平台的 Go CLI 与 helper。构建产物(bin/、dist/、.goreleaser-*/)及实验环境清单不应纳入版本控制;在工作树内生成前,请确认对应路径已被忽略。

请针对准备使用的源码运行下方贡献者检查;历次带日期的验收记录见验证历史。

工具版本以当前检出的 packaging/toolchain.env 为准;正式发行包按签名与公证流程构建。

构建 Mac 原生组件

重新编译本地 Mac 组件前,请先停止正在使用它的所有 Mac 虚拟机。

在运行 macOS 27+ 的 Apple Silicon Mac 上,确认 xcrun 已指向 Xcode 27+(提供 macOS 27 SDK 与 Swift 编译器),然后执行:

BARN_VERSION=1.2.0 make mac-build
export PATH="$PWD/bin/mac:$PATH"
barn mac doctor

make mac-build 会在 bin/mac 下生成配套的 barn、barn-hosts-helper、独立运行器 barn-mac-runner 与原生应用包 Barn.app,同时打包生成 bin/barn-mac-darwin-arm64.tar.gz。可执行 make mac-native-test 运行原生组件测试套件,随后按 macOS 虚拟机教程创建虚拟机。

源码标签 原生应用包 应用标识符(Bundle ID)
v0.9.0 Barn Mac.app io.pgsty.barn.mac-runner
v0.9.1 及之后 Barn.app com.pgsty.barn

当前 CLI 同时兼容 Barn.app 与旧版 Barn Mac.app,而 0.9.0 CLI 仅查找 Barn Mac.app——请始终使用 bin/mac 下同批构建出的 CLI 与应用包。

代码签名与公证

未设置签名环境变量时,make mac-build 默认使用供本机开发测试的 ad-hoc 签名。如需进行证书签名或公证分发:

  • 设置 BARN_CODESIGN_IDENTITY 以使用 Developer ID 证书为 Barn.app 签名。
  • 设置 BARN_NOTARY_PROFILE 与 BARN_MAC_REQUIRE_NOTARIZATION=1,使构建流水线自动校验签名、提交 Apple 公证、装订票据(staple)并验证 Gatekeeper 状态。
  • 设置 BARN_CODESIGN_IDENTITY 后,make mac-build 也会先签名 Go helper,将最终 SHA-256 嵌入 CLI,再签名 CLI。Mac 发布手册进一步说明 CLI/helper/App 联合公证及导出载荷的发行验证。

运行贡献者检查

执行完整的 make check 还需要 Python 3、jq、支持竞态检测(-race)的 C 编译器,以及 packaging/toolchain.env 中固定版本的静态检查工具:

go install honnef.co/go/tools/cmd/staticcheck@v0.8.2
go install golang.org/x/tools/cmd/deadcode@v0.52.0
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.15.0
go install golang.org/x/vuln/cmd/govulncheck@v1.9.0

将 GOBIN(或 $(go env GOPATH)/bin)加入 PATH 后运行:

make test
make check

make check 会依次验证 Go 模块、Shell 脚本语法、仓库维护检查、单元与竞态测试、go vet、staticcheck、deadcode、golangci-lint、govulncheck、四平台交叉编译、镜像流水线与安装器测试以及依赖许可证合规性。打包快照验证流程请参阅发布工程。

10 - 卸载与清理

分别移除 Linux 与 macOS 虚拟机,再清理集成、镜像、网络和程序。

Barn 分别独立管理 Linux 实验环境与 macOS 虚拟机。barn purge 仅删除 Linux 部署,不会删除任何 Mac 虚拟机。 在完成虚拟机、宿主集成、镜像缓存和宿主网络的清理前,请先保留 barn 命令行程序。

选择清理范围

目标 命令
停止运行中的虚拟机并保留磁盘 barn stop;Mac 虚拟机使用 barn mac stop --all
删除单个 Linux 节点 barn destroy <node>
删除 Linux 实验环境,保留持久数据盘 barn destroy
删除 Linux 实验环境、持久数据盘与密钥 barn purge(默认直接删除,--ask 开启确认)
删除指定的 Mac 虚拟机 barn mac destroy <name...>(需输入确认词)

执行删除前,请先通过 barn status(Linux 节点)和 barn mac ls(Mac 虚拟机)核对名称,并将需要保留的文件备份到宿主。

完整清理步骤

  1. 销毁 Linux 与 Mac 虚拟机

    清空整套 Linux 实验环境(含已保留的持久数据盘与部署密钥):

    barn purge

    默认立即删除;如需先查看虚拟机列表与清理范围,改用 barn purge --ask,输入 y/yes 确认或 n/no 取消,不接受 --yes、-y 或 --force。如果还创建过 macOS 虚拟机,先查看列表再按名称逐一销毁:

    barn mac ls
    barn mac destroy mac1 dev
  2. 移除 SSH 与 /etc/hosts 集成

    整套销毁 Linux 部署时会自动移除默认的 ~/.ssh/barn_config 集成。若曾安装过自定义名称的 SSH 片段、/etc/hosts 主机名条目或 Mac SSH 集成,请依次清理:

    barn ssh-config --remove --name lab
    barn hosts uninstall --json
    barn hosts uninstall --yes
    barn mac ssh-config --remove

    以上命令仅清理 Barn 写入的受管配置块,不会影响你原有的 ~/.ssh/config 和 /etc/hosts 条目。

  3. 清理镜像缓存

    预览并删除本地缓存的 Linux 与 macOS 镜像文件:

    barn image prune --dry-run
    barn image prune --yes
    barn mac image prune --installers
    barn mac image prune --installers --yes
  4. 卸载 Linux 宿主网络

    先销毁 Linux 实验环境(只要还有 Linux 虚拟机在运行,该命令就会中止),再预览并卸载多用户共享的 Linux 宿主网络(Mac 虚拟机的私有网络会随虚拟机停止自动释放,无需单独卸载):

    barn network uninstall --json
    barn network uninstall --yes

    宿主网络由 systemd-networkd 管理时,如果存在其他宿主网络接口或无法确认由 Barn 独占,卸载会保留全局 networkd 单元状态;计划中会报告 preserve_networkd,执行结果在 checks.networkd 中说明原因。

  5. 卸载 Barn 程序与剩余文件

    通过包管理器安装的 Barn 可直接用对应命令卸载:

    Homebrew
    brew uninstall barn
    Debian / Ubuntu
    sudo apt remove barn
    RHEL / Fedora
    sudo dnf remove barn
    • 用户态安装脚本(install.sh):删除 ~/.local/bin 下的 barn、barn-hosts-helper、.barn-current、.barn-releases/ 与 .barn-install.lock,并移除 Shell 配置文件中的 PATH 设置。
    • 手动归档或源码构建:停止全部 Mac 虚拟机后,删除解压后的发行目录、bin/mac 或单独复制出去的 Barn.app(0.9.0 版本为 Barn Mac.app),以及保存窗口位置的 ~/Library/Preferences/com.pgsty.barn.plist(0.9.0 版本为 io.pgsty.barn.mac-runner.plist)。
    • 手动安装的 hosts helper:若曾手动安装 /opt/barn/libexec/barn-hosts-helper,在完成 barn hosts uninstall --yes 且确认本机无其他用户使用 Barn 后即可删除。
警告

请务必在销毁全部 Linux 和 Mac 虚拟机之后再删除 ~/.barn(或自定义 BARN_HOME)。 ~/.barn 同时存放两类虚拟机的运行状态、密钥、持久数据盘与基础镜像;若仍有虚拟机目录残留或 destroy 报错,请先通过 barn status / barn mac ls 排查原因,切勿直接递归强删目录。