(params: DockerResolverParameters, config: DevContainerFromDockerfileConfig | DevContainerFromImageConfig, mergedConfig: MergedDevContainerConfig, imageName: string, labels: string[], workspaceMount: string | undefined, additionalMountString: string | undefined, imageDetails: () => Promise<ImageDetails>, containerUser: string | undefined, extraLabels: Record<string, string>)
| 340 | } |
| 341 | |
| 342 | export async function spawnDevContainer(params: DockerResolverParameters, config: DevContainerFromDockerfileConfig | DevContainerFromImageConfig, mergedConfig: MergedDevContainerConfig, imageName: string, labels: string[], workspaceMount: string | undefined, additionalMountString: string | undefined, imageDetails: () => Promise<ImageDetails>, containerUser: string | undefined, extraLabels: Record<string, string>) { |
| 343 | const { common } = params; |
| 344 | common.progress(ResolverProgress.StartingContainer); |
| 345 | |
| 346 | const appPort = config.appPort; |
| 347 | const exposedPorts = typeof appPort === 'number' || typeof appPort === 'string' ? [appPort] : appPort || []; |
| 348 | const exposed = (<string[]>[]).concat(...exposedPorts.map(port => ['-p', typeof port === 'number' ? `127.0.0.1:${port}:${port}` : port])); |
| 349 | |
| 350 | const cwdMount = workspaceMount ? (params.cliVariant === CLIVariant.Wslc ? convertMountToVolume(workspaceMount) : ['--mount', workspaceMount]) : []; |
| 351 | const additionalMount = additionalMountString ? (params.cliVariant === CLIVariant.Wslc ? convertMountToVolume(additionalMountString) : ['--mount', additionalMountString]) : []; |
| 352 | |
| 353 | const envObj = mergedConfig.containerEnv || {}; |
| 354 | const containerEnv = Object.keys(envObj) |
| 355 | .reduce((args, key) => { |
| 356 | args.push('-e', `${key}=${envObj[key]}`); |
| 357 | return args; |
| 358 | }, [] as string[]); |
| 359 | |
| 360 | const containerUserArgs = containerUser ? ['-u', containerUser] : []; |
| 361 | |
| 362 | const featureArgs: string[] = []; |
| 363 | // wslc does not support --init, --privileged, --cap-add, or --security-opt |
| 364 | if (params.cliVariant !== CLIVariant.Wslc) { |
| 365 | if (mergedConfig.init) { |
| 366 | featureArgs.push('--init'); |
| 367 | } |
| 368 | if (mergedConfig.privileged) { |
| 369 | featureArgs.push('--privileged'); |
| 370 | } |
| 371 | for (const cap of mergedConfig.capAdd || []) { |
| 372 | featureArgs.push('--cap-add', cap); |
| 373 | } |
| 374 | for (const securityOpt of mergedConfig.securityOpt || []) { |
| 375 | featureArgs.push('--security-opt', securityOpt); |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | const featureMounts = ([] as string[]).concat( |
| 380 | ...[ |
| 381 | ...mergedConfig.mounts || [], |
| 382 | ...params.additionalMounts, |
| 383 | ].map(m => { |
| 384 | const mountArgs = generateMountCommand(m); |
| 385 | return params.cliVariant === CLIVariant.Wslc ? convertMountArgsToVolume(mountArgs) : mountArgs; |
| 386 | }) |
| 387 | ); |
| 388 | |
| 389 | const customEntrypoints = mergedConfig.entrypoints || []; |
| 390 | const entrypoint = ['--entrypoint', '/bin/sh']; |
| 391 | const cmd = ['-c', `echo Container started |
| 392 | trap "exit 0" 15 |
| 393 | ${customEntrypoints.join('\n')} |
| 394 | exec "$@" |
| 395 | while sleep 1 & wait $!; do :; done`, '-']; // `wait $!` allows for the `trap` to run (synchronous `sleep` would not). |
| 396 | const overrideCommand = mergedConfig.overrideCommand; |
| 397 | if (overrideCommand === false) { |
| 398 | const details = await imageDetails(); |
| 399 | cmd.push(...details.Config.Entrypoint || []); |
no test coverage detected