Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Use distro detection from Microsoft.DotNet.PlatformAbstractions (#24531)
Browse files Browse the repository at this point in the history
  • Loading branch information
krwq authored Nov 3, 2017
1 parent 7cbb09b commit 4bf9019
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 171 deletions.
6 changes: 6 additions & 0 deletions dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<MicrosoftNETCoreDotNetHostPackageVersion>2.0.1-servicing-25615-03</MicrosoftNETCoreDotNetHostPackageVersion>
<MicrosoftNETCoreDotNetHostPolicyPackageVersion>2.0.1-servicing-25615-03</MicrosoftNETCoreDotNetHostPolicyPackageVersion>
<MicrosoftNETCoreAppPackageVersion>2.1.0-preview1-25902-04</MicrosoftNETCoreAppPackageVersion>
<MicrosoftDotNetPlatformAbstractionsPackageVersion>2.1.0-preview1-25902-04</MicrosoftDotNetPlatformAbstractionsPackageVersion>

<!-- CoreFX-built SNI identity package -->
<RuntimeNativeSystemDataSqlClientSniPackageVersion>4.4.0</RuntimeNativeSystemDataSqlClientSniPackageVersion>
Expand Down Expand Up @@ -150,6 +151,11 @@
<ElementName>MicrosoftNETCoreAppPackageVersion</ElementName>
<PackageId>Microsoft.NETCore.App</PackageId>
</XmlUpdateStep>
<XmlUpdateStep Include="CoreSetup">
<Path>$(MSBuildThisFileFullPath)</Path>
<ElementName>MicrosoftDotNetPlatformAbstractionsPackageVersion</ElementName>
<PackageId>Microsoft.DotNet.PlatformAbstractions</PackageId>
</XmlUpdateStep>
<UpdateStep Include="BuildTools">
<UpdaterType>File</UpdaterType>
<Path>$(MSBuildThisFileDirectory)BuildToolsVersion.txt</Path>
Expand Down
4 changes: 4 additions & 0 deletions external/test-runtime/XUnit.Runtime.depproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
<PackageReference Include="Microsoft.3rdpartytools.MarkdownLog">
<Version>0.10.0-alpha-experimental</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions">

This comment has been minimized.

Copy link
@weshaggard

weshaggard Mar 29, 2018

Member

This dependency causes us a cycle between our repo's to build the source/test projects, which is causing issues with the source-build efforts. We are going to need to rethink this dependency.

<Version>$(MicrosoftDotNetPlatformAbstractionsPackageVersion)</Version>
</PackageReference>
<PackageReference Include="CommandLineParser">
<Version>2.1.1-beta</Version>
</PackageReference>
Expand Down Expand Up @@ -95,6 +98,7 @@
<PackageToInclude Include="xunit.runner.utility"/>
<PackageToInclude Include="Microsoft.xunit.netcore.extensions"/>
<PackageToInclude Include="Newtonsoft.Json"/>
<PackageToInclude Include="Microsoft.DotNet.PlatformAbstractions" />
<PackageToInclude Include="$(XUnitRunnerPackageId)" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public static partial class PlatformDetection
public static System.PlatformDetection.Range[] FrameworkRanges { get { throw null; } }
public static bool HasWindowsShell { get { throw null; } }
public static bool IsArmProcess { get { throw null; } }
public static bool IsCentos7 { get { throw null; } }
public static bool IsDebian { get { throw null; } }
public static bool IsDebian8 { get { throw null; } }
public static bool IsDrawingSupported { get { throw null; } }
Expand All @@ -55,7 +54,7 @@ public static partial class PlatformDetection
public static bool IsNetNative { get { throw null; } }
public static bool IsNonZeroLowerBoundArraySupported { get { throw null; } }
public static bool IsNotArmProcess { get { throw null; } }
public static bool IsNotFedoraOrRedHatOrCentos { get { throw null; } }
public static bool IsNotFedoraOrRedHatFamily { get { throw null; } }
public static bool IsNotMacOsHighSierraOrHigher { get { throw null; } }
public static bool IsNotNetNativeRunningAsConsoleApp { get { throw null; } }
public static bool IsNotOneCoreUAP { get { throw null; } }
Expand All @@ -70,10 +69,11 @@ public static partial class PlatformDetection
public static bool IsOSX { get { throw null; } }
public static bool IsSuperUser { get { throw null; } }
public static bool IsTizen { get { throw null; } }
public static bool IsRedHat { get { throw null; } }
public static bool IsNotRedHat { get { throw null; } }
public static bool IsRedHat69 { get { throw null; } }
public static bool IsNotRedHat69 { get { throw null; } }
public static bool IsRedHatFamily { get { throw null; } }
public static bool IsNotRedHatFamily { get { throw null; } }
public static bool IsRedHatFamily6 { get { throw null; } }
public static bool IsRedHatFamily7 { get { throw null; } }
public static bool IsNotRedHatFamily6 { get { throw null; } }
public static bool IsUap { get { throw null; } }
public static Version ICUVersion { get { return null; } }
public static bool IsUbuntu { get { throw null; } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<ReferenceFromRuntime Include="xunit.core" />
<ReferenceFromRuntime Include="Xunit.NetCore.Extensions" />
<ReferenceFromRuntime Include="xunit.assert" />
<ReferenceFromRuntime Include="Microsoft.DotNet.PlatformAbstractions" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Reference Include="System.Security.Principal.Windows" />
Expand Down
194 changes: 47 additions & 147 deletions src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Unix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@ public static partial class PlatformDetection
public static bool IsOpenSUSE => IsDistroAndVersion("opensuse");
public static bool IsUbuntu => IsDistroAndVersion("ubuntu");
public static bool IsDebian => IsDistroAndVersion("debian");
public static bool IsDebian8 => IsDistroAndVersion("debian", "8");
public static bool IsUbuntu1404 => IsDistroAndVersion("ubuntu", "14.04");
public static bool IsUbuntu1604 => IsDistroAndVersion("ubuntu", "16.04");
public static bool IsUbuntu1704 => IsDistroAndVersion("ubuntu", "17.04");
public static bool IsUbuntu1710 => IsDistroAndVersion("ubuntu", "17.10");
public static bool IsCentos7 => IsDistroAndVersion("centos", "7");
public static bool IsDebian8 => IsDistroAndVersion("debian", 8);
public static bool IsUbuntu1404 => IsDistroAndVersion("ubuntu", 14, 4);
public static bool IsUbuntu1604 => IsDistroAndVersion("ubuntu", 16, 4);
public static bool IsUbuntu1704 => IsDistroAndVersion("ubuntu", 17, 4);
public static bool IsUbuntu1710 => IsDistroAndVersion("ubuntu", 17, 10);
public static bool IsTizen => IsDistroAndVersion("tizen");
public static bool IsNotFedoraOrRedHatOrCentos => !IsDistroAndVersion("fedora") && !IsDistroAndVersion("rhel") && !IsDistroAndVersion("centos");
public static bool IsFedora => IsDistroAndVersion("fedora");
public static bool IsWindowsNanoServer => false;
public static bool IsWindowsServerCore => false;
public static bool IsWindowsAndElevated => false;
public static bool IsWindowsRedStone2 => false;
public static bool IsWindowsRedStone2 => false;

public static bool IsRedHat => IsDistroAndVersion("rhel") || IsDistroAndVersion("rhl");
public static bool IsNotRedHat => !IsRedHat;
public static bool IsRedHat69 => IsDistroAndVersion("rhel", "6.9") || IsDistroAndVersion("rhl", "6.9");
public static bool IsNotRedHat69 => !IsRedHat69;
// RedHat family covers RedHat and CentOS
public static bool IsRedHatFamily => IsRedHatFamilyAndVersion();
public static bool IsNotRedHatFamily => !IsRedHatFamily;
public static bool IsRedHatFamily6 => IsRedHatFamilyAndVersion(6);
public static bool IsNotRedHatFamily6 => !IsRedHatFamily6;
public static bool IsRedHatFamily7 => IsRedHatFamilyAndVersion(7);
public static bool IsNotFedoraOrRedHatFamily => !IsFedora && !IsRedHatFamily;

public static Version OSXKernelVersion { get; } = GetOSXKernelVersion();
public static Version OSXKernelVersion { get; } = ToVersion(Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.OperatingSystemVersion);

public static string GetDistroVersionString()
{
Expand All @@ -59,9 +60,9 @@ public static string GetDistroVersionString()
return "OSX Version=" + s_osxProductVersion.ToString();
}

DistroInfo v = ParseOsReleaseFile();
DistroInfo v = GetDistroInfo();

return "Distro=" + v.Id + " VersionId=" + v.VersionId + " Pretty=" + v.PrettyName + " Version=" + v.Version;
return "Distro=" + v.Id + " VersionId=" + v.VersionId;
}

private static readonly Version s_osxProductVersion = GetOSXProductVersion();
Expand All @@ -81,131 +82,25 @@ private static Version GetICUVersion()
ver >> 24);
}

