diff --git a/.goreleaser.yml b/.goreleaser.yml index 3549e31..c04e735 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -45,7 +45,7 @@ brews: libexec.install Dir["*"] bin.write_exec_script "#{libexec}/tart.app/Contents/MacOS/tart" custom_block: | - depends_on :macos => :monterey + depends_on :macos => :ventura on_macos do unless Hardware::CPU.arm? diff --git a/Package.swift b/Package.swift index fc65808..c632f89 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Tart", platforms: [ - .macOS(.v12) + .macOS(.v13) ], products: [ .executable(name: "tart", targets: ["tart"]) diff --git a/README.md b/README.md index 03a3da0..3a9faf0 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Many more companies are using Tart in their internal setups. Here are a few of t ## Usage -Try running a Tart VM on your Apple Silicon device running macOS 12.0 (Monterey) or later (will download a 25 GB image): +Try running a Tart VM on your Apple Silicon device running macOS 13.0 (Ventura) or later (will download a 25 GB image): ```bash brew install cirruslabs/cli/tart diff --git a/Sources/tart/Commands/Create.swift b/Sources/tart/Commands/Create.swift index ab1c487..69930e6 100644 --- a/Sources/tart/Commands/Create.swift +++ b/Sources/tart/Commands/Create.swift @@ -47,11 +47,7 @@ struct Create: AsyncParsableCommand { } if linux { - if #available(macOS 13, *) { - _ = try await VM.linux(vmDir: tmpVMDir, diskSizeGB: diskSize) - } else { - throw UnsupportedOSError("Linux VMs", "are") - } + _ = try await VM.linux(vmDir: tmpVMDir, diskSizeGB: diskSize) } try VMStorageLocal().move(name, from: tmpVMDir) diff --git a/Sources/tart/Credentials/DockerConfigCredentialsProvider.swift b/Sources/tart/Credentials/DockerConfigCredentialsProvider.swift index 4c9a4fa..e510282 100644 --- a/Sources/tart/Credentials/DockerConfigCredentialsProvider.swift +++ b/Sources/tart/Credentials/DockerConfigCredentialsProvider.swift @@ -11,14 +11,10 @@ class DockerConfigCredentialsProvider: CredentialsProvider { if let credentialsFromAuth = config.auths?[host]?.decodeCredentials() { return credentialsFromAuth } - if let helperProgram = config.credHelpers?[host] { + if let helperProgram = try config.findCredHelper(host: host) { return try executeHelper(binaryName: "docker-credential-\(helperProgram)", host: host) } - if let defaultCredsStore = config.credsStore { - return try executeHelper(binaryName: "docker-credential-\(defaultCredsStore)", host: host) - } - return nil } @@ -63,7 +59,26 @@ class DockerConfigCredentialsProvider: CredentialsProvider { struct DockerConfig: Codable { var auths: Dictionary? = Dictionary() var credHelpers: Dictionary? = Dictionary() - var credsStore: String? = nil + + func findCredHelper(host: String) throws -> String? { + // Tart supports wildcards in credHelpers + // Similar to what is requested from Docker: https://github.com/docker/cli/issues/2928 + + guard let credHelpers else { + return nil + } + + for (hostPattern, helperProgram) in credHelpers { + if (hostPattern == host) { + return helperProgram + } + let compiledPattern = try? Regex(hostPattern) + if (try compiledPattern?.wholeMatch(in: host) != nil) { + return helperProgram + } + } + return nil + } } struct DockerAuthConfig: Codable { diff --git a/Sources/tart/Platform/Darwin.swift b/Sources/tart/Platform/Darwin.swift index 59b4ef1..bcb9739 100644 --- a/Sources/tart/Platform/Darwin.swift +++ b/Sources/tart/Platform/Darwin.swift @@ -116,19 +116,11 @@ struct Darwin: PlatformSuspendable { } func pointingDevices() -> [VZPointingDeviceConfiguration] { - if #available(macOS 13, *) { - // Trackpad is only supported by guests starting with macOS Ventura - return [VZMacTrackpadConfiguration(), VZUSBScreenCoordinatePointingDeviceConfiguration()] - } else { - return [VZUSBScreenCoordinatePointingDeviceConfiguration()] - } + // Trackpad is only supported by guests starting with macOS Ventura + [VZMacTrackpadConfiguration(), VZUSBScreenCoordinatePointingDeviceConfiguration()] } func pointingDevicesSuspendable() -> [VZPointingDeviceConfiguration] { - if #available(macOS 13, *) { - return [VZMacTrackpadConfiguration()] - } else { - return [] - } + [VZMacTrackpadConfiguration()] } } diff --git a/Sources/tart/VM.swift b/Sources/tart/VM.swift index 038f03f..51ba2fb 100644 --- a/Sources/tart/VM.swift +++ b/Sources/tart/VM.swift @@ -253,15 +253,9 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject { @MainActor private func start(_ recovery: Bool) async throws { - if #available(macOS 13, *) { - // new API introduced in Ventura - let startOptions = VZMacOSVirtualMachineStartOptions() - startOptions.startUpFromMacOSRecovery = recovery - try await virtualMachine.start(options: startOptions) - } else { - // use method that also available on Monterey - try await virtualMachine.start(recovery) - } + let startOptions = VZMacOSVirtualMachineStartOptions() + startOptions.startUpFromMacOSRecovery = recovery + try await virtualMachine.start(options: startOptions) } @MainActor @@ -324,13 +318,15 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject { let vio = VZVirtioNetworkDeviceConfiguration() vio.attachment = $0 vio.macAddress = vmConfig.macAddress - return vio + return vio } // Storage var attachments = [try VZDiskImageStorageDeviceAttachment(url: diskURL, readOnly: false)] attachments.append(contentsOf: additionalDiskAttachments) - configuration.storageDevices = attachments.map { VZVirtioBlockDeviceConfiguration(attachment: $0) } + configuration.storageDevices = attachments.map { + VZVirtioBlockDeviceConfiguration(attachment: $0) + } // Entropy if !suspendable { @@ -347,15 +343,13 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject { // // A dummy console device useful for implementing // host feature checks in the guest agent software. - if #available(macOS 13, *) { - let consolePort = VZVirtioConsolePortConfiguration() - consolePort.name = "tart-version-\(CI.version)" + let consolePort = VZVirtioConsolePortConfiguration() + consolePort.name = "tart-version-\(CI.version)" - let consoleDevice = VZVirtioConsoleDeviceConfiguration() - consoleDevice.ports[0] = consolePort + let consoleDevice = VZVirtioConsoleDeviceConfiguration() + consoleDevice.ports[0] = consolePort - configuration.consoleDevices.append(consoleDevice) - } + configuration.consoleDevices.append(consoleDevice) try configuration.validate() diff --git a/Sources/tart/VMConfig.swift b/Sources/tart/VMConfig.swift index f8a8e0b..0ff2480 100644 --- a/Sources/tart/VMConfig.swift +++ b/Sources/tart/VMConfig.swift @@ -97,11 +97,7 @@ struct VMConfig: Codable { case .darwin: platform = try Darwin(from: decoder) case .linux: - if #available(macOS 13, *) { - platform = try Linux(from: decoder) - } else { - throw UnsupportedOSError("Linux VMs", "are") - } + platform = try Linux(from: decoder) } cpuCountMin = try container.decode(Int.self, forKey: .cpuCountMin) cpuCount = try container.decode(Int.self, forKey: .cpuCount) diff --git a/Tests/TartTests/DockerConfigTests.swift b/Tests/TartTests/DockerConfigTests.swift new file mode 100644 index 0000000..77aaf60 --- /dev/null +++ b/Tests/TartTests/DockerConfigTests.swift @@ -0,0 +1,16 @@ +import XCTest +@testable import tart + +final class DockerConfigTests: XCTestCase { + func testHelpers() throws { + let config = DockerConfig(credHelpers: [ + "(.*).dkr.ecr.(.*).amazonaws.com": "ecr-login", + "gcr.io": "gcloud" + ]) + + XCTAssertEqual(try config.findCredHelper(host: "gcr.io"), "gcloud") + XCTAssertEqual(try config.findCredHelper(host: "123.dkr.ecr.eu-west-1.amazonaws.com"), "ecr-login") + XCTAssertEqual(try config.findCredHelper(host: "456.dkr.ecr.us-east-1.amazonaws.com"), "ecr-login") + XCTAssertNil(try config.findCredHelper(host: "ghcr.io")) + } +} diff --git a/docs/integrations/cirrus-cli.md b/docs/integrations/cirrus-cli.md index c20d885..89670e4 100644 --- a/docs/integrations/cirrus-cli.md +++ b/docs/integrations/cirrus-cli.md @@ -13,7 +13,7 @@ task: name: hello macos_instance: # can be a remote or a local virtual machine - image: ghcr.io/cirruslabs/macos-monterey-base:latest + image: ghcr.io/cirruslabs/macos-ventura-base:latest hello_script: - echo "Hello from within a Tart VM!" - echo "Here is my CPU info:" @@ -45,7 +45,7 @@ exposes it via [`artifacts` instruction](https://cirrus-ci.org/guide/writing-tas task: name: Build macos_instance: - image: ghcr.io/cirruslabs/macos-monterey-xcode:latest + image: ghcr.io/cirruslabs/macos-ventura-xcode:latest build_script: swift build --product tart binary_artifacts: path: .build/debug/tart diff --git a/docs/integrations/vm-management.md b/docs/integrations/vm-management.md index 0e54636..13bdca4 100644 --- a/docs/integrations/vm-management.md +++ b/docs/integrations/vm-management.md @@ -11,8 +11,8 @@ Tart can create VMs from `*.ipsw` files. You can download a specific `*.ipsw` fi use `latest` instead of a path to `*.ipsw` to download the latest available version: ```bash -tart create --from-ipsw=latest monterey-vanilla -tart run monterey-vanilla +tart create --from-ipsw=latest ventura-vanilla +tart run ventura-vanilla ``` After the initial booting of the VM you'll need to manually go through the macOS installation process. As a convention we recommend creating an `admin` user with an `admin` password. After the regular installation please do some additional modifications in the VM: @@ -54,7 +54,7 @@ Please refer to `tart set --help` for additional details. ## Building with Packer Please refer to [Tart Packer Plugin repository](https://github.com/cirruslabs/packer-plugin-tart) for setup instructions. -Here is an example of a template to build `monterey-base` local image based of a remote image: +Here is an example of a template to build a local image based of a remote image: ```hcl packer { diff --git a/docs/quick-start.md b/docs/quick-start.md index 54c2749..7f9c1dd 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -3,7 +3,7 @@ hide: - navigation --- -Try running a Tart VM on your Apple Silicon device running macOS 12.0 (Monterey) or later (will download a 25 GB image): +Try running a Tart VM on your Apple Silicon device running macOS 13.0 (Ventura) or later (will download a 25 GB image): ```bash brew install cirruslabs/cli/tart