diff --git a/src/installer/corehost/cli/hostpolicy/coreclr.cpp b/src/installer/corehost/cli/hostpolicy/coreclr.cpp index 234353aa4c47e..b329a72d85886 100644 --- a/src/installer/corehost/cli/hostpolicy/coreclr.cpp +++ b/src/installer/corehost/cli/hostpolicy/coreclr.cpp @@ -203,7 +203,8 @@ namespace _X("JIT_PATH"), _X("STARTUP_HOOKS"), _X("APP_PATHS"), - _X("APP_NI_PATHS") + _X("APP_NI_PATHS"), + _X("RUNTIME_IDENTIFIER") }; static_assert((sizeof(PropertyNameMapping) / sizeof(*PropertyNameMapping)) == static_cast(common_property::Last), "Invalid property count"); diff --git a/src/installer/corehost/cli/hostpolicy/coreclr.h b/src/installer/corehost/cli/hostpolicy/coreclr.h index d2ccd5da5510d..a06e81fe2e346 100644 --- a/src/installer/corehost/cli/hostpolicy/coreclr.h +++ b/src/installer/corehost/cli/hostpolicy/coreclr.h @@ -67,6 +67,7 @@ enum class common_property StartUpHooks, AppPaths, AppNIPaths, + RuntimeIdentifier, // Sentinel value - new values should be defined above Last diff --git a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp index 17bfe5d3e99aa..bb4a965126d96 100644 --- a/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp +++ b/src/installer/corehost/cli/hostpolicy/hostpolicy_context.cpp @@ -145,6 +145,7 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a coreclr_properties.add(common_property::FxDepsFile, fx_deps_str.c_str()); coreclr_properties.add(common_property::ProbingDirectories, resolver.get_lookup_probe_directories().c_str()); coreclr_properties.add(common_property::FxProductVersion, clr_library_version.c_str()); + coreclr_properties.add(common_property::RuntimeIdentifier, get_current_runtime_id(true /*use_fallback*/).c_str()); if (!clrjit_path.empty()) coreclr_properties.add(common_property::JitPath, clrjit_path.c_str()); diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs index 412075fad881d..f0357797e8ade 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/ref/System.Runtime.InteropServices.RuntimeInformation.cs @@ -32,6 +32,7 @@ public enum Architecture } public static partial class RuntimeInformation { + public static string RuntimeIdentifier { get { throw null; } } public static string FrameworkDescription { get { throw null; } } public static System.Runtime.InteropServices.Architecture OSArchitecture { get { throw null; } } public static string OSDescription { get { throw null; } } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs index 8d61597264a2a..98537186a4d01 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs @@ -10,6 +10,7 @@ public static partial class RuntimeInformation { private const string FrameworkName = ".NET Core"; private static string? s_frameworkDescription; + private static string? s_runtimeIdentifier; public static string FrameworkDescription { @@ -41,5 +42,18 @@ public static string FrameworkDescription return s_frameworkDescription; } } + + public static string RuntimeIdentifier + { + get + { + if (s_runtimeIdentifier == null) + { + s_runtimeIdentifier = (string?)AppContext.GetData("RUNTIME_IDENTIFIER") ?? "unknown"; + } + + return s_runtimeIdentifier; + } + } } } diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs index 73f692898dbcf..379bff8436dfd 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs @@ -22,7 +22,8 @@ public void DumpRuntimeInformationToConsole() string osd = RuntimeInformation.OSDescription.Trim(); string osv = Environment.OSVersion.ToString(); string osa = RuntimeInformation.OSArchitecture.ToString(); - Console.WriteLine($"### OS: Distro={dvs} Description={osd} Version={osv} Arch={osa}"); + string rid = RuntimeInformation.RuntimeIdentifier; + Console.WriteLine($"### OS: Distro={dvs} Description={osd} Version={osv} Arch={osa} Rid={rid}"); string lcr = PlatformDetection.LibcRelease; string lcv = PlatformDetection.LibcVersion; diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs new file mode 100644 index 0000000000000..75b27d18ed9aa --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/RuntimeIdentifierTests.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.IO; +using System.Linq; +using Microsoft.DotNet.RemoteExecutor; +using Xunit; + +namespace System.Runtime.InteropServices.RuntimeInformationTests +{ + public class RuntimeIdentifierTests + { + [Fact(Skip = "#26780 Need new testhost")] + public void VerifyOSRid() + { + Assert.NotNull(RuntimeInformation.RuntimeIdentifier); + Assert.Same(RuntimeInformation.RuntimeIdentifier, RuntimeInformation.RuntimeIdentifier); + Assert.EndsWith(RuntimeInformation.ProcessArchitecture.ToString(), RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase); + } + + [Fact(Skip = "#26780 Need new testhost")] + public void VerifyEnvironmentVariable() + { + RemoteInvokeOptions options = new RemoteInvokeOptions(); + options.StartInfo.EnvironmentVariables.Add("DOTNET_RUNTIME_ID", "overridenFromEnv-rid"); + + RemoteExecutor.Invoke(() => + { + Assert.Equal("overridenFromEnv-rid", RuntimeInformation.RuntimeIdentifier); + }, options).Dispose(); + } + + [Fact] + public void VerifyAppContextVariable() + { + RemoteExecutor.Invoke(() => + { + AppDomain.CurrentDomain.SetData("RUNTIME_IDENTIFIER", "overriden-rid"); + + Assert.Equal("overriden-rid", RuntimeInformation.RuntimeIdentifier); + }).Dispose(); + } + + [Fact(Skip = "#26780 Need new testhost"), PlatformSpecific(TestPlatforms.Windows)] + public void VerifyWindowsRid() + { + Assert.StartsWith("win", RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase); + } + + [Fact(Skip = "#26780 Need new testhost"), PlatformSpecific(TestPlatforms.Linux)] + public void VerifyLinuxRid() + { + string expectedOSName = File.ReadAllLines("/etc/os-release") + .First(line => line.StartsWith("ID=", StringComparison.OrdinalIgnoreCase)) + .Substring("ID=".Length) + .Trim(); + + Assert.StartsWith(expectedOSName, RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase); + } + + [Fact(Skip = "#26780 Need new testhost"), PlatformSpecific(TestPlatforms.FreeBSD)] + public void VerifyFreeBSDRid() + { + Assert.StartsWith("freebsd", RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase); + } + + [Fact(Skip = "#26780 Need new testhost"), PlatformSpecific(TestPlatforms.OSX)] + public void VerifyOSXRid() + { + Assert.StartsWith("osx", RuntimeInformation.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj index b5c466a5617fd..d2db26f29416e 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/System.Runtime.InteropServices.RuntimeInformation.Tests.csproj @@ -1,10 +1,12 @@ + true $(NetCoreAppCurrent)-Windows_NT;$(NetCoreAppCurrent)-Unix + Common\Interop\Linux\Interop.cgroups.cs