diff --git a/src/spec-node/containerFeatures.ts b/src/spec-node/containerFeatures.ts index e9d89cc67..5a7004865 100644 --- a/src/spec-node/containerFeatures.ts +++ b/src/spec-node/containerFeatures.ts @@ -30,7 +30,7 @@ export const getSafeId = (str: string) => str .replace(/^[\d_]+/g, '_') .toUpperCase(); -export async function extendImage(params: DockerResolverParameters, config: SubstitutedConfig, imageName: string, additionalFeatures: Record>, canAddLabelsToContainer: boolean) { +export async function extendImage(params: DockerResolverParameters, config: SubstitutedConfig, imageName: string, imageNames: string[] | undefined, additionalFeatures: Record>, canAddLabelsToContainer: boolean) { const { common } = params; const { cliHost, output } = common; @@ -50,8 +50,6 @@ export async function extendImage(params: DockerResolverParameters, config: Subs // Got feature extensions -> build the image const dockerfilePath = cliHost.path.join(featureBuildInfo.dstFolder, 'Dockerfile.extended'); await cliHost.writeFile(dockerfilePath, Buffer.from(featureBuildInfo.dockerfilePrefixContent + featureBuildInfo.dockerfileContent)); - const folderImageName = getFolderImageName(common); - const updatedImageName = `${imageName.startsWith(folderImageName) ? imageName : folderImageName}-features`; const args: string[] = []; if (!params.buildKitVersion && @@ -90,6 +88,11 @@ export async function extendImage(params: DockerResolverParameters, config: Subs for (const buildArg in featureBuildInfo.buildArgs) { args.push('--build-arg', `${buildArg}=${featureBuildInfo.buildArgs[buildArg]}`); } + + const folderImageName = getFolderImageName(common); + const updatedImageName: string[] = imageNames ?? [`${imageName.startsWith(folderImageName) ? imageName : folderImageName}-features`]; + updatedImageName.map(imageName => args.push('-t', imageName)); + // Once this is step merged with the user Dockerfile (or working against the base image), // the path will be the dev container context // Set empty dir under temp path as the context for now to ensure we don't have dependencies on the features content @@ -97,7 +100,6 @@ export async function extendImage(params: DockerResolverParameters, config: Subs cliHost.mkdirp(emptyTempDir); args.push( '--target', featureBuildInfo.overrideTarget, - '-t', updatedImageName, '-f', dockerfilePath, emptyTempDir ); @@ -110,7 +112,7 @@ export async function extendImage(params: DockerResolverParameters, config: Subs await dockerCLI(infoParams, ...args); } return { - updatedImageName: [ updatedImageName ], + updatedImageName: updatedImageName, imageMetadata: getDevcontainerMetadata(imageBuildInfo.metadata, config, featuresConfig), imageDetails: async () => imageBuildInfo.imageDetails, }; diff --git a/src/spec-node/devContainersSpecCLI.ts b/src/spec-node/devContainersSpecCLI.ts index 7be28e5fe..b4879c573 100644 --- a/src/spec-node/devContainersSpecCLI.ts +++ b/src/spec-node/devContainersSpecCLI.ts @@ -653,14 +653,8 @@ async function doBuild({ } await inspectDockerImage(params, config.image, true); - const { updatedImageName } = await extendImage(params, configWithRaw, config.image, additionalFeatures, false); - - if (imageNames) { - await Promise.all(imageNames.map(imageName => dockerPtyCLI(params, 'tag', updatedImageName[0], imageName))); - imageNameResult = imageNames; - } else { - imageNameResult = updatedImageName; - } + const { updatedImageName } = await extendImage(params, configWithRaw, config.image, imageNames, additionalFeatures, false); + imageNameResult = updatedImageName; } return { diff --git a/src/spec-node/singleContainer.ts b/src/spec-node/singleContainer.ts index b5fb40e99..507b50883 100644 --- a/src/spec-node/singleContainer.ts +++ b/src/spec-node/singleContainer.ts @@ -120,7 +120,7 @@ export async function buildNamedImageAndExtend(params: DockerResolverParameters, return await buildAndExtendImage(params, configWithRaw as SubstitutedConfig, imageNames, params.buildNoCache ?? false, additionalFeatures); } // image-based dev container - extend - return await extendImage(params, configWithRaw, imageNames[0], additionalFeatures, canAddLabelsToContainer); + return await extendImage(params, configWithRaw, imageNames[0], imageNames.slice(1), additionalFeatures, canAddLabelsToContainer); } async function buildAndExtendImage(buildParams: DockerResolverParameters, configWithRaw: SubstitutedConfig, baseImageNames: string[], noCache: boolean, additionalFeatures: Record>) {