Skip to content

Commit 9a67abd

Browse files
committed
Kill sandbox service on exit to prevent restart race condition
1 parent 62721e7 commit 9a67abd

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

Sources/Services/ContainerAPIService/Containers/ContainersService.swift

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,32 @@ public actor ContainersService {
223223
return
224224
}
225225

226+
let path = self.containerRoot.appendingPathComponent(id)
227+
let bundle = ContainerClient.Bundle(path: path)
228+
let config = try bundle.configuration
229+
let label = Self.fullLaunchdServiceLabel(
230+
runtimeName: config.runtimeHandler,
231+
instanceId: id
232+
)
233+
234+
let isRegistered = try ServiceManager.isRegistered(fullServiceLabel: label)
235+
236+
if isRegistered {
237+
// Stale service exists
238+
self.log.warning("Found stale launchd service for \(id), cleaning up")
239+
try? ServiceManager.kill(fullServiceLabel: label, signal: SIGKILL)
240+
try? await Task.sleep(for: .milliseconds(100))
241+
try? ServiceManager.deregister(fullServiceLabel: label)
242+
}
243+
244+
// Always register service
245+
try Self.registerService(
246+
plugin: self.runtimePlugins.first { $0.name == config.runtimeHandler }!,
247+
loader: self.pluginLoader,
248+
configuration: config,
249+
path: path
250+
)
251+
226252
let runtime = state.snapshot.configuration.runtimeHandler
227253
let sandboxClient = try await SandboxClient.create(
228254
id: id,
@@ -457,14 +483,27 @@ public actor ContainersService {
457483

458484
await self.exitMonitor.stopTracking(id: id)
459485

460-
// Try and shutdown the runtime helper.
486+
// Shutdown the runtime helper immediately to prevent reconnection
461487
do {
462488
self.log.info("Shutting down sandbox service for \(id)")
463489

490+
let path = self.containerRoot.appendingPathComponent(id)
491+
let bundle = ContainerClient.Bundle(path: path)
492+
let config = try bundle.configuration
493+
let label = Self.fullLaunchdServiceLabel(
494+
runtimeName: config.runtimeHandler,
495+
instanceId: id
496+
)
497+
464498
let client = try state.getClient()
465-
try await client.shutdown()
499+
try? await client.shutdown()
500+
try? ServiceManager.kill(fullServiceLabel: label, signal: SIGKILL)
501+
try? await Task.sleep(for: .milliseconds(100))
502+
503+
try ServiceManager.deregister(fullServiceLabel: label)
504+
self.log.info("Cleaned up sandbox service for \(id)")
466505
} catch {
467-
self.log.error("failed to shutdown sandbox service for \(id): \(error)")
506+
self.log.error("failed to cleanup sandbox service for \(id): \(error)")
468507
}
469508

470509
state.snapshot.status = .stopped

0 commit comments

Comments
 (0)