-
Notifications
You must be signed in to change notification settings - Fork 4.9k
[follow-up] Use RedHat code detection from Microsoft.DotNet.PlatformAbstractions #24531
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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() | ||
{ | ||
|
@@ -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(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I meant
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry for delay - had to suspend this PR. The value was not identical since they adjust version a little bit ( |
||
|
@@ -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> | ||
|
@@ -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; | ||
} | ||
|
@@ -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() | ||
|
@@ -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; } | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(nit) Does it work to
using Microsoft.DotNet.PlatformAbstractions;
, or is there some type collision?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eerhardt - type collision - class RuntimeEnvironment unfortunatelly also exists in corefx :-)