-
Expand the capabilities of your Virtualization app
Bring powerful new capabilities in macOS 27 to your Virtualization app. Discover how to automate the setup of macOS guests through user account setup on first boot. We'll explore advanced workflows that involve passthrough of USB accessories to virtual machines, as well as custom network topologies and port forwarding. You'll also learn about recent improvements that can enrich the experience of running your app's virtual machines.
Chapters
- 0:01 - Introduction
- 1:04 - macOS guest provisioning
- 4:34 - Accessory Access
- 8:26 - Advanced network topologies
- 11:35 - DiskImageKit
- 15:57 - Custom Virtio
Resources
Related Videos
WWDC26
-
Search this video…
-
-
1:57 - Provision a macOS guest
import Virtualization let provisioningOptions = VZMacGuestProvisioningOptions() provisioningOptions.fullName = fullName provisioningOptions.username = username provisioningOptions.password = password provisioningOptions.logsInAutomatically = true provisioningOptions.enablesRemoteLogin = true let startOptions = VZMacOSVirtualMachineStartOptions() try startOptions.setGuestProvisioning(provisioningOptions) try await virtualMachine.start(options: startOptions) -
7:12 - Register an Accessory Access listener
import AccessoryAccess let criteria: [AAUSBAccessoryMatchingCriteria] = [] let accessories = try await AAUSBAccessoryManager.shared.registerListener(self, matchingCriteria: criteria) for accessory in accessories { // Handle previously attached accessories. } -
7:39 - Respond to USB accessory connection
import AccessoryAccess import Virtualization class AccessoryListener: NSObject, AAUSBAccessoryListener { func usbAccessoryDidConnect(_ usbAccessory: AAUSBAccessory) { virtualMachine.queue.async { do { let configuration = VZUSBPassthroughDeviceConfiguration(device: usbAccessory) let device = try VZUSBPassthroughDevice(configuration: configuration) self.virtualMachine.usbControllers.first?.attach(device: device) { error in // Handle error if necessary... } } catch { // Handle error... } } } } -
10:04 - Create a custom vmnet network
import Virtualization import vmnet var status: vmnet_return_t = .VMNET_FAILURE guard let networkConfiguration = vmnet_network_configuration_create(.VMNET_SHARED_MODE, &status) else { ... } guard let network = vmnet_network_create(networkConfiguration, &status) else { ... } let attachment = VZVmnetNetworkDeviceAttachment(network: network) let networkDeviceConfiguration = VZVirtioNetworkDeviceConfiguration() networkDeviceConfiguration.attachment = attachment virtualMachineConfiguration.networkDevices = [networkDeviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
14:54 - Use DiskImageKit with Virtualization
import DiskImageKit import Virtualization let baseImage = try DiskImage(opening: .open(url: baseLayerURL, mode: .readOnly)) let cacheImage = try baseImage.appending(.asifLayer(url: cacheLayerURL, type: .cache)) let overlayImage = try DiskImage(opening: .open(url: overlayLayerURL)) let stackedImage = try cacheImage.appending(overlayImage) let storageDeviceAttachment = try VZDiskImageStorageDeviceAttachment(diskImage: stackedImage) let storageDeviceConfiguration = VZVirtioBlockDeviceConfiguration(attachment: storageDeviceAttachment) virtualMachineConfiguration.storageDevices = [storageDeviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
17:41 - Configure a custom Virtio device
import Virtualization let deviceConfiguration = VZCustomVirtioDeviceConfiguration() // Virtio entropy device. deviceConfiguration.deviceID = 4 // PCI class for crypto devices. deviceConfiguration.pciClassID = 0x10 // PCI subclass for network and computing encryption controllers. deviceConfiguration.pciSubclassID = 0x00 // An entropy device uses a single Virtio queue. deviceConfiguration.virtioQueueCount = 1 deviceConfiguration.provider = VZCustomVirtioDeviceDelegateProvider(deviceQueue: deviceQueue, delegate: provider) virtualMachineConfiguration.customVirtioDevices = [deviceConfiguration] let virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration) -
18:20 - Attach a delegate to a VZCustomVirtioDevice
import Virtualization class DeviceConfigurationDelegate: NSObject, VZCustomVirtioDeviceConfigurationDelegate { func customVirtioConfiguration(_ deviceConfiguration: VZCustomVirtioDeviceConfiguration, didCreateDevice device: VZCustomVirtioDevice) { device.delegate = deviceDelegate self.device = device } } -
18:42 - Process Virtio queue elements
import Virtualization class DeviceDelegate: NSObject, VZCustomVirtioDeviceDelegate { func customVirtioDevice(_ device: VZCustomVirtioDevice, didReceiveNotificationFor queue: VZVirtioQueue) { while let element = queue.nextElement() { // Process element... element.returnToQueue() } } }
-
-
- 0:01 - Introduction
The advanced Virtualization capabilities ahead — automating Virtual Mac setup, attaching USB devices with the Accessory Access framework, configuring advanced networking, creating disk images with DiskImageKit, and building custom Virtio devices.
- 1:04 - macOS guest provisioning
Automate the provisioning of user accounts in Setup Assistant for virtual Macs. Use the VZMacGuestProvisioningOptions API to set credentials and enable features like auto-login and SSH on first boot.
- 4:34 - Accessory Access
Pass through USB accessories directly into virtual machines using the Accessory Access framework. This approach gives people explicit control over which physical devices, such as external drives, are passed through to the virtual machine.
- 8:26 - Advanced network topologies
Configure complex network topologies by integrating the vmnet framework with Virtualization. You can create custom network architectures that define exactly how multiple virtual machines interact with each other and the host.
- 11:35 - DiskImageKit
DiskImageKit is a new framework in macOS 27 designed for managing high-performance, space-efficient disk images. You can use layered disk images, including base layers, cache layers, and overlay layers, to share data efficiently across multiple virtual machines.
- 15:57 - Custom Virtio
Define and implement custom paravirtualized devices using the industry-standard Virtio protocol. By using the VZCustomVirtioDevice API, you can enable specialized, high-performance communication between the host and custom drivers running in the virtual machine.