From 24a86b8c08b9eeda978f3cce6fe65e534fcf1199 Mon Sep 17 00:00:00 2001 From: Noah Thornton Date: Fri, 22 May 2026 15:42:43 -0700 Subject: [PATCH] Make LinuxPod.stopContainer return ExitStatus explicitly Update LinuxPod.stopContainer API to return the ExitStatus explicitly when the function call performs the kill and reaping itself. This lets callers observe the correct exit code without having to rely on other mechanisms. --- Sources/Containerization/LinuxPod.swift | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Sources/Containerization/LinuxPod.swift b/Sources/Containerization/LinuxPod.swift index 1ace38b6..85067d96 100644 --- a/Sources/Containerization/LinuxPod.swift +++ b/Sources/Containerization/LinuxPod.swift @@ -860,7 +860,14 @@ extension LinuxPod { } /// Stop a container from executing. - public func stopContainer(_ containerID: String) async throws { + /// + /// Returns the `ExitStatus` read from the container's process when this + /// call performed the kill+reap itself. Returns `nil` for idempotent + /// stops, never-started containers, and stops issued after the VM has + /// already shut down — there is no live exit status to read in those + /// cases. + @discardableResult + public func stopContainer(_ containerID: String) async throws -> ExitStatus? { try await self.state.withLock { state in let createdState = try state.phase.createdState("stopContainer") @@ -873,7 +880,7 @@ extension LinuxPod { // Allow stop to be called multiple times if container.state == .stopped { - return + return nil } // Handle containers that were hotplugged but never started @@ -884,7 +891,7 @@ extension LinuxPod { container.state = .stopped state.containers[containerID] = container - return + return nil } guard container.state == .started, let process = container.process else { @@ -899,11 +906,11 @@ extension LinuxPod { if createdState.vm.state == .stopped { container.state = .stopped state.containers[containerID] = container - return + return nil } try await process.kill(.kill) - try await process.wait(timeoutInSeconds: 3) + let exitStatus = try await process.wait(timeoutInSeconds: 3) try await createdState.vm.withAgent { agent in // Unmount the rootfs @@ -923,6 +930,7 @@ extension LinuxPod { container.process = nil container.state = .stopped state.containers[containerID] = container + return exitStatus } catch { // Try to release the hotplug device and virtiofs shares even on error try? await createdState.vm.releaseHotplug(id: containerID)