Merge nucleic/upbeat-slate-lemur-7euo into dev
This commit is contained in:
+13
-2
@@ -116,8 +116,19 @@ in-tree means the patch can't be lost to a dependency re-resolve.
|
||||
(the `cctl login` write path) gains a delete-and-retry on `errSecDuplicateItem`, since the
|
||||
now-silent `exists` can under-report an unreadable pre-existing item. Mirrors
|
||||
`KeychainOwnedAccess.withoutLegacyKeychainUI` in NucleicCore. Host-side (shipped by a normal
|
||||
`swift build`); `SecKeychain*` deprecation warnings are expected (built with
|
||||
`WARNINGS_AS_ERRORS=false`). Marked `[Nucleic vendored patch]`.
|
||||
`swift build`). The three `SecKeychain*` symbols are formally deprecated but are the only API
|
||||
covering the legacy ACL panel; they're bound directly via `@_silgen_name` (`nucleic_SecKeychain*`,
|
||||
top of file) so the required calls compile without deprecation warnings. Marked
|
||||
`[Nucleic vendored patch]`.
|
||||
|
||||
14. **`Sources/Containerization/Vminitd.swift` — configure the gRPC pipeline before the channel goes
|
||||
active.** `Vminitd.init` used the now-deprecated `HTTP2ClientTransport.WrappedChannel.wrapping(
|
||||
channel:config:serviceConfig:)`, which wraps an already-connected channel best-effort and may drop
|
||||
early server frames such as SETTINGS. Migrated to `wrapping(config:serviceConfig:makeChannel:)`,
|
||||
which invokes the transport's `configure` inside the bootstrap's channel initializer — before the
|
||||
vsock channel becomes active. `init` is now `async throws` (the new overload is async); its callers
|
||||
in `VZVirtualMachineInstance` (`start`/`dialAgent`, both already async) and the integration test now
|
||||
`try await`. Marked `[Nucleic vendored patch]`.
|
||||
|
||||
### GUEST-side patches (require rebuilding the initfs — see below)
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ extension VZVirtualMachineInstance: VirtualMachineInstance {
|
||||
|
||||
try await self.vm.start(queue: self.queue)
|
||||
|
||||
let agent = try Vminitd(
|
||||
let agent = try await Vminitd(
|
||||
connection: try await self.vm.waitForAgent(queue: self.queue),
|
||||
group: self.group
|
||||
)
|
||||
@@ -260,7 +260,7 @@ extension VZVirtualMachineInstance: VirtualMachineInstance {
|
||||
port: Vminitd.port
|
||||
)
|
||||
let handle = try conn.dupHandle()
|
||||
return try Vminitd(connection: handle, group: self.group)
|
||||
return try await Vminitd(connection: handle, group: self.group)
|
||||
} catch {
|
||||
if let err = error as? ContainerizationError {
|
||||
throw err
|
||||
|
||||
@@ -34,18 +34,23 @@ public struct Vminitd: Sendable {
|
||||
public let grpcClient: GRPCClient<HTTP2ClientTransport.WrappedChannel>
|
||||
private let connectionTask: Task<Void, Error>
|
||||
|
||||
public init(connection: FileHandle, group: any EventLoopGroup) throws {
|
||||
let channel = try ClientBootstrap(group: group)
|
||||
.channelInitializer { channel in
|
||||
channel.eventLoop.makeCompletedFuture(withResultOf: {
|
||||
try channel.pipeline.syncOperations.addHandler(HTTP2ConnectBufferingHandler())
|
||||
})
|
||||
}
|
||||
.withConnectedSocket(connection.fileDescriptor).wait()
|
||||
let transport = HTTP2ClientTransport.WrappedChannel.wrapping(
|
||||
channel: channel,
|
||||
public init(connection: FileHandle, group: any EventLoopGroup) async throws {
|
||||
// Configure the gRPC pipeline from inside the channel initializer — before the channel
|
||||
// becomes active — so no early server frames (e.g. SETTINGS) are dropped. `configure` is
|
||||
// supplied by `wrapping(config:serviceConfig:makeChannel:)` and must be called exactly once.
|
||||
let fd = connection.fileDescriptor
|
||||
let transport = try await HTTP2ClientTransport.WrappedChannel.wrapping(
|
||||
config: .defaults { $0.connection.maxIdleTime = nil }
|
||||
)
|
||||
) { configure in
|
||||
try await ClientBootstrap(group: group)
|
||||
.withConnectedSocket(fd) { channel in
|
||||
channel.eventLoop.makeCompletedFuture {
|
||||
try channel.pipeline.syncOperations.addHandler(HTTP2ConnectBufferingHandler())
|
||||
}.flatMap { _ in
|
||||
configure(channel)
|
||||
}
|
||||
}
|
||||
}
|
||||
let grpcClient = GRPCClient(transport: transport)
|
||||
self.grpcClient = grpcClient
|
||||
self.client = Com_Apple_Containerization_Sandbox_V3_SandboxContext.Client(wrapping: self.grpcClient)
|
||||
|
||||
@@ -22,6 +22,15 @@ import Foundation
|
||||
#endif
|
||||
import Security // [Nucleic vendored patch] SecKeychain*UserInteractionAllowed for prompt-free reads
|
||||
|
||||
// [Nucleic vendored patch] `SecKeychainGet/SetUserInteractionAllowed` are formally deprecated but
|
||||
// remain the ONLY API that suppresses the legacy Keychain ACL panel. Bind the C symbols directly —
|
||||
// the deprecation rides on their Swift imports, not the raw symbols — so `withoutInteractiveUI`
|
||||
// compiles without deprecation warnings. Mirrors `KeychainOwnedAccess` in NucleicCore.
|
||||
@_silgen_name("SecKeychainGetUserInteractionAllowed")
|
||||
private func nucleic_SecKeychainGetUserInteractionAllowed(_ state: UnsafeMutablePointer<DarwinBoolean>) -> OSStatus
|
||||
@_silgen_name("SecKeychainSetUserInteractionAllowed")
|
||||
private func nucleic_SecKeychainSetUserInteractionAllowed(_ state: DarwinBoolean) -> OSStatus
|
||||
|
||||
/// Holds the result of a query to the keychain.
|
||||
public struct KeychainQueryResult {
|
||||
public var username: String
|
||||
@@ -260,9 +269,9 @@ public struct KeychainQuery {
|
||||
/// `KeychainOwnedAccess.withoutLegacyKeychainUI` in NucleicCore.
|
||||
private static func withoutInteractiveUI<T>(_ body: () -> T) -> T {
|
||||
var previous = DarwinBoolean(true)
|
||||
SecKeychainGetUserInteractionAllowed(&previous)
|
||||
SecKeychainSetUserInteractionAllowed(false)
|
||||
defer { SecKeychainSetUserInteractionAllowed(previous.boolValue) }
|
||||
_ = nucleic_SecKeychainGetUserInteractionAllowed(&previous)
|
||||
_ = nucleic_SecKeychainSetUserInteractionAllowed(false)
|
||||
defer { _ = nucleic_SecKeychainSetUserInteractionAllowed(previous) }
|
||||
return body()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1730,7 +1730,7 @@ extension IntegrationSuite {
|
||||
try await assertExec(container, id: "create-fifo", cmd: "mkfifo /tmp/test-fifo")
|
||||
|
||||
let vsock = try await container.dialVsock(port: 1024)
|
||||
let vminitd = try Vminitd(connection: vsock, group: Self.eventLoop)
|
||||
let vminitd = try await Vminitd(connection: vsock, group: Self.eventLoop)
|
||||
|
||||
let root = URL(filePath: container.root)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user