From bbfacf872c8e053f56a81940829d427c311e1f5d Mon Sep 17 00:00:00 2001 From: osy <50960678+osy@users.noreply.github.com> Date: Sun, 5 Mar 2023 20:51:53 -0800 Subject: [PATCH] registry: save bookmark to IPSW installer This should allow moved VMs to retain the installer IPSW as well as when UTM is quit and re-opened before an installation is completed. Resolves #4938 --- Managers/UTMAppleVirtualMachine.swift | 16 +++++++++++++--- Managers/UTMRegistryEntry.swift | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Managers/UTMAppleVirtualMachine.swift b/Managers/UTMAppleVirtualMachine.swift index 15d63f158..788bfd8cf 100644 --- a/Managers/UTMAppleVirtualMachine.swift +++ b/Managers/UTMAppleVirtualMachine.swift @@ -72,9 +72,6 @@ import Virtualization let oldConfig = appleConfig config = UTMConfigurationWrapper(wrapping: newConfig) updateConfigFromRegistry() - if #available(macOS 12, *) { - newConfig.system.boot.macRecoveryIpswURL = oldConfig.system.boot.macRecoveryIpswURL - } } override func accessShortcut() async throws { @@ -320,6 +317,10 @@ import Virtualization } changeState(.vmStarting) do { + _ = ipswUrl.startAccessingSecurityScopedResource() + defer { + ipswUrl.stopAccessingSecurityScopedResource() + } try await createAppleVM() #if os(macOS) && arch(arm64) try await withCheckedThrowingContinuation { (continuation: CheckedContinuation) in @@ -502,6 +503,12 @@ extension UTMAppleVirtualMachine { registryEntry.externalDrives = registryEntry.externalDrives.filter({ element in configDrives.contains(where: { $0.id == element.key && $0.isExternal }) }) + // save IPSW reference + if let url = appleConfig.system.boot.macRecoveryIpswURL { + _ = url.startAccessingSecurityScopedResource() + registryEntry.macRecoveryIpsw = try UTMRegistryEntry.File(url: url, isReadOnly: true) + url.stopAccessingSecurityScopedResource() + } } @MainActor override func updateConfigFromRegistry() { @@ -513,5 +520,8 @@ extension UTMAppleVirtualMachine { appleConfig.drives[i].imageURL = registryEntry.externalDrives[id]?.url } } + if let file = registryEntry.macRecoveryIpsw { + appleConfig.system.boot.macRecoveryIpswURL = file.url + } } } diff --git a/Managers/UTMRegistryEntry.swift b/Managers/UTMRegistryEntry.swift index 98d558adb..217a0f6ec 100644 --- a/Managers/UTMRegistryEntry.swift +++ b/Managers/UTMRegistryEntry.swift @@ -35,6 +35,8 @@ import Foundation @Published private var _hasMigratedConfig: Bool + @Published private var _macRecoveryIpsw: File? + private enum CodingKeys: String, CodingKey { case name = "Name" case package = "Package" @@ -45,6 +47,7 @@ import Foundation case windowSettings = "WindowSettings" case terminalSettings = "TerminalSettings" case hasMigratedConfig = "MigratedConfig" + case macRecoveryIpsw = "MacRecoveryIpsw" } init(newFrom vm: UTMVirtualMachine) { @@ -77,6 +80,7 @@ import Foundation _windowSettings = try container.decode([Int: Window].self, forKey: .windowSettings) _terminalSettings = try container.decodeIfPresent([Int: Terminal].self, forKey: .terminalSettings) ?? [:] _hasMigratedConfig = try container.decodeIfPresent(Bool.self, forKey: .hasMigratedConfig) ?? false + _macRecoveryIpsw = try container.decodeIfPresent(File.self, forKey: .macRecoveryIpsw) } func encode(to encoder: Encoder) throws { @@ -92,6 +96,7 @@ import Foundation if _hasMigratedConfig { try container.encode(_hasMigratedConfig, forKey: .hasMigratedConfig) } + try container.encodeIfPresent(_macRecoveryIpsw, forKey: .macRecoveryIpsw) } func asDictionary() throws -> [String: Any] { @@ -195,6 +200,16 @@ extension UTMRegistryEntryDecodable { } } + var macRecoveryIpsw: File? { + get { + _macRecoveryIpsw + } + + set { + _macRecoveryIpsw = newValue + } + } + func setExternalDrive(_ file: File, forId id: String) { externalDrives[id] = file }