private static DistroInfo ParseOsReleaseFile()
static Version ToVersion(string versionString)
{
Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Linux));
if (versionString.IndexOf('.') != -1)
return new Version(versionString);

DistroInfo ret = new DistroInfo();
ret.Id = "";
ret.VersionId = "";
ret.Version = "";
ret.PrettyName = "";

if (File.Exists("/etc/os-release"))
{
foreach (string line in File.ReadLines("/etc/os-release"))
{
if (line.StartsWith("ID=", System.StringComparison.Ordinal))
{
ret.Id = RemoveQuotes(line.Substring("ID=".Length));
}
else if (line.StartsWith("VERSION_ID=", System.StringComparison.Ordinal))
{
ret.VersionId = RemoveQuotes(line.Substring("VERSION_ID=".Length));
}
else if (line.StartsWith("VERSION=", System.StringComparison.Ordinal))
{
ret.Version = RemoveQuotes(line.Substring("VERSION=".Length));
}
else if (line.StartsWith("PRETTY_NAME=", System.StringComparison.Ordinal))
{
ret.PrettyName = RemoveQuotes(line.Substring("PRETTY_NAME=".Length));
}
}
}
else
{
string fileName = null;
if (File.Exists("/etc/redhat-release"))
fileName = "/etc/redhat-release";

if (fileName == null && File.Exists("/etc/system-release"))
fileName = "/etc/system-release";

if (fileName != null)
{
// Parse the format like the following line:
// Red Hat Enterprise Linux Server release 7.3 (Maipo)
using (StreamReader file = new StreamReader(fileName))
{
string line = file.ReadLine();
if (!String.IsNullOrEmpty(line))
{
if (line.StartsWith("Red Hat Enterprise Linux", StringComparison.OrdinalIgnoreCase))
{
ret.Id = "rhel";
}
else if (line.StartsWith("Centos", StringComparison.OrdinalIgnoreCase))
{
ret.Id = "centos";
}
else if (line.StartsWith("Red Hat", StringComparison.OrdinalIgnoreCase))
{
ret.Id = "rhl";
}
else
{
// automatically generate the distro label
string [] words = line.Split(' ');
StringBuilder sb = new StringBuilder();

foreach (string word in words)
{
if (word.Length > 0)
{
if (Char.IsNumber(word[0]) ||
word.Equals("release", StringComparison.OrdinalIgnoreCase) ||
word.Equals("server", StringComparison.OrdinalIgnoreCase))
{
break;
}
sb.Append(Char.ToLower(word[0]));
}
}
ret.Id = sb.ToString();
}

int i = 0;
while (i < line.Length && !Char.IsNumber(line[i])) // stop at first number
i++;

if (i < line.Length)
{
int j = i + 1;
while (j < line.Length && (Char.IsNumber(line[j]) || line[j] == '.'))
j++;

ret.VersionId = line.Substring(i, j - i);
ret.Version = line.Substring(i, line.Length - i);
}

ret.PrettyName = line;
}
}
}
}

