mirror of https://github.com/cirruslabs/tart.git
Multiple bridged interfaces (#578)
* Support multiple Bridged Network interfaces Fixes #572 * Allow duplicated bridged interfaces
This commit is contained in:
parent
8b27fea745
commit
35f5b30bc4
|
|
@ -1,7 +1,7 @@
|
|||
use_compute_credits: true
|
||||
|
||||
env:
|
||||
XCODE_TAG: 15-beta-2
|
||||
XCODE_TAG: 15-beta-5
|
||||
|
||||
task:
|
||||
name: Test on Ventura
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ struct Run: AsyncParsableCommand {
|
|||
""", discussion: """
|
||||
Specify "list" as an interface name (--net-bridged=list) to list the available bridged interfaces.
|
||||
""", valueName: "interface name"))
|
||||
var netBridged: String?
|
||||
var netBridged: [String]
|
||||
|
||||
@Flag(help: ArgumentHelp("Use software networking instead of the default shared (NAT) networking",
|
||||
discussion: "Learn how to configure Softnet for use with Tart here: https://github.com/cirruslabs/softnet"))
|
||||
|
|
@ -105,7 +105,7 @@ struct Run: AsyncParsableCommand {
|
|||
throw ValidationError("--vnc and --vnc-experimental are mutually exclusive")
|
||||
}
|
||||
|
||||
if netBridged != nil && netSoftnet {
|
||||
if netBridged.count > 0 && netSoftnet {
|
||||
throw ValidationError("--net-bridged and --net-softnet are mutually exclusive")
|
||||
}
|
||||
|
||||
|
|
@ -331,23 +331,19 @@ struct Run: AsyncParsableCommand {
|
|||
return try Softnet(vmMACAddress: config.macAddress.string)
|
||||
}
|
||||
|
||||
if let netBridged = netBridged {
|
||||
let matchingInterfaces = VZBridgedNetworkInterface.networkInterfaces.filter { interface in
|
||||
interface.identifier == netBridged || interface.localizedDisplayName == netBridged
|
||||
if netBridged.count > 0 {
|
||||
func findBridgedInterface(_ name: String) throws -> VZBridgedNetworkInterface {
|
||||
let interface = VZBridgedNetworkInterface.networkInterfaces.first { interface in
|
||||
interface.identifier == name || interface.localizedDisplayName == name
|
||||
}
|
||||
if (interface == nil) {
|
||||
throw ValidationError("no bridge interfaces matched \"\(netBridged)\", "
|
||||
+ "available interfaces: \(bridgeInterfaces())")
|
||||
}
|
||||
return interface!
|
||||
}
|
||||
|
||||
if matchingInterfaces.isEmpty {
|
||||
let available = bridgeInterfaces().joined(separator: ", ")
|
||||
throw ValidationError("no bridge interfaces matched \"\(netBridged)\", "
|
||||
+ "available interfaces: \(available)")
|
||||
}
|
||||
|
||||
if matchingInterfaces.count > 1 {
|
||||
throw ValidationError("more than one bridge interface matched \"\(netBridged)\", "
|
||||
+ "consider refining the search criteria")
|
||||
}
|
||||
|
||||
return NetworkBridged(interface: matchingInterfaces.first!)
|
||||
return NetworkBridged(interfaces: try netBridged.map { try findBridgedInterface($0) })
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import Virtualization
|
||||
|
||||
protocol Network {
|
||||
func attachment() -> VZNetworkDeviceAttachment
|
||||
func attachments() -> [VZNetworkDeviceAttachment]
|
||||
func run(_ sema: DispatchSemaphore) throws
|
||||
func stop() async throws
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ import Foundation
|
|||
import Virtualization
|
||||
|
||||
class NetworkBridged: Network {
|
||||
let interface: VZBridgedNetworkInterface
|
||||
let interfaces: [VZBridgedNetworkInterface]
|
||||
|
||||
init(interface: VZBridgedNetworkInterface) {
|
||||
self.interface = interface
|
||||
init(interfaces: [VZBridgedNetworkInterface]) {
|
||||
self.interfaces = interfaces
|
||||
}
|
||||
|
||||
func attachment() -> VZNetworkDeviceAttachment {
|
||||
VZBridgedNetworkDeviceAttachment(interface: interface)
|
||||
func attachments() -> [VZNetworkDeviceAttachment] {
|
||||
interfaces.map { VZBridgedNetworkDeviceAttachment(interface: $0) }
|
||||
}
|
||||
|
||||
func run(_ sema: DispatchSemaphore) throws {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import Foundation
|
|||
import Virtualization
|
||||
|
||||
class NetworkShared: Network {
|
||||
func attachment() -> VZNetworkDeviceAttachment {
|
||||
VZNATNetworkDeviceAttachment()
|
||||
func attachments() -> [VZNetworkDeviceAttachment] {
|
||||
[VZNATNetworkDeviceAttachment()]
|
||||
}
|
||||
|
||||
func run(_ sema: DispatchSemaphore) throws {
|
||||
|
|
|
|||
|
|
@ -92,9 +92,9 @@ class Softnet: Network {
|
|||
}
|
||||
}
|
||||
|
||||
func attachment() -> VZNetworkDeviceAttachment {
|
||||
func attachments() -> [VZNetworkDeviceAttachment] {
|
||||
let fh = FileHandle.init(fileDescriptor: vmFD)
|
||||
return VZFileHandleNetworkDeviceAttachment(fileHandle: fh)
|
||||
return [VZFileHandleNetworkDeviceAttachment(fileHandle: fh)]
|
||||
}
|
||||
|
||||
static func configureSUIDBitIfNeeded() throws {
|
||||
|
|
|
|||
|
|
@ -320,10 +320,12 @@ class VM: NSObject, VZVirtualMachineDelegate, ObservableObject {
|
|||
}
|
||||
|
||||
// Networking
|
||||
let vio = VZVirtioNetworkDeviceConfiguration()
|
||||
vio.attachment = network.attachment()
|
||||
vio.macAddress = vmConfig.macAddress
|
||||
configuration.networkDevices = [vio]
|
||||
configuration.networkDevices = network.attachments().map {
|
||||
let vio = VZVirtioNetworkDeviceConfiguration()
|
||||
vio.attachment = $0
|
||||
vio.macAddress = vmConfig.macAddress
|
||||
return vio
|
||||
}
|
||||
|
||||
// Storage
|
||||
var attachments = [try VZDiskImageStorageDeviceAttachment(url: diskURL, readOnly: false)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue