Mac Operations

Apple Silicon macOS Guest Virtualization Updates, June 2022

It’s been eight months since I published a post with some early experiments and digging into the capabilities of Apple’s new macOS guest VM support on Apple Silicon as of Monterey.

Since then, we’ve seen:

As with the previous post, since my interest in macOS virtualization is always in the context of continuous integration and ephemeral build/test environments, this article is framed around that particular use case. Let’s dive in!

Updated documentation

Apple updated their documentation in early 2022 to include a fully-functional sample Xcode project. Having a working example directly from Apple is nice because:

New support in multiple virtualization products/projects

At the time of the last post, Parallels was the only commercial product which had already shipped basic macOS guest support on Apple Silicon using the new API features. I’m not sure we’ve seen notable improvements from them since, or any new developments from VMware Fusion.

But, we have seen many other products and open source projects adopting this framework! We’ll go through some here:

Anka

In late October, Veertu announced a preview of their 3.0 version of Anka, their hypervisor and CI/CD tooling product, which uses the new framework on Apple Silicon, and several months later the 3.0 version reached a GA release. It already offers an impressive amount of parity with the existing featureset of the Intel-based version:

Both bridged and shared network interfaces are possible. Since Anka was also designed to offer a similar user experience as Docker, it also has the notion of layered images. Given how large macOS CI images need to be (30GB+ with one Xcode version), the possibility to have a base image shared across multiple different image variants makes better space optimization possible.

UTM

UTM is an established open-source virtualization project for macOS and iOS to enable “traditional” virtualization of PC hardware and guest OSes based on Qemu. In the 3.0 release, support for macOS guest VMs on Apple Silicon using the Virtualization framework was added. It “just works” in the same way as with Parallels, but the GUI interface actually allows for more configuration, such as using both shared (NAT-based) and bridged network interfaces. UTM is under active development.

One notable new feature in the 3.2.4 version released in May is that is can run a VM “disposably,” where changes are only written to an ephemeral disk device that is discarded when the VM is stopped. There is a PR open adding this functionality to macOS VMs, where the new VM disk is copied using NSFileManager’s default APIs and are expected to result in an APFS clone operation under the hood (so that the VM’s disk is cloned without needing to actually duplicate block data on underlying storage.)

As far as I’m aware, UTM doesn’t yet offer a command-line interface for managing the VMs.

Tart

In early May, CirrusLabs open-sourced Tart, a CLI-based tool for Apple Silicon VMs specifically for the CI use-case. Currently this comprises:

Much like the other solutions above, it’s in active development.

MacStadium Orka 2.0

MacStadium’s Orka product now in their 2.0 version supports Apple Silicon using the Virtualization framework in a “beta” state. Their documentation lists some of the known limitations where Apple Silicon VMs aren’t at parity with the Intel-based platform images.

VirtualApple

An open-source project by Saagar Jha was published after the previous article. What was particularly cool about this project at the time he released it, was that via a Framework-internal API it allows explicitly configuring a VM to boot to DFU or to the Recovery environment (which allows us to reconfigure security settings such as System Integrity Protection, for example), and also to boot to earlier phases of the boot process and attach a debugger. Tart also borrowed the same internal API to offer --recovery as a startup option for VMs.

Notably, the macOS 13 beta documentation for Virtualization indicates there’s a new VZMacOSVirtualMachineStartOptions subclass with a single property: startUpFromMacOSRecovery. This means there is now a public API for booting the VM into the recovery environment, new in macOS Ventura.

New APIs in macOS Ventura

With WWDC week having just ended, Apple’s published a dedicated video session on the Virtualization framework, including some of the new features intended for supporting Linux guest VMs.

Apple’s documentation delta viewer is a nice way to see all the modifications. There’s a lot changed:

What’s left?

From talking with others interested in this framework, some other desired features tend to come up in conversation:

Support for Automated Device Enrolment testing

Macs owned by an organization often provision them for staff via Automated Device Enrolment, whereby a Mac comes online and is able to automatically enroll into the organization’s MDM by association through Apple Business (or School) Manager. Administrators routinely need to perform end-to-end testing of this enrollment process, and typically have several test machines expressly dedicated for this purpose. But, this requires more physical machines that need a desk, power, network connectivity and peripherals, and may also be more difficult to intentionally reset to a known baseline state. (Erase all Contents and Settings in Monterey makes this situation better).

With Intel-based VMs, administrators have for years been able to override/hardcode the serial number of the VM to mimic a serial number of a physical Mac, and this has allows them to emulate much of the same machine bootstrapping process on their own machines (in a VM) for development and testing purposes.

Many folks have expressed interest in being able to do the same using this new generation of VMs. Some have expressed this in the form of “I’d like to be able to set my VM’s serial number,” although the end goal is for it to be possible for an Apple Silicon VM to be able to behave as a physical machine would when it performs its initial provisioning and is associated with an MDM endpoint in Apple’s DEP environment.

