Skip to content

This is the multi-page printable view of this section. .

Return to the regular view of this page.

Start

Install Farrow, boot one or four nodes, operate the deployment, and resolve common failures.

Use these pages in order:

  1. Installation — build the current source and check the host.
  2. Tutorial — boot one node, expand to four, and use Pigsty.
  3. Operations — start, stop, change, inspect, and destroy nodes.
  4. Troubleshooting — short symptom-to-fix runbooks.

1 - Installation

Build Farrow, verify native acceleration, and understand the one-time host setup.

Supported path today

Build from the current checkout:

cd /path/to/farrow
make build
export PATH="$PWD/bin:$PATH"
farrow version
farrow doctor

There is no published v1 package yet. Do not substitute an unofficial binary for the matching farrow and farrow-hosts-helper build.

The source build requires Go 1.27.x. macOS also needs an existing Homebrew installation; Farrow can install QEMU through Homebrew but never bootstraps Homebrew itself. The current compiled image repository is the development host https://m0/farrow; use FARROW_REPO or --repo when another reachable mirror is required.

Host requirements and dated evidence

Native HVF/KVM is the normal path. Farrow never retries an arbitrary native failure under emulation. TCG is selected only for an explicit foreign vm_arch, or for the catalogued stock EL8 arm64/Apple-Silicon incompatibility. TCG is compatibility evidence, never performance evidence.

Host Last recorded evidence (2026-08-27)
macOS arm64 verified with HVF, QEMU 11.1, and socket_vmnet
Ubuntu 26.04 amd64 verified with KVM, QEMU 10.2.1, and NetworkManager
Rocky Linux 8.10 arm64 guest on macOS arm64 verified with automatic TCG and full readiness
other Debian/Fedora/EL9 amd64 implemented; repeat native validation before relying on it
macOS amd64, Linux arm64 cross-built and unit-tested, not currently native-verified

macOS needs Homebrew. Linux needs systemd plus either NetworkManager or systemd-networkd. farrow setup installs missing supported packages through Homebrew, APT, or DNF.

What setup changes

Run a dry plan first if desired:

farrow setup --dry-run
farrow setup --yes

Setup may install QEMU dependencies, prepare the host fixed-IP network, and install the narrow root-owned hosts publisher. It prints each mutation and the reason for sudo before applying anything.

In automation use --yes. Non-interactive sudo works with either a cached credential or a suitable NOPASSWD policy; every privileged command still uses an exact absolute argv.

Setup is idempotent. A healthy repeat reuses the network and installed helper. Source tests and this dated native matrix are separate: rebuilding a newer working tree does not silently refresh the rows above.

2 - Tutorial

Boot a one-node lab, verify it, expand it to four nodes without restarting the first, and hand the same inventory to Pigsty.

1. Create the lab

mkdir -p ~/lab
cd ~/lab
export FARROW_REPO=https://m0/farrow   # replace outside the development network
farrow setup --dry-run
farrow setup --yes
farrow up

With no existing file, setup writes farrow.yml for one node:

all:
  vars:
    admin_ip: 10.10.10.10
  children:
    nodes:
      hosts:
        10.10.10.10: { nodename: meta }

up downloads and verifies the image, creates the disks and cloud-init seed, starts QEMU, and waits for the guest readiness record.

2. Verify the node

farrow status
farrow ssh meta
farrow exec meta -- hostname
ping 10.10.10.10

The default node has 2 vCPU, 4 GiB memory, a 64 GiB root disk, and a 128 GiB XFS disk at /data.

farrow status also reports the effective Guest architecture and accelerator. The default EL9/EL10 path is native HVF/KVM. On Apple Silicon, vm_image: el8 automatically selects same-architecture TCG for the stock 64K-granule kernel. To run an amd64 Guest explicitly, set deployment-wide vm_arch: amd64; this uses single-threaded TCG and is intentionally much slower. EL7 is available only as a deprecated, native Linux/amd64 BIOS/KVM Guest.

3. Expand to four nodes

Add three host entries below the same hosts: mapping:

        10.10.10.11: { nodename: node-1 }
        10.10.10.12: { nodename: node-2 }
        10.10.10.13: { nodename: node-3 }

Then converge:

farrow plan       # create: node-1, node-2, node-3
farrow up
farrow status

Only the new nodes are created. meta keeps its process and uptime. The control node received the deployment key on its first boot, so it can SSH to the new nodes immediately:

farrow exec meta -- ssh [email protected] hostname

4. Use the same file with Pigsty

If Pigsty already generated pigsty.yml, skip the example file and run Farrow in that checkout:

./configure -c meta
farrow setup
farrow up
./install.yml

Farrow reads the documented VM fields plus native fields for naming, control-node selection, and the login identity. Unconsumed settings such as pg_role, pg_version, repo_*, and node_packages do not produce VM drift; pg_cluster/pg_seq and the node-admin fields are consumed.

