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

Function extendImage

src/spec-node/containerFeatures.ts:31–139  ·  view source on GitHub ↗
(params: DockerResolverParameters, config: SubstitutedConfig<DevContainerConfig>, imageName: string, additionalImageNames: string[], additionalFeatures: Record<string, string | boolean | Record<string, string | boolean>>, canAddLabelsToContainer: boolean)

Source from the content-addressed store, hash-verified

29 .toUpperCase();
30
31export async function extendImage(params: DockerResolverParameters, config: SubstitutedConfig<DevContainerConfig>, imageName: string, additionalImageNames: string[], additionalFeatures: Record<string, string | boolean | Record<string, string | boolean>>, canAddLabelsToContainer: boolean) {
32 const { common } = params;
33 const { cliHost, output } = common;
34
35 const imageBuildInfo = await getImageBuildInfoFromImage(params, imageName, config.substitute);
36 const extendImageDetails = await getExtendImageBuildInfo(params, config, imageName, imageBuildInfo, undefined, additionalFeatures, canAddLabelsToContainer);
37 if (!extendImageDetails?.featureBuildInfo) {
38 // no feature extensions - return
39 if (additionalImageNames.length) {
40 if (params.isTTY) {
41 await Promise.all(additionalImageNames.map(name => dockerPtyCLI(params, 'tag', imageName, name)));
42 } else {
43 await Promise.all(additionalImageNames.map(name => dockerCLI(params, 'tag', imageName, name)));
44 }
45 }
46 return {
47 updatedImageName: [imageName],
48 imageMetadata: getDevcontainerMetadata(imageBuildInfo.metadata, config, extendImageDetails?.featuresConfig),
49 imageDetails: async () => imageBuildInfo.imageDetails,
50 labels: extendImageDetails?.labels,
51 };
52 }
53 const { featureBuildInfo, featuresConfig } = extendImageDetails;
54
55 // Got feature extensions -> build the image
56 const dockerfilePath = cliHost.path.join(featureBuildInfo.dstFolder, 'Dockerfile.extended');
57 await cliHost.writeFile(dockerfilePath, Buffer.from(featureBuildInfo.dockerfilePrefixContent + featureBuildInfo.dockerfileContent));
58 const folderImageName = getFolderImageName(common);
59 const updatedImageName = `${imageName.startsWith(folderImageName) ? imageName : folderImageName}-features`;
60
61 const args: string[] = [];
62 if (!params.buildKitVersion &&
63 (params.buildxPlatform || params.buildxPush)) {
64 throw new ContainerError({ description: '--platform or --push require BuildKit enabled.', data: { fileWithError: dockerfilePath } });
65 }
66 if (params.buildKitVersion) {
67 args.push('buildx', 'build');
68
69 // --platform
70 if (params.buildxPlatform) {
71 output.write('Setting BuildKit platform(s): ' + params.buildxPlatform, LogLevel.Trace);
72 args.push('--platform', params.buildxPlatform);
73 }
74
75 // --push/--output
76 if (params.buildxPush) {
77 args.push('--push');
78 } else {
79 if (params.buildxOutput) {
80 args.push('--output', params.buildxOutput);
81 } else {
82 args.push('--load'); // (short for --output=docker, i.e. load into normal 'docker images' collection)
83 }
84 }
85 if (params.buildxCacheTo) {
86 args.push('--cache-to', params.buildxCacheTo);
87 }
88 if (!isBuildxCacheToInline(params.buildxCacheTo)) {

Callers 2

buildNamedImageAndExtendFunction · 0.90
doBuildFunction · 0.90

Calls 14

dockerPtyCLIFunction · 0.90
dockerCLIFunction · 0.90
getDevcontainerMetadataFunction · 0.90
getFolderImageNameFunction · 0.90
isBuildxCacheToInlineFunction · 0.90
getEmptyContextFolderFunction · 0.90
toPtyExecParametersFunction · 0.90
makeLogFunction · 0.90
toExecParametersFunction · 0.90
getExtendImageBuildInfoFunction · 0.85
writeFileMethod · 0.65

Tested by

no test coverage detected