Reference · reference

Host configuration file

5 min read · 2026-09-02 · vmlab 0.9

The host configuration file holds the settings that belong to this machine rather than to any lab: the subnet pool, the DNS suffix, the pre-shared key for cross-host segments, the viewer command, and the workspace syncer's size guard. Host configuration and WSL 2 explains when to change each one; this chapter lists the fields.

Where it lives

The file is config.wcl in vmlab's XDG config directory, which is ~/.config/vmlab/ unless XDG_CONFIG_HOME moves it. See Files and directories. It is optional: when the file is absent every default applies. When present it must start with import <vmlab-host.wcl>, and a file without the import is rejected with an error naming the missing line. The daemons read it when they start, so a change takes effect on the next vmlab up after the supervisor restarts.

~/.config/vmlab/config.wclwcl
import <vmlab-host.wcl>

host {
  subnet_pool = "10.99.0.0/16"
  dns_suffix  = "lab.local"
  psk         = "shared-secret"
  viewer      = "vncviewer {}"
}

host {}

The one block the file carries. Every field is an override: an absent field leaves the default in place, and a malformed one is reported with its line rather than silently ignored.

wcl
host {
  subnet_pool          = "10.213.0.0/16"
  dns_suffix           = "vmlab.internal"
  dns_upstream         = "1.1.1.1:53"
  disk_low_percent     = 10
  psk                  = "…"
  trunk_port           = 13947
  viewer               = "vncviewer {}"
  fastpath             = "auto"
  oci_chunk_size       = 512MiB
  config_weave_bin_dir = "~/.local/share/config-weave/bin"
  workspace_max_file   = 256MiB
  firmware_dir         = "/opt/vmlab-firmware"
}
FieldTypeDefaultMeaning
subnet_poolutf810.213.0.0/16CIDR the automatic /24 segment subnets are carved from.
dns_suffixutf8vmlab.internalSuffix for auto-registered machine names, <vm>.<lab>.<suffix>.
dns_upstreamutf8host resolverUpstream resolver as ip[:port] for queries the lab DNS cannot answer.
disk_low_percenti6410Free-space percentage, 0 to 100, below which the host.disk_low watchdog fires.
pskutf8nonePre-shared key for cross-host segment links. Set the same value on both hosts.
trunk_porti6413947TCP port the supervisor listens on for inbound cross-host segment trunks, 1 to 65535.
viewerutf8noneVNC viewer command; {} is replaced by the target.
fastpathutf8autoNetwork fast path: auto probes, off forces userspace, sockmap and afxdp force a kernel tier.
oci_chunk_sizeByteSize512MiBOCI layer chunk size for vmlab template push.
config_weave_bin_dirutf8~/.local/share/config-weave/binDirectory holding the config-weave guest binaries playbooks push.
workspace_max_fileByteSize256MiBWorkspace syncer per-file size guard. A larger file is refused by name.
firmware_dirutf8noneUEFI firmware override, laid out <dir>/<arch>/ with the bundled set's file names. Searched before vmlab's bundled firmware and the host's.

The parser enforces these rules, and reports every violation in one pass:

workspace_max_file is host config rather than a @dev argument because the cap is about this developer's link to the guest, not the lab everyone shares; the refusal message names the field. See Dev machines and the workspace syncer. firmware_dir is authoritative for an architecture it has a directory for: a pair missing from <dir>/<arch>/ is an error, never a fall back to firmware you did not choose. An architecture with no directory there uses the bundled set. See Host configuration and WSL 2.

A neutral fast path

auto never selects sockmap; it was measured slower than the userspace fabric and exists for explicit evaluation. Both kernel tiers need CAP_BPF and CAP_NET_ADMIN, and a daemon that cannot prove a tier works on its host falls back to userspace silently. vmlab fastpath reports the tier in use.