Creation
Sylve creates bhyve virtual machines from common command-line flags or a complete JSON request. A VM can start with managed raw or ZVOL storage, installation media or a cloud image, a network attachment, VNC, and boot-time behavior.
Inspect the available resources
Section titled “Inspect the available resources”List existing VMs before choosing an RID:
doas sylve vms listVM RIDs are unique integers from 1 through 9999. An empty node reports No VMs found.
The initial disk must use an existing ZFS pool. Installation media and cloud images are referenced by download UUID, not by the numeric download ID:
doas zpool listdoas sylve downloads list --jsondoas sylve switches listUse a switch name or none during creation. Network objects and switch configuration are covered in the earlier networking guides.
Understand the conservative defaults
Section titled “Understand the conservative defaults”Without --file, only --rid and --name are required. Omitted settings use these defaults:
| Setting | Default |
|---|---|
| CPU topology | 1 socket, 1 core, 1 thread |
| RAM | 1 GiB |
| Initial storage | None |
| Initial network | None |
| VNC | Disabled |
| Start at host boot | Disabled |
| Guest clock | UTC |
This minimal command creates a registered VM without disks or networking:
doas sylve vms create --rid 301 --name example-vmThe interactive console accepts the same named creation options without the leading sylve:
vms create --rid 301 --name example-vmCreate an installable VM
Section titled “Create an installable VM”The following real example creates a 1 vCPU Alpine VM with 1 GiB of RAM, a 4 GiB managed raw disk, an attached installer ISO, VNC bound to the local host, and one interface on TTT:
doas sylve vms create \ --rid 301 \ --name docs-alpine \ --description "CLI documentation example" \ --cpu-sockets 1 \ --cpu-cores 1 \ --cpu-threads 1 \ --ram 1GiB \ --storage-pool zroot \ --storage-type raw \ --storage-size 4GiB \ --storage-emulation virtio-blk \ --iso 306a765d-c9d0-5d53-8a67-bd48b2e0adbe \ --switch TTT \ --network-emulation virtio \ --boot-rom uefi \ --vnc-enabled=true \ --vnc-port 5901 \ --vnc-bind 127.0.0.1 \ --vnc-resolution 1024x768 \ --vnc-wait=false \ --start-at-boot=false \ --start-order 0 \ --time-offset utc \ --jsonLoki returned the identifiers of every resource created or attached:
{ "created": true, "rid": 301, "name": "docs-alpine", "storageAttachmentIds": [5, 6], "networkAttachmentIds": [3], "macObjectIds": [12], "generatedMacObjectIds": [12]}The first storage attachment is the managed raw disk. The second is the retained ISO image. Because no existing MAC object was supplied, Sylve generated MAC object 12 for network attachment 3.
Core creation flags
Section titled “Core creation flags”| Flag | Purpose |
|---|---|
--rid <id> |
Unique VM RID from 1 through 9999. Required without --file. |
--name <name> |
VM name. Required without --file. |
--description <text> |
Optional descriptive text. |
--cpu-sockets <count> |
Positive CPU socket count. |
--cpu-cores <count> |
Positive cores per socket. |
--cpu-threads <count> |
Positive threads per core. |
--ram <size> |
RAM using a human-readable size such as 1GiB. |
--storage-pool <pool> |
Pool for the initial managed raw disk or ZVOL. |
--storage-type <type> |
none, raw, or zvol. |
--storage-size <size> |
Initial managed disk size, such as 20GiB. |
--storage-emulation <type> |
virtio-blk, ahci-hd, or nvme. |
--iso <uuid> |
Download UUID for an ISO or disk image. |
--cloud-init-image <uuid> |
Download UUID for a cloud-init-capable image. Mutually exclusive with --iso. |
--switch <name> |
Initial switch name or none. |
--network-emulation <type> |
virtio or e1000. |
--boot-rom <type> |
uefi, uboot, or none, subject to guest architecture. |
--vnc-enabled=<bool> |
Explicitly enable or disable VNC. |
--vnc-port <port> |
VNC TCP port from 1 through 65535. |
--vnc-bind <address> |
Address on which VNC listens. |
--vnc-resolution <size> |
VNC resolution such as 1024x768. |
--vnc-password-file <path> |
Read the VNC password from a host file. |
--vnc-wait=<bool> |
Wait for a VNC client before guest boot. |
--start-at-boot=<bool> |
Start the VM when the host starts. |
--start-order <number> |
Non-negative ordering value for host startup. |
--time-offset <value> |
Guest clock mode: utc or localtime. |
Boolean flags accept explicit true and false. This matters when a command-line flag overrides a value loaded from a JSON file.
Create from a cloud image
Section titled “Create from a cloud image”Use --cloud-init-image instead of --iso for a download categorized as cloud-init. Cloud-init data, metadata, and network configuration are read from files on the Sylve host:
doas sylve vms create \ --rid 302 \ --name cloud-vm \ --storage-pool zroot \ --storage-type raw \ --storage-size 12GiB \ --storage-emulation virtio-blk \ --cloud-init-image 3936aa0f-b178-538f-b1fa-6c9abbe583e6 \ --cloud-init-data-file /root/cloud-init/user-data.yaml \ --cloud-init-metadata-file /root/cloud-init/meta-data.yaml \ --cloud-init-network-config-file /root/cloud-init/network-config.yaml \ --switch TTT \ --network-emulation virtio \ --boot-rom uefiPaths are resolved by the daemon on the Sylve host. Prefer absolute paths, especially when the direct CLI attaches to an already-running daemon.
Create from a complete JSON request
Section titled “Create from a complete JSON request”Use --file for CPU pinning, PCI passthrough, TPM, serial, ACPI and APIC settings, QGA, raw cloud-init content, an existing MAC object, or extra bhyve options.
{ "name": "json-vm", "rid": 303, "description": "Created from a strict request", "iso": "306a765d-c9d0-5d53-8a67-bd48b2e0adbe", "storagePool": "zroot", "storageType": "raw", "storageSize": 4294967296, "storageEmulationType": "virtio-blk", "switchName": "TTT", "switchEmulationType": "virtio", "macId": 13, "cpuSockets": 1, "cpuCores": 2, "cpuThreads": 1, "cpuPinning": [], "ram": 2147483648, "tpmEmulation": false, "pciDevices": [], "serial": true, "vncEnabled": true, "vncPort": 5903, "vncBind": "127.0.0.1", "vncPassword": "", "vncResolution": "1024x768", "vncWait": false, "cloudInit": false, "bootRom": "uefi", "extraBhyveOptions": [], "apic": true, "acpi": true, "ignoreUMSR": false, "qemuGuestAgent": false, "startAtBoot": false, "startOrder": 0, "timeOffset": "utc"}Submit the request with:
doas sylve vms create --file /root/vm-303.jsonmacId is optional. When it is omitted for a configured switch, Sylve creates a MAC object for the attachment. When it is supplied, it must identify an existing MAC object.
The decoder rejects unknown fields and multiple JSON documents. Explicit creation flags override matching fields from the file:
doas sylve vms create \ --file /root/vm-303.json \ --name replacement-name \ --ram 4GiB \ --vnc-enabled=falseInspect the result
Section titled “Inspect the result”List all VMs or inspect one RID:
doas sylve vms listdoas sylve vms get --rid 301doas sylve vms get --rid 301 --jsonThe concise output captured from Loki is:
RID Name vCPUs RAM Networks────────────────────────────────────────────────301 docs-alpine 1 1 GiB 1Inspect the resources attached during creation:
doas sylve vms storage list --rid 301doas sylve vms network list --rid 301The corresponding console forms place the RID after the leaf command:
vms get 301vms storage list 301vms network list 301The storage inventory labels the raw disk as managed and the ISO as retained. Later storage and deletion guides explain how those ownership classifications affect detach and removal operations.