This is the multi-page printable view of this section. .
Reference
-
1: Command Reference
- 1.1: Preparation and Utilities
- 1.2: Linux Lifecycle
- 1.3: Guest Access and Hosts
- 1.4: Image Commands
- 1.5: Repository Commands
- 1.6: Host Network Commands
- 1.7: macOS Commands
- 2: Configuration
- 3: CLI Contracts
- 4: Mac Runtime Reference
- 5: Images
- 6: Image Pipeline
Use these pages to look up every command, configuration field, output schema, and image catalog rule in Barn 1.2.0. The version table identifies changes since 1.1.0. For task-oriented walkthroughs, start with the Guides.
- Command Reference — Every Linux and macOS command, complete option tables, defaults, examples, and version availability
- Linux Configuration — Inventory discovery, variables, defaults, data disks, host shares, and node drift rules
- CLI Contracts — Global flags, Linux lifecycle commands, structured JSON/YAML output, and exit codes
- Mac Runtime Reference —
barn macsubcommands, VM settings, JSON schemas, error reasons, and runtime files - Linux Images — Embedded catalog
2026110502, aliases, repository verification, local imports, and cache pruning - Image Pipeline — Contributor tools for validating and offline-normalizing Linux qcow2 candidates
Barn’s public interface is the barn CLI (barn version, barn <command> --help); Go packages under internal/ are internal implementation details. The image tables reflect the catalog embedded in Barn 1.2.0, while barn update can activate newer signed repository metadata without replacing the binary. For release verification and build gates, see Release Engineering.
1 - Command Reference
Find a command below for its arguments, complete local option table, examples, and effects. This reference follows the command-index and command-family organization of PIG. Barn’s CLI contracts describe structured output and exit codes; Configuration defines inventory fields.
Version baseline
This reference covers Barn 1.2.0, released on 2026-11-12 from 90f6158. Its 57 operation commands and 174 local option entries were checked against the CLI help output in both languages.
| Label | Availability | Behavior |
|---|---|---|
| 1.1.0 | Options available in both 1.1.0 and 1.2.0 | 1.1.0 used 2 vCPUs / 4 GiB by default and accepted CPU/memory resize through the inventory |
| 1.2.0 | Added in 1.2.0 | Resource flags and environment overrides, vm_scale, root-disk growth, lifecycle --parallel, vm_hosts, and hosts install -f; defaults are now 1 vCPU / 2 GiB |
To preserve the previous defaults when upgrading, set vm_cpu: 2 and vm_mem: 4GiB explicitly and inspect barn plan. Existing applied VMs keep their resources until a resource-changing operation is requested. Use barn version and barn COMMAND --help to check an installed build. See the release notes and release validation.
Command index
| Task | Commands and detailed reference |
|---|---|
| Prepare | setup, init, validate, doctor |
| Plan and create | plan, up |
| Start and stop | start, stop, restart, reload |
| Change and inspect | resize, recreate, status |
| Delete | destroy, purge |
| Access Linux guests | ssh, exec, logs, provision, ssh-config |
| Publish host names | hosts install, hosts uninstall |
| Refresh catalog | update, image sync, image reset |
| Manage Linux images | image list, info, pull, import, prune |
| Maintain a repository | repo scan, build, verify |
| Host network | network status, install, uninstall |
| Native macOS VMs | mac ls, up, start, stop, restart, configure, recreate, destroy |
| Mac access | mac open, ssh, exec, password, ssh-config, logs |
| Mac preparation | mac setup, doctor, image ls, image update, image prune |
| CLI utilities | version, completion, help |
Global options
| Option | Meaning |
|---|---|
-h, --help |
Human-readable help for the selected command; exits 0 |
--json |
Structured JSON on stdout; progress and diagnostics stay on stderr |
--yaml |
Structured YAML on stdout; mutually exclusive with --json |
-v, --verbose |
Bounded diagnostics on stderr |
--version |
Root-command shortcut to display build identity; use barn version --json for a structured report |
Global output options can appear before or after a subcommand, but must precede the remote-command -- separator used by ssh and exec. -f, -I, -A, -p, and --yes are local options: consult the selected command’s table. -f means follow for logs; -n means line count for mac logs. Long boolean options accept =true or =false.
BARN_OUTPUT and BARN_VERBOSE set presentation defaults. BARN_HOME selects private state (default ~/.barn); use an absolute path when changing directories. Linux and Mac machines share that data root but have independent lifecycles. See environment variables and exit codes.
barn and help
With no arguments, text mode prints complete help and exits 0; JSON/YAML mode returns suggested actions[]. Explicit help always prints human-readable text. Groups image, repo, network, hosts, and mac image require a subcommand and exit 2 without one. The mac group is the exception: it defaults to mac ls. It is hidden from root help on Linux and Intel Macs, while explicit Mac help remains available.
Short aliases are scoped to their parent. barn im ls is barn image list; barn mac st is barn mac ls. The per-command pages list each alias. There is no rm alias for purge.
1.1 - Preparation and Utilities
Initialize inventories, prepare the host, validate configuration, and inspect the CLI.
This reference covers Barn 1.2.0. Option tables distinguish options also available in 1.1.0 from additions in 1.2.0; see the version baseline. All commands inherit the global options.
barn setup
Prepare host packages, the fixed-IP network, images, and the selected inventory. It does not create the Linux VMs: run barn up afterward. With no template or -f, reuse the discovered inventory or generate meta. The templates meta, dual, trio, and full contain 1, 2, 3, and 4 nodes. -c and specification flags customize a generated template; explicit specification flags cannot be used to rewrite an existing inventory. In 1.2.0, specification environment variables are also ignored when setup reuses an inventory.
--dry-run previews the transaction. Applying it requires terminal confirmation or --yes; operating-system privilege prompts can still occur. On a fresh unedited default template, setup may choose a free private /24 and save barn.yml.before-network-change if the default subnet conflicts. Explicit inventories retain their subnet. On Linux, foreign-architecture QEMU emulators and firmware need separate installation.
Aliases: s.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-c, --cidr string |
generated template network as a canonical RFC1918 IPv4 /24 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
-d, --dry-run |
show the resolved setup plan without changing anything | 1.1.0 |
-f, --file string |
Inventory to prepare; mutually exclusive with a template argument | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
--mirror |
use the China official repository at repo.pigsty.cc; overridden by --repo |
1.1.0 |
-m, --mode string |
macOS fixed-IP network backend: host or shared (default “host”) | 1.1.0 |
-r, --repo string |
image repository URL or local directory, also used for socket_vmnet; overrides --mirror and $BARN_REPO |
1.1.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
-y, --yes |
accept the one-time setup plan (required without a terminal) | 1.1.0 |
barn init
Generate a Pigsty-compatible YAML inventory. The default is the one-node meta template in ./barn.yml; dual, trio, and full add nodes at .11, .12, and .13. The control node is .10. Existing files require --force; -o - prints the inventory. This command does not download images or prepare the host.
Barn 1.2.0 defaults to 1 vCPU and 2 GiB per node, with a 64 GiB root and a separate 128 GiB /data disk. Generated templates persist all six specification fields, including vm_scale. Version 1.1.0 used 2 vCPUs and 4 GiB by default. See specification defaults.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-c, --cidr string |
rebase the generated template to a canonical RFC1918 IPv4 /24 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
--force |
Overwrite the destination inventory; default preserves existing files | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
-o, --output string |
write to this path instead of ./barn.yml; ‘-’ writes to stdout | 1.1.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
barn validate
Read one inventory, validate the fields Barn consumes, and report the resolved nodes. It accepts no node selectors. Discovery checks barn.yml, barn.yaml, pigsty.yml, then pigsty.yaml in the current directory; no inventory means an error even if applied state exists. Overrides affect this validation only. Use --json to inspect the resolved specification, and plan to compare it with an existing deployment.
Aliases: v.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
-f, --file string |
Inventory to validate; otherwise use local discovery, with no applied-state fallback | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
-r, --repo string |
image repository whose catalog checks the images; overrides $BARN_REPO | 1.1.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
barn doctor
Probe QEMU, native acceleration, firmware, OpenSSH, a short accelerated boot test, and host networking. This is a host diagnostic and takes no inventory or node arguments. Missing compute capabilities fail the command; missing network setup is reported as informational. Inspect barn network status for the detailed network plan and barn mac doctor for native macOS VMs.
Aliases: dt.
No local options beyond --help; global presentation options still apply.
barn version
Print version, source commit, build time, host OS, and architecture. Development builds normally report dev; release identity comes from the build stamp. Use this report when matching documentation or filing an issue. The root shortcut barn --version is also available.
Aliases: ver.
No local options beyond --help; global presentation options still apply.
barn completion
Require one shell name: bash, zsh, fish, or powershell. Print its completion script to stdout; the command does not install the script. Completion includes scoped flags, templates, image aliases, and best-effort node names. Reload it after upgrading Barn. Use text output when sourcing shell code.
No local options beyond --help; global presentation options still apply.
Implementation
command_setup.go · command_misc.go · command_root.go
The version baseline identifies the released source and the changes since 1.1.0.
1.2 - Linux Lifecycle
Plan, create, start, resize, inspect, and explicitly remove Linux virtual machines.
This reference covers Barn 1.2.0. Option tables distinguish options also available in 1.1.0 from additions in 1.2.0; see the version baseline. All commands inherit the global options.
Node arguments are resolved names such as meta and node-1. Omit them to select all nodes in the command’s inventory/applied scope. IP addresses, groups, and vm_alias are not selectors. plan, up, reload, resize, and recreate read -f, then the current directory’s inventory, then applied state. Other lifecycle commands use applied state directly.
Specification overrides, scaling, and their environment variables are defined in Configuration. The 1.2.0 concurrency option applies only where --parallel is listed; plan, resize, and status do not accept it. For structured results and exit codes, see CLI contracts.
barn plan
Compare the effective desired inventory with applied state without changing VMs or downloading images. Report exact images, resources, per-disk actions, and nodes needing creation, resize, recreation, start, or explicit removal. Catalog images need only local metadata; inspecting a named local image also needs qemu-img.
Exit 0 means the plan was produced, including plans blocked by omitted nodes. Automation must inspect action, blocked, and the change arrays. Explicit selectors retain the applied definitions of unselected peers. Planning output describes the result.
Aliases: pl.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
-f, --file string |
desired inventory; defaults to the discovered inventory, then the applied state | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
-r, --repo string |
image repository URL or directory; overrides $BARN_REPO | 1.1.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
barn up
Create missing nodes, start stopped nodes, and retry unfinished guest setup while keeping healthy running VMs alive. It waits for management SSH unless --no-wait is set, and refreshes host SSH aliases and guest host/control-node entries. Non-fatal guest setup problems appear in warnings; ready nodes still succeed.
On an interactive first run, it can prepare missing host dependencies and generate meta when no inventory or applied deployment exists. Scripts should run setup --yes first. Existing definition changes require resize or recreate; inventory omissions require explicit destroy. --rollback only removes safe, uncommitted artifacts from preparation failures in this run.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
-f, --file string |
desired inventory; defaults to the discovered inventory, then the applied state | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
--mirror |
use the China official repository at repo.pigsty.cc; overridden by --repo |
1.1.0 |
-n, --no-wait |
return once QEMU is running, without waiting for the guest to boot | 1.1.0 |
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
-r, --repo string |
image repository URL or directory; overrides --mirror and $BARN_REPO |
1.1.0 |
--rollback |
remove safe artifacts from nodes that fail to prepare | 1.1.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
barn start
Start selected stopped nodes from applied state and wait for SSH. It works from any directory using the same BARN_HOME, without reading an inventory or creating nodes. It refreshes SSH access; use up to retry unfinished guest setup on an already-running VM. An unavailable share fails its node while independent nodes continue.
| Option | Meaning / default | Available in |
|---|---|---|
-n, --no-wait |
return once QEMU is running, without waiting for the guest to boot | 1.1.0 |
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
barn stop
Stop selected running Linux VMs using their recorded process identities. It retains root disks, data disks, keys, and deployment state. With no names, stop the whole Linux deployment; it does not stop named macOS VMs or remove the host network.
| Option | Meaning / default | Available in |
|---|---|---|
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
barn restart
Stop and start existing nodes using applied state. Inventory edits are not read. Use reload to re-read an inventory, or resize/recreate to apply changed definitions. It waits for SSH unless --no-wait is set.
| Option | Meaning / default | Available in |
|---|---|---|
-n, --no-wait |
return once QEMU is running, without waiting for the guest to boot | 1.1.0 |
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
barn reload
Validate the desired specification and startup dependencies before stopping selected nodes, then converge them through up. It can create newly added nodes. Changes requiring resize or recreation, and omitted applied nodes, fail preflight before any VM stops. Use restart when you want only the recorded configuration.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
-f, --file string |
desired inventory; defaults to the discovered inventory, then the applied state | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
--mirror |
use the China official repository at repo.pigsty.cc; overridden by --repo |
1.1.0 |
-n, --no-wait |
return once QEMU is running, without waiting for the guest to boot | 1.1.0 |
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
-r, --repo string |
image repository URL or directory; overrides --mirror and $BARN_REPO |
1.1.0 |
--rollback |
remove safe artifacts from nodes that fail to prepare | 1.1.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
barn resize
Apply CPU/memory changes and grow the root disk while preserving VM identity, disks, and SSH keys. Desired resources come from the inventory, environment, or CLI overrides. Supported CPU/memory increases use hotplug; decreases or unsupported live changes use a stop/start fallback. Image, architecture, data-disk, network, share, create, and remove changes cannot be applied by resize.
Use -D 128GiB to grow the existing root to 128 GiB. Root growth stops QEMU, expands its image, boots the guest to grow and verify a last plain ext4/XFS root partition, then restores an initially stopped VM to stopped. Targets must grow and align to 512 bytes. Retry an interrupted growth with the same target; shrinking, LVM, encrypted roots, and non-last partitions are unsupported. See root growth and recovery. CLI overrides do not rewrite the inventory.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
-f, --file string |
desired inventory; defaults to the discovered inventory, then the applied state | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
barn recreate
Replace the selected VMs from the desired inventory. This deletes their root disks and non-persistent data disks; compatible persistent data disks are reattached. Inspect plan first. A terminal asks you to type recreate; scripts require --yes or --force (no -y).
No selector means the whole inventory. If it omits an applied node, the operation fails before stopping VMs; explicitly destroy that node or restore it in the inventory. Selected recreation preserves unselected peers. A successful recreation also refreshes SSH access.
Aliases: rc.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
override deployment vm_arch: native, amd64, or arm64; environment overrides require 1.2.0 | 1.1.0 |
-C, --cpu string |
Base vCPUs before scale, integer 1–256; effective CPU count is also limited to 256; overrides BARN_CPU | 1.2.0 |
-D, --disk string |
Absolute root capacity, at least the base virtual size; bare integer means GiB; overrides BARN_DISK | 1.2.0 |
-f, --file string |
desired inventory; defaults to the discovered inventory, then the applied state | 1.1.0 |
--force |
recreate without the interactive confirmation (required without a terminal) | 1.1.0 |
-I, --image string |
override vm_image/vm_version for selected nodes; environment overrides require 1.2.0 | 1.1.0 |
-M, --mem string |
Base memory before scale, minimum 512 MiB; bare integer means MiB; overrides BARN_MEM | 1.2.0 |
--mirror |
use the China official repository at repo.pigsty.cc; overridden by --repo |
1.1.0 |
-n, --no-wait |
return once QEMU is running, without waiting for the guest to boot | 1.1.0 |
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
-r, --repo string |
image repository URL or directory; overrides --mirror and $BARN_REPO |
1.1.0 |
-S, --scale string |
Integer 1–256 multiplying base CPU and memory only; disk does not scale; overrides BARN_SCALE | 1.2.0 |
--yes |
same as --force |
1.1.0 |
barn status
Inspect recorded node configuration and live QEMU process identity without requiring the inventory directory. running reports a verified VM process, not an SSH readiness probe. --verbose adds runtime details; --json exposes node records, active-operation notes, and failures. A degraded node can produce exit 5 while healthy peers are still listed. The 1.2.0 text output uses compact SPEC values such as 2c4g.
Aliases: st.
No local options beyond --help; global presentation options still apply.
barn destroy
Delete selected VMs, or the whole deployment without selectors. Root and non-persistent data disks are deleted; persistent data disks are retained unless a whole-deployment deletion flag is explicit. Terminal confirmation requires typing destroy; scripts need --yes or --force, with no -y.
--delete-persistent and --purge require whole-deployment scope. --purge also removes deployment keys and state. The image cache, host network, and native Mac VMs remain. Removing the control node promotes the first remaining node; update admin_ip and run up to configure its control SSH access.
Aliases: de.
| Option | Meaning / default | Available in |
|---|---|---|
--delete-persistent |
also delete owned persistent data disks | 1.1.0 |
--force |
destroy without the interactive confirmation (required without a terminal) | 1.1.0 |
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
--purge |
terminal disposal: also delete persistent disks, keys, and deployment state | 1.1.0 |
--yes |
same as --force |
1.1.0 |
barn purge
Immediately delete the entire Linux deployment, including root disks, persistent data disks, keys, state, and the default SSH fragment. It takes no node names and reads no inventory. It has no --yes, -y, or --force: use --ask when you want to review the scope and confirm with y/yes (Enter cancels).
Cached images, host networking, and Mac VMs remain. An absent deployment is an idempotent success; ambiguous retained artifacts still require identity checks. The 1.2.0 --parallel flag controls node work during disposal.
| Option | Meaning / default | Available in |
|---|---|---|
--ask |
show the deletion scope and ask for y/yes before purging | 1.1.0 |
-p, --parallel int |
Node concurrency: omitted = max(1, logical CPUs - 2); 0 = all selected nodes; positive = limit | 1.2.0 |
Implementation
command_lifecycle.go · main.go
The version baseline identifies the released source and the changes since 1.1.0.
1.3 - Guest Access and Hosts
Connect to Linux guests, run scripts, read logs, and publish SSH or hosts entries.
This reference covers Barn 1.2.0. Option tables distinguish options also available in 1.1.0 from additions in 1.2.0; see the version baseline. All commands inherit the global options.
barn ssh
Open an interactive SSH session on the selected prepared node, defaulting to the prepared control node (or first prepared node). Remote commands require --; arguments after it are joined for the remote shell like ordinary ssh. Put Barn options before the separator. Node selectors are resolved node names, not IP addresses, aliases, or groups.
A remote command returns its exit status unchanged. Structured interactive SSH sends session output to stderr and the final report to stdout. See SSH argument rules.
No local options beyond --help; global presentation options still apply.
barn exec
Run one remote command on the selected prepared node, with the same default-node selection as ssh. -- and a non-empty first command argument are required. Separate arguments preserve spaces, quotes, and later empty values. Use sh -c for pipelines, redirection, or variable expansion; a single command string is also accepted as compatibility shell shorthand.
Text mode forwards the child output and exit status. Structured output includes success, exit_code, stdout, and stderr. A nonzero remote exit is passed through, so inspect that result before interpreting the number as a Barn error class.
Aliases: ex.
No local options beyond --help; global presentation options still apply.
barn logs
Read the selected node’s serial console or QEMU diagnostic log, defaulting to the prepared control/first node. --source events selects the deployment-wide bounded event log and takes no node argument; it can be read before deployment state exists. Following logs emits a stream rather than one final document. -f means follow here, not inventory. QEMU argv is hidden unless verbose output is enabled.
Aliases: l.
| Option | Meaning / default | Available in |
|---|---|---|
-f, --follow |
continue streaming appended log data | 1.1.0 |
-s, --source string |
log source: serial, qemu, or events (default “serial”) | 1.1.0 |
barn provision
Stream a local Bash script over the verified deployment SSH connection to selected running nodes, or all nodes if no names are supplied. The script is not left behind as a guest file; its digest is recorded for auditing. It does not create or start VMs.
--script is required. The default concurrency is 1 and the timeout is one hour for the operation. Unlike development lifecycle concurrency, --parallel 0 is invalid. --sudo uses noninteractive guest sudo -n; ensure the guest user has the required permission. Review per-node output and failures in structured mode.
| Option | Meaning / default | Available in |
|---|---|---|
-p, --parallel int |
Positive concurrency limit; default 1; zero is invalid | 1.1.0 |
-s, --script string |
local Bash script to stream to each selected guest | 1.1.0 |
--sudo |
run the guest script through sudo -n | 1.1.0 |
-t, --timeout duration |
hard deadline for the operation (default 1h0m0s) | 1.1.0 |
barn ssh-config
Print the Linux deployment’s OpenSSH fragment. --install writes a fragment and one Include in ~/.ssh/config; printing and installation accept node selectors. --remove removes only the named Barn fragment, needs no deployment state, and takes no nodes. Install and remove are mutually exclusive.
The default prefix is barn and its fragment is ~/.ssh/barn_config. Normal lifecycle commands maintain the default fragment automatically. If the user’s SSH configuration cannot be safely edited, Barn reports the manual Include instruction; direct barn ssh remains usable.
Aliases: sc.
| Option | Meaning / default | Available in |
|---|---|---|
-i, --install |
install the deployment fragment and one Include in ~/.ssh/config | 1.1.0 |
--name string |
SSH Host and fragment prefix (default “barn”) | 1.1.0 |
--remove |
remove the Include and fragment Barn installed | 1.1.0 |
barn hosts install
Publish applied node names and aliases in the Barn-owned block of the host’s /etc/hosts, using the digest-matched privileged helper. On a terminal it shows the change and asks before applying; in noninteractive or structured mode it only previews unless --yes is passed. An unchanged block requires no privilege. This file is not automatically published by up.
Barn 1.2.0 adds -f pigsty.yml, publishing inventory nodes plus all.vars.vm_hosts before VM creation. It replaces the whole Barn block, so a later call without -f drops inventory-only service names. See local service names.
Aliases: i.
| Option | Meaning / default | Available in |
|---|---|---|
-f, --file string |
Inventory nodes, aliases and vm_hosts; usable before VM creation | 1.2.0 |
-y, --yes |
apply the displayed privileged plan without confirmation (sudo may still ask for a password) | 1.1.0 |
barn hosts uninstall
Remove only the Barn-owned /etc/hosts block while retaining other entries. It needs no inventory or deployment state. Terminal mode displays a plan and asks; noninteractive/structured mode previews unless --yes is supplied. Removing the block does not delete VMs or change guest DNS configuration.
Aliases: u.
| Option | Meaning / default | Available in |
|---|---|---|
-y, --yes |
apply the displayed privileged plan without confirmation (sudo may still ask for a password) | 1.1.0 |
Implementation
command_root.go · command_access.go · main.go
The version baseline identifies the released source and the changes since 1.1.0.
1.4 - Image Commands
Refresh signed catalogs, inspect or download images, import local files, and prune caches.
This reference covers Barn 1.2.0. Option tables distinguish options also available in 1.1.0 from additions in 1.2.0; see the version baseline. All commands inherit the global options.
Official repositories and HTTP sources require a trusted detached signature. An explicitly selected custom HTTPS repository or local directory can be unsigned, provided the source is exactly that repository’s catalog.json. Any supplied signature must verify. See catalog trust.
barn update
Fetch catalog.json and its signature when required by repository policy, verify trust and revision rules, then atomically activate the catalog. Ordinary commands use local metadata and never update it implicitly. This updates image metadata, not the Barn executable. Repository precedence is --repo > --mirror > BARN_REPO > the global official repository. See repository selection and trust.
| Option | Meaning / default | Available in |
|---|---|---|
--mirror |
use the China official repository at repo.pigsty.cc; overridden by --repo |
1.1.0 |
-r, --repo string |
image repository URL or directory; overrides --mirror and $BARN_REPO |
1.1.0 |
barn image list
List every catalog architecture and registered local image. It has no image selector or architecture filter. The active local catalog is used; run barn update explicitly to refresh it. Aliases barn images and barn im select the same image command group.
Aliases: ls.
| Option | Meaning / default | Available in |
|---|---|---|
-r, --repo string |
image repository URL or directory; overrides $BARN_REPO | 1.1.0 |
barn image info
Inspect metadata and verified cache state for one image, using the catalog default if omitted. Select a family (u24), channel (u24:stable), or numeric version prefix (el9@9). Architecture defaults to native. The compatibility spelling --architecture/-a is also accepted for --arch/-A. It does not download the artifact. Supported aliases and exact embedded versions are in Linux images.
Aliases: in.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
artifact architecture (defaults to native): native, amd64 (x86_64, x64), or arm64 (aarch64, a64) | 1.1.0 |
-r, --repo string |
image repository URL or directory; overrides $BARN_REPO | 1.1.0 |
barn image pull
Download the selected artifact and verify its SHA-256, byte size, qcow2 structure, and virtual capacity before activating the cache entry. Omitted image and architecture select the catalog default and native host architecture. Existing valid cached bytes are reused. The catalog’s upstream URL is provenance, not a download fallback. --architecture/-a remains a compatibility alias. A foreign artifact does not install the corresponding QEMU emulator.
Aliases: p.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
artifact architecture (defaults to native): native, amd64 (x86_64, x64), or arm64 (aarch64, a64) | 1.1.0 |
--mirror |
use the China official repository at repo.pigsty.cc; overridden by --repo |
1.1.0 |
-r, --repo string |
image repository URL or directory; overrides --mirror and $BARN_REPO |
1.1.0 |
barn image import
Copy a local regular qcow2 image into the private cache and validate its container, optionally against an expected digest. Relative paths, ~/, and symlinks to regular files are accepted. qemu-img is required; importing does not boot the image, add cloud-init, or change credentials.
A local-* name registers an immutable inventory reference and requires boot mode plus the source login user. Named imports can record a foreign architecture with -A; qcow2 metadata does not identify CPU architecture, and unnamed imports cannot use -A. Set both vm_image and a matching vm_arch when using it. See import and cache rules.
Aliases: i.
| Option | Meaning / default | Available in |
|---|---|---|
-A, --arch string |
Guest architecture recorded with --name; defaults to native; does not convert the image |
1.1.0 |
-b, --boot string |
required with --name: bios or uefi |
1.1.0 |
--name string |
Immutable local-* alias; requires --boot and --source-user |
1.1.0 |
-s, --sha256 string |
optional expected SHA-256 | 1.1.0 |
-u, --source-user string |
required with --name: source image login user |
1.1.0 |
barn image sync
Activate a catalog from one exact URL or local file, reading its adjacent .minisig signature under the trust policy above. This is the recovery/import path; use update for the configured repository’s normal endpoint. --repo chooses which repository’s active metadata to replace. An unsigned custom source must be exactly <repo>/catalog.json; an arbitrary recovery file requires a trusted signature.
Older revisions require --allow-downgrade. For custom repositories that allow unsigned catalogs, switching from a previously signed catalog to an unsigned one also requires this flag. It never permits an invalid signature or bypasses the official-repository signature requirement and revision-content checks. Future downgrade protection still remembers the highest revision.
Aliases: sy.
| Option | Meaning / default | Available in |
|---|---|---|
--allow-downgrade |
activate a catalog older than the newest revision seen so far | 1.1.0 |
-r, --repo string |
Repository whose active catalog is replaced | 1.1.0 |
barn image reset
Reactivate the catalog embedded in the current binary for the selected repository. It keeps the highest accepted revision used by downgrade protection. Cached images and VM disks are retained; this is not a cache deletion command.
| Option | Meaning / default | Available in |
|---|---|---|
-r, --repo string |
Repository whose active catalog is reset to the embedded catalog | 1.1.0 |
barn image prune
List reclaimable cache files by default. --yes deletes candidates; it is mutually exclusive with --dry-run. The selected active catalog, applied node base-image digests, and registered local aliases protect their referenced files. Stale recognized staging files can also be removed; quarantined .corrupt-* files remain.
Preview with the same repository selection you will use for deletion. Deletion is sequential; an error on a later file does not restore files already removed. See pruning rules.
Aliases: pr.
| Option | Meaning / default | Available in |
|---|---|---|
-d, --dry-run |
show unreferenced images and stale staging files without deleting | 1.1.0 |
-r, --repo string |
image repository URL or directory; overrides $BARN_REPO | 1.1.0 |
-y, --yes |
Delete the listed unreferenced files; mutually exclusive with --dry-run |
1.1.0 |
Implementation
The version baseline identifies the released source and the changes since 1.1.0.
1.5 - Repository Commands
Scan, build, and verify static image repositories from repo.yaml and qcow2 artifacts.
This reference covers Barn 1.2.0. Option tables distinguish options also available in 1.1.0 from additions in 1.2.0; see the version baseline. All commands inherit the global options.
barn repo scan
Scan one repository root containing repo.yaml and a flat images/ directory. Report tracked, missing, untracked, and unsafe qcow2 files without changing them or requiring qemu-img. Successful scanning exits 0 even with findings; automation must inspect missing and unsafe rather than rely on the exit code alone.
No local options beyond --help; global presentation options still apply.
barn repo build
Validate repo.yaml, inspect the declared qcow2 artifacts with qemu-img, calculate final digests/sizes, and atomically generate catalog.json. Missing or unsafe artifacts fail the build; untracked files are omitted. repo.yaml and image bytes are preserved.
This command does not sign or publish a catalog. Increment the revision for changed contents, keep artifact filenames immutable, and use the separate contributor signing tools before publication. See repository format.
No local options beyond --help; global presentation options still apply.
barn repo verify
Rebuild the expected catalog in memory and require byte-for-byte agreement with the existing catalog.json, using repo.yaml and actual image bytes. Requires qemu-img. It checks repository consistency; detached-signature verification belongs to catalog activation and the signing tools.
No local options beyond --help; global presentation options still apply.
Implementation
The version baseline identifies the released source and the changes since 1.1.0.
1.6 - Host Network Commands
Inspect, install, and remove the fixed-IP network used by Linux guests.
This reference covers Barn 1.2.0. Option tables distinguish options also available in 1.1.0 from additions in 1.2.0; see the version baseline. All commands inherit the global options.
barn network status
Inspect the one host-wide Linux-guest network: backend, installed CIDR, ownership, health, and lifecycle preflight findings. --cidr checks an expected subnet; omitting it inspects the installed one. It is read-only. This network is separate from each native Mac VM’s private network.
Aliases: st.
| Option | Meaning / default | Available in |
|---|---|---|
-c, --cidr string |
Optional expected private /24; otherwise inspect the installed subnet | 1.1.0 |
barn network install
Inspect or install the host-wide backend: socket_vmnet on macOS or barn0 through the active Linux network manager. On a terminal it shows a privileged plan and asks; structured/noninteractive calls only preview unless --yes is supplied. On a fresh Mac, use setup to obtain the pinned socket_vmnet archive first.
--archive and --interface-id are macOS-only. host/shared are macOS vmnet modes; Linux rejects shared. An existing network must match the chosen configuration; review status before changing subnet or mode.
Aliases: i.
| Option | Meaning / default | Available in |
|---|---|---|
-a, --archive string |
macOS: pinned socket_vmnet archive | 1.1.0 |
-c, --cidr string |
network: an RFC1918 IPv4 /24 (default “10.10.10.0/24”) | 1.1.0 |
-i, --interface-id string |
macOS: persistent vmnet UUID | 1.1.0 |
-m, --mode string |
macOS vmnet mode: host or shared (default “host”) | 1.1.0 |
-y, --yes |
apply the displayed privileged plan without confirmation (sudo may still ask for a password) | 1.1.0 |
barn network uninstall
Remove only Barn-owned network configuration and restore recorded host settings. Stop running Linux guests first: the operation refuses a live deployment. Terminal mode asks after showing the plan; structured/noninteractive calls preview unless --yes is set. This does not delete VM disks or native Mac networks.
Aliases: u.
| Option | Meaning / default | Available in |
|---|---|---|
-y, --yes |
apply the displayed privileged plan without confirmation (sudo may still ask for a password) | 1.1.0 |
Implementation
The version baseline identifies the released source and the changes since 1.1.0.
1.7 - macOS Commands
Manage named native macOS VMs, desktop access, restore images, and shared bases.
This reference covers Barn 1.2.0. All options below were also available in 1.1.0.
Native macOS VMs require Apple Silicon, macOS 27+, and the matching Barn.app native app bundle, invoked as the logged-in desktop user. Their state lives under $BARN_HOME/mac and is independent of the Linux inventory.
For an optional name, Barn selects the sole existing VM or mac1; multiple VMs without mac1 require an explicit name. configure, recreate, and destroy always require names. start and stop accept multiple names or --all. At most two macOS VMs can run concurrently across apps on the host, including an active base installation. See machine rules, networking, output, and files.
Mac resource sizes use binary units even for GB, unlike Linux inventory decimal GB; a bare Mac size is bytes. These commands ignore Linux BARN_IMAGE/BARN_ARCH/BARN_CPU/BARN_MEM/BARN_SCALE/BARN_DISK overrides.
barn mac ls
Show every machine: its state, address, SSH readiness, macOS version and resources. It reads local records and asks each running machine, and never creates, downloads or starts anything.
Running barn mac without a subcommand also lists machines.
Aliases: list, status, st.
No local options beyond --help; global presentation options still apply.
barn mac up
Create the named machine (mac1 by default), start it, and wait until SSH and passwordless sudo work. Without a prepared macOS base, up first downloads the restore image from Apple after confirmation and installs it once; later machines clone that base.
Creation options apply to a new machine. For an existing machine, up starts it and rejects options that differ from its configuration; use configure for supported setting changes.
--no-wait returns once the VM is running. First-boot provisioning may still be in progress; run barn mac up NAME again to wait for SSH and finish initialization.
| Option | Meaning / default | Available in |
|---|---|---|
--clipboard on|off |
on/off, true/false, or yes/no; default on, active while the desktop window is focused | 1.1.0 |
--cpu int |
vCPUs, default 4; minimum 2, maximum host logical CPU count | 1.1.0 |
--disk size |
Base capacity, minimum 32 GiB; default uses the prepared base, or 100 GiB initially | 1.1.0 |
--ipsw string |
install macOS from this restore image instead of downloading from Apple | 1.1.0 |
--memory size |
Memory, default 8 GiB; a whole MiB from 4 GiB to host RAM | 1.1.0 |
-n, --no-wait |
return once the VM runs; first boot may still be initializing | 1.1.0 |
--open |
show the desktop as soon as the VM runs | 1.1.0 |
--share [name=]path[:ro] |
Repeatable [name=]path[:ro|:rw]; default writable, mounted under /Volumes/My Shared Files | 1.1.0 |
--subnet string |
Canonical private /24, or auto; default selects the first free subnet | 1.1.0 |
--user string |
Guest administrator; default is the host username, or barn if that name is invalid | 1.1.0 |
-y, --yes |
download macOS from Apple without asking (required without a terminal) | 1.1.0 |
barn mac start
Start existing machines and wait for SSH without creating machines or downloading images. --recovery boots macOS Recovery with its desktop shown.
Select names or --all, not both. Ordinary start requires completed first-boot initialization; use up to finish an uninitialized VM.
| Option | Meaning / default | Available in |
|---|---|---|
--all |
start every machine | 1.1.0 |
-n, --no-wait |
return once the VM runs, without waiting for SSH | 1.1.0 |
--open |
show the desktop as soon as the VM runs | 1.1.0 |
--recovery |
boot macOS Recovery and show its desktop | 1.1.0 |
barn mac stop
Shut machines down normally through macOS. A machine that has not stopped after two minutes is powered off, and the result says so. --force powers off at once, like holding a power button; unsaved work in the guest is lost.
| Option | Meaning / default | Available in |
|---|---|---|
--all |
stop every machine | 1.1.0 |
--force |
Power off immediately instead of requesting shutdown; unsaved guest work is lost | 1.1.0 |
barn mac restart
Shut a machine down normally and start it again, applying configuration changes.
Accepts at most one name; there is no --all. Omitted names follow the default-machine rule above.
| Option | Meaning / default | Available in |
|---|---|---|
-n, --no-wait |
return once the VM runs, without waiting for SSH | 1.1.0 |
--open |
show the desktop as soon as the VM runs | 1.1.0 |
barn mac configure
Change settings of an existing machine without touching its disk or account. CPUs, memory, shared folders and the network change while the machine is stopped; the clipboard setting can change anytime. Saved configuration, including clipboard changes, applies at the next start; use the menu-bar control to toggle clipboard sharing in the current session.
An explicit name is required. Omitted flags retain their values. --share adds or replaces a named share; --unshare removes one.
| Option | Meaning / default | Available in |
|---|---|---|
--clipboard on|off |
on/off, true/false, or yes/no; omitted retains the setting | 1.1.0 |
--cpu int |
vCPUs, minimum 2 and maximum host logical CPU count; omitted retains current value | 1.1.0 |
--memory size |
Memory, a whole MiB from 4 GiB to host RAM; omitted retains current value | 1.1.0 |
--share [name=]path[:ro] |
Add or replace a named share; repeatable, writable by default, optional :ro or :rw | 1.1.0 |
--subnet string |
move to this private /24 network, or auto for the first free one | 1.1.0 |
--unshare stringArray |
stop sharing the named folder (repeatable) | 1.1.0 |
barn mac recreate
Erase the machine’s disk and start a fresh macOS with the same name, account, resources, shared folders and address. --update uses the newest prepared base (see barn mac image update). Its files, apps and settings are lost.
A terminal asks you to type recreate; scripts require --yes or --force, with no -y shorthand.
| Option | Meaning / default | Available in |
|---|---|---|
--force |
skip the confirmation (required without a terminal) | 1.1.0 |
-n, --no-wait |
return once the VM runs, without waiting for SSH | 1.1.0 |
--update |
use the newest prepared macOS base | 1.1.0 |
--yes |
Same as --force; no -y shorthand |
1.1.0 |
barn mac destroy
Power machines off and delete them: disk, keys, password and settings. The shared macOS base and other machines are kept; barn mac image prune removes unused bases.
Explicit names are required. A terminal asks you to type destroy; scripts require --yes or --force, with no -y. Shared host folders are retained.
| Option | Meaning / default | Available in |
|---|---|---|
--force |
skip the confirmation (required without a terminal) | 1.1.0 |
--yes |
Same as --force; no -y shorthand |
1.1.0 |
barn mac open
Show the machine’s desktop window, starting the machine first when it is stopped. Closing the window keeps the machine running in the background; the clipboard is shared while the window is focused.
An uninitialized running VM can be viewed here; for a stopped uninitialized VM use mac up NAME --open.
No local options beyond --help; global presentation options still apply.
barn mac ssh
Connect with the machine’s own key and pinned host key. Everything before – must be empty or one known machine name, apart from Barn flags. A remote command requires –, and its first argument must not be empty. For exec, pass the program and its arguments separately to preserve argument boundaries, including later empty values. Use sh -c explicitly for shell expressions. A single command string remains supported as shell shorthand for compatibility. exec requires a command. ssh passes the command line to the remote shell like plain ssh. Without a command, ssh opens an interactive session.
No local options beyond --help; global presentation options still apply.
barn mac exec
Connect with the machine’s own key and pinned host key. Everything before – must be empty or one known machine name, apart from Barn flags. A remote command requires –, and its first argument must not be empty. For exec, pass the program and its arguments separately to preserve argument boundaries, including later empty values. Use sh -c explicitly for shell expressions. A single command string remains supported as shell shorthand for compatibility. exec requires a command. ssh passes the command line to the remote shell like plain ssh. Without a command, ssh opens an interactive session.
No local options beyond --help; global presentation options still apply.
barn mac password
Show the password of the machine’s login account, needed for the lock screen and administrator prompts in its desktop. It is stored next to the machine’s SSH key with the same protection. --copy puts it on the clipboard instead of printing it.
| Option | Meaning / default | Available in |
|---|---|---|
-c, --copy |
copy to the clipboard instead of printing | 1.1.0 |
barn mac ssh-config
Print the OpenSSH fragment that lets ssh, scp, rsync and editors reach each machine by name with its own key and pinned host key. The first machine to become ready installs it as one Include in ~/.ssh/config, and lifecycle commands keep it current. –remove deletes only what Barn installed and keeps it out until –install. A name that ~/.ssh/config already uses for another host is published by address only.
--install and --remove are mutually exclusive. This command takes no machine selectors.
| Option | Meaning / default | Available in |
|---|---|---|
-i, --install |
install the entries as one Include in ~/.ssh/config | 1.1.0 |
--remove |
remove the entries Barn installed | 1.1.0 |
barn mac logs
Show the last lines of the machine’s runtime log: startup, network, shutdown and Apple Virtualization errors.
--lines/-n must be positive and defaults to 100. There is no follow flag; -n means lines, not no-wait.
| Option | Meaning / default | Available in |
|---|---|---|
-n, --lines int |
number of recent lines (default 100) | 1.1.0 |
barn mac setup
Download macOS from Apple after you confirm, or read –ipsw, and install it once into the unbooted base that every machine is cloned from. up does this automatically; setup lets you do it ahead of time.
| Option | Meaning / default | Available in |
|---|---|---|
--disk size |
Base capacity, minimum 32 GiB and default 100 GiB | 1.1.0 |
--ipsw string |
install macOS from this restore image instead of downloading from Apple | 1.1.0 |
-y, --yes |
download macOS from Apple without asking (required without a terminal) | 1.1.0 |
barn mac image ls
List restore images and bases with their state, disk usage and the machines that use them.
This local-state query does not invoke the native runner.
Aliases: list.
No local options beyond --help; global presentation options still apply.
barn mac image update
Ask Apple for the newest macOS 27 restore image, download it after you confirm, and install it as the default base for new machines. Existing machines keep their base until barn mac recreate –update.
| Option | Meaning / default | Available in |
|---|---|---|
--ipsw string |
use this restore image instead of downloading from Apple | 1.1.0 |
-y, --yes |
download without asking (required without a terminal) | 1.1.0 |
barn mac image prune
List unused bases except the current default base. --installers also includes downloaded restore images and partial downloads. Deletion requires --yes.
| Option | Meaning / default | Available in |
|---|---|---|
--installers |
include downloaded restore images and partial downloads | 1.1.0 |
-y, --yes |
Delete the listed unused images; otherwise only list candidates | 1.1.0 |
barn mac doctor
Check macOS and Apple Silicon support, the Mac component’s signature, free disk space, the prepared base, and every machine: its files, keys, shared folders, network and SSH. It changes nothing and starts nothing.
No local options beyond --help; global presentation options still apply.
Implementation
The version baseline identifies the released source and the changes since 1.1.0.
2 - Configuration
This reference covers Barn 1.2.0. Linux defaults are 1 vCPU and 2 GiB. To preserve the 1.1.0 defaults on upgrade, explicitly set vm_cpu: 2 and vm_mem: 4GiB. See the version baseline and check the installed build with barn version and --help.
Discovery
Barn resolves the inventory path by checking an explicit -f argument first, then searching the current working directory for barn.yml, barn.yaml, pigsty.yml, and pigsty.yaml in that order. All four filenames use the same Pigsty-compatible YAML inventory format.
When no inventory file is present in the current directory, plan, up, reload, recreate, and resize fall back to the applied specification stored in BARN_HOME (default ~/.barn) if a deployment already exists. validate always requires an inventory file on disk. The file must resolve to a regular file no larger than 4 MiB; symlinks are supported. Relative shared-directory paths resolve beside the inventory’s real file. Barn stops at the first matching filename and reports any parse or validation error directly rather than falling through to the next candidate.
Barn stores applied deployment state in BARN_HOME. Renaming the inventory does not change the deployment; use an absolute BARN_HOME to address the same deployment across working directories.
A complete inventory
barn init [meta|dual|trio|full] generates a 1-, 2-, 3-, or 4-node topology template. meta uses .10, and larger templates add node-1 at .11, node-2 at .12, and node-3 at .13 (defining VM topology while leaving Pigsty service roles to your upper-layer playbook). Pass --cidr to change the /24 prefix while keeping the host octets, or run barn init full -o - to print a template to stdout without writing a file.
This inventory defines two managed nodes with meta as the control node. Save it as barn.yml and inspect the resolved configuration before starting any VMs:
validate checks YAML syntax, field rules, and image catalog references (pass --repo to check against another repository’s catalog) without starting VMs or downloading images. Its JSON output includes valid, source, spec_hash, and resolved; if the local image catalog cannot be read, it emits a warning and leaves image selectors unresolved. During up, Barn verifies local-* imported image bytes, host capabilities, shared directories, networking, and guest SSH readiness.
What Barn reads
An inventory must contain a top-level all: group, from which Barn traverses hosts and nested children mappings. Barn parses static YAML directly—without evaluating Ansible inventory plugins, Jinja expressions, group_vars, or host_vars. If the same IPv4 address appears in multiple groups, Barn merges its inherited variables into a single node definition.
Barn reads node IPv4 keys, nodename, admin_ip, pg_cluster, pg_seq, node_admin_username, node_admin_uid, and the vm_* variables listed below:
- Control node: Barn reads
admin_ipfromall.vars. Ifadmin_ipis omitted or does not match a managed node, Barn selects the first managed node encountered in YAML traversal order (reading each group’shostsbefore itschildren). Setadmin_ipexplicitly so the control node stays fixed when you reorder groups. - Login account: All nodes share one login username matching
[a-z_][a-z0-9_-]{0,31}. For the defaultdbauser, an explicitnode_admin_uidmust be88. For a custom username, Barn verifies thatnode_admin_uidis an integer if present, while the guest assigns the account’s UID at creation time. - Upper-layer Pigsty fields: Variables outside Barn’s scope—such as
pg_role,pg_version,repo_*, andnode_packages—are ignored by Barn and never trigger VM configuration drift. - Inheritance and validation: Variables inherit along
all.vars→ nestedchildren.<group>.vars→ host variables. Host-level list variables such asvm_disksreplace inherited lists wholesale. If two sibling groups at the same depth set conflicting values for the same node, override the variable on the host entry. Unknownvm_*keys, invalid types, Jinja templates, duplicate YAML keys, and multi-document YAML streams fail validation with line numbers, violated rules, and spelling suggestions for mistypedvm_*names. YAML anchors and<<merge keys are supported (explicit keys win, followed by the first mapping in a merge sequence). - Skipped nodes: Hosts with
vm_skip: truemay use hostnames or IPv6 keys and do not participate in the managed/24; at least one managed node must remain. Skipping an existing node marks itmissinginplanwithout destroying it.
VM variables
| Variable | Default | Meaning |
|---|---|---|
vm_skip |
false |
Skip virtualization for this physical or external host |
vm_image |
u24 |
Image family, :channel reference, or image@version selector |
vm_version |
unset | Newest numeric version matching this prefix, such as 9 or 9.7 |
vm_arch |
native |
Deployment-wide guest architecture; follows the host unless explicitly set to amd64 or arm64 |
vm_cpu |
1 |
Base vCPU count; the effective count after scaling must be 1–256 |
vm_mem |
2048 |
Base memory size: bare integer in MiB, or an explicit unit string such as 8GiB (minimum 512MiB) |
vm_scale |
1 |
Positive integer multiplying CPU and memory only |
vm_hosts |
[] |
Extra local hosts mappings, declared only in all.vars |
vm_disk |
64 |
Root disk capacity: bare integer in GiB, or an explicit unit string such as 64GiB |
vm_disks |
[{path: /data}] |
Extra data disks (defaults to one 128 GiB non-persistent disk mounted at /data) |
vm_alias |
[] |
Additional guest /etc/hosts, SSH config, and optional host /etc/hosts aliases |
vm_shares |
[] |
QEMU 9p host-directory shares on Linux and macOS hosts |
An empty host mapping (10.10.10.10: {}) is enough to define a complete VM with default settings. Managed nodes require distinct usable addresses in the configured /24.
Bare integers specify MiB for vm_mem and GiB for disks. Size strings accept positive integers with case-insensitive units, including 8G, 512m, 4gib, and 64GB. K/M/G/T and KiB/MiB/GiB/TiB use binary powers; KB/MB/GB/TB use decimal powers. Fractions such as 1.5GiB and unitless strings such as "8192" are invalid. up checks that the root disk is at least as large as the base image’s virtual size.
When vm_image is omitted, Barn defaults to u24 (Ubuntu 24.04) from the binary’s embedded catalog regardless of any default declared in a custom repository. Built-in aliases such as ubuntu → u24 are normalized against the embedded catalog during inventory parsing, so custom repositories should use their canonical family names in vm_image rather than reassigning built-in aliases.
Use vm_version when you want to keep the image family and version prefix in separate fields:
If an exact version match exists in the catalog, Barn selects it; otherwise it matches dot-separated numeric prefixes and picks the highest version (9.8 selects the latest 9.8.* build, 9 selects the latest 9.x release, and 9.10 sorts after 9.9). Use vm_version only with a bare family name in vm_image (without :channel or @version).
Resource scaling in 1.2.0
Resolve vm_cpu, vm_mem, and vm_scale independently: host variables override the deepest group, which overrides parent groups and all.vars. Missing values default to 1 vCPU, 2048 MiB, and a scale of 1. Multiply once after inheritance:
| Settings | Effective CPU | Effective memory |
|---|---|---|
| None | 1 | 2 GiB |
vm_scale: 3 |
3 | 6 GiB |
vm_cpu: 2, vm_scale: 3 |
6 | 6 GiB |
vm_mem: 4GiB, vm_scale: 3 |
3 | 12 GiB |
vm_cpu: 2, vm_mem: 4GiB, vm_scale: 3 |
6 | 12 GiB |
A host’s vm_scale: 1 replaces a group’s vm_scale: 3; group and host scales do not compound. Equal-depth conflicts require a host override. Scale accepts integers from 1 to 256, subject to the effective 256-vCPU limit and memory overflow checks. Quoted numbers, fractions, booleans, null, zero, and negative values fail validation. Base memory still requires at least 512 MiB. Root disks, data disks, and shares are unaffected. Use the exact keys vm_cpu and vm_mem; vm_memory is not an alias.
Inspect barn plan -f pigsty.yml, then apply CPU/memory changes with barn resize -f pigsty.yml. Existing deployments that omit these fields will show a resource decrease when their inventory is read by the new build. Add vm_cpu: 2 and vm_mem: 4096 before upgrading to preserve the previous defaults. Commands using applied state without an inventory keep the recorded resources.
Local service names in 1.2.0
Inventory-based hosts publication is available in Barn 1.2.0.
Declare finite service mappings in all.vars.vm_hosts. Barn combines them with node names and vm_alias when publishing from an explicit inventory:
Each entry requires address and a non-empty names list. Addresses must be canonical IPv4 addresses in the inventory’s private /24, within .9–.254; .1–.8 are reserved for the host and DHCP. Identical name/address pairs deduplicate; names compare without case, and different destinations fail validation. Existing conflicting names outside the Barn-owned block also stop publication. A hosts record does not configure a VIP in a guest.
These mappings affect only the host’s /etc/hosts. Editing them does not change the VM spec hash, configure guest DNS, or trigger VM drift. Without -f, hosts install publishes only names and aliases from applied VM state, replacing the whole Barn block; repeat the explicit inventory command to retain service names. up never publishes this file automatically. An unchanged plan needs no sudo; each changed system hosts file requires privilege. Wildcards, SRV records, and live primary discovery require a DNS service.
Pigsty’s development bin/sandbox-dns extracts its portal, node, PostgreSQL, VIP, and MinIO names for this interface. See the migration audit.
Specification overrides
Barn 1.2.0 accepts unified CLI and environment inputs for six specification fields. Version 1.1.0 supports the image/architecture flags but not the four resource flags or these environment variables.
| Inventory field | CLI | Environment variable | Default |
|---|---|---|---|
vm_image |
--image/-I |
BARN_IMAGE |
u24 |
vm_arch |
--arch/-A |
BARN_ARCH |
native |
vm_cpu |
--cpu/-C |
BARN_CPU |
1 |
vm_mem |
--mem/-M |
BARN_MEM |
2048 MiB |
vm_scale |
--scale/-S |
BARN_SCALE |
1 |
vm_disk |
--disk/-D |
BARN_DISK |
64 GiB |
Each field follows CLI > nonempty environment > host > deepest child group > parent group > all.vars > default. CPU and memory always specify bases; multiply each once by the final scale after applying overrides. Disk capacity does not scale. -S 3 replaces the previous multiplier; add -S 1 for exact final CPU/memory. CLI and environment override host values on selected nodes. Put common defaults in all.vars when host exceptions should remain effective. Inventory syntax, field types, and inheritance conflicts must remain valid.
init and template-generating setup write all six choices, including defaults, and save CPU/memory bases and scale. The first interactive up also saves its choices if it needs to generate an inventory. Lifecycle overrides on an existing file change only the current desired specification without rewriting YAML; reading the original file later reports drift. When only applied state remains, --scale or BARN_SCALE requires -f; CPU/memory can set absolute values with an implicit scale of 1.
Environment variables affect only commands accepting the corresponding specifications. status/start/stop/restart/destroy/purge, independent image management, and barn mac ignore these six variables. So does setup when reusing an inventory. resize accepts CPU/memory/scale, root capacity, and its existing I/A consistency checks; BARN_DISK only grows the root disk. Whitespace-only environment values mean unset, and invalid values shadowed by CLI do not fail: BARN_CPU=bad barn plan -C 2 uses 2. Effective environment overrides are preserved as explicit flags in follow-up commands.
--disk sets the absolute system root capacity, which must be at least the base image’s virtual size. Planning checks catalog metadata; creation checks the actual image again. It applies to creation, explicit recreation, and in-place root growth through resize -D. Growth supports last plain ext4/XFS root partitions and never shrinks them; see root disk growth for the workflow and recovery. Recreation replaces root and nonpersistent data disks. The default 128 GiB /data disk remains separate.
Image and architecture overrides
Image and architecture follow the same specification precedence as the resource fields: CLI flags, nonempty environment variables, inventory values, then defaults.
Guests default to the host architecture: arm64 on Apple Silicon and amd64 on Intel/AMD hosts. Another architecture can be selected through the CLI, environment, or inventory. Precedence is --arch/-A → BARN_ARCH → inventory vm_arch → native (host architecture). Use -A native to override the environment and inventory and follow the host again.
| Architecture | Aliases | Meaning |
|---|---|---|
native |
— | Follow the current host; also the default when unset |
amd64 |
x86_64, x64 |
Select an x86-64 guest |
arm64 |
aarch64, a64 |
Select an ARM64 guest |
vm_arch applies to the entire deployment; define it once under all.vars. Every managed node must resolve to the same architecture. Node variables and selectors cannot create a deployment with mixed architectures.
--image/-I overrides BARN_IMAGE and the selected nodes’ vm_image/vm_version without changing architecture. Without the flag, a nonempty BARN_IMAGE overrides the inventory image. The catalog must provide the requested architecture variant; a missing variant is an error and never selects another architecture automatically.
Overrides on up, plan, reload, recreate, resize, and validate change only the desired configuration for that invocation. To keep a choice, set all.vars.vm_arch and the relevant node or group vm_image, removing any superseded vm_version. init and template-generating setup write the choices into the new inventory. Setup’s -I/-A flags cannot be used with an existing inventory.
When no inventory file exists, lifecycle commands use the saved deployment specification before applying explicit overrides. start and restart always use applied state. Omitting -A or editing the inventory never converts an existing VM: up reports drift, and switching architecture requires recreate with all existing nodes selected. resize applies CPU/memory changes and grows supported root disks; image and architecture changes require recreate.
Guests whose architecture differs from the host use QEMU TCG. On Linux, barn setup installs the native emulator; install the target qemu-system-* binary and UEFI firmware before starting a foreign guest. See Runtime policy for acceleration and image exceptions.
Data disks
Each entry in vm_disks configures an additional virtual block device:
path: Absolute mount path, normalized automatically; spaces, Unicode, and shell punctuation are supported. Simple paths retain existing disk names; other paths get stable digest-based names. Identities must be unique within a node. System directories and overlapping mount paths remain invalid.size: Disk capacity, defaulting to128(128 GiB). Accepts a GiB integer or an explicit size string.fs: Filesystem type—auto(default),xfs, orext4. On a blankautodisk, Barn formats with XFS whenmkfs.xfsis available in the guest and falls back to ext4 otherwise. Explicitxfsorext4settings require that filesystem tool and never fall back. Healthy existing filesystems are mounted as-is.persistent: Whentrue, ordinarybarn destroyandbarn recreatekeep the disk image on the host so the recreated node reattaches it when the disk identity and definition remain compatible. Setvm_disks: []to create a node with no extra data disks.
Data disks are disposable test storage. During up, Barn formats a blank data disk with the configured fs. It resets an existing ext4 or XFS filesystem, persistent: true disks included, only when the guest’s read-only check (e2fsck -fn or xfs_repair -n) reports recognized corruption, and records the reset in nodes[].repairs. A disk with a partition table, a signature without a filesystem UUID, another filesystem type, features the guest tools do not support, or an unrecognized checker failure keeps its data and gets a warning in nodes[].warnings; so do transient probe errors, missing block devices, busy mounts, and host I/O errors. Root disks and host shares are never formatted.
Shares
vm_shares mounts host directories into Linux guests through QEMU Virtio-9p on Linux and macOS hosts, with readonly: true by default. Host QEMU and the guest kernel must support 9p; backend device limits apply. Native macOS guests use VirtioFS through barn mac --share.
Shared sources use the invoking user’s actual filesystem permissions:
hostaccepts absolute paths,~/, inventory-relative paths, and directory symlinks.guestmust be absolute and is normalized automatically; spaces, Unicode, and shell punctuation are accepted, while control characters are rejected.- Resolved host directories must exist, be accessible, and not overlap
BARN_HOME; ownership by the invoking user is not required. - Host sources may overlap and may be shared by multiple readers or writers. Users coordinate concurrent writes. Guest mount targets within one node must not overlap.
guestpaths cannot overlap data-disk mounts, system directories, or the login user’s.sshdirectory. Use 9p shares for source code and build artifacts rather than PostgreSQL data directories.- If a writable share (
readonly: false) cannot be written by the guest user, Barn mounts it read-only, reports a warning, and leaves host file ownership untouched; fix host permissions and re-runbarn upto upgrade the mount. - Changing
vm_shareson an existing node requiresbarn recreate. Missing host directories duringuporstartfail only the affected node, whilerestart,reload, andrecreateverify share paths before stopping running VMs.
Names and addresses
Barn resolves each node’s name from the first available source: explicit nodename, <pg_cluster>-<pg_seq>, or node-<last-octet>. Node names must be unique across the deployment, be 1–63 characters long, contain only lowercase letters, digits, and hyphens, and neither start nor end with -. vm_alias accepts additional lowercase DNS names (dots allowed) that must be distinct from all node names and other aliases.
All managed nodes in a deployment must belong to a single RFC1918 /24 subnet: .1 is the host gateway, .2–.8 are reserved, and .9–.254 are available for nodes. Inside the guest, the fixed-IP NIC carries the configured inventory address (inspectable via ip -br addr).
Drift
Explicit node selectors apply only selected changes: plan node-1, up node-1, reload node-1, recreate node-1, and resize node-1 retain the applied definitions of unselected peers, even when edited or omitted in the inventory. The entire inventory must still parse correctly. Images for uncreated, unselected nodes are not resolved. Conflicts with applied addresses, aliases, control-node roles, or deployment-wide settings are still rejected.
Barn computes a specification hash for every resolved node:
barn upcreates newly added nodes, starts stopped nodes, and retries unfinished guest provisioning on running nodes without restarting their QEMU processes.- Modifying a node’s CPU or memory uses
barn resize <node>and preserves its identity and disks. Barn 1.2.0 also supports grow-only root capacity throughresize -D. Image, data-disk, share, or other VM definition changes requirebarn recreate <node>. Removing a node from the inventory (or settingvm_skip: true) reports the node asmissinginplanwithout automatically destroying it. - Changing deployment-wide settings (
vm_arch, login username, or the/24subnet) requires recreating the entire deployment. - Because
planandupresolve image channels and version prefixes against the active catalog, runningbarn updatecan introduce image drift even whenbarn.ymlhas not changed. Always keep an explicitnodenameon each host so renamingpg_clusterdoes not turn an existing node into amissingold node plus a new node.
3 - CLI Contracts
This page describes Barn 1.2.0 global presentation, Linux lifecycle semantics, structured output, and exit codes. For syntax, options, defaults, and examples, use the Command Reference. Native Mac runtime contracts are in Mac Reference.
Every command documents its local flags and examples through --help:
Running barn with no arguments prints the same complete help as barn --help and exits 0; with --json or --yaml it returns an actions[] array of suggested next commands instead. Invoking a command group without a subcommand—such as barn image—exits 2 (printing help in text mode or a usage error object in JSON/YAML mode). Explicit --help always prints human-readable help and exits 0. Use barn --version or barn version to inspect the build identity.
Commands
| Area | Commands |
|---|---|
| Prepare | setup, init, validate, doctor |
| Lifecycle | plan, up, start, stop, restart, reload, resize, recreate, status, destroy, purge |
| Access | ssh, exec, logs, provision, ssh-config, hosts install/uninstall |
| Images | update, image list/info/pull/import/sync/prune/reset, repo scan/build/verify |
| Host network | network status/install/uninstall |
| macOS guests | mac … — see Mac Commands |
| Misc | version, completion |
Ordinary commands read the active local image catalog without contacting remote repositories. Run barn update to fetch, verify, and activate the configured repository’s catalog, or barn image sync to recover a catalog from an exact URL or local file. Neither command replaces the barn executable.
Frequently used commands define short aliases within their scope:
| Command | Aliases | Command | Aliases |
|---|---|---|---|
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, resize, provision, hosts, purge, update, repo, mac, and completion have no top-level shorthand (rm is not an alias for purge). Inside subcommand groups, hosts and network map i/u to install/uninstall, network status accepts st, and image maps list=ls, info=in, pull=p, prune=pr, sync=sy, and import=i.
Barn manages a single deployment per BARN_HOME (default ~/.barn; see Configuration), so commands that operate on applied state work from any directory when BARN_HOME points to the same location. Use an absolute BARN_HOME when changing working directories. Each command resolves its desired-state source independently (-f is a per-command flag rather than a global flag):
| Commands | Desired-state source |
|---|---|
setup [template] |
Explicit -f, then local discovery, otherwise generates meta (template and -f are mutually exclusive) |
init [template] |
Generates a new inventory without reading existing state; --force overwrites an existing file |
validate |
Explicit -f, then local discovery; never falls back to applied state |
plan, up, reload, recreate, resize |
Explicit -f, then local discovery, then the applied deployment specification |
| Other lifecycle & access commands | Operate directly on applied state in BARN_HOME |
When a host dependency or the Barn network is missing, up, start, restart, and reload on a terminal prepare the host as barn setup does: they show the host-preparation plan and ask once before installing packages or the network (sudo may still prompt for your OS password). When neither an inventory file nor an applied deployment exists, an interactive barn up also generates the default meta inventory first. Without a terminal these commands only report what is missing. Run barn setup --dry-run to inspect the plan, and barn setup --yes to prepare the host from a script.
If the default 10.10.10.0/24 subnet conflicts with an existing host route while preparing a fresh, unedited default template, setup selects another free RFC1918 /24 and backs up the prior template as barn.yml.before-network-change. Explicit -f inventories, edited files, and existing deployments always keep their configured subnet.
Important flags
| Flag | Meaning |
|---|---|
--json, --yaml |
Emit structured output on stdout while keeping progress on stderr (long-form only) |
-v, --verbose |
Emit bounded diagnostic logs on stderr |
-c, --cidr |
Set the RFC1918 /24 subnet for init/setup templates or network inspection/installation |
-I, --image |
Choose an image for a generated template or override selected nodes’ vm_image/vm_version on commands listed below |
-A, --arch |
Select guest or artifact architecture: native, amd64 (x86_64, x64), or arm64 (aarch64, a64) |
-f, --file |
Select an inventory file for commands that read desired state |
-r, --repo |
Select an image repository URL or path, overriding --mirror and BARN_REPO |
--mirror |
Use the China official repository (https://repo.pigsty.cc/barn) for setup, up, reload, recreate, update, and image pull |
-m, --mode |
Select host or shared network mode on macOS |
-d, --dry-run |
Print the execution plan for setup or image prune without modifying state |
--yes |
Confirm host, setup, image, or destruction plans; -y is available only where listed below |
--force (init, destroy, recreate) |
Overwrite an existing inventory (init) or skip the interactive confirmation word (long-form only, as -f means --file) |
--ask (purge) |
Display the VM list and deletion scope, then require y/yes before deleting |
-n, --no-wait |
Return as soon as QEMU starts, skipping guest SSH readiness and recovery checks |
--rollback (up, reload) |
Clean up uncommitted preparation artifacts for nodes that failed during the current run |
--delete-persistent |
Delete persistent: true data disks during a whole-deployment destroy |
--purge |
Delete all deployment disks, SSH keys, and state during a whole-deployment destroy, while keeping cached base images |
Each command exposes only the flags that apply to its operation:
| Command | Local controls |
|---|---|
init |
--output/-o (default ./barn.yml; - writes to stdout), --cidr/-c, --image/-I, --arch/-A, --force |
setup [meta|dual|trio|full] |
--file/-f, --cidr/-c, --image/-I, --arch/-A, --repo/-r, --mirror, --mode/-m, --dry-run/-d, --yes/-y (defaults to meta) |
validate |
--file/-f, --repo/-r, --image/-I, --arch/-A; accepts no node arguments |
plan |
--file/-f, --repo/-r, --image/-I, --arch/-A |
up, reload |
--file/-f, --repo/-r, --image/-I, --arch/-A, --mirror, --no-wait/-n, --rollback |
recreate |
--file/-f, --repo/-r, --image/-I, --arch/-A, --mirror, --yes/--force, --no-wait/-n |
resize |
--file/-f, --image/-I, --arch/-A (still applies only CPU/memory changes) |
start, restart |
--no-wait/-n |
stop, status |
Node selectors and global presentation flags only |
destroy |
--yes/--force, --delete-persistent, --purge (the last two require whole-deployment scope) |
purge |
Deletes immediately; --ask enables confirmation; accepts no node arguments or --yes, -y, --force |
doctor, version |
Global presentation flags only |
provision |
Required --script/-s; --sudo; --parallel/-p positive integer (default 1); --timeout/-t positive duration (default 1h) |
ssh-config |
Optional node selectors; --install/-i or --remove (mutually exclusive); --name (default barn). --remove takes no nodes and works without deployment state |
logs |
--source/-s serial|qemu|events (default serial); --follow/-f (events is deployment-wide and takes no node) |
image info, image pull |
Optional image selector, --arch/-A (legacy -a also works), --repo/-r; pull also accepts --mirror |
image import |
--sha256/-s; named imports (--name local-*) also require --boot/-b bios|uefi and --source-user/-u, with optional --arch/-A to record guest architecture |
image prune |
--dry-run/-d or --yes/-y (mutually exclusive); --repo/-r |
image sync |
Source URL or file path, --repo/-r, and optional --allow-downgrade |
update |
--repo/-r, --mirror |
image list, image reset |
--repo/-r |
repo scan/build/verify |
One repository directory; relative paths, ~/, and directory symlinks are supported |
network install |
--cidr/-c (default 10.10.10.0/24), --mode/-m (default host), --yes/-y; macOS-only --archive/-a, --interface-id/-i |
network status |
Optional --cidr/-c |
network uninstall, hosts install/uninstall |
--yes/-y |
hosts install (1.2.0) |
--file/-f: publish inventory nodes and vm_hosts, including before VM creation |
Notes on flag behavior:
setup --dry-runandsetup --yesare mutually exclusive.--cidradjusts generated templates and never rewrites an existing-ffile. Forvalidateagainst the China mirror, pass--repo https://repo.pigsty.cc/barn.initand template-generatingsetupwrite-Iand-Aintoall.vars.vm_imageandall.vars.vm_arch;setuprejects these generation flags when using an existing inventory.up,plan,reload,recreate,resize, andvalidateapply overrides in memory for that invocation. Image overrides affect selected nodes; architecture affects the whole deployment. See precedence and defaults.- Standalone
image info/pull/importdefault to the host architecture without reading inventoryvm_arch; select another with-A.image import -Arequires--name. Since qcow2 metadata cannot identify the guest CPU, the declared architecture must match the actual image. networkandhostsinstall/uninstalldisplay a plan and prompt for confirmation on a terminal (installdefaults to yes;uninstalldefaults to no). Without--yes, they only print the plan and exit0when stdin is not a terminal or the output is--json/--yaml; checkappliedin the structured report, or pass--yesto apply the plan. On macOS, first-time network installation is handled bybarn setup.network uninstallrefuses to remove the host network while VMs are running, and stopping or destroying a deployment leaves the host network installed. On Linux,network uninstallkeeps the global networkd unit state when other host links exist or exclusive Barn use cannot be established; the plan reportspreserve_networkd, and the applied report explains the decision inchecks.networkd.- Safety and repository flags (
--ask,--mirror,--force,--rollback,--remove,--allow-downgrade,--sudo,--delete-persistent,--purge) are long-form only. On Linux commands,-fselects--file(exceptbarn logs -f, where-fmeans--follow),-nmeans--no-wait(whereasbarn mac logs -nsets the line count), and-dmeans--dry-run. barn purgedeletes immediately by default: all nodes, persistent disks, SSH keys, deployment state, and the default SSH config fragment are removed; cached images and the host network remain. Only--askdisplays the node list and deletion scope before prompting:y/yesconfirms;n/no, an empty line, or EOF cancels with exit130. It does not accept--yes,-y, or--force. With no deployment, defaultbarn purgeand whole-deploymentbarn destroysucceed cleanly; purge also removes retained persistent disks with intact Barn ownership metadata. Unverifiable retained directories still prevent deletion. If deployment state is missing,destroy --force --delete-persistentanddestroy --force --purgedirect you tobarn purge.
Specification flags and SPEC display
Barn 1.2.0 adds --cpu/-C, --mem/-M, --scale/-S, and --disk/-D, sharing input rules with --image/-I and --arch/-A. Specification options are available on:
| Command | Added support |
|---|---|
init, template-generating setup |
C/M/S/D, saved in the new inventory |
validate, plan, up, reload, recreate |
C/M/S/D, overriding the current desired specification |
resize |
C/M/S/D, applying CPU/memory changes and root growth; retain existing I/A checks |
setup reusing an inventory |
Reject specification overrides and ignore specification environment variables |
start/stop/restart/status/destroy/purge |
No specification inputs; retain applied state |
See specification overrides for parameters, units, environment variables, and persistence. up/reload do not automatically apply resource changes to existing nodes; use resize or explicit recreate.
Node tables use SPEC for effective CPU and memory, such as 1c2g, 2c4g, and 8c16g. c means vCPU and g means GiB; 1536 MiB appears exactly as 1.5g, and 512 MiB as 0.5g. Capacities not divisible by MiB retain their exact byte count with b; unknown specifications show -.
status and completion results show applied resources; plan/validate/setup show desired resources. Plans show changes as 2c4g → 4c8g, with root capacity in a separate ROOT column. The init summary, live lifecycle progress, and ordinary terminal completion results also display SPEC. When scale differs from 1, output explains the base, multiplier, result, and sources; --verbose also explains calculations with scale 1. JSON retains numeric CPU and byte capacities, with bases, scale, effective results, and sources under resources; scripts need not parse the abbreviation.
In-place root disk growth
-D is an absolute target. Repeating a completed target neither changes the disk nor restarts the VM; shrinking fails. Growth requires downtime. Running nodes return to running; stopped nodes temporarily boot for checks and expansion, then return to stopped. Supported roots use 512-byte logical sectors and a last plain ext4/XFS partition in a GPT or primary MBR layout. LVM, encrypted devices, later partitions, and missing tools fail before image modification. Existing root data, VM UUIDs, and SSH keys are retained; data disks are not resized.
Barn persists recovery stages and checks image, guest disk, partition, and filesystem capacities before completion. On failure, status shows a root-resize warning. Fix the reported problem and repeat the same resize -D target. A grown image is never shrunk to undo incomplete guest expansion. An inventory retaining the old size reports drift on the next run; update vm_disk to keep the new size permanently. See root growth acceptance for implementation details and measurements.
Lifecycle concurrency in 1.2.0
Barn 1.2.0 defaults Linux VM lifecycle concurrency to max(1, logical CPUs - 2), using the logical CPU count available to the Barn process. Each phase uses at most its selected node count. Released Barn 1.1.0 uses at most four workers and has no lifecycle --parallel flag.
In 1.2.0, up, start, stop, restart, reload, recreate, destroy, and purge accept --parallel/-p with zero or a positive integer. Omitting the flag uses the CPU-based default; explicitly passing --parallel 0 runs all selected nodes concurrently. A positive value sets the concurrency limit, and --parallel 1 runs node work serially. The override applies to disk preparation, startup, and shutdown where those phases occur; state commits and artifact removal retain their existing ordering. Values above 16 are accepted, and values above the node count create no extra workers. The option belongs to the command invocation and is preserved in suggested retry commands, including an explicit zero.
A startup worker remains occupied while its guest boots and passes SSH/readiness checks. With --no-wait, it becomes available after QEMU starts and its process identity is verified. Disk preparation completes before the startup phase begins. provision --parallel keeps its separate default of 1; native macOS guest limits are documented under Mac commands.
Implementation and regression coverage: concurrency.go, concurrency_test.go, and lifecycle_parallel_test.go.
Native acceptance on 2026-11-10 used six Debian 13 guests in a temporary BARN_HOME on macOS/arm64 with 18 logical CPUs. The automatic default was 16 and reached six concurrent startups; an explicit value of 1 kept startup and shutdown serial; an explicit value of 32 reached six concurrent restarts. All guests passed readiness checks, and the test deployment was destroyed afterward.
On 2026-11-11, a second isolated run on the same host verified explicit zero with 18 Debian 13 guests: all 18 started concurrently and passed readiness checks in 39.6 seconds. Selecting three nodes for stop/start produced a concurrency peak of three in each phase while preserving the other 15 VM processes. The test deployment was destroyed afterward, and all six pre-existing VM processes remained unchanged. Regression tests also cover positive limits above 16, negative values rejected before state changes, and retries retaining explicit zero.
Structured failures
Always check the process exit code first, then parse the command’s output.
In human-readable text mode, operations lasting one second or longer on a terminal redraw a single live table (NAME ADDRESS STATE MESSAGE, ITEM STATE MESSAGE, or IMAGE STATE MESSAGE) on stderr above a completion line ending with [DONE], [FAILED], or [CANCELLED]. When both stdout and stderr are a terminal without --verbose, the completed table freezes in place so stdout prints only follow-up hints (connect:, retry:, next:). Ordinary failures print error: <message> on stderr, followed by the last stderr lines of any failed external program and an actionable next: command when available. SSH child exit failures pass the remote process output through directly without adding a wrapper error line.
In --json or --yaml mode, commands that define their own report schema (doctor, network, provision, lifecycle commands, and ssh/exec) return that report schema directly on stdout—for example, exec returns success, exit_code, stdout, and stderr. When a command fails before producing a command-specific report, Barn writes a single generic failure object to stdout:
error: One of the stable error classes in the Exit codes table (recreate_requiredandnodes_removedare reported asreasonvalues undererror: "conflict", and resource collisions useerror: "resource").message: Human-readable summary.- Optional context fields:
reason,next,operation_id, andcommand(name,argv,exit_status,signal,timed_out,stderr).
Single-result commands emit one JSON or YAML document. logs --follow uses NDJSON or a YAML document stream; structured interactive SSH sends session output to stderr and its final report to stdout. The design rationale is in CLI contracts.
Lifecycle results
When invoked without node arguments, lifecycle commands target all managed nodes in the deployment, whereas ssh, exec, and per-node logs default to the prepared control node (or the first prepared node if the control node is not yet prepared). Node selectors must be resolved node names such as meta—IP addresses, group names, and vm_alias entries are not valid command-line selectors.
restartrestarts applied nodes using their committed state without re-readingbarn.yml.reloadvalidates the effective desired specification and startup dependencies before stopping selected nodes, then runsupfor that selection. It can add nodes; changes that replace an existing VM still requirerecreate.resizeapplies effective CPU/memory changes, includingvm_scale, and supports root growth. Supported increases may be hot-plugged; decreases, older VMs, and unsupported backends use a stop/start fallback while preserving the VM identity and disks. It refuses image, data-disk, network, share, create, remove, and deployment-wide changes.recreateapplies changed node definitions by replacing root disks and non-persistent data disks while reattaching compatible persistent data disks. Explicitplan,up,reload,recreate, andresizeselections retain unselected peers’ applied definitions, including peers edited or omitted in YAML. Uncreated, unselected nodes do not require image resolution. Conflicting addresses, aliases, control-node roles, or deployment-wide settings still fail preflight; omitting selectors applies the whole inventory.- When configuration drift requires a destructive action,
upandreloadexit with aconflicterror pointing tobarn planandbarn recreate <node>orbarn destroy <node>. On a terminal,recreateanddestroylist the nodes they replace or remove and require typing the command name unless--yes(or--force) is passed; without a terminal they exit2unless one of those flags is present. Without node arguments, both apply to the whole deployment.
A whole-deployment recreate refuses an inventory that omits an existing node before any VM stops (conflict, reason nodes_removed, exit 4). Remove that node explicitly with barn destroy <node>, or add it back to the inventory. Barn checks the scope again under the destruction lock; if the applied state changed during preflight, recreate exits with reason deployment_changed, and you can review the plan and retry.
Destroying the control node makes the first remaining node the control node. Update the inventory’s control role (admin_ip) to that node, then run barn up to install its control SSH access; --no-wait defers that step. Until you do, an inventory that still names the deleted node as control is role drift and up refuses it; to bring the old node back, add it as a regular node. Barn refuses to destroy the control node, before deleting anything, when the successor has an unfinished prepare record that cannot be completed, and the error names the successor.
Planning
barn plan is read-only and exits 0 even when its recommended action is resize, recreate, or blocked-removal; automation scripts should inspect action, the create, resize, recreate, start, and missing arrays, and the optional blocked explanation string.
For catalog images, plan resolves configuration and catalog metadata locally without requiring QEMU or host networking; for local-* imported images, it also verifies the cached image via qemu-img. Plans never download images and display exact image versions, total CPU/memory/disk resources, drift reasons, and per-disk actions (including the default 128 GiB /data disk).
Starting and SSH configuration
barn up verifies host capabilities and IP availability, creates new nodes, starts stopped nodes, verifies SSH readiness on running nodes, and refreshes Barn’s host SSH client fragment (~/.ssh/barn_config) and guest /etc/hosts + control-node SSH entries. recreate performs the same full refresh; start and restart also refresh SSH aliases; per-node destroy removes the destroyed node’s SSH entry; and whole-deployment destroy removes the fragment.
If a VM lifecycle action succeeds but updating ~/.ssh/config fails (or if ~/.ssh/config is a symlink or hard link, which Barn never edits), Barn writes ~/.ssh/barn_config, prints the Include line to add manually, records the notice in warnings[], and exits 0 (barn ssh continues to work directly).
On the control node, Barn-managed SSH entries accept replacement host keys without writing to known_hosts, keeping recreated lab nodes reachable while preserving any custom SSH entries you added yourself.
Readiness
A Linux guest is considered ready once management SSH succeeds. Non-fatal post-boot issues are reported in nodes[].warnings, and completed recovery actions (such as formatting a damaged data disk) are recorded in nodes[].repairs; the command still exits 0. Re-running barn up retries any unfinished guest setup steps on running VMs without restarting them.
Passing --no-wait returns as soon as the QEMU process is running, deferring SSH readiness, disk recovery, and guest /etc/hosts updates to the next barn up.
Data disks describes which disk problems Barn repairs (reported in repairs) and which it only reports (in warnings). Existing guests receive the current recovery helper on their next barn up readiness check.
Node failures
When one or more nodes fail during a batch operation, Barn preserves any nodes that succeeded, exits 5, and summarizes each failure as N of M node(s) failed: <node> (<stage>: <error>); ... across stages such as prepare, start, readiness, bootstrap, guest-setup, stop, and status. Structured output populates failures[] with node, stage, error, and optional reason (plus rolled_back when --rollback cleaned up uncommitted node preparation files). For readiness or bootstrap failures, check barn logs <node> and see A node did not become ready.
Status
barn status reports each node’s name, IP (ADDRESS), state (running means the QEMU process is alive; it does not probe guest SSH), exact image, vCPUs, and memory, flagging TCG emulation when active (and on Apple Silicon when Mac VMs exist, appends mac: <names>; barn mac ls). Pass --verbose to include forwarded SSH ports, architecture, accelerator, and QEMU PID. If a node is degraded—including when an online resize was interrupted after hotplugging (stage: "resize", reason: "resize_incomplete")—status still lists its healthy peers, populates failures[], and exits 5.
Recovery and interrupted operations
- Fault isolation: During
uporstart, a missing host share or failed new-node preparation affects only that node; independent stopped nodes still start, and the command exits5with a retry command that preserves your-f,--repo, and flag arguments. - Setup event log: Host
setupand its follow-up lifecycle run share oneoperation_id. If initial setup fails before a deployment exists, you can still inspect the bounded phase log viabarn logs --source events --json(which records phase transitions without sensitive arguments or credentials;setup --dry-runwrites no log). - Retained persistent disks: Persistent disks left behind by a previously removed node do not block destroying the remaining nodes; use
destroy --delete-persistentorpurgeto remove them. - macOS setup ordering: On macOS,
setupfinishes Homebrew discovery/installation or the pinnedsocket_vmnetarchive download before prompting for administrator privileges, so downloads neither expire an earliersudotoken nor prompt for a password when a download fails. - PID and journal reconciliation: If a recorded QEMU PID has been reused by an unrelated process, Barn marks the node
stopped; if astopwas interrupted while the VM process remained alive, Barn marks itrunning. If an onlineresizewas interrupted after modifying the live guest,statusreportsresize_incomplete; retrybarn resize <node>or runbarn restart <node>. Other interrupted transitions print the recovery command (destroyresolves interrupted state directly), and a failed initialupautomatically rolls back uncommitted journal artifacts on the next run. - Cancellation: When a command is cancelled, Barn sends SIGTERM to the external program it is running, which
sudoforwards to the privileged command, and waits at most 10 seconds for that process and its inherited output pipes. Descendants that ignore SIGTERM need external supervision.
Logs and environment
barn logs reads the guest serial console (--source serial) by default. Pass --source qemu for QEMU stderr diagnostics or --source events for the deployment-wide bounded event log. Adding --follow (-f) streams raw bytes in text mode, NDJSON lines in --json mode, or YAML documents in --yaml mode. QEMU argv is omitted from normal log output unless --verbose is set.
| Environment variable | Purpose |
|---|---|
BARN_HOME |
Private state directory (default ~/.barn); accepts relative paths, ~/, and directory symlinks, but not / or the home root. Prefer an absolute path across working directories |
BARN_IMAGE/BARN_ARCH/BARN_CPU/BARN_MEM/BARN_SCALE/BARN_DISK |
1.2.0 VM specification overrides; CLI takes priority. Read only by commands accepting each field; see specification overrides |
BARN_REPO |
Default image repository URL or path; overridden by --mirror and --repo |
BARN_OUTPUT |
Default output format (text, json, or yaml); overridden by --json/--yaml |
BARN_VERBOSE |
Boolean default for diagnostic output; overridden by -v/--verbose |
BARN_VMNET_ARCHIVE |
Path to a local pinned socket_vmnet archive for macOS setup; accepts relative paths, ~/, and symlinks (SHA-256 verification still applies) |
NO_COLOR |
Any non-empty value disables ANSI color output |
Explicit --json, --yaml, and -v/--verbose override BARN_OUTPUT and BARN_VERBOSE, and --help works even when those variables hold invalid values. Any other command exits 2 (usage) while an invalid value is not overridden on the command line.
SSH passthrough and completion
Remote commands require --. Pass barn exec meta -- hostname rather than barn exec meta hostname, and use sh -c explicitly for a shell command string.
barn sshwithout a command opens an interactive login shell; with-- command..., it joins the arguments after--with spaces and passes them to the guest shell.barn execrequires-- command...and passes the program and each argument separately, preserving spaces, quotes, empty arguments (after the first non-empty command token), and shell metacharacters literally. Wrap pipelines, redirections, variable expansion, or compound commands insh -c '...'.- Positional arguments before
--may contain at most one known node name (defaulting to the control node when omitted). Unknown node names or extra selectors before--fail immediately with exit code2(usage), listing known nodes and suggestingbarn status. - Barn flags (
--json,-v,--help) must appear before--; everything after--(including a second--,-V, or-o...) is passed to the remote command and cannot alter local OpenSSH client options.
Generate shell completion with barn completion bash|zsh|fish|powershell (for Bash, reload after upgrades via source <(barn completion bash)). Completion suggests commands, aliases, templates, image aliases, enumerated flags, YAML files for -f, and node names from the current inventory or applied state, and stops suggesting Barn flags after --.
Exit codes
| Code | error |
Meaning |
|---|---|---|
0 |
Success (including ready guests with non-fatal warnings[] or repairs[]) |
|
1 |
runtime |
Operation executed and failed (external tool, download, or guest failure) |
2 |
usage |
Invalid CLI syntax, missing inventory file, or invalid configuration/image selector |
3 |
capability |
Host lacks a required dependency, active Barn network, or privilege |
4 |
conflict |
Operation conflicts with current deployment state or another active barn process |
5 |
partial |
Node-level batch failure; inspect failures[] (successful peer nodes remain intact) |
6 |
resource |
Host IP address, port, subnet, or disk path is already in use |
7 |
integrity |
Digest, catalog signature or signed revision, instance identity, or file ownership verification failed |
130 |
cancelled |
Interrupted by SIGINT/SIGTERM or interactive confirmation declined |
An image catalog whose signature is missing or does not verify fails with reason: "catalog_signature", and a catalog that reuses an accepted or embedded revision number with different bytes fails with reason: "catalog_equivocation". Permission and I/O errors while reading a cached catalog signature are runtime failures (exit 1).
When another barn process holds the deployment lock, mutating commands wait up to 10 minutes while reporting the lock holder, then exit 4 with reason: "deployment_busy" on timeout. Read-only and access commands (status, ssh, exec, ssh-config, hosts) do not wait on the lock; status displays the last committed state and notes the active operation in note.
ssh and exec return the remote command’s exit code verbatim (including 255, which can indicate either an OpenSSH transport failure or a remote command exiting 255), keeping text output, JSON exit_code, and process exit status identical.
4 - Mac Runtime Reference
Running macOS guests requires an Apple Silicon Mac on macOS 27 or later, invoked as the logged-in desktop user. Commands that talk to the native runner reject root with mac_root and unsupported hosts with mac_host_unsupported. Top-level --help hides mac on Linux and Intel Macs, while local-state queries such as barn mac image ls work without invoking the runner. Running barn mac with no subcommand executes barn mac ls.
This reference covers the Barn 1.2.0 command interface and Barn.app, the native macOS app bundle that runs the VMs (runner protocol 2). The Apple Silicon release and Homebrew installation include the app; see macOS Guests.
For complete per-command syntax, options, and examples, see the macOS Command Reference. This page collects machine rules, networking, result formats, and state files.
Commands
| Command | Purpose |
|---|---|
ls |
List every VM with state, IP, SSH status, macOS build, resources, and shares (aliases: list, status, st) |
up [name] |
Create the VM if needed, start it, and wait for SSH and passwordless sudo |
start [name...] |
Start existing VMs |
stop [name...] |
Request a clean macOS shutdown, powering off after two minutes if still running |
restart [name] |
Stop and start a VM, applying any pending hardware, share, or subnet changes |
open [name] |
Open the desktop window, starting the VM first if needed |
ssh [name] [-- command...] |
Open an interactive shell, or pass a command string after -- to the guest shell |
exec [name] -- command... |
Execute a remote program while preserving argument boundaries |
configure name |
Update CPUs, memory, shares, or subnet while stopped; clipboard can change while running |
recreate name |
Replace a VM with a fresh macOS clone while keeping its hardware and network settings |
destroy name... |
Delete one or more VMs |
password [name] |
Print or copy the guest login password |
ssh-config |
Print, install, or remove ~/.ssh/barn-mac_config entries |
logs [name] |
Read recent lines from the VM’s runner.log |
setup |
Download and prepare the default macOS base image without creating a VM |
image ls |
List cached .ipsw restore files and prepared base images alongside the VMs using them (alias: list) |
image update |
Download and prepare Apple’s latest macOS 27 build as the default base image |
image prune |
List unused images, or delete them when --yes is passed |
doctor |
Check host eligibility, Barn.app, base images, and every VM slot |
SSH and exec
Remote commands require --, for example barn mac exec dev -- sw_vers. Interactive barn mac ssh dev needs no separator.
Before --, pass Barn flags and at most one existing VM name (omitting the name selects the sole VM or mac1). ssh without a command opens an interactive shell; exec requires a non-empty command after --. Unknown VM names or invalid arguments fail with exit code 2 (usage) before attempting a connection and point to barn mac ls.
ssh joins arguments after -- into a command string for the guest shell, whereas exec passes the program and arguments separately (preserving spaces, quotes, and subsequent empty arguments). Use sh -c '...' for pipelines, redirection, or compound commands. Put Barn flags (--json, -v, --help) before --; everything after -- belongs to the guest command.
For compatibility, exec also accepts a single command string as shell shorthand. In new scripts, pass separate arguments or use an explicit sh -c so the intended shell interpretation is clear.
Flags by command
| Command | Flags |
|---|---|
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, --yes/--force, -n/--no-wait |
destroy |
--yes/--force |
password |
-c/--copy |
ssh-config |
-i/--install, --remove |
logs |
-n/--lines positive integer (default 100); returns the requested line count |
setup |
--ipsw, --disk, -y/--yes |
image update |
--ipsw, -y/--yes |
image prune |
--installers, -y/--yes |
When a VM name is optional, omitting it selects the only existing VM or mac1; if multiple VMs exist and none is named mac1, Barn asks you to specify a name. start and stop accept multiple names or --all. On a terminal, destroy and recreate print what will be deleted and ask you to type the command name; --yes (or --force) skips the question and is required without a terminal. Neither command has a -y shorthand, and mac stop --force means immediate power-off.
--no-wait returns as soon as the VM process is running; for a newly created VM, run barn mac up NAME without --no-wait to finish SSH key installation and sudo setup. Ordinary start requires a VM that has completed its first boot—if an uninitialized VM is already running, use barn mac open NAME to view its first boot, or barn mac up NAME --open if it is stopped. Passing --recovery boots directly into the macOS Recovery desktop without waiting for normal SSH readiness.
Flag values
| Flag | Value |
|---|---|
--cpu |
vCPU count: at least 2 and at most the Mac’s logical CPU count (default 4) |
--memory |
Memory size in binary units (16G, 16GiB, 16GB) or exact bytes; must be a whole MiB between 4 GiB and host RAM (default 8 GiB) |
--disk |
Base image disk capacity, minimum 32 GiB (defaults to the prepared base image’s capacity, or 100 GiB for the first base image; requesting another size installs a matching base image if needed) |
--user |
Guest administrator username (defaults to your host macOS username, or barn if the host name is not a valid account identifier) |
--share |
[name=]path[:ro|:rw], repeatable; name defaults to the last path component and ~/ expands to your home directory |
--clipboard |
on or off (also accepts true/false, yes/no; default on) |
--subnet |
Canonical private /24 such as 10.10.30.0/24, or auto for the first free subnet |
If you run up on an existing VM with creation flags that differ from its recorded settings, up exits with mac_configuration_conflict and prints the exact configure or recreate command in next::
- Use
barn mac configurewhile the VM is stopped to change--cpu,--memory,--share/--unshare,--subnet, or--clipboard(clipboard changes can also be saved while the VM is running and take effect on the next start; use the menu bar item to toggle clipboard sync for the active session). Share names may contain spaces and Unicode, must be valid UTF-8 of 1–255 bytes, and cannot be.,.., or contain/or ASCII control characters; reusing a share name inconfigure --shareupdates its path and mode, while--unshareremoves that share. - The guest administrator account (
--user) and disk capacity (--disk) are fixed for the lifetime of a VM and preserved acrossrecreate. Create a new VM if you need a different account or disk size. - To upgrade a VM to a newer macOS build, run
barn mac image updatefollowed bybarn mac recreate NAME --update. Becauserecreate --updatepreserves the VM’s disk capacity, if the new macOS build does not yet have a base image at a custom disk size (for example,200G), prepare it first withbarn mac setup --disk 200G.
Machines
- Names: 1–32 characters starting with a lowercase letter and containing lowercase letters, digits, or internal hyphens (for example
mac1,dev,build-2). - Two-VM host limit: Apple’s Virtualization framework allows at most two macOS VMs to run simultaneously on a single Mac across all apps (including an active
.ipswbase-image installation). Barn never stops a running VM to make room for another.ls.runningcounts VMs in the currentBARN_HOME, while Apple’s framework enforces the host-wide limit. - Administrator account: Configured with passwordless sudo, Ed25519 SSH key authentication, automatic desktop login, and Remote Login enabled. SSH password authentication is disabled, and the random local password is saved in the VM slot’s
passwordfile (0600). - Hostnames: The guest ComputerName matches
<name>and LocalHostName isbarn-<name>(barn-<name>.local). - Shared folders: Mounted inside the guest via a single VirtioFS device at
/Volumes/My Shared Files/<name>. Each host source must resolve to an existing directory; symlinks are supported. Names accept spaces and Unicode. - Clipboard sync: Syncs plain text up to 1 MiB over the VM’s SSH connection whenever the desktop window gains or loses focus, skipping pasteboard items marked concealed.
- Shutdown:
barn mac stoprequests a clean guest shutdown and waits up to two minutes before powering the VM off ("forced": true);--forcepowers off immediately.
Networks
Each VM’s runner process creates an isolated user-space network at startup and tears it down on exit—without root privileges or a background daemon—using Apple’s shared-mode vmnet API:
| Item | Value |
|---|---|
| Subnet | First free /24 from 10.10.20.0/24 through 10.10.59.0/24 that avoids host routes and other VMs (or an explicit --subnet) |
| Gateway | .1 on the Mac host |
| Guest IP | .10, assigned via a vmnet DHCP reservation for the VM’s MAC address |
| Topology | Host-to-guest routing and outbound NAT per VM subnet, with no LAN bridging or inbound port forwards |
If a newly added host route (such as a VPN) overlaps the VM’s saved subnet, start refuses to boot with mac_subnet_in_use; run barn mac configure NAME --subnet auto to move the VM to a free subnet. Because Barn pins SSH host keys to barn-mac-<instance_id> rather than the IP address, changing subnets keeps SSH trust intact.
If macOS Local Network privacy blocks a third-party terminal or IDE from reaching the guest subnet (often surfacing as No route to host), enable that app under System Settings → Privacy & Security → Local Network. Barn routes its own Go SSH transport through /usr/bin/nc and invokes /usr/bin/ssh for user sessions so Apple system binaries handle the local-network socket directly.
JSON output
All barn mac commands except interactive ssh support --json and --yaml on stdout while writing progress to stderr.
ls
| Field | Values |
|---|---|
state |
prepared (created, never completed first boot), starting, running, stopping, stopped, unknown |
ready |
true when this check verified guest SSH connectivity and passwordless sudo |
ssh |
ready, pending (first boot in progress), unavailable, offline, unchecked |
observed |
Present when the running guest reports a macOS build different from its base image |
window_visible |
Present while the VM’s desktop window is open |
error, warnings |
Last recorded failure on the slot and any SSH issues detected during this check |
Lifecycle results
Single-machine operations (up, restart, open, recreate, configure) return a single machine result object, while batch operations (start, stop, destroy) return {"machines": [...]} even when called with one name. If a multi-VM batch partially fails, the response includes both the succeeded entries and the failures and exits 5.
| Field | Values |
|---|---|
action |
created, started, running (already running), restarted, recreated, opened, configured, stopped, powered_off, already_stopped, destroyed, absent |
forced |
true when stop timed out and powered off the VM |
window |
true when the desktop window was opened |
warnings |
Non-fatal notices, such as a clipboard change that takes effect on next start |
Other structured responses:
exec --json: Returns the same schema as Linuxbarn exec --json(node,exit_code,stdout,stderr).password --json: Returns the password, or{"name": "mac1", "copied": true}when combined with--copy.ssh-config --json: Returnsfragmentwhen printing, or installation status when combined with--install/--remove.logs --json: Returnsnameandlogs.doctor --json: Returnsokandchecks[](name,ok,detail, and optionalnext), exiting3if any check fails.
Failures
Exit codes follow the Barn CLI exit code table, and ssh/exec pass through the remote command’s exit status. Structured error objects include stable reason codes and a next recovery command:
| Reason | Exit | Meaning and next step |
|---|---|---|
mac_host_unsupported |
3 |
Host is not Apple Silicon or is running macOS older than 27 |
mac_runner_missing |
3 |
Barn.app / native runner is not installed alongside the barn CLI |
mac_runner_protocol |
3 |
Installed Barn.app uses a different runner protocol version; reinstall matching CLI and app builds |
mac_root |
2 |
Invoked as root; run as the logged-in desktop user without sudo |
mac_download_consent |
2 |
Non-interactive macOS download requires --yes (or supply a local file with --ipsw) |
mac_machine_absent |
4 |
Named VM does not exist; create it with barn mac up NAME |
mac_not_initialized |
4 |
VM has not finished its first boot; complete initialization with barn mac up NAME |
mac_not_running |
4 |
ssh or exec called on a stopped VM; run barn mac start NAME |
mac_running |
4 |
Requested configuration change requires the VM to be stopped; run barn mac stop NAME |
mac_configuration_conflict |
4 |
up flags differ from the existing VM; run the suggested configure or recreate command |
ssh_config_linked |
4 |
~/.ssh/config is a symlink or hard link; add the printed Include line manually |
mac_vm_limit |
6 |
Two macOS VMs are already running on this Mac; stop the reported VM first |
mac_subnet_in_use |
6 |
A host route overlaps the VM’s subnet; run barn mac configure NAME --subnet auto |
disk_full |
6 |
Insufficient free disk space to download or install the macOS base image |
mac_machine_damaged |
7 |
An initialized VM slot is missing its disk or identity files (the slot directory is preserved for inspection) |
mac_readiness_interrupted |
130 |
barn mac stop interrupted a first-boot SSH readiness wait |
Files
$BARN_HOME/mac
- config.jsonInstallation identity, default base image, and ssh_config_off flag
- images/
- ipsw/
- <build>.ipswCached Apple restore image (.partial while downloading)
- <build>.ipsw.jsonRestore image metadata and digest
- base/
- <id>/Read-only, unbooted macOS base image bundle
- ipsw/
- slots/
- <name>/
- state.jsonMachine record (schema 2)
- disk.asifCopy-on-write APFS disk layer cloned from the base image
- machine-id.binApple Virtualization machine identifier
- auxiliary-storage.binNVRAM / boot auxiliary storage
- id_ed25519Per-VM SSH private key
- id_ed25519.pubPer-VM SSH public key
- known_hostsPinned guest host key under barn-mac-<instance>
- passwordGenerated guest login password (mode 0600)
- runner.logPer-VM runtime log read by barn mac logs
- <name>/
- runtime/Global state lock and per-machine operation locks
Additional host and guest paths:
- Control sockets:
/tmp/barn-mac-<uid>-<hash>/. - OpenSSH fragment:
barn mac ssh-configmanages~/.ssh/barn-mac_configand a# barn-mac:includeblock in~/.ssh/config(independent of the Linux# barn:includeblock). Runningbarn mac ssh-config --removesetsssh_config_offinconfig.jsonso subsequent lifecycle commands do not re-add theIncludeblock until you runbarn mac ssh-config --install. - Desktop preferences: Barn stores window positions in
~/Library/Preferences/com.pgsty.barn.plist(0.9.0used~/Library/Preferences/io.pgsty.barn.mac-runner.plist). - Runner discovery: The
barnCLI locates the runner relative to its resolved binary path across app bundle (Barn.app/Contents/MacOS/barn-mac-runner), pkg installer, and Homebrewlibexeclayouts, or viaBARN_MAC_RUNNERwith an absolute path, relative path, or~/path. Before executing VM operations, the CLI verifies runner protocol2;barn mac doctoralso verifies the runner’s local code signature. - Guest configuration files: Inside the macOS guest, Barn writes
~/.ssh/authorized_keys,/private/etc/sudoers.d/80-barn, and/etc/ssh/sshd_config.d/000-barn.conf, configuresComputerNameandLocalHostName, and disables idle sleep viapmset.
Image pruning keeps base images that interrupted recreates still reference until recovery cleanup finishes. A malformed recovery journal stops barn mac image ls, the space estimate in barn mac doctor, and pruning until it is repaired, and every image stays in place. If one machine’s state cannot be read, barn mac ls fails for all machines, while commands that name the other machines keep working.
5 - Images
Barn resolves Linux guest images from a static catalog and immutable qcow2 artifacts. Official and HTTP repositories require Ed25519/minisign catalog signatures, while explicitly selected local directory and HTTPS repositories may be unsigned. You can activate newer image catalogs with barn update without replacing the barn binary; the binary defines the trusted signing public keys and qcow2 safety rules.
el7 (CentOS Linux 7.9) is a deprecated compatibility image. Every other version in the embedded catalog is supported.
Aliases and pull order
Barn 1.2.0 embeds image catalog 2026110502, including Debian 13 image 20261103.2651.1. It covers 9 distribution families with one stable version each, for 17 image artifacts: el7 is amd64-only, and every other family provides both amd64 and arm64. When no image is specified, Barn selects u24:stable (Ubuntu 24.04 LTS) on the host’s native architecture.
The table below lists the stable channel targets in embedded catalog 2026110502. Run barn update followed by barn image list to inspect the latest catalog published on your selected repository, and see Platforms and Limits for host support details.
| Family | Embedded stable |
Accepted aliases |
|---|---|---|
d12 |
20261026.2643.1 |
debian12, bookworm |
d13 |
20261103.2651.1 |
debian13, debian, trixie |
el7 |
7.9.20221112.0 |
c7, centos7, centos79 |
el8 |
8.10.20240528.3 |
rocky8 |
el9 |
9.8.20260525.2 |
rocky9, rocky |
el10 |
10.2.20260525.0 |
rocky10 |
u22 |
20261020.0.1 |
ubuntu22, ubuntu2204, jammy |
u24 |
20261017.0.1 |
ubuntu, ubuntu24, ubuntu2404, noble |
u26 |
20261016.0.1 |
ubuntu26, ubuntu2604, resolute |
Distribution notes:
u22,u24, andu26are Ubuntu 22.04, 24.04, and 26.04 LTS;d12andd13are Debian 12 and 13. Barn’s image recipe builds them from the distributions’ cloud images: the image ships adbauser (UID/GID 88), XFS userspace tools are present, anden_US.UTF-8is available whileC.UTF-8stays the default locale.el7is CentOS Linux 7.9 (amd64BIOS), andel8,el9, andel10are Rocky Linux (amd64andarm64UEFI).el8andel9go through the same recipe (dba, UID/GID 88);el10andel7are the distributions’ unmodified cloud images.cloud-initconfigures accounts and networking on first boot for every image.- Running
barn updateupdates what:stableor a numeric prefix resolves to for new nodes without altering running VMs or pinned@versionselectors. If an existing inventory uses a channel or prefix whose target changed in the updated catalog,barn planandbarn upreport the image drift and requirebarn recreatebefore replacing any node.
| Alias | Distribution | Architectures | Boot | Status |
|---|---|---|---|---|
el7 |
CentOS Linux 7.9 / 2211 | amd64 |
BIOS | deprecated |
el8 |
Rocky Linux 8.10 | amd64, arm64 |
UEFI | supported |
el9 |
Rocky Linux 9.8 | amd64, arm64 |
UEFI | supported |
el10 |
Rocky Linux 10.2 | amd64, arm64 |
UEFI | supported |
d12, d13 |
Debian 12 / 13 | amd64, arm64 |
UEFI | supported |
u22, u24, u26 |
Ubuntu 22.04 / 24.04 / 26.04 LTS | amd64, arm64 |
UEFI | supported |
barn image list prints every version and architecture in the active catalog along with registered local-* aliases. barn image info defaults to the host architecture (like image pull) and can inspect uncached catalog metadata without QEMU; if a local cache file is present, info also runs qemu-img verification on it. Neither list nor info downloads image files.
Catalog status values indicate support tier (supported, testing, deprecated, or unknown); non-supported images still boot normally and emit a status warning.
When pulling an image, Barn executes four steps:
- Load the active catalog — Reads the selected repository’s active local catalog once for the command (either the binary’s embedded catalog or the revision last activated for that repository by
barn updateorbarn image sync). - Resolve the selector and architecture — Resolves
image[:channel]orimage@version-prefix(defaulting tou24:stableon the official catalog) and the target architecture. Standaloneimage pulldefaults to the host; lifecycle commands usevm_arch, also defaulting to the host when unset.--arch/-Aoverrides either choice; see configuration precedence. - Verify the local cache — Reuses an existing cached file immediately if its byte size, SHA-256 digest, and
qemu-imgstructural checks all pass. - Download with resume and digest checks — Downloads the artifact from the selected repository with automatic retries and HTTP range resumption, verifying the final size, SHA-256, and
qcow2header before moving it into the cache. The two official mirrors (https://repo.pigsty.io/barnandhttps://repo.pigsty.cc/barn) can fall back to each other during artifact downloads, while custom--reposources download exclusively from the specified root. Upstream URLs recorded in the catalog serve as provenance metadata only.
Repository selection precedence is --repo → --mirror (https://repo.pigsty.cc/barn) → BARN_REPO → compiled default (https://repo.pigsty.io/barn). Both official endpoints require valid minisign catalog signatures.
Because each repository root maintains its own active catalog state in $BARN_HOME/images/manifests/, pass the same --repo (or BARN_REPO) when working with a custom repository—even after its images are cached locally—and run barn update --repo <root> before using custom aliases from a newly selected repository. Once the catalog and image files are cached and verified, all ordinary commands work offline.
Barn automatically restores read-only permissions (0444) on verified cache files. If an unreferenced cached file fails verification, Barn renames it to .corrupt-<timestamp> before re-downloading; if a VM still uses that base image, Barn leaves the file in place and reports an integrity error.
Runtime policy
When guest and host architectures match, Barn uses hardware virtualization (Apple HVF on macOS, KVM on Linux) with one built-in exception: the stock Rocky Linux 8 arm64 kernel uses a 64 KiB page size that Apple HVF does not support, so Barn automatically runs el8 on Apple Silicon under same-architecture QEMU TCG and flags tcg in status output. Cross-architecture guests (after resolving vm_arch and any command override) also run under TCG; for amd64 guests on arm64 hosts, Barn pins TCG to a single translation thread to preserve x86 memory ordering.
The ARM64 TCG runtime uses cortex-a72 to avoid firmware hangs with the max CPU model in some QEMU/AAVMF combinations. ARM64 guests on Linux x86-64 have passed an actual Barn boot and SSH check. Barn’s catalog and runtime currently accept only amd64 and arm64; other architectures offered by a distribution or QEMU still require Barn integration before use with barn up.
el7 is supported only on native linux/amd64. On Linux hosts, barn setup installs the native QEMU package set; before booting a foreign vm_arch with up or recreate, install the target architecture’s qemu-system-* emulator and UEFI firmware (barn plan can resolve catalog images without them, though local-* imports still require qemu-img).
Trust and verification
Release binaries embed both production Ed25519 public verification keys (private signing keys live outside the source repository). Catalog activation rejects unknown signing keys, malformed JSON, conflicting content at the same revision number (equivocation), and revisions lower than the repository’s highest accepted revision unless --allow-downgrade is passed to barn image sync. A missing or failed signature and an equivocating revision exit 7 (integrity; see exit codes). A new trusted signature over identical catalog bytes is accepted, which also repairs a damaged cached signature.
Every cached or imported image must be a standalone qcow2 file matching its declared byte size and SHA-256 digest, with no backing file, external data file, encryption, or unknown incompatible qcow2 feature bits. Barn marks verified base images read-only and creates copy-on-write overlay disks for each VM node.
barn updatefetches, verifies, and activates the current catalog from--repoor--mirror.barn image syncactivates a catalog from an explicit URL or file path (for unsigned custom repositories, the source path must be<repo>/catalog.json) and supports--allow-downgrade.barn image resetreverts the active catalog for--repo(or default repo) back to the binary’s embedded catalog while keeping the recorded highest-revision watermark intact.
Static repository format
A static Barn image repository uses the following directory layout:
/srv/barn
- repo.yamlAuthoritative human-edited policy and version declarations (schema 1)
- catalog.jsonGenerated runtime image catalog with digests and sizes (schema 3)
- catalog.json.minisigMinisign signature (required for official and HTTP repositories)
- images/
- <image>-<version>-<arch>.qcow2Immutable qcow2 image artifacts
repo.yaml (schema: 1) declares defaults, aliases, channels, versions, architectures, boot modes, support status, source_user (for example, rocky upstream or dba after official normalization), and optional upstream provenance URLs—without manual checksums or byte sizes. barn repo build inspects the qcow2 files and generates catalog.json (schema: 3) with each variant’s filename, SHA-256 digest, file size, and virtual disk capacity.
When a variant omits file, Barn expects images/<image>-<version>-<arch>.qcow2 (for example, images/u24-1-amd64.qcow2 and images/u24-1-arm64.qcow2).
Repository management rules (barn repo scan|build|verify /absolute/repo):
- Repository roots accept relative paths,
~/, and directory symlinks. The root andimages/may be shared writable directories.repo.yamlmay link to a non-empty regular file up to 4 MiB. Artifact entries remain regular files;catalog.jsonoutput symlinks are not overwritten. - Boot mode inherits along
variant→family→defaults.boot; status inherits alongvariant→version→unknown. Every family must define the default channel pointing to an existing version, and family/alias names must be unique and cannot start withlocal-. Avoid reassigning built-in aliases (ubuntu,debian,rocky, etc.) to different families, because inventory parsing normalizes built-in aliases via the embedded catalog first. - Channels and dot-separated numeric prefixes (
el9@9.8,el9@9) resolve to an exact version key when present or the highest matching numeric version, yielding an immutable artifact identity(image, exact version, arch): barn repo scanis read-only and does not requireqemu-img; it exits0while reporting anymissing,unsafe, oruntrackedfiles in its output arrays (automation must check thatmissingandunsafeare empty).barn repo buildandbarn repo verifyrequireqemu-img.buildvalidatesrepo.yaml, inspects everyqcow2artifact, and atomically writescatalog.json(failing if any declared artifact ismissingorunsafe, and omittinguntrackedfiles).verifychecks that the existingcatalog.jsonmatches a fresh build byte-for-byte. Incrementrevisionwhenever catalog contents change, upload immutable.qcow2files before updatingcatalog.jsonandcatalog.json.minisig, and publish the catalog and signature together.
Local layout and imports
Barn stores cached catalogs, downloaded images, and local imports under $BARN_HOME/images (default ~/.barn/images):
$BARN_HOME/images
- manifests/Active catalog.json and highest accepted revision per repository
- local-images.jsonRegistry of named local-* image aliases
- local/
- <sha256>.qcow2Imported local qcow2 files indexed by content digest
- d13/
- d13-20261103.2651.1-arm64.qcow2Verified read-only catalog artifacts by family
- u24/
- u24-20261017.0.1-arm64.qcow2
Import a local qcow2 file into the cache or register it under a local-* alias:
Import rules:
image importaccepts relative paths,~/, and symlinks to regular files, and requiresqemu-img. Reads are bounded by the actual local file size or declared catalog size; downloads stop on overflow, while legacy downloads without a declared artifact size are bounded at 8 GiB. Optional--sha256verifies an expected digest.image importcopies and validates theqcow2container as-is without modifying guest credentials, installingcloud-init, or booting the image.- Source filenames may contain spaces or Unicode and need no particular extension; Barn validates the qcow2 contents. New imports use
local/<sha256>.qcow2, so different images can share a source filename and identical bytes reuse a cache entry. Existing aliases keep their original cache paths when reimported. Updates that exceed the 1 MiB registry metadata limit fail before changing existing aliases. - Named imports (
--name local-<alias>) require--boot bios|uefiand--source-user <user>and default to the host architecture.--arch/-Acan record an explicitamd64orarm64architecture, including aliases. The qcow2 metadata cannot identify the guest CPU, and import does not convert architectures. Match inventoryvm_archor the lifecycle command’s-Awhen using the image. Aliases are immutable and can be referenced viavm_image: local-mybase; unnamed imports only pre-populate the cache and cannot accept-A.
Pruning
barn image prune (or barn image prune --dry-run) lists candidate files that can be reclaimed; passing --yes deletes them.
prune protects all artifacts referenced by the selected repository’s active catalog, all base image digests used by currently applied nodes, and all registered local-* aliases (preserving cached images across destroy and purge). Only unreferenced images from older catalogs or other repositories and recognized stale staging files become candidates; quarantined .corrupt-* files are left in place for manual inspection, and unexpected/unsafe files cause an error. Always preview with --dry-run (passing --repo when checking a custom repository), as prune --yes deletes candidates sequentially without rolling back earlier deletions if a later file fails inspection.
To export the binary’s embedded schema-3 catalog byte-for-byte when bootstrapping a mirror, run go run ./tools/catalogexport /absolute/new/catalog.json. Any public catalog published at the embedded revision number must match those exact bytes.
6 - Image Pipeline
Use packaging/image-pipeline/build.sh in the Barn source checkout to validate or offline-normalize a downloaded qcow2 candidate against an expected SHA-256 digest. The builder runs locally without network access, signing keys, or changes to Barn runtime state, and produces a testing candidate bundle ready for smoke testing and release review.
Host requirements:
- Tools: Python 3 and
qemu-imgfor all modes;offlinemode also requires workinglibguestfstools (virt-customizeandvirt-cat). You can override tool binaries with--qemu-img,--virt-customize, and--virt-cator theQEMU_IMG,VIRT_CUSTOMIZE, andVIRT_CATenvironment variables. - Out-of-tree storage: Keep source images, RPM/DEB package caches, and output directories outside the Git working tree (the repository tracks recipes and lockfiles only).
- Architecture:
--archrecords the target metadata architecture; runofflinecustomization on a host wherelibguestfscan execute the guest’s architecture.
Modes and profiles
validate: Copies and re-hashes the source image, verifies a single-fileqcow2structure withqemu-img check, and writes an evidence bundle without modifying guest files or credentials.offline: Runsvirt-customize --no-networkandvirt-caton the staged copy to normalize guest access: it verifies that UID/GID88is free of unrelated accounts, configures the lockeddba/adminidentity, disables SSH password and root login, strips SSH host keys, shell history, machine-id, andcloud-initcaches, restores SELinux labels, and verifies a deterministic guest marker.
build.sh defaults to --profile base. The available profiles are:
| Profile | Normalization steps | Package inputs |
|---|---|---|
base |
Account, sudo, SSH, and cloud-init normalization only | None (package flags rejected) |
el8 |
Base normalization plus Python 3, SSH drop-in include, legacy network cleanup, chronyd, and SELinux relabeling |
Locked RPM dependency set |
el9 |
Base normalization plus legacy network cleanup and SELinux relabeling | None (package flags rejected) |
d12, d13 |
Base normalization plus offline XFS userspace tools and en_US.UTF-8 / C.UTF-8 locale setup |
Locked DEB dependency set |
validate mode accepts only --profile base. In offline mode, el8, d12, and d13 require both --package-lock and --package-cache matching the profile and architecture. For official catalog targets, use build-official.py to drive these inputs automatically.
Official candidate matrix
packaging/image-pipeline/build-official.py builds the eight offline-normalized official targets—Debian 12/13 (d12, d13) and Rocky Linux 8/9 (el8, el9) on amd64 and arm64—using the upstream URLs, package locks, release versions, SHA-256 digests, and SOURCE_DATE_EPOCH pinned in official-v1.json (the catalog’s Ubuntu artifacts come from the same recipe run directly by pipeline.py; Ubuntu cloud images already ship xfsprogs, so they need no offline package lock).
Usage notes:
- Create
--source-cache,--package-cache, and--outputbeforehand and pass canonical absolute paths. With--fetch, the wrapper downloads any missing pinned HTTPS inputs and verifies their SHA-256 digests before runningvirt-customize --no-network; without--fetch, all locked inputs must already be present in the cache directories. - Omit
--targetto build all eight targets, or repeat--targetto build a subset.--listprints the exact releases pinned in your checkout.
Once all eight target bundles have been built, assemble them into a candidate static repository by passing the parent directory (or repeating --assemble-from across multiple parent directories) that contains the bundle directories:
--assemble-from requires exactly one bundle for each of the eight targets and writes to a new --output path that does not yet exist, invoking barn repo build and barn repo verify (using barn on PATH or --barn /absolute/path/to/barn). The assembled repository maps its channels to candidate (for example d13:candidate) with status testing so you can run live VM acceptance checks before promoting images to stable and supported.
Validate a single downloaded image
Path and size constraints:
--sourcemust be a canonical absolute path to a regular file (not a symlink) up to 16 GiB, and--outputmust be a new path inside an existing parent directory.- Barn validates runtime image artifacts against their declared catalog sizes (or actual file size on local import; see Local image import). The contributor pipeline retains its own recipe bounds.
- The builder acquires an adjacent lockfile, stages work in a
0700temporary directory, and atomically renames the completed bundle into--output(cleaning up only its staging directory on failure).
Each completed output bundle contains:
| File | Purpose |
|---|---|
<name>-<release>-<arch>-<digest-prefix>.qcow2 |
Validated read-only candidate qcow2 image |
build-recipe.json |
Builder invocation, tool versions, and input digests |
manifest-candidate.json |
Unsigned candidate metadata (status: "testing") |
provenance.intoto.json |
SLSA build provenance statement |
sbom.spdx.json |
SPDX software bill of materials covering declared pipeline inputs and injected packages |
validation.json |
Before/after qcow2 checks, normalization marker results, and pending release gates |
checksums.txt |
SHA-256 checksums of all files in the bundle |
package-lock.json |
Included when the profile installs locked RPM/DEB packages |
With fixed inputs and tool versions, validate mode is byte-for-byte reproducible; for offline mode, build the candidate twice and compare the bundles when preparing release evidence. Promoting a candidate to a public supported release requires running live VM smoke tests across target host/guest combinations, updating repo.yaml with the new catalog revision and supported status, running barn repo build and barn repo verify, signing catalog.json.minisig, and verifying the published repository endpoints.