Apple folks, I’m aware of at least these FBs from companies interested in this: FB9947609, FB9948459, FB10025718, FB10026549, FB10027549, FB10076121.

Snapshots

When users refer to snapshots as a functionality of a hypervisor, they may be referring to at least one of:

I think we see already there’s some OS-level primitives of how to do the first one. Qemu QCOW2 disk formats offer this with the notion of a “backing file,” where one base disk image can be used for all reads and all writes are directed to a new disk image (which could, for example, be discarded, as in the above-linked new feature in UTM). APFS file cloning allows us to make an independent “lazy” copy of the file that would change only once a new VM has been booted using that new cloned file. There’s a slight caveat there that APFS cloning requires the source and destination to be part of the same logical volume.

A dedicated API for snapshots of the entire VM state including some or all of the above could certainly be interesting, as this is historically something that commercial hypervisor products have had to provide themselves.

Wrap-up

To wrap up, a few other thoughts and addenda that don’t fit above, but are worth mentioning and thinking about as we see the first major iteration on this framework from Apple:

CacaoCast

CacaoCast, a French (both as-in of France and as-in Canadian!) podcast about Mac and Apple development, discussed macOS VMs for a few episodes and gave a shout-out to the previous post in their episode here. Merci les gars!

Continued development for cloud-native use-cases

Will we see Xcode Cloud begin to use environments powered by Apple Silicon-based VMs? It seems they currently use commodity Xeon hardware to power these VMs, which must also afford a much higher VM-per-host density than the allowed 2 (as per the EULA and as is enforced for consumers of the new framework APIs). At some point we won’t be seeing Intel-based OSes in use at all, but will we begin to see ARM-based macOS VMs possible on commodity hardware as we have seen done on Qemu/KVM for many years?

Host-guest OS independence

One of the wins of using virtualization for server workloads is that the system OS version used to run tasks can be decoupled from the OS version running on the underlying hosts. For example, today in order to test and validate a new beta OS and its tools, iOS simulators, automation, etc. on a “bare-metal” macOS installation, I need to upgrade a small segment of my Mac CI machines to that beta OS, and lose some capacity in the meantime. I should (in theory) be able to instead just build a new image of the beta OS and selectively run it on certain workloads, allowing me to reserve my full capacity for regular use, and then gradually upgrade hosts to newer macOS versions at my convenience.

But, as much of the macOS VM support in this framework is delivered by paravirtualized VirtIO drivers, there is some more tight coupling still to the hosts. For example, we can see renderer communication and version negotiation information in the OS log in this example of a Montery 12.4 host and a Ventura 13.0 (beta 1) GPU client:

com.apple.Virtualization.VirtualMachine: (ParavirtualizedGraphics) [com.apple.gpusw.ParavirtualizedGraphics:renderer] Guest requested binary version: 43, setting binary version to: 31

We can see from the API docs that certain VM functionality will be supported only with newer macOS host versions, as they rely on functionality provided by the host’s paravirtualization support. It is also possible that we also observe different performance or bugs. For example, while today I can successfully boot and run UI tests in an iOS 16 simulator in a Monterey VM running Xcode 14 (on a Monterey host), I can’t do the same in Ventura VM (beta 1, mind) on the same Monterey host. I do have success doing the same on a Ventura host.

All this being said, I was never able to get a macOS Ventura beta VM up and running faster than this year’s WWDC. Previously, there would be some fumbling with VMware Fusion and some tribal knowledge shared around on forums for either how to get the new beta OS to boot, or simply how to upgrade an existing VM to the new beta version, and there’d often be odd performance or UI bugs that might never be addressed. This year, with a built copy of Apple’s sample documentation project and the IPSW I’d downloaded from the developer portal, I was running through Ventura’s Setup Assistant in a VM in under 5 minutes. It took longer for me to download the OS image than to install it and boot into a new functioning VM. A huge 👏 to everyone at Apple who has worked on the underlying functionality that makes this possible.

Performance parity

Having much of this VM functionality “hinged” on Apple’s API implementation and host/guest OS support in some ways introduces some restrictions (the API’s implementation is private). The upside however – besides this excellent integration and driver acceleration at the OS level – is that virtualization projects (both commercial and open-source) can differentiate on things other than the hypervisor performance or grahpics acceleration: development/testing workflows, custom host<->guest integrations, user interface, etc. We see this already in some of the different tools I’ve outlined above.

I can download Apple’s sample documentation project, compile it and expect the same baseline performance as with commercial offerings, and this hasn’t been possible before. As I mentioned earlier, this also makes it possible to partner with Apple engineering on virtualization support in general, reproducing issues in feedback, etc. in a way that was difficult in the prior time of having no official macOS guest VM support APIs from Apple.