mirror of
https://github.com/cirruslabs/tart.git
synced 2026-10-03 12:46:26 +02:00
* Use let for the immutable disk image storage attachment * Don't bind the unused error when catching connection-pool failures * Report errors thrown inside tart run's fire-and-forget tasks We were discarding any error thrown inside these unstructured tasks, which silently hid failures to run the control socket or to start and stop the VM, and which the compiler now warns about. Wrap them in an ErrorReportingTask, which spawns the task and reports any thrown error to stderr, rather than repeating a do/catch at every call site. An unstructured task spawned from a synchronous context (a signal handler or SwiftUI action) has no parent to propagate the error to, so reporting it is the best we can do. * Avoid blocking SwiftNIO calls in async guest agent connections The gRPC channel setup in "tart exec" and the MAC address resolver created a dedicated event loop group and tore both it and the channel down with the blocking syncShutdownGracefully() and wait(), which are unavailable from async contexts (the former is an error in the Swift 6 language mode). Factor the connection out into a withGuestAgentChannel() helper that uses the process-wide singleton event loop group, so there is no group to shut down, and closes the channel with the async close().get().
29 lines
940 B
Swift
29 lines
940 B
Swift
import Foundation
|
|
import Network
|
|
import GRPC
|
|
import Cirruslabs_TartGuestAgent_Apple_Swift
|
|
import Cirruslabs_TartGuestAgent_Grpc_Swift
|
|
|
|
class AgentResolver {
|
|
static func ResolveIP(_ controlSocketPath: String) async throws -> IPv4Address? {
|
|
do {
|
|
return try await resolveIP(controlSocketPath)
|
|
} catch is GRPCConnectionPoolError {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
private static func resolveIP(_ controlSocketPath: String) async throws -> IPv4Address? {
|
|
try await withGuestAgentChannel(unixDomainSocketPath: controlSocketPath) { channel in
|
|
// Invoke ResolveIP() gRPC method
|
|
let callOptions = CallOptions(timeLimit: .timeout(.seconds(1)))
|
|
let agentAsyncClient = AgentAsyncClient(channel: channel)
|
|
let resolveIPCall = agentAsyncClient.makeResolveIpCall(ResolveIPRequest(), callOptions: callOptions)
|
|
|
|
let response = try await resolveIPCall.response
|
|
|
|
return IPv4Address(response.ip)
|
|
}
|
|
}
|
|
}
|