@@ -130,80 +130,82 @@ public actor ContainersService {
130130 public func create( configuration: ContainerConfiguration , kernel: Kernel , options: ContainerCreateOptions ) async throws {
131131 self . log. debug ( " \( #function) " )
132132
133- guard containers [ configuration. id] == nil else {
134- throw ContainerizationError (
135- . exists,
136- message: " container already exists: \( configuration. id) "
137- )
138- }
139-
140- var allHostnames = Set < String > ( )
141- for container in containers. values {
142- for attachmentConfiguration in container. snapshot. configuration. networks {
143- allHostnames. insert ( attachmentConfiguration. options. hostname)
133+ try await self . lock. withLock { context in
134+ guard await self . containers [ configuration. id] == nil else {
135+ throw ContainerizationError (
136+ . exists,
137+ message: " container already exists: \( configuration. id) "
138+ )
144139 }
145- }
146140
147- var conflictingHostnames = [ String] ( )
148- for attachmentConfiguration in configuration. networks {
149- if allHostnames. contains ( attachmentConfiguration. options. hostname) {
150- conflictingHostnames. append ( attachmentConfiguration. options. hostname)
141+ var allHostnames = Set < String > ( )
142+ for container in await self . containers. values {
143+ for attachmentConfiguration in container. snapshot. configuration. networks {
144+ allHostnames. insert ( attachmentConfiguration. options. hostname)
145+ }
151146 }
152- }
153147
154- guard conflictingHostnames. isEmpty else {
155- throw ContainerizationError (
156- . exists ,
157- message : " hostname(s) already exist: \( conflictingHostnames) "
158- )
159- }
148+ var conflictingHostnames = [ String ] ( )
149+ for attachmentConfiguration in configuration . networks {
150+ if allHostnames . contains ( attachmentConfiguration . options . hostname ) {
151+ conflictingHostnames. append ( attachmentConfiguration . options . hostname )
152+ }
153+ }
160154
161- let runtimePlugin = self . runtimePlugins. filter {
162- $0. name == configuration. runtimeHandler
163- } . first
164- guard let runtimePlugin else {
165- throw ContainerizationError (
166- . notFound,
167- message: " unable to locate runtime plugin \( configuration. runtimeHandler) "
168- )
169- }
155+ guard conflictingHostnames. isEmpty else {
156+ throw ContainerizationError (
157+ . exists,
158+ message: " hostname(s) already exist: \( conflictingHostnames) "
159+ )
160+ }
170161
171- let path = self . containerRoot. appendingPathComponent ( configuration. id)
172- let systemPlatform = kernel. platform
173- let initFs = try await getInitBlock ( for: systemPlatform. ociPlatform ( ) )
162+ let runtimePlugin = self . runtimePlugins. filter {
163+ $0. name == configuration. runtimeHandler
164+ } . first
165+ guard let runtimePlugin else {
166+ throw ContainerizationError (
167+ . notFound,
168+ message: " unable to locate runtime plugin \( configuration. runtimeHandler) "
169+ )
170+ }
174171
175- let bundle = try ContainerClient . Bundle. create (
176- path: path,
177- initialFilesystem: initFs,
178- kernel: kernel,
179- containerConfiguration: configuration
180- )
181- do {
182- let containerImage = ClientImage ( description: configuration. image)
183- let imageFs = try await containerImage. getCreateSnapshot ( platform: configuration. platform)
184- try bundle. setContainerRootFs ( cloning: imageFs)
185- try bundle. write ( filename: " options.json " , value: options)
186-
187- try Self . registerService (
188- plugin: runtimePlugin,
189- loader: self . pluginLoader,
190- configuration: configuration,
191- path: path
192- )
172+ let path = self . containerRoot. appendingPathComponent ( configuration. id)
173+ let systemPlatform = kernel. platform
174+ let initFs = try await self . getInitBlock ( for: systemPlatform. ociPlatform ( ) )
193175
194- let snapshot = ContainerSnapshot (
195- configuration: configuration,
196- status: . stopped,
197- networks: [ ]
176+ let bundle = try ContainerClient . Bundle. create (
177+ path: path,
178+ initialFilesystem: initFs,
179+ kernel: kernel,
180+ containerConfiguration: configuration
198181 )
199- self . containers [ configuration. id] = ContainerState ( snapshot: snapshot)
200- } catch {
201182 do {
202- try bundle. delete ( )
183+ let containerImage = ClientImage ( description: configuration. image)
184+ let imageFs = try await containerImage. getCreateSnapshot ( platform: configuration. platform)
185+ try bundle. setContainerRootFs ( cloning: imageFs)
186+ try bundle. write ( filename: " options.json " , value: options)
187+
188+ try Self . registerService (
189+ plugin: runtimePlugin,
190+ loader: self . pluginLoader,
191+ configuration: configuration,
192+ path: path
193+ )
194+
195+ let snapshot = ContainerSnapshot (
196+ configuration: configuration,
197+ status: . stopped,
198+ networks: [ ]
199+ )
200+ await self . setContainerState ( configuration. id, ContainerState ( snapshot: snapshot) , context: context)
203201 } catch {
204- self . log. error ( " failed to delete bundle for container \( configuration. id) : \( error) " )
202+ do {
203+ try bundle. delete ( )
204+ } catch {
205+ self . log. error ( " failed to delete bundle for container \( configuration. id) : \( error) " )
206+ }
207+ throw error
205208 }
206- throw error
207209 }
208210 }
209211
0 commit comments