5. Stop or remove it

farrow stop
farrow start
farrow destroy --force

Normal destroy preserves the verified image cache, deployment keys, and persistent disks. Use --delete-persistent or --purge only when intended.

3 - Operations

The normal lifecycle for the one deployment: inspect, access, scale, change, stop, and destroy.

Inspect and access

farrow status
farrow ssh meta
farrow exec node-1 -- hostname
farrow logs meta --source serial
farrow ss                         # install SSH aliases; then: ssh meta

Applied state is under ~/.farrow; these commands work from any directory. Status includes the persisted Guest architecture and accelerator, so TCG is never an invisible fallback. plan, up, reload, and recreate prefer -f, then a discovered Inventory, then the applied spec when no file exists. validate always needs a file.

Stop and start

farrow stop                       # alias: halt
farrow start
farrow restart node-1
farrow reload -f farrow.yml       # stop, re-read config, converge

restart uses applied state. reload reads the Inventory again.

Change the deployment

farrow plan
farrow up                         # create additions and start stopped selected nodes
farrow recreate node-1 --force    # applies a changed VM definition

Inventory changes fall into three visible fields:

Field Meaning Action
create desired node has no state farrow up
recreate VM definition changed farrow recreate <node> --force
missing stateful node left the file restore it, or destroy it explicitly

Deleting YAML never deletes a VM. Unconsumed Pigsty changes produce action:none; native naming and node-admin fields are consumed even though they do not begin with vm_.

Destroy

farrow destroy node-3 --force
farrow destroy --force
farrow destroy --force --delete-persistent
farrow destroy --force --purge

--delete-persistent and --purge are valid only for whole-deployment destroy, not with node selectors. --purge removes persistent disks, keys, and deployment state; images remain cached. Host network removal is separate and refuses while a VM is attached:

farrow network uninstall --yes

Images

farrow image list
farrow image info u24
farrow image pull u24
farrow image prune --dry-run

Images are signed-catalog entries and SHA-256 checked before use. Current images are testing, except EOL EL7 which is deprecated, so starts print the corresponding warning.

4 - Troubleshooting

Short, safe runbooks for setup, networking, images, drift, interrupted state, and SSH.

Start read-only:

farrow doctor --json
farrow network status --json
farrow status --json

No configuration found

For the first deployment, run plan, up, or validate beside farrow.yml/pigsty.yml, or pass -f /path/to/file. Once state exists, plan, up, reload, and recreate can fall back to its applied spec. Status, start, stop, SSH, and destroy always use applied state. If status prints the same message, the selected FARROW_HOME has no applied state.

Setup needs sudo

The line before the prompt names the exact host mutation. Farrow attaches an interactive terminal directly to sudo when the privileged step begins. Automation needs an existing credential or a suitable NOPASSWD policy, then passes --yes.

Native acceleration or compatibility runtime is unavailable

Native paths require HVF on macOS or KVM on Linux. TCG is selected only for an explicit foreign vm_arch or a built-in image/host compatibility rule; an arbitrary native failure never falls back. Homebrew QEMU contains both system emulators. Linux setup installs only the native family, so a foreign Guest also requires its matching qemu-system-* binary and firmware.

plan, up, and recreate validate the selected emulator and firmware before any destructive mutation. Performance results from TCG are not meaningful.

Network is partial or invalid

Do not delete host files by hand. Review the owned cleanup plan:

farrow network status --json --verbose
farrow network uninstall

Apply it with --yes only when it names Farrow-owned paths. Linux bridge smoke failures now trigger automatic manifest-bounded rollback; an explicit automatic rollback failed message means manual inspection is required.

Linux bridge helper fails

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

Debian/Ubuntu uses root:<caller-accessible-group> 4750; the caller does not have to belong to kvm when /dev/kvm access comes from a desktop ACL.

Plan reports recreate or missing

recreate needs farrow recreate <node> --force. missing is only a report: restore the host entry or run farrow destroy <node> --force.

SSH fails

Check farrow status, farrow ssh-config, and the serial log. Farrow’s own SSH uses a loopback management port; direct Ansible traffic uses the fixed IP.

Catalog or image verification fails

The current binary embeds active and standby Catalog public keys. Unknown signers, version rollback/equivocation, artifact size/SHA mismatch, and unsafe qcow2 structure are distinct integrity failures. Use a correctly signed repository or farrow image import --sha256 ...; do not copy bytes directly into ~/.farrow/images.

A command was killed

Run farrow status. A provably live or dead runtime is converged from its recorded identity; an ambiguous process remains blocked. Do not kill an unknown PID based only on a state file.

If a recorded QEMU process still exists but its QMP socket is absent, preserve the evidence and inspect serial/QEMU logs before using stop to converge it. Do not delete runtime sockets or state files by hand.

For a bug report include the exact command and exit code, farrow version, the three JSON reports above, host OS/architecture, and QEMU version.