return ret;
// minor version is required by Version
// let's default it to 0
return new Version(int.Parse(versionString), 0);
}

private static string RemoveQuotes(string s)
private static DistroInfo GetDistroInfo() => new DistroInfo()
{
s = s.Trim();
if (s.Length >= 2 && s[0] == '"' && s[s.Length - 1] == '"')
{
// Remove quotes.
s = s.Substring(1, s.Length - 2);
}

return s;
}
Id = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.OperatingSystem,
VersionId = ToVersion(Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.OperatingSystemVersion)
};

private struct DistroInfo
private static bool IsRedHatFamilyAndVersion(int major = -1, int minor = -1, int build = -1, int revision = -1)
{
public string Id { get; set; }
public string VersionId { get; set; }
public string Version { get; set; }
public string PrettyName { get; set; }
return IsDistroAndVersion((distro) => distro == "rhel" || distro == "centos", major, minor, build, revision);
}

/// <summary>
Expand All @@ -214,12 +109,17 @@ private struct DistroInfo
/// <param name="distroId">The distribution id.</param>
/// <param name="versionId">The distro version. If omitted, compares the distro only.</param>
/// <returns>Whether the OS platform matches the given Linux distro and optional version.</returns>
private static bool IsDistroAndVersion(string distroId, string versionId = null)
private static bool IsDistroAndVersion(string distroId, int major = -1, int minor = -1, int build = -1, int revision = -1)
{
return IsDistroAndVersion((distro) => distro == distroId, major, minor, build, revision);
}

