Vminitd: Rework ManagedContainer (#168)

This gets rid of some design decisions that I was not fond of. This
changes the process start for both execs and the init process to happen
internally in the object, as well as makes it so that all exec
functionalities can happen on the container object itself. This allows
us to get rid of the `if request.id == containerID` branches in the
rpcs, and handle this entirely in the object itself using its internal
state.

The existing integration tests should stress this just fine I believe.
This commit is contained in:
Danny Canter
2025-06-25 14:07:31 -04:00
committed by GitHub
parent 4bacf4c578
commit 2dfabeb4f9
2 changed files with 36 additions and 52 deletions
+28 -20
View File
@@ -91,34 +91,29 @@ extension ManagedContainer {
self._execs[id] = process
}
func getExec(id: String) throws -> ManagedProcess {
guard let exec = self._execs[id] else {
throw ContainerizationError(
.invalidState,
message: "exec \(id) does not exist in container \(self.id)"
)
}
return exec
func start(execID: String) async throws -> Int32 {
let proc = try self.getExecOrInit(execID: execID)
return try await ProcessSupervisor.default.start(process: proc)
}
func start() throws -> Int32 {
try self.initProcess.start()
func wait(execID: String) async throws -> Int32 {
let proc = try self.getExecOrInit(execID: execID)
return await proc.wait()
}
func wait() async -> Int32 {
await self.initProcess.wait()
func kill(execID: String, _ signal: Int32) throws {
let proc = try self.getExecOrInit(execID: execID)
try proc.kill(signal)
}
func kill(_ signal: Int32) throws {
try self.initProcess.kill(signal)
func resize(execID: String, size: Terminal.Size) throws {
let proc = try self.getExecOrInit(execID: execID)
try proc.resize(size: size)
}
func resize(size: Terminal.Size) throws {
try self.initProcess.resize(size: size)
}
func close() throws {
try self.initProcess.close()
func close(execID: String) throws {
let proc = try self.getExecOrInit(execID: execID)
try proc.close()
}
func deleteExec(id: String) throws {
@@ -134,6 +129,19 @@ extension ManagedContainer {
func delete() throws {
try self._bundle.delete()
}
func getExecOrInit(execID: String) throws -> ManagedProcess {
if execID == self.id {
return self.initProcess
}
guard let proc = self._execs[execID] else {
throw ContainerizationError(
.invalidState,
message: "exec \(execID) does not exist in container \(self.id)"
)
}
return proc
}
}
extension ContainerizationOCI.Bundle {
+8 -32
View File
@@ -465,13 +465,7 @@ extension Initd: Com_Apple_Containerization_Sandbox_V3_SandboxContextAsyncProvid
}
let ctr = try await self.state.get(container: request.containerID)
if request.id == request.containerID {
try await ctr.kill(request.signal)
} else {
let proc = try await ctr.getExec(id: request.id)
try proc.kill(request.signal)
}
try await ctr.kill(execID: request.id, request.signal)
return .init()
}
@@ -520,16 +514,7 @@ extension Initd: Com_Apple_Containerization_Sandbox_V3_SandboxContextAsyncProvid
do {
let ctr = try await self.state.get(container: request.containerID)
// FIXME: This should just happen inside of ManagedContainer.
let pid: Int32
if request.id == request.containerID {
let process = ctr.initProcess
pid = try await ProcessSupervisor.default.start(process: process)
} else {
let process = try await ctr.getExec(id: request.id)
pid = try await ProcessSupervisor.default.start(process: process)
}
let pid = try await ctr.start(execID: request.id)
return .with {
$0.pid = pid
@@ -565,14 +550,11 @@ extension Initd: Com_Apple_Containerization_Sandbox_V3_SandboxContextAsyncProvid
do {
let ctr = try await self.state.get(container: request.containerID)
let size = Terminal.Size(width: UInt16(request.columns), height: UInt16(request.rows))
if request.id == request.containerID {
try await ctr.resize(size: size)
} else {
let proc = try await ctr.getExec(id: request.id)
try proc.resize(size: size)
}
let size = Terminal.Size(
width: UInt16(request.columns),
height: UInt16(request.rows)
)
try await ctr.resize(execID: request.id, size: size)
} catch {
log.error(
"resizeProcess",
@@ -607,13 +589,7 @@ extension Initd: Com_Apple_Containerization_Sandbox_V3_SandboxContextAsyncProvid
do {
let ctr = try await self.state.get(container: request.containerID)
let exitCode: Int32
if request.id == request.containerID {
exitCode = await ctr.wait()
} else {
let proc = try await ctr.getExec(id: request.id)
exitCode = await proc.wait()
}
let exitCode = try await ctr.wait(execID: request.id)
return .with {
$0.exitCode = exitCode