vzkit

package
v0.4.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 21, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package vzkit provides shared infrastructure for building macOS and Linux virtual machines using Apple's Virtualization framework via purego.

It extracts common VM plumbing — dispatch queues, run loops, completion handlers, vsock, VirtioFS, networking, and VM lifecycle management — so that higher-level tools (vz-macos, vz-container, etc.) can share one tested implementation instead of duplicating it.

All Objective-C interop uses purego (cgo-free). The generated bindings from github.com/tmc/apple provide the type-safe wrappers.

Index

Constants

View Source
const (
	RunLoopRunFinished      = 1
	RunLoopRunStopped       = 2
	RunLoopRunTimedOut      = 3
	RunLoopRunHandledSource = 4
)

CFRunLoop return values.

Variables

This section is empty.

Functions

func AddMemoryBalloonDevice

func AddMemoryBalloonDevice(config vz.VZVirtualMachineConfiguration)

AddMemoryBalloonDevice adds a VirtIO traditional memory balloon device to a VM configuration. This enables runtime memory control.

func BuildLinuxVMConfig

func BuildLinuxVMConfig(cfg LinuxVMConfig) (vz.VZVirtualMachineConfiguration, error)

BuildLinuxVMConfig creates a VZVirtualMachineConfiguration from a LinuxVMConfig. It sets up platform, boot loader, storage, network, serial console, entropy, memory balloon, and vsock devices.

func CanStart

func CanStart(queue *Queue, vm vz.VZVirtualMachine) bool

CanStart reports whether the VM is in a state that allows starting.

func CanStop

func CanStop(queue *Queue, vm vz.VZVirtualMachine) bool

CanStop reports whether the VM is in a state that allows stopping.

func CreateBlockDevice

CreateBlockDevice creates a VZVirtioBlockDeviceConfiguration from a disk attachment.

func CreateDirectoryShare

func CreateDirectoryShare(path string, readOnly bool) (vz.VZSingleDirectoryShare, error)

CreateDirectoryShare creates a VZSingleDirectoryShare for VirtioFS.

func CreateDiskAttachment

func CreateDiskAttachment(path string, readOnly bool) (vz.VZDiskImageStorageDeviceAttachment, error)

CreateDiskAttachment creates a VZDiskImageStorageDeviceAttachment from a file path.

func CreateDiskImage

func CreateDiskImage(path string, sizeGB uint64) error

CreateDiskImage creates a sparse disk image of the given size in gigabytes.

func CreateMacGraphicsConfig

func CreateMacGraphicsConfig(displays []DisplayConfig) (vz.VZMacGraphicsDeviceConfiguration, error)

CreateMacGraphicsConfig creates a VZMacGraphicsDeviceConfiguration with the specified displays.

func CreateNetworkAttachment

func CreateNetworkAttachment(config NetworkConfig) (vz.VZNetworkDeviceAttachment, error)

CreateNetworkAttachment creates a network device attachment based on config.

func CreateNetworkDevice

func CreateNetworkDevice(config NetworkConfig) (vz.VZVirtioNetworkDeviceConfiguration, error)

CreateNetworkDevice creates a VZVirtioNetworkDeviceConfiguration with a random MAC.

func CreateSerialConsole

func CreateSerialConsole(readFd, writeFd int) (vz.VZVirtioConsoleDeviceSerialPortConfiguration, error)

CreateSerialConsole creates a VZVirtioConsoleDeviceSerialPortConfiguration connected to the given read and write file descriptors.

func CreateStdioSerialConsole

func CreateStdioSerialConsole() (vz.VZVirtioConsoleDeviceSerialPortConfiguration, error)

CreateStdioSerialConsole creates a serial console connected to stdin/stdout.

func CreateVM

func CreateVM(config vz.VZVirtualMachineConfiguration, queue *Queue) vz.VZVirtualMachine

CreateVM creates a VZVirtualMachine bound to the given dispatch queue.

func CreateVirtioFSDevices

func CreateVirtioFSDevices(mounts []VolumeMount) ([]vz.VZVirtioFileSystemDeviceConfiguration, error)

CreateVirtioFSDevices creates VirtioFS device configurations for the given mounts.

func CreateVirtioGraphicsConfig

