Skip to content

Commit 4dda672

Browse files
authored
Backport 46067 to 9.0.2xx (#46170)
2 parents 3c7fc88 + 003130a commit 4dda672

File tree

2 files changed

+120
-11
lines changed

2 files changed

+120
-11
lines changed

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@
3434
<Target Name="ComputeContainerBaseImage"
3535
Returns="$(ContainerBaseImage)">
3636
<PropertyGroup>
37-
<ContainerRuntimeIdentifiers Condition="'$(BuildingInsideVisualStudio)' != 'true' and '$(ContainerRuntimeIdentifiers)' == '' and '$(IsRidAgnostic)' != 'true'">$(RuntimeIdentifiers)</ContainerRuntimeIdentifiers>
3837
<!-- The Container RID should default to the RID used for the entire build (to ensure things run on the platform they are built for), but the user knows best and so should be able to set it explicitly.
3938
For builds that have a RID, we default to that RID. Otherwise, we default to the Linux RID matching the architecture of the currently-executing SDK. -->
40-
<ContainerRuntimeIdentifier Condition="'$(ContainerRuntimeIdentifier)' == '' and '$(ContainerRuntimeIdentifiers)' == '' and '$(IsRidAgnostic)' != 'true'">$(RuntimeIdentifier)</ContainerRuntimeIdentifier>
39+
<ContainerRuntimeIdentifier Condition="'$(ContainerRuntimeIdentifier)' == '' and '$(RuntimeIdentifier)' != ''">$(RuntimeIdentifier)</ContainerRuntimeIdentifier>
40+
<ContainerRuntimeIdentifiers Condition="'$(BuildingInsideVisualStudio)' != 'true' and '$(ContainerRuntimeIdentifiers)' == '' and '$(IsRidAgnostic)' != 'true'">$(RuntimeIdentifiers)</ContainerRuntimeIdentifiers>
4141
<ContainerRuntimeIdentifier Condition="'$(ContainerRuntimeIdentifier)' == '' and '$(ContainerRuntimeIdentifiers)' == ''">linux-$(NETCoreSdkPortableRuntimeIdentifier.Split('-')[1])</ContainerRuntimeIdentifier>
4242

4343
<_ContainerIsUsingMicrosoftDefaultImages Condition="'$(ContainerBaseImage)' == ''">true</_ContainerIsUsingMicrosoftDefaultImages>
4444
<_ContainerIsUsingMicrosoftDefaultImages Condition="'$(ContainerBaseImage)' != ''">false</_ContainerIsUsingMicrosoftDefaultImages>
4545
</PropertyGroup>
4646

4747
<ItemGroup>
48-
<_TargetRuntimeIdentifiers Include="$(ContainerRuntimeIdentifiers)" Condition="'$(ContainerRuntimeIdentifiers)' != ''" />
49-
<_TargetRuntimeIdentifiers Include="$(ContainerRuntimeIdentifier)" Condition="'$(ContainerRuntimeIdentifiers)' == ''" />
48+
<_TargetRuntimeIdentifiers Include="$(ContainerRuntimeIdentifier)" Condition="'$(ContainerRuntimeIdentifier)' != ''" />
49+
<_TargetRuntimeIdentifiers Include="$(ContainerRuntimeIdentifiers)" Condition="@(_TargetRuntimeIdentifiers->Count()) == 0" />
5050
</ItemGroup>
5151

5252
<ComputeDotnetBaseImageAndTag
@@ -298,9 +298,9 @@
298298

299299
<Target Name="_PublishMultiArchContainers" DependsOnTargets="$(PublishContainerDependsOn)" >
300300
<Error Text="ContainerArchiveOutputPath is invalid. It can only be a directory in multi-arch scenario because the runtime identifier is appended in the end of the filename."
301-
Condition="'$(ContainerArchiveOutputPath)' != '' and
302-
!$(ContainerArchiveOutputPath.EndsWith('/')) and
303-
!$(ContainerArchiveOutputPath.EndsWith('\\')) and
301+
Condition="'$(ContainerArchiveOutputPath)' != '' and
302+
!$(ContainerArchiveOutputPath.EndsWith('/')) and
303+
!$(ContainerArchiveOutputPath.EndsWith('\\')) and
304304
$(ContainerArchiveOutputPath.EndsWith('.tar.gz'))" />
305305

306306
<ItemGroup>
@@ -400,7 +400,14 @@
400400
Condition="'$(IsPublishable)' == 'true' AND '$(EnableSdkContainerSupport)' == 'true'">
401401
<PropertyGroup>
402402
<_IsMultiTFMBuild Condition="'$(TargetFrameworks)' != '' and '$(TargetFramework)' == ''">true</_IsMultiTFMBuild>
403-
<_IsMultiRIDBuild Condition="'$(BuildingInsideVisualStudio)' != 'true' and (('$(RuntimeIdentifiers)' != '' and '$(RuntimeIdentifier)' == '') or ('$(ContainerRuntimeIdentifiers)' != '' and '$(ContainerRuntimeIdentfier)' == ''))">true</_IsMultiRIDBuild>
403+
<!-- we are multi-RID if:
404+
* we have CRIDs and no CRID
405+
* we have RIDs and no (CRIDs or CRID or RID)
406+
-->
407+
<_HasCRIDsAndNoCRID Condition="'$(ContainerRuntimeIdentifiers)' != '' and '$(ContainerRuntimeIdentifier)' == ''">true</_HasCRIDsAndNoCRID>
408+
<_HasRIDs Condition="'$(RuntimeIdentifiers)' != ''">true</_HasRIDs>
409+
<_NoCRIDsOrCRIDorRID Condition="'$(ContainerRuntimeIdentifiers)' == '' and '$(ContainerRuntimeIdentifier)' == '' and '$(RuntimeIdentifier)' == ''">true</_NoCRIDsOrCRIDorRID>
410+
<_IsMultiRIDBuild Condition="'$(BuildingInsideVisualStudio)' != 'true' and ('$(_HasCRIDsAndNoCRID)' == true or ('$(_HasRIDs)' == 'true' and '$(_NoCRIDsOrCRIDorRID)' == 'true'))">true</_IsMultiRIDBuild>
404411
<_IsSingleRIDBuild Condition="'$(_IsMultiRIDBuild)' == ''">true</_IsSingleRIDBuild>
405412
</PropertyGroup>
406413

test/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,108 @@ public void EndToEndMultiArch_LocalRegistry()
780780
newProjectDir.Delete(true);
781781
}
782782

