Cloud-Init Provisioning
Always inject public SSH keys, hostnames, and bootstrap scripts via declarative cloudInit instead of manual golden images.
This guide covers the complete operational lifecycle of virtual machines in PiVirt—from declarative provisioning and runtime lifecycle transitions to snapshot trees, metadata tagging, ISO swapping, and live migration.
PiVirt tracks virtual machines through deterministic lifecycle states managed by pivirtd and reported through ConnectRPC / gRPC:
stateDiagram-v2
[*] --> Pending: Spec Submitted
Pending --> Creating: Allocating Resources
Creating --> Running: Boot Complete
Running --> Stopping: Graceful ACPI / SIGTERM
Stopping --> Stopped: Process Exited
Running --> Pausing: Suspend to Memory
Pausing --> Paused: CPU vCPUs Halted
Paused --> Resuming: Wake vCPUs
Resuming --> Running: Execution Resumed
Running --> Migrating: Live Migration
Migrating --> Running: Target Handover
Stopped --> Deleting: Cleanup
Paused --> Deleting: Force Stop & Cleanup
Running --> Deleting: Force Stop & Cleanup
Deleting --> Deleted: Disks Cleaned
Deleted --> [*]
Create a VM instance quickly using pvcli:
pvcli vm create --name web-01 \ --image ubuntu-24.04 \ --cpu 2 \ --memory 4Gi \ --disk 20Gi \ --network virbr0Define VM infrastructure as code using the PiVirt YAML specification:
apiVersion: pivirt.pilab.hu/v1kind: VirtualMachinemetadata: name: web-01 namespace: default labels: pivirt.pilab.hu/owner: devops-team pivirt.pilab.hu/ha-enabled: "true"spec: cpu: cores: 2 model: host-passthrough memory: size: 4Gi hugepages: false disks: - name: root size: 20Gi pool: default format: qcow2 bus: virtio nics: - name: eth0 network: virbr0 model: virtio cloudInit: userData: | #cloud-config packages: - nginx - curl runcmd: - systemctl enable --now nginxApply the specification:
pvcli vm create -f vm-spec.yaml# Start VMpvcli vm start web-01
# Start with a specific timeoutpvcli vm start web-01 --timeout 60sSends an ACPI shutdown signal to the guest operating system, allowing services to stop cleanly:
pvcli vm stop web-01Instantly terminates the QEMU process (equivalent to pulling the power plug):
pvcli vm stop web-01 --force# Restart VM (Graceful reboot)pvcli vm restart web-01
# Force immediate restartpvcli vm restart web-01 --force
# Pause VM execution (freezes vCPUs in RAM)pvcli vm pause web-01
# Resume paused VMpvcli vm resume web-01# Delete VM (preserves external storage disks if configured)pvcli vm delete web-01
# Cascade delete (removes VM runtime specification and attached volume disks)pvcli vm delete web-01 --cascadePiVirt supports instant disk and RAM snapshots with branching trees.
# Create a named snapshotpvcli vm snapshot create web-01 --name "pre-upgrade" --description "Before apt full-upgrade"
# List snapshots and inspect tree hierarchypvcli vm snapshot list web-01
# Restore snapshotpvcli vm snapshot restore web-01 --name "pre-upgrade"
# Delete snapshotpvcli vm snapshot delete web-01 --name "pre-upgrade"VMs carry an arbitrary key/value metadata map stored inside the VM’s config.yaml. Labels work like Kubernetes annotations—use a reverse-DNS prefix to namespace system keys:
# Set labelspivirtctl vm label set web-01 \ pivirt.pilab.hu/owner=org-production \ pivirt.pilab.hu/drs-pool=pool1 \ pivirt.pilab.hu/ha-enabled=true
# List all labelspivirtctl vm label list web-01
# Remove a labelpivirtctl vm label delete web-01 pivirt.pilab.hu/suspend-reason| Key | Type | Purpose |
|---|---|---|
pivirt.pilab.hu/owner |
string (UUID) | Owning organization or user |
pivirt.pilab.hu/drs-pool |
string | DRS scheduler placement pool |
pivirt.pilab.hu/ha-enabled |
true/false |
High-availability failover eligibility |
pivirt.pilab.hu/node-select |
hostname | Preferred hypervisor host |
A stopped VM can be renamed atomically. The daemon renames the VM instance directory and updates all configuration references:
# Stop VM before renamingpivirtctl vm stop web-01
# Rename instancepivirtctl vm rename web-01 web-prod-01
# Start under new namepivirtctl vm start web-prod-01Virtual CD-ROM drives can have their ISO image swapped or ejected at runtime without restarting the VM:
# Swap ISO in cdrom0 on running VMpivirtctl vm iso change web-prod-01 cdrom0 /var/lib/pivirtd/isos/ubuntu-24.04.iso
# Eject CD-ROM discpivirtctl vm iso eject web-prod-01 cdrom0Migrates memory and vCPU execution to a target host with near-zero downtime over the cluster network:
pvcli vm migrate web-prod-01 --target node-02 --livepvcli vm stop web-prod-01pvcli vm migrate web-prod-01 --target node-02pvcli vm start web-prod-01# Serial console (interactive text)pvcli vm console web-prod-01
# Inspect VNC port and display bindingpvcli vm vnc web-prod-01# Connect via standard VNC client: vncviewer localhost:5900
# Inspect runtime metadata in YAML/JSONpvcli vm get web-prod-01 -o yamlCloud-Init Provisioning
Always inject public SSH keys, hostnames, and bootstrap scripts via declarative cloudInit instead of manual golden images.
Storage Cache Mode
Use cache: none and io: native on clustered storage (iSCSI, OCFS2, LVM) to ensure data integrity and enable safe live migrations.
Multi-Queue VirtIO
Enable multi-queue on high-throughput NICs and disks to distribute interrupt handling across multiple vCPUs.
Hugepages Allocation
For memory-intensive workloads (databases, Kubernetes nodes), configure 2Mi or 1Gi hugepages to eliminate TLB miss latency.
YAML Config Schema
Full schema documentation for VM specifications, disks, and network attachments.
View Schema Reference
Live Migration Guide
Deep dive into pre-copy memory synchronization and NBD storage mirroring.
View Migration Guide
Storage Configuration
Configure iSCSI SAN, OCFS2 clustered volumes, and LVM thin pools.
View Storage Guide
Troubleshooting Runbooks
Diagnose disk locks, missing DHCP IPs, and boot failures.
View Troubleshooting