Skip to content

Commit dc6d68f

Browse files
authored
Allow users to set a specific ContainerImageFormat to force OCI support (#46011)
1 parent 982a3c4 commit dc6d68f

26 files changed

+306
-98
lines changed

src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66

77
namespace Microsoft.NET.Build.Containers;
88

9+
internal enum KnownImageFormats
10+
{
11+
OCI,
12+
Docker
13+
}
14+
915
internal static class ContainerBuilder
1016
{
1117
internal static async Task<int> ContainerizeAsync(
@@ -34,6 +40,7 @@ internal static async Task<int> ContainerizeAsync(
3440
string? archiveOutputPath,
3541
bool generateLabels,
3642
bool generateDigestLabel,
43+
KnownImageFormats? imageFormat,
3744
ILoggerFactory loggerFactory,
3845
CancellationToken cancellationToken)
3946
{
@@ -99,6 +106,15 @@ internal static async Task<int> ContainerizeAsync(
99106
logger.LogInformation(Strings.ContainerBuilder_StartBuildingImage, imageName, string.Join(",", imageName), sourceImageReference);
100107
cancellationToken.ThrowIfCancellationRequested();
101108

109+
// forcibly change the media type if required
110+
imageBuilder.ManifestMediaType = imageFormat switch
111+
{
112+
null => imageBuilder.ManifestMediaType,
113+
KnownImageFormats.Docker => SchemaTypes.DockerManifestV2,
114+
KnownImageFormats.OCI => SchemaTypes.OciManifestV1,
115+
_ => imageBuilder.ManifestMediaType // should be impossible unless we add to the enum
116+
};
117+
102118
Layer newLayer = Layer.FromDirectory(publishDirectory.FullName, workingDir, imageBuilder.IsWindows, imageBuilder.ManifestMediaType);
103119
imageBuilder.AddLayer(newLayer);
104120
imageBuilder.SetWorkingDirectory(workingDir);

src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ internal sealed class ImageBuilder
1919

2020
// the mutable internal manifest that we're building by modifying the base and applying customizations
2121
private readonly ManifestV2 _manifest;
22-
private readonly string _manifestMediaType;
2322
private readonly ImageConfig _baseImageConfig;
2423
private readonly ILogger _logger;
2524

@@ -32,15 +31,15 @@ internal sealed class ImageBuilder
3231
public ImageConfig BaseImageConfig => _baseImageConfig;
3332

3433
/// <summary>
35-
/// MediaType of the output manifest.
34+
/// MediaType of the output manifest. By default, this will be the same as the base image manifest.
3635
/// </summary>
37-
public string ManifestMediaType => _manifestMediaType; // output the same media type as the base image manifest.
36+
public string ManifestMediaType { get; set; }
3837

3938
internal ImageBuilder(ManifestV2 manifest, string manifestMediaType, ImageConfig baseImageConfig, ILogger logger)
4039
{
4140
_baseImageManifest = manifest;
4241
_manifest = new ManifestV2() { SchemaVersion = manifest.SchemaVersion, Config = manifest.Config, Layers = new(manifest.Layers), MediaType = manifest.MediaType };
43-
_manifestMediaType = manifestMediaType;
42+
ManifestMediaType = manifestMediaType;
4443
_baseImageConfig = baseImageConfig;
4544
_logger = logger;
4645
}
@@ -70,14 +69,20 @@ internal BuiltImage Build()
7069
ManifestConfig newManifestConfig = _manifest.Config with
7170
{
7271
digest = imageDigest,
73-
size = imageSize
72+
size = imageSize,
73+
mediaType = ManifestMediaType switch
74+
{
75+
SchemaTypes.OciManifestV1 => SchemaTypes.OciImageConfigV1,
76+
SchemaTypes.DockerManifestV2 => SchemaTypes.DockerContainerV1,
77+
_ => SchemaTypes.OciImageConfigV1 // opinion - defaulting to modern here, but really this should never happen
78+
}
7479
};
7580

7681
ManifestV2 newManifest = new ManifestV2()
7782
{
7883
Config = newManifestConfig,
7984
SchemaVersion = _manifest.SchemaVersion,
80-
MediaType = _manifest.MediaType,
85+
MediaType = ManifestMediaType,
8186
Layers = _manifest.Layers
8287
};
8388

src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net10.0/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateDigestLabel.get -> b
243243
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateDigestLabel.set -> void
244244
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerNames.get -> Microsoft.Build.Framework.ITaskItem![]!
245245
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerNames.set -> void
246+
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageFormat.get -> string?
247+
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageFormat.set -> void
246248
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties
247249
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]!
248250
Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.set -> void

src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateDigestLabel.get -> b
9090
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateDigestLabel.set -> void
9191
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerNames.get -> Microsoft.Build.Framework.ITaskItem![]!
9292
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerNames.set -> void
93+
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageFormat.get -> string?
94+
Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageFormat.set -> void
9395
override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ToolName.get -> string!
9496
override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateCommandLineCommands() -> string!
9597
override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateFullPathToTool() -> string!

src/Containers/Microsoft.NET.Build.Containers/Registry/SchemaTypes.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ internal class SchemaTypes
99
internal const string DockerContainerV1 = "application/vnd.docker.container.image.v1+json";
1010
internal const string DockerManifestListV2 = "application/vnd.docker.distribution.manifest.list.v2+json";
1111
internal const string DockerManifestV2 = "application/vnd.docker.distribution.manifest.v2+json";
12+
1213
internal const string OciManifestV1 = "application/vnd.oci.image.manifest.v1+json"; // https://containers.gitbook.io/build-containers-the-hard-way/#registry-format-oci-image-manifest
1314
internal const string OciImageIndexV1 = "application/vnd.oci.image.index.v1+json";
15+
internal const string OciImageConfigV1 = "application/vnd.oci.image.config.v1+json";
16+
1417
internal const string DockerLayerGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip";
1518
internal const string OciLayerGzipV1 = "application/vnd.oci.image.layer.v1.tar+gzip";
1619
}

0 commit comments

Comments
 (0)