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
|
(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
|
now-silent `exists` can under-report an unreadable pre-existing item. Mirrors
|
||||||
`KeychainOwnedAccess.withoutLegacyKeychainUI` in NucleicCore. Host-side (shipped by a normal
|
`KeychainOwnedAccess.withoutLegacyKeychainUI` in NucleicCore. Host-side (shipped by a normal
|
||||||
`swift build`); `SecKeychain*` deprecation warnings are expected (built with
|
`swift build`). The three `SecKeychain*` symbols are formally deprecated but are the only API
|
||||||
`WARNINGS_AS_ERRORS=false`). Marked `[Nucleic vendored patch]`.
|
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)
|
### GUEST-side patches (require rebuilding the initfs — see below)
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ extension VZVirtualMachineInstance: VirtualMachineInstance {
|
|||||||
|
|
||||||
try await self.vm.start(queue: self.queue)
|
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),
|
connection: try await self.vm.waitForAgent(queue: self.queue),
|
||||||
group: self.group
|
group: self.group
|
||||||
)
|
)
|
||||||
@@ -260,7 +260,7 @@ extension VZVirtualMachineInstance: VirtualMachineInstance {
|
|||||||
port: Vminitd.port
|
port: Vminitd.port
|
||||||
)
|
)
|
||||||
let handle = try conn.dupHandle()
|
let handle = try conn.dupHandle()
|
||||||
return try Vminitd(connection: handle, group: self.group)
|
return try await Vminitd(connection: handle, group: self.group)
|
||||||
} catch {
|
} catch {
|
||||||
if let err = error as? ContainerizationError {
|
if let err = error as? ContainerizationError {
|
||||||
throw err
|
throw err
|
||||||
|
|||||||
@@ -34,18 +34,23 @@ public struct Vminitd: Sendable {
|
|||||||
public let grpcClient: GRPCClient<HTTP2ClientTransport.WrappedChannel>
|
public let grpcClient: GRPCClient<HTTP2ClientTransport.WrappedChannel>
|
||||||
private let connectionTask: Task<Void, Error>
|
private let connectionTask: Task<Void, Error>
|
||||||
|
|
||||||
public init(connection: FileHandle, group: any EventLoopGroup) throws {
|
public init(connection: FileHandle, group: any EventLoopGroup) async throws {
|
||||||
let channel = try ClientBootstrap(group: group)
|
// Configure the gRPC pipeline from inside the channel initializer — before the channel
|
||||||
.channelInitializer { channel in
|
// becomes active — so no early server frames (e.g. SETTINGS) are dropped. `configure` is
|
||||||
channel.eventLoop.makeCompletedFuture(withResultOf: {
|
// supplied by `wrapping(config:serviceConfig:makeChannel:)` and must be called exactly once.
|
||||||
try channel.pipeline.syncOperations.addHandler(HTTP2ConnectBufferingHandler())
|
let fd = connection.fileDescriptor
|
||||||
})
|
let transport = try await HTTP2ClientTransport.WrappedChannel.wrapping(
|
||||||
}
|
|
||||||
.withConnectedSocket(connection.fileDescriptor).wait()
|
|
||||||
let transport = HTTP2ClientTransport.WrappedChannel.wrapping(
|
|
||||||
channel: channel,
|
|
||||||
config: .defaults { $0.connection.maxIdleTime = nil }
|
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)
|
let grpcClient = GRPCClient(transport: transport)
|
||||||
self.grpcClient = grpcClient
|
self.grpcClient = grpcClient
|
||||||
self.client = Com_Apple_Containerization_Sandbox_V3_SandboxContext.Client(wrapping: self.grpcClient)
|
self.client = Com_Apple_Containerization_Sandbox_V3_SandboxContext.Client(wrapping: self.grpcClient)
|
||||||
|
|||||||
@@ -22,6 +22,15 @@ import Foundation
|
|||||||
#endif
|
#endif
|
||||||
import Security // [Nucleic vendored patch] SecKeychain*UserInteractionAllowed for prompt-free reads
|
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.
|
/// Holds the result of a query to the keychain.
|
||||||
public struct KeychainQueryResult {
|
public struct KeychainQueryResult {
|
||||||
public var username: String
|
public var username: String
|
||||||
@@ -260,9 +269,9 @@ public struct KeychainQuery {
|
|||||||
/// `KeychainOwnedAccess.withoutLegacyKeychainUI` in NucleicCore.
|
/// `KeychainOwnedAccess.withoutLegacyKeychainUI` in NucleicCore.
|
||||||
private static func withoutInteractiveUI<T>(_ body: () -> T) -> T {
|
private static func withoutInteractiveUI<T>(_ body: () -> T) -> T {
|
||||||
var previous = DarwinBoolean(true)
|
var previous = DarwinBoolean(true)
|
||||||
SecKeychainGetUserInteractionAllowed(&previous)
|
_ = nucleic_SecKeychainGetUserInteractionAllowed(&previous)
|
||||||
SecKeychainSetUserInteractionAllowed(false)
|
_ = nucleic_SecKeychainSetUserInteractionAllowed(false)
|
||||||
defer { SecKeychainSetUserInteractionAllowed(previous.boolValue) }
|
defer { _ = nucleic_SecKeychainSetUserInteractionAllowed(previous) }
|
||||||
return body()
|
return body()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1730,7 +1730,7 @@ extension IntegrationSuite {
|
|||||||
try await assertExec(container, id: "create-fifo", cmd: "mkfifo /tmp/test-fifo")
|
try await assertExec(container, id: "create-fifo", cmd: "mkfifo /tmp/test-fifo")
|
||||||
|
|
||||||
let vsock = try await container.dialVsock(port: 1024)
|
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)
|
let root = URL(filePath: container.root)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user