Hello,
We develop a sandboxed Mac App Store app that runs virtual machines with Virtualization.framework on Apple silicon (macOS 27). Users want to
install a macOS guest onto an external USB disk and start the VM from it, so they can keep a VM on portable storage or on a disk larger than the
Mac's internal drive.
What we tried
- USB passthrough: we attach the disk before the VM starts, with VZUSBPassthroughDeviceConfiguration (from an AAUSBAccessory) on a
VZXHCIControllerConfiguration.- Linux guests install onto the disk and boot from it without problems.
- For a macOS guest, VZMacOSInstaller fails to start when the USB disk is the only storage:
- As we understand it, a macOS VM can only start from its own storage devices, never from a USB device, so even a successful install would not
boot.
- VZDiskBlockDeviceStorageDeviceAttachment: this needs an open file handle to /dev/diskN. That requires admin rights, which a sandboxed app can't
obtain, so we can't use it in our App Store app.
Questions
- Is there a supported way to install a macOS guest onto an external USB disk and start the VM from it?
- Is there a sandbox-compatible way to get a VZDiskBlockDeviceStorageDeviceAttachment for an external disk, for example after user consent,
similar to how AccessoryAccess grants USB devices? - If neither is possible today, is support for this planned, or is there a recommended alternative?
Thank you for any guidance.
Thanks for the info.
I talked with some folks internally about this and, yeah, it’s pretty much what I said early. On Apple silicon there a strong connection between the internal and external drive, and that’s carried over to virtual Apple silicon.
I think you can resolve your specific issue by ignoring the VM side of this and just creating a bootable installer. See Create a bootable installer for macOS.
As to the users requesting this, my advice is that collect use cases from them and decide whether they’re worth sending it to Feedback Assistant.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"