(params: DockerResolverParameters, buildParams: DockerCLIParameters, configWithRaw: SubstitutedConfig<DevContainerFromDockerComposeConfig>, projectName: string, composeFiles: string[], envFile: string | undefined, composeConfig: any, container: ContainerDetails | undefined, idLabels: string[], additionalFeatures: Record<string, string | boolean | Record<string, string | boolean>>)
| 333 | } |
| 334 | |
| 335 | async function startContainer(params: DockerResolverParameters, buildParams: DockerCLIParameters, configWithRaw: SubstitutedConfig<DevContainerFromDockerComposeConfig>, projectName: string, composeFiles: string[], envFile: string | undefined, composeConfig: any, container: ContainerDetails | undefined, idLabels: string[], additionalFeatures: Record<string, string | boolean | Record<string, string | boolean>>) { |
| 336 | const { common } = params; |
| 337 | const { persistedFolder, output } = common; |
| 338 | const { cliHost: buildCLIHost } = buildParams; |
| 339 | const { config } = configWithRaw; |
| 340 | const featuresBuildOverrideFilePrefix = 'docker-compose.devcontainer.build'; |
| 341 | const featuresStartOverrideFilePrefix = 'docker-compose.devcontainer.containerFeatures'; |
| 342 | |
| 343 | common.progress(ResolverProgress.StartingContainer); |
| 344 | |
| 345 | // If dockerComposeFile is an array, add -f <file> in order. https://docs.docker.com/compose/extends/#multiple-compose-files |
| 346 | const composeGlobalArgs = ([] as string[]).concat(...composeFiles.map(composeFile => ['-f', composeFile])); |
| 347 | if (envFile) { |
| 348 | composeGlobalArgs.push('--env-file', envFile); |
| 349 | } |
| 350 | |
| 351 | const infoOutput = makeLog(buildParams.output, LogLevel.Info); |
| 352 | const services = Object.keys(composeConfig.services || {}); |
| 353 | if (services.indexOf(config.service) === -1) { |
| 354 | throw new ContainerError({ description: `Service '${config.service}' configured in devcontainer.json not found in Docker Compose configuration.`, data: { fileWithError: composeFiles[0] } }); |
| 355 | } |
| 356 | |
| 357 | let cancel: () => void; |
| 358 | const canceled = new Promise<void>((_, reject) => cancel = reject); |
| 359 | const { started } = await startEventSeen(params, { [projectLabel]: projectName, [serviceLabel]: config.service }, canceled, common.output, common.getLogLevel() === LogLevel.Trace); // await getEvents, but only assign started. |
| 360 | |
| 361 | const service = composeConfig.services[config.service]; |
| 362 | const originalImageName = service.image || getDefaultImageName(await buildParams.dockerComposeCLI(), projectName, config.service); |
| 363 | |
| 364 | // Try to restore the 'third' docker-compose file and featuresConfig from persisted storage. |
| 365 | // This file may have been generated upon a Codespace creation. |
| 366 | const labels = container?.Config?.Labels; |
| 367 | output.write(`PersistedPath=${persistedFolder}, ContainerHasLabels=${!!labels}`); |
| 368 | |
| 369 | let didRestoreFromPersistedShare = false; |
| 370 | if (container) { |
| 371 | if (labels) { |
| 372 | // update args for `docker-compose up` to use cached overrides |
| 373 | const configFiles = labels['com.docker.compose.project.config_files']; |
| 374 | output.write(`Container was created with these config files: ${configFiles}`); |
| 375 | |
| 376 | // Parse out the full name of the 'containerFeatures' configFile |
| 377 | const files = configFiles?.split(',') ?? []; |
| 378 | const persistedBuildFile = await checkForPersistedFile(buildCLIHost, output, files, featuresBuildOverrideFilePrefix); |
| 379 | const persistedStartFile = await checkForPersistedFile(buildCLIHost, output, files, featuresStartOverrideFilePrefix); |
| 380 | if ((persistedBuildFile.fileExists || !persistedBuildFile.foundLabel) // require build file if in label |
| 381 | && persistedStartFile.fileExists // always require start file |
| 382 | ) { |
| 383 | didRestoreFromPersistedShare = true; |
| 384 | if (persistedBuildFile.fileExists) { |
| 385 | composeGlobalArgs.push('-f', persistedBuildFile.file); |
| 386 | } |
| 387 | if (persistedStartFile.fileExists) { |
| 388 | composeGlobalArgs.push('-f', persistedStartFile.file); |
| 389 | } |
| 390 | } |
| 391 | } |
| 392 | } |
no test coverage detected