Skip to content

Commit 750f6e9

Browse files
committed
Remove experimental flag for metadata
1 parent c89f4e4 commit 750f6e9

13 files changed

Lines changed: 58 additions & 150 deletions

File tree

src/spec-common/injectHeadless.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ export interface ResolverParameters {
6262
buildxOutput: string | undefined;
6363
skipFeatureAutoMapping: boolean;
6464
skipPostAttach: boolean;
65-
experimentalImageMetadata: boolean;
6665
containerSessionDataFolder?: string;
6766
skipPersistingCustomizationsFromFeatures: boolean;
6867
omitConfigRemotEnvFromMetadata?: boolean;

src/spec-node/containerFeatures.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export async function extendImage(params: DockerResolverParameters, config: Subs
3434
const { common } = params;
3535
const { cliHost, output } = common;
3636

37-
const imageBuildInfo = await getImageBuildInfoFromImage(params, imageName, config.substitute, common.experimentalImageMetadata);
37+
const imageBuildInfo = await getImageBuildInfoFromImage(params, imageName, config.substitute);
3838
const extendImageDetails = await getExtendImageBuildInfo(params, config, imageName, imageBuildInfo, undefined, additionalFeatures, canAddLabelsToContainer);
3939
if (!extendImageDetails?.featureBuildInfo) {
4040
// no feature extensions - return
@@ -224,7 +224,7 @@ function getImageBuildOptions(params: DockerResolverParameters, config: Substitu
224224
dstFolder,
225225
dockerfileContent: `
226226
FROM $_DEV_CONTAINERS_BASE_IMAGE AS dev_containers_target_stage
227-
${getDevcontainerMetadataLabel(getDevcontainerMetadata(imageBuildInfo.metadata, config, { featureSets: [] }, [], getOmitDevcontainerPropertyOverride(params.common)), params.common.experimentalImageMetadata)}
227+
${getDevcontainerMetadataLabel(getDevcontainerMetadata(imageBuildInfo.metadata, config, { featureSets: [] }, [], getOmitDevcontainerPropertyOverride(params.common)))}
228228
`,
229229
overrideTarget: 'dev_containers_target_stage',
230230
dockerfilePrefixContent: `${syntax ? `# syntax=${syntax}` : ''}
@@ -297,7 +297,7 @@ async function getFeaturesBuildOptions(params: DockerResolverParameters, devCont
297297
.replace('#{nonBuildKitFeatureContentFallback}', useBuildKitBuildContexts ? '' : `FROM ${buildContentImageName} as dev_containers_feature_content_source`)
298298
.replace('#{featureLayer}', getFeatureLayers(featuresConfig, containerUser, remoteUser, useBuildKitBuildContexts, contentSourceRootPath))
299299
.replace('#{containerEnv}', generateContainerEnvs(featuresConfig))
300-
.replace('#{devcontainerMetadata}', getDevcontainerMetadataLabel(imageMetadata, common.experimentalImageMetadata))
300+
.replace('#{devcontainerMetadata}', getDevcontainerMetadataLabel(imageMetadata))
301301
.replace('#{containerEnvMetadata}', getContainerEnvMetadata(devContainerConfig.config.containerEnv))
302302
;
303303
const syntax = imageBuildInfo.dockerfile?.preamble.directives.syntax;

src/spec-node/devContainers.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import { getPackageConfig, PackageConfiguration } from '../spec-utils/product';
1919
import { dockerBuildKitVersion } from '../spec-shutdown/dockerUtils';
2020
import { Event } from '../spec-utils/event';
2121

22-
export const experimentalImageMetadataDefault = true;
2322

2423
export interface ProvisionOptions {
2524
dockerPath: string | undefined;
@@ -56,7 +55,6 @@ export interface ProvisionOptions {
5655
additionalFeatures?: Record<string, string | boolean | Record<string, string | boolean>>;
5756
skipFeatureAutoMapping: boolean;
5857
skipPostAttach: boolean;
59-
experimentalImageMetadata: boolean;
6058
containerSessionDataFolder?: string;
6159
skipPersistingCustomizationsFromFeatures: boolean;
6260
omitConfigRemotEnvFromMetadata?: boolean;
@@ -138,7 +136,6 @@ export async function createDockerParams(options: ProvisionOptions, disposables:
138136
buildxOutput: options.buildxOutput,
139137
skipFeatureAutoMapping: options.skipFeatureAutoMapping,
140138
skipPostAttach: options.skipPostAttach,
141-
experimentalImageMetadata: options.experimentalImageMetadata,
142139
containerSessionDataFolder: options.containerSessionDataFolder,
143140
skipPersistingCustomizationsFromFeatures: options.skipPersistingCustomizationsFromFeatures,
144141
omitConfigRemotEnvFromMetadata: options.omitConfigRemotEnvFromMetadata,

src/spec-node/devContainersSpecCLI.ts

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import yargs, { Argv } from 'yargs';
88

99
import * as jsonc from 'jsonc-parser';
1010

11-
import { createDockerParams, createLog, experimentalImageMetadataDefault, launch, ProvisionOptions } from './devContainers';
11+
import { createDockerParams, createLog, launch, ProvisionOptions } from './devContainers';
1212
import { SubstitutedConfig, createContainerProperties, createFeaturesTempFolder, envListToObj, inspectDockerImage, isDockerFileConfig, SubstituteConfig, addSubstitution, findContainerAndIdLabels } from './utils';
1313
import { URI } from 'vscode-uri';
1414
import { ContainerError } from '../spec-common/errors';
@@ -117,7 +117,6 @@ function provisionOptions(y: Argv) {
117117
'additional-features': { type: 'string', description: 'Additional features to apply to the dev container (JSON as per "features" section in devcontainer.json)' },
118118
'skip-feature-auto-mapping': { type: 'boolean', default: false, hidden: true, description: 'Temporary option for testing.' },
119119
'skip-post-attach': { type: 'boolean', default: false, description: 'Do not run postAttachCommand.' },
120-
'experimental-image-metadata': { type: 'boolean', default: experimentalImageMetadataDefault, hidden: true, description: 'Temporary option for testing.' },
121120
'dotfiles-repository': { type: 'string', description: 'URL of a dotfiles Git repository (e.g., https://github.com/owner/repository.git)' },
122121
'dotfiles-install-command': { type: 'string', description: 'The command to run after cloning the dotfiles repository. Defaults to run the first file of `install.sh`, `install`, `bootstrap.sh`, `bootstrap`, `setup.sh` and `setup` found in the dotfiles repository`s root folder.' },
123122
'dotfiles-target-path': { type: 'string', default: '~/dotfiles', description: 'The path to clone the dotfiles repository to. Defaults to `~/dotfiles`.' },
@@ -184,7 +183,6 @@ async function provision({
184183
'additional-features': additionalFeaturesJson,
185184
'skip-feature-auto-mapping': skipFeatureAutoMapping,
186185
'skip-post-attach': skipPostAttach,
187-
'experimental-image-metadata': experimentalImageMetadata,
188186
'dotfiles-repository': dotfilesRepository,
189187
'dotfiles-install-command': dotfilesInstallCommand,
190188
'dotfiles-target-path': dotfilesTargetPath,
@@ -243,7 +241,6 @@ async function provision({
243241
additionalFeatures,
244242
skipFeatureAutoMapping,
245243
skipPostAttach,
246-
experimentalImageMetadata,
247244
containerSessionDataFolder,
248245
skipPersistingCustomizationsFromFeatures: false,
249246
omitConfigRemotEnvFromMetadata: omitConfigRemotEnvFromMetadata,
@@ -394,7 +391,6 @@ async function doSetUp({
394391
buildxOutput: undefined,
395392
skipFeatureAutoMapping: false,
396393
skipPostAttach: false,
397-
experimentalImageMetadata: true,
398394
skipPersistingCustomizationsFromFeatures: false,
399395
dotfiles: {
400396
repository: dotfilesRepository,
@@ -424,7 +420,7 @@ async function doSetUp({
424420
const config1 = addSubstitution(config0, config => beforeContainerSubstitute(undefined, config));
425421
const config = addSubstitution(config1, config => containerSubstitute(cliHost.platform, config1.config.configFilePath, envListToObj(container.Config.Env), config));
426422

427-
const imageMetadata = getImageMetadataFromContainer(container, config, undefined, undefined, true, output).config;
423+
const imageMetadata = getImageMetadataFromContainer(container, config, undefined, undefined, output).config;
428424
const mergedConfig = mergeConfiguration(config.config, imageMetadata);
429425
const containerProperties = await createContainerProperties(params, container.Id, configs?.workspaceConfig.workspaceFolder, mergedConfig.remoteUser);
430426
await setupInContainer(common, containerProperties, mergedConfig, lifecycleCommandOriginMapFromMetadata(imageMetadata));
@@ -467,7 +463,6 @@ function buildOptions(y: Argv) {
467463
'output': { type: 'string', description: 'Overrides the default behavior to load built images into the local docker registry. Valid options are the same ones provided to the --output option of docker buildx build.' },
468464
'additional-features': { type: 'string', description: 'Additional features to apply to the dev container (JSON as per "features" section in devcontainer.json)' },
469465
'skip-feature-auto-mapping': { type: 'boolean', default: false, hidden: true, description: 'Temporary option for testing.' },
470-
'experimental-image-metadata': { type: 'boolean', default: experimentalImageMetadataDefault, hidden: true, description: 'Temporary option for testing.' },
471466
'skip-persisting-customizations-from-features': { type: 'boolean', default: false, hidden: true, description: 'Do not save customizations from referenced Features as image metadata' },
472467
});
473468
}
@@ -502,7 +497,6 @@ async function doBuild({
502497
'output': buildxOutput,
503498
'additional-features': additionalFeaturesJson,
504499
'skip-feature-auto-mapping': skipFeatureAutoMapping,
505-
'experimental-image-metadata': experimentalImageMetadata,
506500
'skip-persisting-customizations-from-features': skipPersistingCustomizationsFromFeatures,
507501
}: BuildArgs) {
508502
const disposables: (() => Promise<unknown> | undefined)[] = [];
@@ -546,7 +540,6 @@ async function doBuild({
546540
buildxOutput,
547541
skipFeatureAutoMapping,
548542
skipPostAttach: true,
549-
experimentalImageMetadata,
550543
skipPersistingCustomizationsFromFeatures: skipPersistingCustomizationsFromFeatures,
551544
dotfiles: {}
552545
}, disposables);
@@ -692,7 +685,6 @@ function runUserCommandsOptions(y: Argv) {
692685
'remote-env': { type: 'string', description: 'Remote environment variables of the format name=value. These will be added when executing the user commands.' },
693686
'skip-feature-auto-mapping': { type: 'boolean', default: false, hidden: true, description: 'Temporary option for testing.' },
694687
'skip-post-attach': { type: 'boolean', default: false, description: 'Do not run postAttachCommand.' },
695-
'experimental-image-metadata': { type: 'boolean', default: experimentalImageMetadataDefault, hidden: true, description: 'Temporary option for testing.' },
696688
'dotfiles-repository': { type: 'string', description: 'URL of a dotfiles Git repository (e.g., https://github.com/owner/repository.git)' },
697689
'dotfiles-install-command': { type: 'string', description: 'The command to run after cloning the dotfiles repository. Defaults to run the first file of `install.sh`, `install`, `bootstrap.sh`, `bootstrap`, `setup.sh` and `setup` found in the dotfiles repository`s root folder.' },
698690
'dotfiles-target-path': { type: 'string', default: '~/dotfiles', description: 'The path to clone the dotfiles repository to. Defaults to `~/dotfiles`.' },
@@ -750,7 +742,6 @@ async function doRunUserCommands({
750742
'remote-env': addRemoteEnv,
751743
'skip-feature-auto-mapping': skipFeatureAutoMapping,
752744
'skip-post-attach': skipPostAttach,
753-
'experimental-image-metadata': experimentalImageMetadata,
754745
'dotfiles-repository': dotfilesRepository,
755746
'dotfiles-install-command': dotfilesInstallCommand,
756747
'dotfiles-target-path': dotfilesTargetPath,
@@ -797,7 +788,6 @@ async function doRunUserCommands({
797788
buildxOutput: undefined,
798789
skipFeatureAutoMapping,
799790
skipPostAttach,
800-
experimentalImageMetadata,
801791
skipPersistingCustomizationsFromFeatures: false,
802792
dotfiles: {
803793
repository: dotfilesRepository,
@@ -833,7 +823,7 @@ async function doRunUserCommands({
833823
const config1 = addSubstitution(config0, config => beforeContainerSubstitute(envListToObj(idLabels), config));
834824
const config = addSubstitution(config1, config => containerSubstitute(cliHost.platform, config1.config.configFilePath, envListToObj(container.Config.Env), config));
835825

836-
const imageMetadata = getImageMetadataFromContainer(container, config, undefined, idLabels, experimentalImageMetadata, output).config;
826+
const imageMetadata = getImageMetadataFromContainer(container, config, undefined, idLabels, output).config;
837827
const mergedConfig = mergeConfiguration(config.config, imageMetadata);
838828
const containerProperties = await createContainerProperties(params, container.Id, configs?.workspaceConfig.workspaceFolder, mergedConfig.remoteUser);
839829
const updatedConfig = containerSubstitute(cliHost.platform, config.config.configFilePath, containerProperties.env, mergedConfig);
@@ -882,7 +872,6 @@ function readConfigurationOptions(y: Argv) {
882872
'include-merged-configuration': { type: 'boolean', default: false, description: 'Include merged configuration.' },
883873
'additional-features': { type: 'string', description: 'Additional features to apply to the dev container (JSON as per "features" section in devcontainer.json)' },
884874
'skip-feature-auto-mapping': { type: 'boolean', default: false, hidden: true, description: 'Temporary option for testing.' },
885-
'experimental-image-metadata': { type: 'boolean', default: experimentalImageMetadataDefault, hidden: true, description: 'Temporary option for testing.' },
886875
})
887876
.check(argv => {
888877
const idLabels = (argv['id-label'] && (Array.isArray(argv['id-label']) ? argv['id-label'] : [argv['id-label']])) as string[] | undefined;
@@ -920,7 +909,6 @@ async function readConfiguration({
920909
'include-merged-configuration': includeMergedConfig,
921910
'additional-features': additionalFeaturesJson,
922911
'skip-feature-auto-mapping': skipFeatureAutoMapping,
923-
'experimental-image-metadata': experimentalImageMetadata,
924912
}: ReadConfigurationArgs) {
925913
const disposables: (() => Promise<unknown> | undefined)[] = [];
926914
const dispose = async () => {
@@ -980,17 +968,17 @@ async function readConfiguration({
980968
}
981969

982970
const additionalFeatures = additionalFeaturesJson ? jsonc.parse(additionalFeaturesJson) as Record<string, string | boolean | Record<string, string | boolean>> : {};
983-
const needsFeaturesConfig = includeFeaturesConfig || (includeMergedConfig && (!container || !experimentalImageMetadata));
971+
const needsFeaturesConfig = includeFeaturesConfig || (includeMergedConfig && !container);
984972
const featuresConfiguration = needsFeaturesConfig ? await readFeaturesConfig(params, pkg, configuration.config, extensionPath, skipFeatureAutoMapping, additionalFeatures) : undefined;
985973
let mergedConfig: MergedDevContainerConfig | undefined;
986974
if (includeMergedConfig) {
987975
let imageMetadata: ImageMetadataEntry[];
988976
if (container) {
989-
imageMetadata = getImageMetadataFromContainer(container, configuration, featuresConfiguration, idLabels, experimentalImageMetadata, output).config;
977+
imageMetadata = getImageMetadataFromContainer(container, configuration, featuresConfiguration, idLabels, output).config;
990978
const substitute2: SubstituteConfig = config => containerSubstitute(cliHost.platform, configuration.config.configFilePath, envListToObj(container.Config.Env), config);
991979
imageMetadata = imageMetadata.map(substitute2);
992980
} else {
993-
const imageBuildInfo = await getImageBuildInfo(params, configuration, experimentalImageMetadata);
981+
const imageBuildInfo = await getImageBuildInfo(params, configuration);
994982
imageMetadata = getDevcontainerMetadata(imageBuildInfo.metadata, configuration, featuresConfiguration).config;
995983
}
996984
mergedConfig = mergeConfiguration(configuration.config, imageMetadata);
@@ -1043,7 +1031,6 @@ function execOptions(y: Argv) {
10431031
'default-user-env-probe': { choices: ['none' as 'none', 'loginInteractiveShell' as 'loginInteractiveShell', 'interactiveShell' as 'interactiveShell', 'loginShell' as 'loginShell'], default: defaultDefaultUserEnvProbe, description: 'Default value for the devcontainer.json\'s "userEnvProbe".' },
10441032
'remote-env': { type: 'string', description: 'Remote environment variables of the format name=value. These will be added when executing the user commands.' },
10451033
'skip-feature-auto-mapping': { type: 'boolean', default: false, hidden: true, description: 'Temporary option for testing.' },
1046-
'experimental-image-metadata': { type: 'boolean', default: experimentalImageMetadataDefault, hidden: true, description: 'Temporary option for testing.' },
10471034
})
10481035
.positional('cmd', {
10491036
type: 'string',
@@ -1105,7 +1092,6 @@ export async function doExec({
11051092
'default-user-env-probe': defaultUserEnvProbe,
11061093
'remote-env': addRemoteEnv,
11071094
'skip-feature-auto-mapping': skipFeatureAutoMapping,
1108-
'experimental-image-metadata': experimentalImageMetadata,
11091095
_: restArgs,
11101096
}: ExecArgs & { _?: string[] }) {
11111097
const disposables: (() => Promise<unknown> | undefined)[] = [];
@@ -1153,7 +1139,6 @@ export async function doExec({
11531139
skipFeatureAutoMapping,
11541140
buildxOutput: undefined,
11551141
skipPostAttach: false,
1156-
experimentalImageMetadata,
11571142
skipPersistingCustomizationsFromFeatures: false,
11581143
dotfiles: {}
11591144
}, disposables);
@@ -1181,7 +1166,7 @@ export async function doExec({
11811166
if (!container) {
11821167
bailOut(common.output, 'Dev container not found.');
11831168
}
1184-
const imageMetadata = getImageMetadataFromContainer(container, config, undefined, idLabels, experimentalImageMetadata, output).config;
1169+
const imageMetadata = getImageMetadataFromContainer(container, config, undefined, idLabels, output).config;
11851170
const mergedConfig = mergeConfiguration(config.config, imageMetadata);
11861171
const containerProperties = await createContainerProperties(params, container.Id, configs?.workspaceConfig.workspaceFolder, mergedConfig.remoteUser);
11871172
const updatedConfig = containerSubstitute(cliHost.platform, config.config.configFilePath, containerProperties.env, mergedConfig);

src/spec-node/dockerCompose.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ async function _openDockerComposeDevContainer(params: DockerResolverParameters,
6868
// collapsedFeaturesConfig = collapseFeaturesConfig(featuresConfig);
6969
}
7070

71-
const imageMetadata = getImageMetadataFromContainer(container, configWithRaw, undefined, idLabels, common.experimentalImageMetadata, common.output).config;
71+
const imageMetadata = getImageMetadataFromContainer(container, configWithRaw, undefined, idLabels, common.output).config;
7272
const mergedConfig = mergeConfiguration(configWithRaw.config, imageMetadata);
7373
containerProperties = await createContainerProperties(params, container.Id, remoteWorkspaceFolder, mergedConfig.remoteUser);
7474

@@ -176,9 +176,9 @@ export async function buildAndExtendDockerCompose(configWithRaw: SubstitutedConf
176176
dockerfile = modifiedDockerfile;
177177
}
178178
}
179-
imageBuildInfo = await getImageBuildInfoFromDockerfile(params, originalDockerfile, serviceInfo.build?.args || {}, serviceInfo.build?.target, configWithRaw.substitute, common.experimentalImageMetadata);
179+
imageBuildInfo = await getImageBuildInfoFromDockerfile(params, originalDockerfile, serviceInfo.build?.args || {}, serviceInfo.build?.target, configWithRaw.substitute);
180180
} else {
181-
imageBuildInfo = await getImageBuildInfoFromImage(params, composeService.image, configWithRaw.substitute, common.experimentalImageMetadata);
181+
imageBuildInfo = await getImageBuildInfoFromImage(params, composeService.image, configWithRaw.substitute);
182182
}
183183

184184
// determine whether we need to extend with features

src/spec-node/featuresCLI/test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export function featuresTestOptions(y: Argv) {
1919
'base-image': { type: 'string', alias: 'i', default: 'ubuntu:focal', description: 'Base Image. Not used for scenarios.' }, // TODO: Optionally replace 'scenario' configs with this value?
2020
'remote-user': { type: 'string', alias: 'u', describe: 'Remote user. Not used for scenarios.', }, // TODO: Optionally replace 'scenario' configs with this value?
2121
'log-level': { choices: ['info' as 'info', 'debug' as 'debug', 'trace' as 'trace'], default: 'info' as 'info', description: 'Log level.' },
22-
'skip-image-metadata': { type: 'boolean', default: false, description: 'Skip applying image metadata to the resultant test image. Image metadata is potentially appended to base images built with the dev container CLI' },
2322
'quiet': { type: 'boolean', alias: 'q', default: false, description: 'Quiets output' },
2423
})
2524
// DEPRECATED: Positional arguments don't play nice with the variadic/array --features option.
@@ -57,7 +56,6 @@ export interface FeaturesTestCommandInput {
5756
skipAutogenerated: boolean;
5857
remoteUser: string | undefined;
5958
quiet: boolean;
60-
skipImageMetadata: boolean;
6159
logLevel: LogLevel;
6260
disposables: (() => Promise<unknown> | undefined)[];
6361
}
@@ -77,7 +75,6 @@ async function featuresTest({
7775
'skip-autogenerated': skipAutogenerated,
7876
'remote-user': remoteUser,
7977
quiet,
80-
'skip-image-metadata': skipImageMetadata,
8178
'log-level': inputLogLevel,
8279
}: FeaturesTestArgs) {
8380
const disposables: (() => Promise<unknown> | undefined)[] = [];
@@ -107,7 +104,6 @@ async function featuresTest({
107104
skipScenarios,
108105
skipAutogenerated,
109106
remoteUser,
110-
skipImageMetadata,
111107
disposables
112108
};
113109

0 commit comments

Comments
 (0)