Skip to content

Commit 22dfd6e

Browse files
authored
CLI: Fix stop not signalling waiters (apple#972)
1 parent 4958cf2 commit 22dfd6e

File tree

2 files changed

+32
-29
lines changed

2 files changed

+32
-29
lines changed

‎Sources/Services/ContainerAPIService/Containers/ContainersService.swift‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ public actor ContainersService {
361361
let waitFunc: ExitMonitor.WaitHandler = {
362362
log.info("registering container \(id) with exit monitor")
363363
let code = try await client.wait(id)
364-
log.info("container \(id) finished in exit monitor")
364+
log.info("container \(id) finished in exit monitor, exit code \(code)")
365365

366366
return code
367367
}

‎Sources/Services/ContainerSandboxService/SandboxService.swift‎

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -204,14 +204,14 @@ public actor SandboxService {
204204
czConfig.bootLog = BootLog.file(path: bundle.bootlog, append: true)
205205
}
206206

207-
await self.setContainer(
208-
ContainerInfo(
209-
container: container,
210-
config: config,
211-
attachments: attachments,
212-
bundle: bundle,
213-
io: (in: stdin, out: stdout, err: stderr)
214-
))
207+
let ctrInfo = ContainerInfo(
208+
container: container,
209+
config: config,
210+
attachments: attachments,
211+
bundle: bundle,
212+
io: (in: stdin, out: stdout, err: stderr)
213+
)
214+
await self.setContainer(ctrInfo)
215215

216216
do {
217217
try await container.create()
@@ -224,7 +224,7 @@ public actor SandboxService {
224224
await self.setState(.booted)
225225
} catch {
226226
do {
227-
try await self.cleanupContainer()
227+
try await self.cleanupContainer(containerInfo: ctrInfo)
228228
await self.setState(.created)
229229
} catch {
230230
self.log.error("failed to cleanup container: \(error)")
@@ -444,7 +444,7 @@ public actor SandboxService {
444444
if case .stopped(_) = await self.state {
445445
return message.reply()
446446
}
447-
try await self.cleanupContainer()
447+
try await self.cleanupContainer(containerInfo: ctr, exitStatus: exitStatus)
448448
} catch {
449449
self.log.error("failed to cleanup container: \(error)")
450450
}
@@ -669,7 +669,7 @@ public actor SandboxService {
669669
}
670670
try await self.monitor.track(id: id, waitingOn: waitFunc)
671671
} catch {
672-
try? await self.cleanupContainer()
672+
try? await self.cleanupContainer(containerInfo: info)
673673
self.setState(.created)
674674
throw error
675675
}
@@ -762,7 +762,6 @@ public actor SandboxService {
762762

763763
try await self.lock.withLock { [self] _ in
764764
let ctrInfo = try await getContainer()
765-
let ctr = ctrInfo.container
766765

767766
switch await self.state {
768767
case .stopped(_), .stopping:
@@ -772,23 +771,11 @@ public actor SandboxService {
772771
}
773772

774773
do {
775-
try await ctr.stop()
776-
} catch {
777-
self.log.notice("failed to stop sandbox gracefully: \(error)")
778-
}
779-
780-
do {
781-
try await cleanupContainer()
774+
try await cleanupContainer(containerInfo: ctrInfo, exitStatus: exitStatus)
782775
} catch {
783776
self.log.error("failed to cleanup container: \(error)")
784777
}
785778
await setState(.stopped(exitStatus.exitCode))
786-
787-
let waiters = await self.waiters[id] ?? []
788-
for cc in waiters {
789-
cc.resume(returning: exitStatus)
790-
}
791-
await self.removeWaiters(for: id)
792779
}
793780
}
794781

@@ -997,21 +984,37 @@ public actor SandboxService {
997984

998985
// Now actually bring down the vm.
999986
try await lc.stop()
987+
1000988
return code
1001989
}
1002990

1003-
private func cleanupContainer() async throws {
991+
private func cleanupContainer(containerInfo: ContainerInfo, exitStatus: ExitStatus? = nil) async throws {
992+
let container = containerInfo.container
993+
let id = container.id
994+
995+
do {
996+
try await container.stop()
997+
} catch {
998+
self.log.error("failed to stop container during cleanup: \(error)")
999+
}
1000+
10041001
// Give back our lovely IP(s)
10051002
await self.stopSocketForwarders()
1006-
let containerInfo = try self.getContainer()
10071003
for attachment in containerInfo.attachments {
10081004
let client = NetworkClient(id: attachment.network)
10091005
do {
10101006
try await client.deallocate(hostname: attachment.hostname)
10111007
} catch {
1012-
self.log.error("failed to deallocate hostname \(attachment.hostname) on network \(attachment.network): \(error)")
1008+
self.log.error("failed to deallocate hostname \(attachment.hostname) on network \(attachment.network) during cleanup: \(error)")
10131009
}
10141010
}
1011+
1012+
let status = exitStatus ?? ExitStatus(exitCode: 255)
1013+
let waiters = self.waiters[id] ?? []
1014+
for cc in waiters {
1015+
cc.resume(returning: status)
1016+
}
1017+
self.removeWaiters(for: id)
10151018
}
10161019
}
10171020

0 commit comments

Comments
 (0)