WWDC Quick Look 💓 By SwiftGGTeam
Create macOS or Linux virtual machines

Create macOS or Linux virtual machines

Watch original video

Highlight

The Virtualization framework lets developers create and run macOS and Linux virtual machines on Apple Silicon through Swift code, with GPU acceleration, file sharing, virtio graphics devices, and Rosetta 2 to run x86-64 Linux binaries.

Core Content

Testing system-level changes on a Mac often means multiple machines, repeated OS reinstalls, or full virtualization software. The problems are hard-to-replicate environments, weak test isolation, and CI or classroom scenarios where everyone struggles to get the same machine state.

Apple’s Virtualization framework turns VM configuration into Swift objects. Developers describe CPU, memory, storage, input, display, and platform properties, then create a VZVirtualMachine and start it. macOS runs in Apple Silicon VMs; Linux runs on both Apple Silicon and Intel Macs.

This session’s value is the path from “boot a VM” to “install a full macOS or Linux system.” The macOS section covers virtual Mac platform properties, restore image installation, GPU acceleration, trackpad, and file sharing. The Linux section covers ISO installation, EFI boot, virtio graphics, and Rosetta.

Detailed Content

Booting a VM from configuration

(03:01) VM configuration starts with VZVirtualMachineConfiguration. It defines CPU, memory, and devices. To start, create a VZVirtualMachine from the configuration and call start().

var configuration = VZVirtualMachineConfiguration()
configuration.cpuCount = 4
configuration.memorySize = (4 * 1024 * 1024 * 1024) as UInt64
configuration.storageDevices = [newBlockDevice()]
configuration.pointingDevices = [newPointingDevice()]

let virtualMachine = VZVirtualMachine(configuration: configuration)
try await virtualMachine.start()

Key points:

  • VZVirtualMachineConfiguration is the root object for virtual hardware configuration
  • cpuCount and memorySize set compute resources
  • storageDevices and pointingDevices add virtual devices
  • VZVirtualMachine represents a running VM instance

(04:33) Display VM content with VZVirtualMachineView.

let virtualMachineView = VZVirtualMachineView()
virtualMachineView.virtualMachine = virtualMachine

Key points:

  • VZVirtualMachineView can be placed in a Mac app like any NSView
  • The virtualMachine property binds the VM to display
  • Suitable for VM managers, teaching sandboxes, or test tools

Creating a virtual Mac

(07:43) A virtual Mac needs VZMacPlatformConfiguration with three Mac-specific properties: hardware model, auxiliary storage, and machine identifier.

let platform = VZMacPlatformConfiguration()

let hardwareModel = VZMacHardwareModel(dataRepresentation: savedHardwareModel)
platform.hardwareModel = hardwareModel!

let auxiliaryStorage = VZMacAuxiliaryStorage(contentsOf: auxiliaryStorageURL)
platform.auxiliaryStorage = auxiliaryStorage

let machineIdentifier = VZMacMachineIdentifier(dataRepresentation: savedIdentifier)
platform.machineIdentifier = machineIdentifier!

configuration.platform = platform
configuration.bootLoader = VZMacOSBootLoader()

Key points:

  • VZMacHardwareModel determines which macOS versions the virtual Mac can run
  • VZMacAuxiliaryStorage is non-volatile storage for the virtual Mac
  • VZMacMachineIdentifier is a unique VM identifier, similar to a real Mac serial number
  • VZMacOSBootLoader boots macOS

Installing macOS

(09:16) Installation has three steps: obtain a restore image, generate a compatible configuration, and run the installer.

let restoreImage = try await VZMacOSRestoreImage.latestSupported
try await download(restoreImage.url)

let requirements = restoreImage.mostFeaturefulSupportedConfiguration
platform.hardwareModel = requirements!.hardwareModel
configuration.cpuCount = requirements!.minimumSupportedCPUCount
configuration.memorySize = requirements!.minimumSupportedMemorySize

let virtualMachine = VZVirtualMachine(configuration: configuration)
let installer = VZMacOSInstaller(virtualMachine: virtualMachine,
                                 restoringFromImageAt: imageURL)
