Changelog
Product notes for operators. Words: Home, Device, Workload, Library. Not a cluster.
Unreleased items live on stacked draft PRs and may change before they land on main.
Unreleased
Section titled “Unreleased”- Settings Home Device URL save persists a custom host (picker or Other / DNS) across reload. With Tailscale up, the default shown URL is
https://<magicdns>with no port. LAN stayshttp://<host>:7777. - GPU passthrough setup: Intel/AMD IOMMU, vfio-pci, and IOMMU group checks on a Linux Device. Host GPU blanking and In use by host are information, not Attach blockers. Guide: GPU passthrough.
- Appliance getting-started is Ubuntu / Debian
.deband macOS Apple Silicon.pkg. Bootstrap is inspect-then-run (get-barkvisor.sh). Updates are Settings → Updates, notbrew upgrade barkvisor. Networks Bridge setup Applies Linuxbr0and starts macOSsocket_vmnet; equivalent commands stay on the page. Uninstall reverts tagged files and never default-deletes sharedbr0. Homebrew is runtimeqemu/swtpm/socket_vmnetonly. - Device daemon runs as root on Linux (
User=root) and macOS (LaunchDaemon withoutUserName). QEMU drops tobarkvisor/qemuwith kvm/disk on Linux. macOS HVF/USB stay the daemon uid until a drop is proven. Networks Bridge setup uses Apply/Revert on Linux (br0) and macOS (socket_vmnet+networksetup).--checkreports socket plus service. No XPC helper. NAT still works when bridged host networking is down. - Settings Home is Device URL, not remote access. Pairing and login QR
host=and ModelsOPENAI_BASE_URLuse the saved Device URL. Require Tailscale for the Home API is gone. - Library depot is gone. Catalog Download writes into this Device. Missing images download from the internet.
- Sentry is gone. Device logs stay on stdout / the Logs page; no DSN, no crash upload.
- Create VM puts the SSH key on Configure when the recipe needs it (not under Advanced). First login requires a key. No key: an error and a Settings → SSH Keys link (new tab). Coming back refreshes the list.
- Web console is passkey-only: first-run setup Add a passkey, login is Sign in with passkey, extra keys under Settings → Passkeys. No username/password in the SPA. Needs https or localhost and a hostname, not a raw IP (
127.0.0.1counts as an IP; uselocalhost). You cannot delete the last passkey. HeadlessPOST /api/setup/adminandPOST /api/auth/loginstay for scripts. Native Console stays password-only. - Create VM from a catalog OS recipe (AlmaLinux, Ubuntu, Debian, …) no longer dies on
users:in the recipe user-data. The VM is created after the image is ready; a first click that only starts the download says so and lists the image under Images. - Packages ship two binaries:
barkvisor(SPA Home Device) andbarkvisor-agent(API-only Device, symlink). Linux hasbarkvisor.serviceandbarkvisor-agent.service; they Conflict. One process per Device. - Swift toolchain is 6.3.3 locally (mise /
.swift-version) and on Linux CI, guest-boot, and package Docker builds.swift-tools-versionis 6.3. - Default VM disk directory is on the Device page.
/settings?tab=disksredirects to Devices. The Disks list still creates disks and can pick a folder per disk. - Linux Create Disk and Workload start fail closed when this Device cannot open a host block device for read/write. The error names the path and that the BarkVisor user needs the disk group (or a udev ACL). QEMU is not started with that
-drive. When group disk exists, postinst adds the service user to it, writesbarkvisor.service.d/disk.conf(SupplementaryGroups=disk), andtry-restarts a running unit so upgrades pick up/dev/sdX. A host without group disk still starts. - PCI picker occupancy is GPU host driver / Workload claim, not every bound kernel module.
- USB attach persists serial when present, else
bus:port. A stick with no serial (Logitech receiver) can attach; copy warns replug may change the path. Never invent a serial. Listing keeps the sysfs serial when falling back to lsusb. QEMU still useshostbus/hostaddrafter that match. - Sidebar All vs one Device scopes Home lists (Workloads, Library, Networks, Logs). Logs can still refine inside that scope. Dashboard widgets show/hide locally; Reset restores defaults. This Device CPU/memory charts stay on Device detail — they are not Home-wide lists.
- Ollama: when Ollama is down, the page shows install steps (macOS Homebrew
brew install ollama/brew services start ollama; Linux distro package plus https://ollama.com/download) and Recheck. AgentBox and Mac mini are not install targets. The inspect pane shows the completions URL. Nav stays visible for admin and inference. Start uses Devices that already have the weights (no picker for one reachable location; sidebar Device skips the picker). Pull-by-name lands on the Device selected in the left rail. Completions stay on Home:7777/v1, not Device:11434. Device GPU/CPU live stats stay on Device detail. - Device stats history includes GPU busy percent (
hostGpuPercent) on Mac (IOAccelerator) and Linux (gpu_busy_percent/ i915 RC6). Device detail shows CPU, memory, and GPU. Ollama has no live Device stats. Occupancy / passthrough is unchanged; i915 is not unbound. - Library used/free is the Library path volume (not always the data dir). Unknown capacity is not shown as zeros. Create Disk can override the default directory; Linux can attach a host block device as raw (macOS has no block-device option). Image download progress is a real percent in web and Console.
- Linux GPU list labels NVIDIA / Intel / AMD and can show several cards per vendor. Workload detail has a PCI picker for VFIO beyond GPUs (boot disk and last uplink excluded). Hidden on macOS.
- Settings: pairing offer and phone sign-in QR live on Settings → Pairing (
?tab=pairing). - Networks Bridge setup uses the same Apply/Revert flow on Linux (
br0) and macOS (socket_vmnet+networksetup): DHCP or static for this Device. - Logs: SQLITE_FULL no longer tight-loops Device stderr. Prune logs (and extra DB backups) on disk-full writes, skip the insert, and warn once. Homebrew/pkg postinstall boots out leftover privileged helper files so they cannot reconnect every 15s.
- Template Onyx (Lite) in
repos/templates.json: Ubuntu 24.04, NAT:80, cloud-init installs Onyx Lite. Ollama URL is a deploy input (defaulthttp://10.0.2.2:11434). After deploy on This Device, Open Onyx ishttp://127.0.0.1/. SSH key picker only when the recipe declaresssh_keys(Pi-hole now does). The in-app Chat page is gone (/chat, Console tab). Completions stay on/v1/chat/completions; talk via Library Onyx. - Models inference how-to
OPENAI_BASE_URLuses the saved Device URL, then MagicDNS/tailnet IP, then LAN. HTTPS Tailscale Serve origins contribute hostname only; LAN stayshttp://<host>:7777. Cage URL is stillhttp://10.0.2.2:11434/v1. - Device detail (web and Console) shows that Device’s version, platform, arch, accelerator, uptime, and GPU passthrough readiness. Self uses
/api/system/aboutand capabilities; members go through the Home proxy. Unreachable members keep the unknown copy, with no invented numbers. Console Settings keeps Connection and the phone sign-in QR; About is no longer origin-global. - Home hop errors no longer all say Device is unreachable. A connect timeout, cancel, or TLS failure is Home cannot hop; a member HTTP 5xx is the Device answering badly (Ollama down on that hop); HTTP 4xx on that hop is the Device rejecting the request, not Ollama down. Only a failed health probe is offline. Web and Console Device pills use those
reachabilitycodes (memberHTTPis HTTP error, not Unreachable). The same codes land on/api/home/devices/healthreachability/reachabilityError. - Ollama Models: Export JSON (web download and Console share sheet) is a point-in-time snapshot of
/api/psfields already on the catalog —name,size,sizeVRAM,running,host. No history table. - Ollama Models shows the Home completions URL (
:7777/v1/chat/completions), not Device:11434. Coding Agent cloud-init still writes a real inference key when a grant is supplied. - Settings → Updates applies a checksummed Ubuntu / Debian
.debor macOS.pkgon a root appliance.swift runand a leftover Homebrew keg stay fail-closed. Do notbrew upgrade barkvisor. - macOS no longer ships a privileged XPC helper. Install Homebrew
socket_vmnetas your user (brew install socket_vmnet). Do notsudo brew install. The root Device daemon starts the service. - Bridged start on Linux denies when
/etc/qemu/bridge.confis missing or unreadable (same as the Networks UI). - GPU attach (PAS-275): Linux Devices list GPUs with their IOMMU group and attach/detach them like USB (
GET /api/system/gpu-devices,POST/DELETE /api/vms/{id}/gpu). Fail closed if IOMMU/vfio/KVM is not ready. Occupancy is the host GPU driver, not an Ollama TCP probe. Detach, stop, and delete unbind vfio-pci so the host can reclaim the card. Attaching a GPU to a Coding Agent Workload rewrites cloud-init for guest Ollama athttp://127.0.0.1:11434/v1. Vue and the native console offer attach when the Device is ready. - GPU passthrough (PAS-274): Linux Devices probe IOMMU groups, vfio-pci, and KVM and report
gpuPassthrough/vfioon capabilities. macOS always explains that GPU passthrough is unavailable. - Coding session (PAS-273): Agent Workloads expire with a stop, not a destroy. Web and Console show a 15-minute warning, then a receipt (stopped at, last git push or NO PUSH) after the guest exits. Resume, Reset to Library image, and Burn. Kill and TTL stop unload the local-model grant when no other Agent session is running. Graceful Stop keeps the grant so Resume can keep using already-loaded models.
- Coding Agent (PAS-272): Agent-class Workloads on the Coding Agent image talk through Chat or Terminal in the web UI and the native console.
OPENAI_BASE_URLis the Home Ollama grant (http://10.0.2.2:11434/v1). ttyd stays loopback-only. - Chat (PAS-270): web and native console simple chat when the Home catalog has at least one Ollama model. Pick a model, POST
/v1/chat/completionswithstream: true, tokens append as they arrive. Hidden when Ollama is down or no model is pulled. - RBAC (PAS-286): two Home roles, admin and inference. First user is admin. Console sessions and API tokens inherit the user role. Admin can mint an inference-only token for an Agent Workload. Inference may list models that are already there and call chat completions through the BarkVisor proxy; pull, keys, USB attach, pairing, and Device changes return 403.
- Ollama (PAS-269): if Ollama is reachable on a Device, Home shows Ollama for pull/start/stop and a merged catalog. Chat completions (
/v1/chat/completions) route by model name — already-running, then the healthier Device. Inference API keys can list models and complete; they cannot pull or see the upstream Ollama key. BarkVisor does not require Ollama to install. - Remote access (PAS-89): detect Tailscale if installed (
tailscale ip -4/ MagicDNS), advertise it on inventory and pairing/sign-in QRs, optional “require tailnet for remote Home API”, WireGuard detection only. BarkVisor does not bundle Tailscale. - SPA inventory: Workloads, disks, networks, and logs share one Home-by-Device fetch helper (last-known when a Device is unreachable).
Workloads list
Section titled “Workloads list”- Running Workloads show SSH and HTTP chips from guest-info listeners. Links match Overview: bridged guest IP, This Device NAT through hostfwd, never localhost on a member, never loopback. The IP column is copyable only on bridged.
Home of more than one Device
Section titled “Home of more than one Device”- Pair another Device from Settings → Pairing → Add a Device. Pick a LAN IPv4, IPv6 unique-local, or DNS name for
host=in the offer, then scan the QR or paste the fullbarkvisor://pair/v1?…in setup, or runbarkvisor join --codeon an API-only host. Changing the address re-issues the URI and the QR. A rejected address (localhost, public, metadata) returns 400 and drops the previous pairing code. - Join allow-list now includes CGNAT
100.64.0.0/10(still blocks100.100.100.200, loopback, link-local, public, and metadata). An older joiner still rejects those offers — upgrade it or pick a LAN IP. - Optional
BARKVISOR_JOIN_CODEon first boot. Join is always console-local on that Device. - Devices share one Home login. The dashboard lists every Device and health.
- Create, start, and stop Workloads on a picked Device through the Home proxy (
:7777). The browser or phone does not open member IPs. Agent traffic uses mTLS on:7778. - Recommended Device is a suggestion. You can place a Workload on any reachable Device.
- A Device still runs if peers are down. Local SQLite owns runtime.
Library
Section titled “Library”- Images are no longer filtered to this Device’s arch only. Download ARM64 or x86_64 as needed.
- Library fetch keeps the HTTP body when headers and bytes arrive together (Linux hop client).
- Configurable Library directory (new downloads; existing files are not migrated).
- Optional depot Device: on a local miss, fetch image bytes over the agent plane, verify checksum, then store locally. Depot down falls back to the internet.
- Catalog pins use dated Ubuntu snapshot URLs so checksums stay stable.
Worker-only Device
Section titled “Worker-only Device”SKIP_FRONTEND=1install skips the SPA. Same daemon, no extra process role.barkvisoralways has aservecommand so systemd does not exit 64.
- Copy and paste text between this computer and a desktop guest (Paste / Copy on the VNC toolbar, or ⌘V / Ctrl+V). Linux guests need
spice-vdagent; Windows guests need Spice guest tools. Restart the Workload after upgrade so QEMU adds the vdagent channel. - If this Device’s QEMU was built without
qemu-vdagent(packaged BarkVisor QEMU 10.2), start omits that chardev so Workloads such as HAOS still boot. Clipboard paste is then unavailable until a QEMU with SPICE ships. - Display to a member Device no longer drops after the first framebuffer. The Home hop buffer is 8 MiB so QEMU RFB updates are not treated as overflow.
- Member Display hops the agent plane straight to the QEMU VNC socket. The extra loopback through this Device’s
:7777WebSocket was dropping the RFB banner. - Member Display no longer dies after the first picture. Tight framebuffer reads were sent as 16 KiB+ WebSocket frames; the Home hop (NIO client max 16 KiB) closed mid-update. The hop now chunks at 12 KiB.
Create VM
Section titled “Create VM”- Place on This Device or any reachable member. Incompatibility is a warning, not a lock.
- Guest default follows This Device’s arch so a recommended ARM64 member does not grey out an x86 Home.
Guest ports
Section titled “Guest ports”- Workload detail shows TCP listening ports from the guest addon (SSH, HTTP, and common dev servers). Loopback stays internal and is never a URL. Members use the same guest-info hop as This Device.
- Listening ports are the common set only (SSH, HTTP/S, typical self-host UIs such as Home Assistant 8123, Plex, OpenClaw, Jellyfin, Ollama, *arr, DBs, RDP, VNC) — rpcbind and the rest stay hidden. HTTP that actually answers
HEAD /(or a well-known HTTP port when the probe cannot run) is an Open link. - This Device NAT Overview offers Publish this port when a common TCP listener has no matching hostfwd. The host port is the guest port if free, otherwise the next free NAT claim (PAS-64). One click opens the existing port-forwards editor. Restart is still required if QEMU is already started. Loopback listeners stay hidden. Member NAT is not a click: localhost would be the wrong machine.
- A failed collect clears the snapshot (
null, hidden in the web UI) instead of keeping stale ports. Collection shares a ~3s budget and caps guest-exec output. Unchanged snapshots skip rewriting port columns. Labeled common ports sort first. - A Windows Workload with the VirtIO guest addon reports the same TCP listen set (
netstat -anoor PowerShell). Missing bash/python skips the HTTP probe and uses the well-known scheme. Denied exec staysnulland backs off like Linux.
Platform
Section titled “Platform”-
Restarting the Device daemon no longer stops Workloads. systemd signals only BarkVisor; QEMU stays up and is reattached. Use Workload Stop to shut a guest down.
-
Linux packages (appliance channel is
.deb; builders still emit.rpm/ tarball), systemd, NAT and bridged networking, USB passthrough. -
Native console app talks to the dashboard Device only (Local Network permission is for
:7777). -
Phone and Mac Console / Display open a Workload on a reachable member the same way the Home web UI does (Home WebSocket tunnel). Create VM stays web-only.
0.x — single Device
Section titled “0.x — single Device”The first public line is a Home of one: one daemon, Vue SPA on port 7777, QEMU Workloads, Library images and templates, NAT and optional bridge, console and VNC, cloud-init, SSH keys.
See First launch, Quickstart, and the roadmap.