MCPcopy Index your code
hub / github.com/devcontainers/cli / generateFeaturesComposeOverrideContent

Function generateFeaturesComposeOverrideContent

src/spec-node/dockerCompose.ts:504–573  ·  view source on GitHub ↗
(
	updatedImageName: string,
	originalImageName: string,
	mergedConfig: MergedDevContainerConfig,
	config: DevContainerFromDockerComposeConfig,
	versionPrefix: string,
	imageDetails: () => Promise<ImageDetails>,
	service: any,
	additionalLabels: string[],
	additionalMounts: Mount[],
	params: DockerResolverParameters,
)

Source from the content-addressed store, hash-verified

502}
503
504async function generateFeaturesComposeOverrideContent(
505 updatedImageName: string,
506 originalImageName: string,
507 mergedConfig: MergedDevContainerConfig,
508 config: DevContainerFromDockerComposeConfig,
509 versionPrefix: string,
510 imageDetails: () => Promise<ImageDetails>,
511 service: any,
512 additionalLabels: string[],
513 additionalMounts: Mount[],
514 params: DockerResolverParameters,
515) {
516 const overrideImage = updatedImageName !== originalImageName;
517
518 const user = mergedConfig.containerUser;
519 const env = mergedConfig.containerEnv || {};
520 const capAdd = mergedConfig.capAdd || [];
521 const securityOpts = mergedConfig.securityOpt || [];
522 const mounts = [
523 ...mergedConfig.mounts || [],
524 ...additionalMounts,
525 ].map(m => typeof m === 'string' ? parseMount(m) : m);
526 const namedVolumeMounts = mounts.filter(m => m.type === 'volume' && m.source);
527 const customEntrypoints = mergedConfig.entrypoints || [];
528 const composeEntrypoint: string[] | undefined = typeof service.entrypoint === 'string' ? shellQuote.parse(service.entrypoint) : service.entrypoint;
529 const composeCommand: string[] | undefined = typeof service.command === 'string' ? shellQuote.parse(service.command) : service.command;
530 const { overrideCommand } = mergedConfig;
531 const userEntrypoint = overrideCommand ? [] : composeEntrypoint /* $ already escaped. */
532 || ((await imageDetails()).Config.Entrypoint || []).map(c => c.replace(/\$/g, '$$$$')); // $ > $$ to escape docker-compose.yml's interpolation.
533 const userCommand = overrideCommand ? [] : composeCommand /* $ already escaped. */
534 || (composeEntrypoint ? [/* Ignore image CMD per docker-compose.yml spec. */] : ((await imageDetails()).Config.Cmd || []).map(c => c.replace(/\$/g, '$$$$'))); // $ > $$ to escape docker-compose.yml's interpolation.
535
536 const hasGpuRequirement = config.hostRequirements?.gpu;
537 const addGpuCapability = hasGpuRequirement && await checkDockerSupportForGPU(params);
538 if (hasGpuRequirement && hasGpuRequirement !== 'optional' && !addGpuCapability) {
539 params.common.output.write('No GPU support found yet a GPU was required - consider marking it as "optional"', LogLevel.Warning);
540 }
541 const gpuResources = addGpuCapability ? `
542 deploy:
543 resources:
544 reservations:
545 devices:
546 - capabilities: [gpu]` : '';
547
548 return `${versionPrefix}services:
549 '${config.service}':${overrideImage ? `
550 image: ${updatedImageName}` : ''}
551 entrypoint: ["/bin/sh", "-c", "echo Container started\\n
552trap \\"exit 0\\" 15\\n
553${customEntrypoints.join('\\n\n')}\\n
554exec \\"$$@\\"\\n
555while sleep 1 & wait $$!; do :; done", "-"${userEntrypoint.map(a => `, ${JSON.stringify(a)}`).join('')}]${userCommand !== composeCommand ? `
556 command: ${JSON.stringify(userCommand)}` : ''}${mergedConfig.init ? `
557 init: true` : ''}${user ? `
558 user: ${user}` : ''}${Object.keys(env).length ? `
559 environment:${Object.keys(env).map(key => `
560 - '${key}=${String(env[key]).replace(/\n/g, '\\n').replace(/\$/g, '$$$$').replace(/'/g, '\'\'')}'`).join('')}` : ''}${mergedConfig.privileged ? `
561 privileged: true` : ''}${capAdd.length ? `

Callers 1

Calls 6

parseMountFunction · 0.90
checkDockerSupportForGPUFunction · 0.90
imageDetailsFunction · 0.70
convertMountToVolumeFunction · 0.70
writeMethod · 0.65

Tested by

no test coverage detected