private static bool IsDistroAndVersion(Predicate<string> distroPredicate, int major = -1, int minor = -1, int build = -1, int revision = -1)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
DistroInfo v = ParseOsReleaseFile();
if (v.Id == distroId && (versionId == null || v.VersionId == versionId))
DistroInfo v = GetDistroInfo();
if (distroPredicate(v.Id) && VersionEquivalentWith(major, minor, build, revision, v.VersionId))
{
return true;
}
Expand All @@ -228,18 +128,12 @@ private static bool IsDistroAndVersion(string distroId, string versionId = null)
return false;
}

private static Version GetOSXKernelVersion()
private static bool VersionEquivalentWith(int major, int minor, int build, int revision, Version actualVersionId)
{
if (IsOSX)
{
byte[] bytes = new byte[256];
IntPtr bytesLength = new IntPtr(bytes.Length);
Assert.Equal(0, sysctlbyname("kern.osrelease", bytes, ref bytesLength, null, IntPtr.Zero));
string versionString = Encoding.UTF8.GetString(bytes);
return Version.Parse(versionString);
}

return new Version(0, 0, 0);
return (major == -1 || major == actualVersionId.Major)
&& (minor == -1 || minor == actualVersionId.Minor)
&& (build == -1 || build == actualVersionId.Build)
&& (revision == -1 || revision == actualVersionId.Revision);
}

private static Version GetOSXProductVersion()
Expand Down Expand Up @@ -302,5 +196,11 @@ private static Version GetOSXProductVersion()
private static extern int GlobalizationNative_GetICUVersion();

public static bool IsSuperUser => geteuid() == 0;

private struct DistroInfo
{
public string Id { get; set; }
public Version VersionId { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ public static partial class PlatformDetection
public static bool IsUbuntu1604 => false;
public static bool IsUbuntu1704 => false;
public static bool IsUbuntu1710 => false;
public static bool IsCentos7 => false;
public static bool IsTizen => false;
public static bool IsNotFedoraOrRedHatOrCentos => true;
public static bool IsNotFedoraOrRedHatFamily => true;
public static bool IsFedora => false;
public static bool IsWindowsNanoServer => (IsNotWindowsIoTCore && GetInstallationType().Equals("Nano Server", StringComparison.OrdinalIgnoreCase));
public static bool IsWindowsServerCore => GetInstallationType().Equals("Server Core", StringComparison.OrdinalIgnoreCase);
public static int WindowsVersion => GetWindowsVersion();
public static bool IsMacOsHighSierraOrHigher { get; } = false;
public static Version ICUVersion => new Version(0, 0, 0, 0);
public static bool IsRedHat => false;
public static bool IsNotRedHat => true;
public static bool IsRedHat69 => false;
public static bool IsNotRedHat69 => true;
public static bool IsRedHatFamily => false;
public static bool IsNotRedHatFamily => true;
public static bool IsRedHatFamily6 => false;
public static bool IsRedHatFamily7 => false;
public static bool IsNotRedHatFamily6 => true;

public static bool IsWindows10Version1607OrGreater =>
GetWindowsVersion() == 10 && GetWindowsMinorVersion() == 0 && GetWindowsBuildNumber() >= 14393;
Expand Down
Loading

0 comments on commit 4bf9019

Please sign in to comment.