Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for legacy ISOs on Apple Silicon #106

Closed
15 changes: 15 additions & 0 deletions Mist/Helpers/Codesigner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,19 @@ enum Codesigner {
throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError)
}
}

/// Ad-hoc signs the file at the provided URL.
///
/// - Parameters:
/// - url: The URL of the file to ad-hoc sign.
///
/// - Throws: A `MistError` if the command failed to execute.
static func adhocSign(_ url: URL) async throws {
let arguments: [String] = ["codesign", "--sign", "-", "--force", url.path]
let response: HelperToolCommandResponse = try ShellExecutor.shared.execute(arguments)

guard response.terminationStatus == 0 else {
throw MistError.invalidTerminationStatus(status: response.terminationStatus, output: response.standardOutput, error: response.standardError)
}
}
}
14 changes: 14 additions & 0 deletions Mist/Helpers/TaskManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,13 @@ class TaskManager: ObservableObject {
try await DiskImageMounter.mount(temporaryImageURL, mountPoint: installer.temporaryISOMountPointURL)
},
MistTask(type: .create, description: "macOS Installer in temporary Disk Image") {
// Workaround to make OS X Yosemite 10.10 to macOS Catalina 10.15 createinstallmedia work on Apple Silicon
if
let architecture: Architecture = Hardware.architecture,
architecture == .appleSilicon, !installer.bigSurOrNewer {
try await Codesigner.adhocSign(createInstallMediaURL)
}

// Workaround to make macOS Sierra 10.12 createinstallmedia work
if installer.version.hasPrefix("10.12") {
let infoPlistURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Info.plist")
Expand Down Expand Up @@ -563,6 +570,13 @@ class TaskManager: ObservableObject {
let mountPointURL: URL = .init(fileURLWithPath: volume.path)
let tasks: [MistTask] = [
MistTask(type: .create, description: "Bootable Installer") {
// Workaround to make OS X Yosemite 10.10 to macOS Catalina 10.15 createinstallmedia work on Apple Silicon
if
let architecture: Architecture = Hardware.architecture,
architecture == .appleSilicon, !installer.bigSurOrNewer {
try await Codesigner.adhocSign(createInstallMediaURL)
}

// Workaround to make macOS Sierra 10.12 createinstallmedia work
if installer.version.hasPrefix("10.12") {
let infoPlistURL: URL = installer.temporaryInstallerURL.appendingPathComponent("Contents/Info.plist")
Expand Down
22 changes: 1 addition & 21 deletions Mist/Views/List/InstallerExportView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ struct InstallerExportView: View {
private var exportPackage: Bool = false
var installer: Installer
@Binding var exports: [InstallerExportType]
private var isoCompatible: Bool {
guard let architecture: Architecture = Hardware.architecture else {
return false
}

return architecture == .intel || (architecture == .appleSilicon && installer.bigSurOrNewer)
}

private var compatibilityMessage: String {
"**Note:** ISOs are unavailable for building **macOS Catalina 10.15 and older** on [Apple Silicon Macs](https://support.apple.com/en-us/HT211814)."
}

var body: some View {
VStack {
Expand All @@ -41,16 +30,11 @@ struct InstallerExportView: View {
InstallerExportViewItem(exportType: .diskImage, selected: $exportDiskImage)
.disabled(exports.count == 1 && exportDiskImage)
InstallerExportViewItem(exportType: .iso, selected: $exportISO)
.disabled(isoCompatible ? exports.count == 1 && exportISO : true)
.opacity(isoCompatible ? 1 : 0.5)
.disabled(exports.count == 1 && exportISO)
InstallerExportViewItem(exportType: .package, selected: $exportPackage)
.disabled(exports.count == 1 && exportPackage)
Spacer()
}
if !isoCompatible {
Text(.init(compatibilityMessage))
.padding(.top)
}
}
.padding()
.onChange(of: exportApplication) { _ in
Expand All @@ -73,10 +57,6 @@ struct InstallerExportView: View {
private func updateExports() {
var exports: [InstallerExportType] = []

if !isoCompatible, exportISO {
exportISO = false
}

if !exportApplication, !exportDiskImage, !exportISO, !exportPackage {
exportApplication = true
}
Expand Down
5 changes: 1 addition & 4 deletions Mist/Views/List/ListRowInstaller.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ struct ListRowInstaller: View {
}

var body: some View {
// swiftlint:disable:next closure_body_length
HStack {
ListRowDetail(
imageName: installer.imageName,
Expand All @@ -92,9 +91,7 @@ struct ListRowInstaller: View {
}
.help("Download and export macOS Installer")
.buttonStyle(.mistAction)
if
let architecture: Architecture = Hardware.architecture,
(architecture == .appleSilicon && installer.bigSurOrNewer) || (architecture == .intel && installer.mavericksOrNewer) {
if installer.mavericksOrNewer {
Button {
pressButton(.volumeSelection)
} label: {
Expand Down
2 changes: 1 addition & 1 deletion Mist/Views/Settings/SettingsISOsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct SettingsISOsView: View {
private let imageName: String = "ISO"
private let title: String = "ISOs"
// swiftlint:disable:next line_length
private let description: String = "ISOs are Bootable macOS Installer Disk Images that can be restored on external USB drives, or used with virtualization software (ie. [Parallels Desktop](https://www.parallels.com/au/products/desktop/), [UTM](https://mac.getutm.app), [VMware Fusion](https://www.vmware.com/au/products/fusion.html), [VirtualBox](https://www.virtualbox.org)).\n\n**Note:** ISOs are unavailable for building **macOS Catalina 10.15 and older** on [Apple Silicon Macs](https://support.apple.com/en-us/HT211814)."
private let description: String = "ISOs are Bootable macOS Installer Disk Images that can be restored on external USB drives, or used with virtualization software (ie. [Parallels Desktop](https://www.parallels.com/au/products/desktop/), [UTM](https://mac.getutm.app), [VMware Fusion](https://www.vmware.com/au/products/fusion.html), [VirtualBox](https://www.virtualbox.org))."

var body: some View {
VStack(alignment: .leading) {
Expand Down
Loading