783+
[DockerAvailableFact]
784+
public void MultiArchStillAllowsSingleRID()
785+
{
786+
string imageName = NewImageName();
787+
string imageTag = "1.0";
788+
string qualifiedImageName = $"{imageName}:{imageTag}";
789+
790+
// Create a new console project
791+
DirectoryInfo newProjectDir = CreateNewProject("console");
792+
793+
// Run PublishContainer for multi-arch-capable, but single-arch actual
794+
CommandResult commandResult = new DotnetCommand(
795+
_testOutput,
796+
"publish",
797+
"/t:PublishContainer",
798+
// make it so the app is _able_ to target both linux TFMs
799+
"/p:RuntimeIdentifiers=\"linux-x64;linux-arm64\"",
800+
// and that it opts into to multi-targeting containers for both of those linux TFMs
801+
"/p:ContainerRuntimeIdentifiers=\"linux-x64;linux-arm64\"",
802+
// but then only actually publishes for one of them
803+
"/p:ContainerRuntimeIdentifier=linux-x64",
804+
$"/p:ContainerBaseImage={DockerRegistryManager.FullyQualifiedBaseImageAspNet}",
805+
$"/p:ContainerRepository={imageName}",
806+
$"/p:ContainerImageTag={imageTag}",
807+
"/p:EnableSdkContainerSupport=true",
808+
"/bl")
809+
.WithWorkingDirectory(newProjectDir.FullName)
810+
.Execute();
811+
812+
// Check that the app was published for each RID,
813+
// images were created locally for each RID
814+
// and image index was NOT created
815+
commandResult.Should().Pass()
816+
// no rid-specific path because we didn't pass RuntimeIdentifier
817+
.And.NotHaveStdOutContaining(GetPublishArtifactsPath(newProjectDir.FullName, "linux-x64"))
818+
.And.HaveStdOutContaining($"Pushed image '{qualifiedImageName}' to local registry")
819+
.And.NotHaveStdOutContaining("Pushed image index");
820+
821+
// Check that the containers can be run
822+
CommandResult processResultX64 = ContainerCli.RunCommand(
823+
_testOutput,
824+
"--rm",
825+
"--name",
826+
$"test-container-{imageName}",
827+
qualifiedImageName)
828+
.Execute();
829+
processResultX64.Should().Pass().And.HaveStdOut("Hello, World!");
830+
831+
// Cleanup
832+
newProjectDir.Delete(true);
833+
}
834+
835+
[DockerAvailableFact]
836+
public void MultiArchStillAllowsSingleRIDUsingJustRIDProperties()
837+
{
838+
string imageName = NewImageName();
839+
string imageTag = "1.0";
840+
string qualifiedImageName = $"{imageName}:{imageTag}";
841+
842+
// Create a new console project
843+
DirectoryInfo newProjectDir = CreateNewProject("console");
844+
845+
// Run PublishContainer for multi-arch-capable, but single-arch actual
846+
CommandResult commandResult = new DotnetCommand(
847+
_testOutput,
848+
"publish",
849+
"/t:PublishContainer",
850+
// make it so the app is _able_ to target both linux TFMs
851+
"/p:RuntimeIdentifiers=\"linux-x64;linux-arm64\"",
852+
// but then only actually publishes for one of them
853+
"-r", "linux-x64",
854+
$"/p:ContainerBaseImage={DockerRegistryManager.FullyQualifiedBaseImageAspNet}",
855+
$"/p:ContainerRepository={imageName}",
856+
$"/p:ContainerImageTag={imageTag}",
857+
"/p:EnableSdkContainerSupport=true",
858+
"/bl")
859+
.WithWorkingDirectory(newProjectDir.FullName)
860+
.Execute();
861+
862+
// Check that the app was published for each RID,
863+
// images were created locally for each RID
864+
// and image index was NOT created
865+
commandResult.Should().Pass()
866+
.And.HaveStdOutContaining(GetPublishArtifactsPath(newProjectDir.FullName, "linux-x64", configuration: "Release"))
867+
.And.NotHaveStdOutContaining(GetPublishArtifactsPath(newProjectDir.FullName, "linux-arm64", configuration: "Release"))
868+
.And.HaveStdOutContaining($"Pushed image '{qualifiedImageName}' to local registry")
869+
.And.NotHaveStdOutContaining("Pushed image index");
870+
871+
// Check that the containers can be run
872+
CommandResult processResultX64 = ContainerCli.RunCommand(
873+
_testOutput,
874+
"--rm",
875+
"--name",
876+
$"test-container-{imageName}-x64",
877+
qualifiedImageName)
878+
.Execute();
879+
processResultX64.Should().Pass().And.HaveStdOut("Hello, World!");
880+
881+
// Cleanup
882+
newProjectDir.Delete(true);
883+
}
884+
783885
private DirectoryInfo CreateNewProject(string template, [CallerMemberName] string callerMemberName = "")
784886
{
785887
DirectoryInfo newProjectDir = new DirectoryInfo(Path.Combine(TestSettings.TestArtifactsDirectory, callerMemberName));
@@ -800,8 +902,8 @@ private DirectoryInfo CreateNewProject(string template, [CallerMemberName] strin
800902
return newProjectDir;
801903
}
802904

803-
private string GetPublishArtifactsPath(string projectDir, string rid)
804-
=> Path.Combine(projectDir, "bin", "Debug", ToolsetInfo.CurrentTargetFramework, rid, "publish");
905+
private string GetPublishArtifactsPath(string projectDir, string rid, string configuration = "Debug")
906+
=> Path.Combine(projectDir, "bin", configuration, ToolsetInfo.CurrentTargetFramework, rid, "publish");
805907

806908
[DockerIsAvailableAndSupportsArchFact("linux/arm64")]
807909
public void EndToEndMultiArch_ArchivePublishing()
@@ -1176,7 +1278,7 @@ public void EndToEndMultiArch_Labels()
11761278
// Run PublishContainer for multi-arch with ContainerGenerateLabels
11771279
new DotnetCommand(
11781280
_testOutput,
1179-
"build",
1281+
"publish",
11801282
"/t:PublishContainer",
11811283
"/p:RuntimeIdentifiers=\"linux-x64;linux-arm64\"",
11821284
$"/p:ContainerBaseImage={DockerRegistryManager.FullyQualifiedBaseImageAspNet}",

0 commit comments

Comments
 (0)