Files
luma/Sources/LumaCore/VirtualMachines/Virtualization/VirtualizationBackend.swift
Ole André Vadla Ravnås cfc7a1d960 core: Build the macOS guest on arm64 only
Virtualization's macOS-guest API is not there on Intel.
2026-09-10 21:41:04 +02:00

108 lines
3.6 KiB
Swift

import Foundation
#if canImport(Virtualization)
import Virtualization
@MainActor
public final class VirtualizationBackend: VirtualMachineBackend {
public let id = "virtualization"
public let name = "Virtualization"
public init() {
}
public var templates: [VirtualMachineTemplate] {
[
VirtualMachineTemplate(
id: VirtualizationTemplate.macOS,
backendID: id,
name: "macOS",
summary: """
A macOS guest run by Virtualization.framework. The first boot installs it from a restore image, \
which takes a while; every boot after that starts what was installed. Frida injects the xnu agent \
into its kernel.
""",
iconName: "xnu",
operatingSystem: .macOS,
architecture: .arm64,
agentFlavor: .xnuArm64,
parameters: [
VirtualMachineParameter(
id: VirtualizationParameter.restoreImage,
name: "Restore image",
kind: .filePath(extensions: ["ipsw"])
),
VirtualMachineParameter(
id: VirtualizationParameter.diskSize,
name: "Disk",
kind: .number(default: 64, min: 32, max: 2048, unit: "GB")
),
VirtualMachineParameter(
id: VirtualizationParameter.memory,
name: "Memory",
kind: .number(default: 8192, min: 2048, max: 65536, unit: "MB")
),
VirtualMachineParameter(
id: VirtualizationParameter.processors,
name: "Processors",
kind: .number(default: 4, min: 1, max: 16, unit: nil)
),
]
),
]
}
public func availability(for template: VirtualMachineTemplate) -> VirtualMachineAvailability {
guard #available(macOS 13, *) else {
return .unavailable(reason: "A virtual machine of this kind needs macOS 13 or newer")
}
guard isAppleSilicon else {
return .unavailable(reason: "Virtualization.framework runs Apple silicon guests only")
}
return .available
}
public func launch(_ request: VirtualMachineLaunchRequest) async throws -> any VirtualMachine {
guard #available(macOS 13, *) else {
throw VirtualMachineError.launchFailed(reason: "A macOS guest needs macOS 13 or newer")
}
#if arch(arm64)
let machine = VirtualizationMachine(request: request)
try await machine.start()
return machine
#else
throw VirtualMachineError.launchFailed(reason: "Virtualization.framework runs Apple silicon guests only")
#endif
}
private var isAppleSilicon: Bool {
#if arch(arm64)
return true
#else
return false
#endif
}
}
enum VirtualizationTemplate {
static let macOS = "virtualization.macos"
static let linux = "virtualization.linux"
}
enum VirtualizationParameter {
static let restoreImage = "restore-image"
static let kernel = "kernel"
static let ramdisk = "ramdisk"
static let disk = "disk"
static let symbols = "symbols"
static let commandLine = "command-line"
static let diskSize = "disk-size"
static let memory = "memory"
static let processors = "processors"
}
#endif