func CreateVirtioGraphicsConfig(displays []DisplayConfig) (vz.VZVirtioGraphicsDeviceConfiguration, error)

CreateVirtioGraphicsConfig creates a VZVirtioGraphicsDeviceConfiguration with the specified displays (for Linux/generic VMs using VirtIO GPU).

func ExtractNSErrorMessage

func ExtractNSErrorMessage(nsError objc.ID) string

ExtractNSErrorMessage extracts the localized error message from an NSError. Returns an empty string if the error ID is zero.

func FormatNSErrorDetailed

func FormatNSErrorDetailed(nsError objc.ID) string

FormatNSErrorDetailed returns a multi-line string with full NSError details including domain, code, failure reason, recovery suggestion, user info, and underlying errors.

func NSDataFromBytes

func NSDataFromBytes(data []byte) foundation.NSData

NSDataFromBytes creates an NSData object from Go bytes.

func NSDataToBytes

func NSDataToBytes(data foundation.NSData) []byte

NSDataToBytes extracts the bytes from an NSData object.

func PrintNSErrorDetailed

func PrintNSErrorDetailed(nsError objc.ID)

PrintNSErrorDetailed prints detailed NSError information to stdout.

func Retain

func Retain(id interface{ Retain() })

Retain retains an Objective-C object to prevent premature deallocation. This is needed for objects passed to the Virtualization framework.

func RunRunLoopAggressively

func RunRunLoopAggressively()

RunRunLoopAggressively pumps both CFRunLoop and NSRunLoop multiple times. Use this for long-running async operations that need thorough event processing.

func RunRunLoopOnce

func RunRunLoopOnce()

RunRunLoopOnce runs the main CFRunLoop briefly to process pending callbacks.

func RunRunLoopUntilDone

func RunRunLoopUntilDone(done func() bool, progress func())

RunRunLoopUntilDone runs the main run loop until done returns true. It pumps both CFRunLoop and NSRunLoop to ensure async callbacks are delivered. The optional progress callback is invoked each iteration.

func SetBalloonTarget

func SetBalloonTarget(queue *Queue, vm vz.VZVirtualMachine, sizeGB float64) error

SetBalloonTarget sets the memory balloon target size in gigabytes. The size is rounded down to a 1 MB boundary.

func StartVM

func StartVM(queue *Queue, vm vz.VZVirtualMachine, completion func(error))

StartVM starts a VZVirtualMachine on its queue and calls completion with the result. The call dispatches synchronously to the queue to issue the start, but the completion fires asynchronously.

func StopVM

func StopVM(queue *Queue, vm vz.VZVirtualMachine, completion func(error))

StopVM requests a stop of a VZVirtualMachine on its queue.

func VMState

func VMState(queue *Queue, vm vz.VZVirtualMachine) vz.VZVirtualMachineState

VMState returns the current state of a VZVirtualMachine, dispatching to queue.

func ValidateConfig

func ValidateConfig(config vz.VZVirtualMachineConfiguration) error

ValidateConfig validates a VZVirtualMachineConfiguration and returns any error.

Types

type BalloonInfo

type BalloonInfo struct {
	HasBalloon     bool
	TargetGB       float64
	MinimumAllowMB uint64
}

BalloonInfo contains memory balloon device information.

func GetBalloonInfo

func GetBalloonInfo(queue *Queue, vm vz.VZVirtualMachine) (BalloonInfo, error)

BalloonInfo retrieves memory balloon information from a running VM. The call dispatches to the VM's queue.

type DisplayConfig

type DisplayConfig struct {
	Width  int // Width in pixels
	Height int // Height in pixels
	PPI    int // Pixels per inch (default 144)
}

DisplayConfig represents a single display configuration.

func DefaultDisplayConfig

func DefaultDisplayConfig() DisplayConfig

DefaultDisplayConfig returns the default display configuration (1920x1200 @ 144 PPI).

func DefaultLinuxDisplayConfig

func DefaultLinuxDisplayConfig() DisplayConfig

DefaultLinuxDisplayConfig returns the default display for Linux VMs (1920x1080 @ 144 PPI).

func ParseDisplaySpec

func ParseDisplaySpec(s string) (DisplayConfig, error)

ParseDisplaySpec parses a display specification string.

