Skip to content

Commit 56ef042

Browse files
authored
Force OCI format for inner images when publishing tarballs or to local docker instances (#47398)
1 parent 36cf069 commit 56ef042

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,16 @@
304304
<!--We don't want to skip publishing individual images in case of local daemon podman because podman loads multi-arch tarball differently - only individual image for the current platform.-->
305305
<_SkipContainerPublishing>false</_SkipContainerPublishing>
306306
<_SkipContainerPublishing Condition="$(ContainerArchiveOutputPath) != '' or ( $(ContainerRegistry) == '' and ( $(LocalRegistry) == '' or $(LocalRegistry) == 'Docker' ) )">true</_SkipContainerPublishing>
307-
307+
308308
<!--We want to skip CreateImageIndex task in case of local daemon podman because it is not supported.-->
309309
<_SkipCreateImageIndex>false</_SkipCreateImageIndex>
310310
<_SkipCreateImageIndex Condition="$(ContainerArchiveOutputPath) == '' and $(ContainerRegistry) == '' and $(LocalRegistry) == 'Podman'">true</_SkipCreateImageIndex>
311+
312+
<!-- Figure out what format the inner images should be coerced to -->
313+
<!-- If a user had an opinion, use that -->
314+
<_SingleImageContainerFormat Condition="'$(ContainerImageFormat)' != ''">$(ContainerImageFormat)</_SingleImageContainerFormat>
315+
<!-- If we are publishing to local tarball or to local Docker, force OCI to prevent mismatches between inner images and the outer manifest -->
316+
<_SingleImageContainerFormat Condition="$(_SkipContainerPublishing) == 'true' ">OCI</_SingleImageContainerFormat>
311317
</PropertyGroup>
312318

313319
<ItemGroup>
@@ -337,7 +343,8 @@
337343
ContainerUser=$(ContainerUser);
338344
ContainerGenerateLabels=$(ContainerGenerateLabels);
339345
ContainerGenerateLabelsImageBaseDigest=$(ContainerGenerateLabelsImageBaseDigest);
340-
_SkipContainerPublishing=$(_SkipContainerPublishing)
346+
_SkipContainerPublishing=$(_SkipContainerPublishing);
347+
ContainerImageFormat=$(_SingleImageContainerFormat)
341348
"/>
342349
<_rids Remove ="$(_rids)" />
343350
</ItemGroup>

src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,4 +1427,45 @@ static string[] DecideEntrypoint(string rid, string appName, string workingDir)
14271427
return new[] { $"{workingDir}/{binary}" };
14281428
}
14291429
}
1430+
1431+
[DockerAvailableFact(checkContainerdStoreAvailability: true)]
1432+
public void EnforcesOciSchemaForMultiRIDTarballOutput()
1433+
{
1434+
string imageName = NewImageName();
1435+
string tag = "1.0";
1436+
1437+
// Create new console app
1438+
DirectoryInfo newProjectDir = CreateNewProject("webapp");
1439+
1440+
// Run PublishContainer for multi-arch with ContainerGenerateLabels
1441+
var publishResult = new DotnetCommand(
1442+
_testOutput,
1443+
"publish",
1444+
"/t:PublishContainer",
1445+
"/p:RuntimeIdentifiers=\"linux-x64;linux-arm64\"",
1446+
$"/p:ContainerBaseImage={DockerRegistryManager.FullyQualifiedBaseImageAspNet}",
1447+
$"/p:ContainerRepository={imageName}",
1448+
$"/p:ContainerImageTag={tag}",
1449+
"/p:EnableSdkContainerSupport=true",
1450+
"/p:ContainerArchiveOutputPath=archive.tar.gz",
1451+
"-getProperty:GeneratedImageIndex",
1452+
"-getItem:GeneratedContainers",
1453+
"/bl")
1454+
.WithWorkingDirectory(newProjectDir.FullName)
1455+
.Execute();
1456+
1457+
publishResult.Should().Pass();
1458+
var jsonDump = JsonDocument.Parse(publishResult.StdOut);
1459+
var index = JsonDocument.Parse(jsonDump.RootElement.GetProperty("Properties").GetProperty("GeneratedImageIndex").ToString());
1460+
var containers = jsonDump.RootElement.GetProperty("Items").GetProperty("GeneratedContainers").EnumerateArray().ToArray();
1461+
1462+
index.RootElement.GetProperty("mediaType").GetString().Should().Be("application/vnd.oci.image.index.v1+json");
1463+
containers.Should().HaveCount(2);
1464+
foreach (var container in containers)
1465+
{
1466+
container.GetProperty("ManifestMediaType").GetString().Should().Be("application/vnd.oci.image.manifest.v1+json");
1467+
}
1468+
// Cleanup
1469+
newProjectDir.Delete(true);
1470+
}
14301471
}

0 commit comments

Comments
 (0)