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

Function getFeaturesBuildOptions

src/spec-node/containerFeatures.ts:227–361  ·  view source on GitHub ↗
(params: DockerResolverParameters, devContainerConfig: SubstitutedConfig<DevContainerConfig>, featuresConfig: FeaturesConfig, baseName: string, imageBuildInfo: ImageBuildInfo, composeServiceUser: string | undefined)

Source from the content-addressed store, hash-verified

225}
226
227async function getFeaturesBuildOptions(params: DockerResolverParameters, devContainerConfig: SubstitutedConfig<DevContainerConfig>, featuresConfig: FeaturesConfig, baseName: string, imageBuildInfo: ImageBuildInfo, composeServiceUser: string | undefined): Promise<ImageBuildOptions | undefined> {
228 const { common } = params;
229 const { cliHost, output } = common;
230 const { dstFolder } = featuresConfig;
231
232 if (!dstFolder || dstFolder === '') {
233 output.write('dstFolder is undefined or empty in addContainerFeatures', LogLevel.Error);
234 return undefined;
235 }
236
237 // With Buildkit (0.8.0 or later), we can supply an additional build context to provide access to
238 // the container-features content.
239 // For non-Buildkit, we build a temporary image to hold the container-features content in a way
240 // that is accessible from the docker build for non-BuiltKit builds
241 // TODO generate an image name that is specific to this dev container?
242 const buildKitVersionParsed = params.buildKitVersion?.versionMatch ? parseVersion(params.buildKitVersion.versionMatch) : undefined;
243 const minRequiredVersion = [0, 8, 0];
244 const useBuildKitBuildContexts = buildKitVersionParsed ? !isEarlierVersion(buildKitVersionParsed, minRequiredVersion) : false;
245 const buildContentImageName = 'dev_container_feature_content_temp';
246 const disableSELinuxLabels = useBuildKitBuildContexts && await isUsingSELinuxLabels(params);
247 // Access Docker engine version
248 const dockerEngineVersionParsed = params.dockerEngineVersion?.versionMatch ? parseVersion(params.dockerEngineVersion.versionMatch) : undefined;
249 const minDockerEngineVersion = [23, 0, 0];
250 const skipDefaultSyntax = dockerEngineVersionParsed ? !isEarlierVersion(dockerEngineVersionParsed, minDockerEngineVersion) : false;
251 const omitPropertyOverride = params.common.skipPersistingCustomizationsFromFeatures ? ['customizations'] : [];
252 const imageMetadata = getDevcontainerMetadata(imageBuildInfo.metadata, devContainerConfig, featuresConfig, omitPropertyOverride, getOmitDevcontainerPropertyOverride(params.common));
253 const { containerUser, remoteUser } = findContainerUsers(imageMetadata, composeServiceUser, imageBuildInfo.user);
254 const builtinVariables = [
255 `_CONTAINER_USER=${containerUser}`,
256 `_REMOTE_USER=${remoteUser}`,
257 ];
258 const envPath = cliHost.path.join(dstFolder, 'devcontainer-features.builtin.env');
259 await cliHost.writeFile(envPath, Buffer.from(builtinVariables.join('\n') + '\n'));
260
261 // When copying via buildkit, the content is accessed via '.' (i.e. in the context root)
262 // When copying via temp image, the content is in '/tmp/build-features'
263 const contentSourceRootPath = useBuildKitBuildContexts ? '.' : '/tmp/build-features/';
264 const dockerfile = getContainerFeaturesBaseDockerFile(contentSourceRootPath)
265 .replace('#{nonBuildKitFeatureContentFallback}', useBuildKitBuildContexts ? '' : `FROM ${buildContentImageName} as dev_containers_feature_content_source`)
266 .replace('#{featureLayer}', getFeatureLayers(featuresConfig, containerUser, remoteUser, useBuildKitBuildContexts, contentSourceRootPath))
267 .replace('#{containerEnv}', generateContainerEnvsV1(featuresConfig))
268 .replace('#{devcontainerMetadata}', getDevcontainerMetadataLabel(imageMetadata))
269 .replace('#{containerEnvMetadata}', generateContainerEnvs(devContainerConfig.config.containerEnv, true))
270 ;
271 const syntax = imageBuildInfo.dockerfile?.preamble.directives.syntax;
272 const omitSyntaxDirective = common.omitSyntaxDirective; // Can be removed when https://github.com/moby/buildkit/issues/4556 is fixed
273 const dockerfilePrefixContent = `${omitSyntaxDirective ? '' :
274 skipDefaultSyntax ? (syntax ? `# syntax=${syntax}` : '') :
275 useBuildKitBuildContexts && !(imageBuildInfo.dockerfile && supportsBuildContexts(imageBuildInfo.dockerfile)) ? '# syntax=docker/dockerfile:1.4' :
276 syntax ? `# syntax=${syntax}` : ''}
277ARG _DEV_CONTAINERS_BASE_IMAGE=placeholder
278`;
279
280 // Build devcontainer-features.env and devcontainer-features-install.sh file(s) for each features source folder
281 for await (const fSet of featuresConfig.featureSets) {
282 if (fSet.internalVersion === '2')
283 {
284 for await (const fe of fSet.features) {

Callers 1

getExtendImageBuildInfoFunction · 0.85

Calls 15

parseVersionFunction · 0.90
isEarlierVersionFunction · 0.90
getDevcontainerMetadataFunction · 0.90
getFeatureLayersFunction · 0.90
generateContainerEnvsFunction · 0.90
supportsBuildContextsFunction · 0.90
toPtyExecParametersFunction · 0.90
makeLogFunction · 0.90
dockerPtyCLIFunction · 0.90

Tested by

no test coverage detected