Formats:

  • "1920x1080" — width x height at default PPI
  • "1920x1080@144" — width x height at specific PPI
  • "4k" — preset for 3840x2160
  • "1080p" — preset for 1920x1080
  • "720p" — preset for 1280x720
  • "retina" — preset for 2560x1600 @ 227 PPI

type DisplaySlice

type DisplaySlice []DisplayConfig

DisplaySlice implements flag.Value for collecting multiple -display flags.

func (*DisplaySlice) Set

func (s *DisplaySlice) Set(value string) error

func (*DisplaySlice) String

func (s *DisplaySlice) String() string

type ErrorCompletionHandler

type ErrorCompletionHandler struct {
	// contains filtered or unexported fields
}

ErrorCompletionHandler captures an optional NSError from an Objective-C completion handler callback (void (^)(NSError *)).

Usage:

h := vmkit.NewErrorCompletionHandler()
objcMethod(h.Block())
h.Wait()
if err := h.Error(); err != nil { ... }

func NewErrorCompletionHandler

func NewErrorCompletionHandler() *ErrorCompletionHandler

NewErrorCompletionHandler creates a completion handler for error-only callbacks.

func (*ErrorCompletionHandler) Block

func (h *ErrorCompletionHandler) Block() objc.Block

Block returns the underlying objc.Block for passing to Objective-C methods.

func (*ErrorCompletionHandler) Done

func (h *ErrorCompletionHandler) Done() bool

Done reports whether the completion handler has been called.

func (*ErrorCompletionHandler) Error

func (h *ErrorCompletionHandler) Error() error

Error returns the error if one was received, or nil.

func (*ErrorCompletionHandler) Wait

func (h *ErrorCompletionHandler) Wait()

Wait blocks until the completion handler is called.

type LinuxVMConfig

type LinuxVMConfig struct {
	CPUs     uint   // Number of CPUs
	MemoryGB uint64 // Memory in gigabytes

	DiskPath string // Path to the main disk image
	ISOPath  string // Optional ISO to attach as second block device (read-only)

	// Boot mode: set KernelPath for direct boot, leave empty for EFI boot.
	KernelPath string
	InitrdPath string
	CmdLine    string

	// EFI state directory (for efi.nvram and linux-machine.id).
	StateDir string

	// Peripherals
	Volumes  []VolumeMount // VirtioFS mounts
	Network  NetworkConfig // Network configuration
	Headless bool          // Skip graphics if true
}

LinuxVMConfig describes the configuration for a Linux virtual machine.

type NetworkConfig

type NetworkConfig struct {
	Mode      NetworkMode
	Interface string // For bridged mode: the host interface name (e.g., "en0")
}

NetworkConfig holds network configuration settings.

func ParseNetworkMode

func ParseNetworkMode(s string) (NetworkConfig, error)

ParseNetworkMode parses a network mode string.

Formats:

  • "nat" - NAT networking (default)
  • "bridged:en0" - Bridged to specific interface
  • "vmnet" - VMNet shared networking
  • "none" - No networking

type NetworkMode

type NetworkMode string

NetworkMode represents the type of network configuration.

const (
	NetworkModeNAT     NetworkMode = "nat"
	NetworkModeBridged NetworkMode = "bridged"
	NetworkModeVMNet   NetworkMode = "vmnet"
	NetworkModeNone    NetworkMode = "none"
)

type Queue

type Queue struct {
	// contains filtered or unexported fields
}

Queue wraps a dispatch queue for VM operations. The Virtualization framework requires VM operations to happen on a specific queue.

func NewQueue

func NewQueue(label string) *Queue

NewQueue creates a serial dispatch queue with the given label.

func WrapQueue

func WrapQueue(q dispatch.Queue) *Queue

WrapQueue creates a Queue from an existing dispatch.Queue.

func (*Queue) Async

func (q *Queue) Async(work func())

Async executes work asynchronously on the dispatch queue.

func (*Queue) Queue

func (q *Queue) Queue() dispatch.Queue

Queue returns the underlying dispatch.Queue.

func (*Queue) Sync

func (q *Queue) Sync(work func())

Sync executes work synchronously on the dispatch queue.

type SnapshotManager

type SnapshotManager struct {
	// contains filtered or unexported fields
}

