diff --git a/Sources/tart/Commands/IP.swift b/Sources/tart/Commands/IP.swift index c17bc58..3f82072 100644 --- a/Sources/tart/Commands/IP.swift +++ b/Sources/tart/Commands/IP.swift @@ -1,5 +1,6 @@ import ArgumentParser import Foundation +import Network import SystemConfiguration struct IP: AsyncParsableCommand { @@ -8,13 +9,15 @@ struct IP: AsyncParsableCommand { @Argument(help: "VM name") var name: String + @Option(help: "Number of seconds to wait for a potential VM booting") + var wait: UInt16 = 0 + func run() async throws { do { let vmDir = try VMStorage().read(name) let vmConfig = try VMConfig.init(fromURL: vmDir.configURL) - let vmMacAddress = MACAddress(fromString: vmConfig.macAddress.string)! - guard let ip = try ARPCache.ResolveMACAddress(macAddress: vmMacAddress) else { + guard let ip = try await resolveIP(vmConfig, secondsToWait: wait) else { print("no IP address found, is your VM running?") Foundation.exit(1) @@ -29,4 +32,19 @@ struct IP: AsyncParsableCommand { Foundation.exit(1) } } + + private func resolveIP(_ config: VMConfig, secondsToWait: UInt16) async throws -> IPv4Address? { + let waitUntil = Calendar.current.date(byAdding: .second, value: Int(secondsToWait), to: Date.now)! + let vmMacAddress = MACAddress(fromString: config.macAddress.string)! + + repeat { + if let ip = try ARPCache.ResolveMACAddress(macAddress: vmMacAddress) { + return ip + } + + try await Task.sleep(nanoseconds: 1_000_000) + } while Date.now < waitUntil + + return nil + } }