Support wildcards in `credHelpers` (#592)

* Support wildcards in `credHelpers`

With #591 `tart pull` fails when for example you have `ecr-login` set as the default `credsStore` but you try to pull our images from `ghcr.io`.

This change reverts #591 and instead supports regex in `credHelpers`. This is not supported by Docker itself but highly demanded in https://github.com/docker/cli/issues/2928

I think it's fine to support it for Tart.

Additionally this change bumps the minimum host macOS version to Ventura in order to bring `Regex`. Yes, `Regex` only supported in Swift for macOS 13+ 🤦‍♂️I think it's fine in the light of Sonoma release and Tart 2.0.0.

* Removed Monterey mentions from docs
This commit is contained in:
Fedor Korotkov 2023-08-28 11:37:49 -04:00 committed by GitHub
parent f45551cbf0
commit 4bb248e7b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 63 additions and 54 deletions

View File

@ -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?

View File

@ -4,7 +4,7 @@ import PackageDescription
let package = Package(
name: "Tart",
platforms: [
.macOS(.v12)
.macOS(.v13)
],
products: [
.executable(name: "tart", targets: ["tart"])

View File

@ -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

View File

@ -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)

View File

@ -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<String, DockerAuthConfig>? = Dictionary()
var credHelpers: Dictionary<String, String>? = 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 {

View File

@ -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()]
}
}

View File

@ -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()

View File

@ -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)

View File

@ -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"))
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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