SnapshotManager handles VM state snapshot operations. Snapshots are stored as .vmstate files in a "snapshots" subdirectory of the VM directory.

func NewSnapshotManager

func NewSnapshotManager(vmDir string) *SnapshotManager

NewSnapshotManager creates a snapshot manager for the given VM directory.

func (*SnapshotManager) Delete

func (m *SnapshotManager) Delete(name string) error

Delete removes a named snapshot.

func (*SnapshotManager) List

func (m *SnapshotManager) List() ([]SnapshotMeta, error)

List returns all available snapshots sorted by creation time (newest first).

func (*SnapshotManager) Restore

func (m *SnapshotManager) Restore(vm vz.VZVirtualMachine, queue *Queue, name string) error

Restore restores a VM from a previously saved snapshot. The VM must be stopped before calling Restore.

func (*SnapshotManager) Save

func (m *SnapshotManager) Save(vm vz.VZVirtualMachine, queue *Queue, name string) error

Save saves the current VM state to a named snapshot. If the VM is running it is paused first, and resumed after the save completes. If the VM is already paused it stays paused.

type SnapshotMeta

type SnapshotMeta struct {
	Name     string    `json:"name"`
	Created  time.Time `json:"created"`
	Size     int64     `json:"size"`
	VMState  string    `json:"vmState"`
	FilePath string    `json:"filePath"`
}

SnapshotMeta is the on-disk metadata format for VM state snapshots.

type VolumeMount

type VolumeMount struct {
	HostPath string // Absolute path on host
	Tag      string // VirtioFS tag (empty = auto-mount tag)
	ReadOnly bool
}

VolumeMount represents a host-to-guest volume mount configuration. Format: host_path[:tag][:ro|rw]

func ParseVolumeSpec

func ParseVolumeSpec(spec string) (VolumeMount, error)

ParseVolumeSpec parses a docker-style volume specification. Format: host_path[:tag][:ro|rw]

Examples:

/path/to/dir                    -> auto-mount tag, read-write
/path/to/dir:ro                 -> auto-mount tag, read-only
/path/to/dir:MyVolume           -> /Volumes/MyVolume, read-write
/path/to/dir:MyVolume:ro        -> /Volumes/MyVolume, read-only

type VsockConn

type VsockConn struct {
	// contains filtered or unexported fields
}

VsockConn wraps a VZVirtioSocketConnection as a net.Conn.

func NewVsockConn

func NewVsockConn(vzConn vz.VZVirtioSocketConnection) (*VsockConn, error)

NewVsockConn converts a VZVirtioSocketConnection into a net.Conn. It extracts the file descriptor and wraps it with net.FileConn.

func (*VsockConn) Close

func (c *VsockConn) Close() error

func (*VsockConn) LocalAddr

func (c *VsockConn) LocalAddr() net.Addr

func (*VsockConn) Read

func (c *VsockConn) Read(b []byte) (int, error)

func (*VsockConn) RemoteAddr

func (c *VsockConn) RemoteAddr() net.Addr

func (*VsockConn) SetDeadline

func (c *VsockConn) SetDeadline(t time.Time) error

func (*VsockConn) SetReadDeadline

func (c *VsockConn) SetReadDeadline(t time.Time) error

func (*VsockConn) SetWriteDeadline

func (c *VsockConn) SetWriteDeadline(t time.Time) error

func (*VsockConn) Write

func (c *VsockConn) Write(b []byte) (int, error)

type VsockManager

type VsockManager struct {

	// DispatchFunc, if set, dispatches the VZ API call onto the VM's queue.
	// Virtualization framework calls must run on the VM's dispatch queue;
	// calling from an arbitrary goroutine causes SIGTRAP crashes.
	DispatchFunc func(fn func())
	// contains filtered or unexported fields
}

VsockManager manages the VZVirtioSocketDevice for a running VM.

func NewVsockManager

func NewVsockManager(vm vz.VZVirtualMachine) (*VsockManager, error)

NewVsockManager wraps the first VZVirtioSocketDevice from a running VM.

func (*VsockManager) Connect

func (m *VsockManager) Connect(port uint32) (net.Conn, error)

Connect establishes a vsock connection to the guest on the given port.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL