Skip to content

Instantly share code, notes, and snippets.

@KhaosT
Last active February 8, 2024 04:51
Show Gist options
  • Star 51 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save KhaosT/fb0499130bbfcb5754d2174e78cb68b9 to your computer and use it in GitHub Desktop.
Save KhaosT/fb0499130bbfcb5754d2174e78cb68b9 to your computer and use it in GitHub Desktop.
//
// ViewController.swift
// MacVM
//
// Created by Khaos Tian on 6/8/21.
//
import Cocoa
import Virtualization
class ViewController: NSViewController, VZVirtualMachineDelegate {
private var virtualMachine: VZVirtualMachine?
private var installer: VZMacOSInstaller?
override func loadView() {
let view = VZVirtualMachineView()
view.capturesSystemKeys = true
self.view = view
}
override func viewDidLoad() {
super.viewDidLoad()
let button = NSButton(
title: "Start",
target: self,
action: #selector(didTapStartButton(_:))
)
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate(
[
button.trailingAnchor.constraint(equalTo: view.trailingAnchor),
button.bottomAnchor.constraint(equalTo: view.bottomAnchor)
]
)
}
@objc
func didTapStartButton(_ sender: Any) {
startVM()
}
private func startVM() {
let restoreImageURL = URL(fileURLWithPath: "/Users/khaos/Downloads/UniversalMac_12.0_21A5268h_Restore.ipsw")
VZMacOSRestoreImage.load(from: restoreImageURL) { result in
switch result {
case .success(let image):
NSLog("Image: \(image)")
DispatchQueue.main.async {
self.setupVM(with: image)
}
case .failure(let error):
NSLog("Error: \(error)")
}
}
}
private func setupVM(with image: VZMacOSRestoreImage) {
guard let supportedConfig = image.mostFeaturefulSupportedConfiguration else {
NSLog("No supported config")
return
}
let bootloader = VZMacOSBootLoader()
let entropy = VZVirtioEntropyDeviceConfiguration()
let networkDevice = VZVirtioNetworkDeviceConfiguration()
networkDevice.attachment = VZNATNetworkDeviceAttachment()
let graphics = VZMacGraphicsDeviceConfiguration()
graphics.displays = [
VZMacGraphicsDisplayConfiguration(
widthInPixels: 2560,
heightInPixels: 1600,
pixelsPerInch: 220
)
]
let keyboard = VZUSBKeyboardConfiguration()
let pointingDevice = VZUSBScreenCoordinatePointingDeviceConfiguration()
var storages: [VZStorageDeviceConfiguration] = []
do {
let attachment = try VZDiskImageStorageDeviceAttachment(
url: URL(fileURLWithPath: "/Users/khaos/Downloads/vmdisk.dmg"),
readOnly: false
)
let storage = VZVirtioBlockDeviceConfiguration(attachment: attachment)
storages.append(storage)
} catch {
NSLog("Storage Error: \(error)")
}
let configuration = VZVirtualMachineConfiguration()
configuration.bootLoader = bootloader
let platform = VZMacPlatformConfiguration()
platform.hardwareModel = supportedConfig.hardwareModel
if let machineID = UserDefaults.standard.object(forKey: "machine_id") as? Data {
if let identifier = VZMacMachineIdentifier(dataRepresentation: machineID) {
platform.machineIdentifier = identifier
} else {
NSLog("Failed to recreate machine id")
}
} else {
UserDefaults.standard.set(
platform.machineIdentifier.dataRepresentation,
forKey: "machine_id"
)
}
if FileManager.default.fileExists(atPath: "/Users/khaos/Downloads/aux.img") {
platform.auxiliaryStorage = VZMacAuxiliaryStorage(
contentsOf: URL(fileURLWithPath: "/Users/khaos/Downloads/aux.img")
)
} else {
platform.auxiliaryStorage = try? VZMacAuxiliaryStorage(
creatingStorageAt: URL(fileURLWithPath: "/Users/khaos/Downloads/aux.img"),
hardwareModel: platform.hardwareModel,
options: []
)
}
configuration.platform = platform
configuration.cpuCount = 2
configuration.memorySize = 8 * 1024 * 1024 * 1024
configuration.entropyDevices = [entropy]
configuration.networkDevices = [networkDevice]
configuration.graphicsDevices = [graphics]
configuration.keyboards = [keyboard]
configuration.pointingDevices = [pointingDevice]
configuration.storageDevices = storages
do {
try configuration.validate()
let vm = VZVirtualMachine(configuration: configuration, queue: .main)
vm.delegate = self
if let view = view as? VZVirtualMachineView {
view.virtualMachine = vm
}
vm.start { result in
switch result {
case .success:
NSLog("Success")
case .failure(let error):
NSLog("Error: \(error)")
}
}
// let installer = VZMacOSInstaller(virtualMachine: vm, restoreImage: image)
// installer.install { result in
// switch result {
// case .success:
// NSLog("Success")
// case .failure(let error):
// NSLog("Error: \(error)")
// }
// }
self.virtualMachine = vm
// self.installer = installer
} catch {
NSLog("Error: \(error)")
}
}
func guestDidStop(_ virtualMachine: VZVirtualMachine) {
NSLog("DidStop")
}
func virtualMachine(_ virtualMachine: VZVirtualMachine, didStopWithError error: Error) {
NSLog("Stop with Error: \(error)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment