Skip to content

Vminitd: Rework ManagedContainer #168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions vminitd/Sources/vminitd/ManagedContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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() throws -> Int32 {
try self.initProcess.start()
func start(execID: String) async throws -> Int32 {
let proc = try self.getExecOrInit(execID: execID)
return try await ProcessSupervisor.default.start(process: proc)
}

func wait() async -> Int32 {
await self.initProcess.wait()
func wait(execID: String) async throws -> Int32 {
let proc = try self.getExecOrInit(execID: execID)
return await proc.wait()
}

func kill(_ signal: Int32) throws {
try self.initProcess.kill(signal)
func kill(execID: String, _ signal: Int32) throws {
let proc = try self.getExecOrInit(execID: execID)
try proc.kill(signal)
}

func resize(size: Terminal.Size) throws {
try self.initProcess.resize(size: size)
func resize(execID: String, size: Terminal.Size) throws {
let proc = try self.getExecOrInit(execID: execID)
try proc.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 {
Expand All @@ -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 {
Expand Down
40 changes: 8 additions & 32 deletions vminitd/Sources/vminitd/Server+GRPC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down