try await installer.install()

Key points:

  • latestSupported fetches the latest stable macOS restore image supported by the current system
  • mostFeaturefulSupportedConfiguration provides compatible configuration requirements
  • Minimum CPU and memory come from image requirements, not developer guesses
  • VZMacOSInstaller installs the restore image into the VM

macOS devices: GPU, trackpad, file sharing

(10:58) GPU acceleration uses VZMacGraphicsDeviceConfiguration.

let graphicsConfiguration = VZMacGraphicsDeviceConfiguration()
graphicsConfiguration.displays = [
    VZMacGraphicsDisplayConfiguration(widthInPixels: 1920,
                                      heightInPixels: 1200,
                                      pixelsPerInch: 80)
]
configuration.graphicsDevices = [graphicsConfiguration]

Key points:

  • VZMacGraphicsDeviceConfiguration exposes GPU capabilities to the virtual Mac
  • Display configuration defines resolution and pixel density
  • Metal can run inside the VM with good graphics performance

(12:33) Share files between host and virtual Mac with a virtio file system device.

let sharedDirectory = VZSharedDirectory(url: directoryURL, readOnly: false)
let share = VZSingleDirectoryShare(directory: sharedDirectory)

let tag = VZVirtioFileSystemDeviceConfiguration.macOSGuestAutomountTag
let sharingDevice = VZVirtioFileSystemDeviceConfiguration(tag: tag)
sharingDevice.share = share

configuration.directorySharingDevices = [sharingDevice]

Key points:

  • VZSharedDirectory specifies the host directory and read/write permissions
  • VZSingleDirectoryShare shares a single directory
  • macOSGuestAutomountTag lets the virtual Mac auto-mount the shared directory
  • Changes on host and guest are reflected immediately

Linux: EFI, virtio graphics, and Rosetta

(17:27) Linux uses EFI boot.

let efi = VZEFIBootLoader()
efi.variableStore = VZEFIVariableStore(creatingVariableStoreAt: storeURL,
                                       options: [])
configuration.bootLoader = efi

Key points:

  • VZEFIBootLoader suits Linux distributions
  • VZEFIVariableStore stores EFI variables
  • ISO install images can be mounted via USB mass storage devices

(18:24) Linux graphics output uses virtio GPU.

let virtioGPU = VZVirtioGraphicsDeviceConfiguration()
virtioGPU.scanouts = [
    VZVirtioGraphicsScanoutConfiguration(widthInPixels: 1280, heightInPixels: 720)
]
configuration.graphicsDevices = [virtioGPU]

Key points:

  • VZVirtioGraphicsDeviceConfiguration provides a Linux graphics device
  • scanouts defines output resolution
  • Suitable for full GUI Linux distributions

(21:02) Rosetta support is provided to Linux through directory sharing.

let rosettaDirectoryShare = try! VZLinuxRosettaDirectoryShare()
let directorySharingDevice = VZVirtioFileSystemDeviceConfiguration(tag: "RosettaShare")
directorySharingDevice.share = rosettaDirectoryShare

configuration.directorySharingDevices = [directorySharingDevice]

Key points:

  • VZLinuxRosettaDirectoryShare provides the Rosetta runtime
  • After mounting virtiofs in Linux, register binfmt
  • x86-64 Linux binaries can run in Apple Silicon Linux VMs

Core Takeaways

  • Isolated macOS regression test machines: Create a virtual Mac from a fixed restore image before each test, install the app, and run UI or compatibility tests. Good for release flows that need a clean system state.

  • Embed Linux toolchains in Mac developer apps: Launch GUI or CLI Linux with the Virtualization framework and access project files through shared directories. Users don’t need to manually configure full virtualization environments.

  • Reproducible lab environments for teaching: Course apps can create VMs with the same CPU, memory, disk, and Linux distribution in one tap. Student environments stay consistent; instructors troubleshoot more easily.

  • Run legacy x86-64 Linux tools: When research, EDA, or compiler toolchains ship old binaries, run them with Rosetta in Apple Silicon Linux VMs to reduce recompilation and tool replacement costs.

Comments

GitHub Issues · utterances