Skip to content

Commit 19b1e3f

Browse files
authored
Merge pull request #216 from WeihanLi/dev
1.0.69
2 parents fd3d6df + e626a28 commit 19b1e3f

File tree

3 files changed

+73
-16
lines changed

3 files changed

+73
-16
lines changed

build/version.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<VersionMajor>1</VersionMajor>
44
<VersionMinor>0</VersionMinor>
5-
<VersionPatch>68</VersionPatch>
5+
<VersionPatch>69</VersionPatch>
66
<VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix>
77
</PropertyGroup>
88
</Project>

src/WeihanLi.Common/Helpers/ApplicationHelper.cs

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,34 @@ public static LibraryInfo GetLibraryInfo(Assembly assembly)
6363
/// </summary>
6464
public static string? GetDotnetPath()
6565
{
66+
var environmentOverride = Environment.GetEnvironmentVariable("DOTNET_ROOT");
67+
if (!string.IsNullOrEmpty(environmentOverride) && Directory.Exists(environmentOverride))
68+
{
69+
var execFileName =
70+
#if NET6_0_OR_GREATER
71+
OperatingSystem.IsWindows()
72+
#else
73+
RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
74+
#endif
75+
? "dotnet.exe"
76+
: "dotnet"
77+
;
78+
var dotnetExePath = Path.Combine(environmentOverride, execFileName);
79+
if (File.Exists(dotnetExePath))
80+
return dotnetExePath;
81+
82+
throw new InvalidOperationException($"dotnet executable file not found under specified DOTNET_ROOT {environmentOverride}");
83+
}
6684
return ResolvePath("dotnet");
6785
}
6886

6987
public static string GetDotnetDirectory()
7088
{
71-
var environmentOverride = Environment.GetEnvironmentVariable("DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR");
72-
if (!string.IsNullOrEmpty(environmentOverride))
73-
{
74-
return environmentOverride;
75-
}
76-
7789
var dotnetExe = GetDotnetPath();
7890

7991
if (dotnetExe.IsNotNullOrEmpty() && !InteropHelper.RunningOnWindows)
8092
{
81-
// e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to
93+
// e.g. on Linux the 'dotnet' command from PATH is a symbol link so we need to
8294
// resolve it to get the actual path to the binary
8395
dotnetExe = InteropHelper.Unix.RealPath(dotnetExe) ?? dotnetExe;
8496
}
@@ -97,15 +109,15 @@ public static string GetDotnetDirectory()
97109

98110
public static string? ResolvePath(string execName) => ResolvePath(execName, ".exe");
99111

100-
public static string? ResolvePath(string execName, string? ext)
112+
public static string? ResolvePath(string execName, string? windowsExt)
101113
{
102114
var executableName = execName;
103115
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
104116
&& !Path.HasExtension(execName)
105-
&& string.IsNullOrEmpty(ext)
117+
&& !string.IsNullOrEmpty(windowsExt)
106118
)
107119
{
108-
executableName += ext;
120+
executableName = $"{executableName}{windowsExt}";
109121
}
110122
var searchPaths = Guard.NotNull(Environment.GetEnvironmentVariable("PATH"))
111123
.Split(new[] { Path.PathSeparator }, options: StringSplitOptions.RemoveEmptyEntries)
@@ -125,7 +137,7 @@ private static RuntimeInfo GetRuntimeInfo()
125137
#else
126138
var currentProcess = System.Diagnostics.Process.GetCurrentProcess();
127139
#endif
128-
return new RuntimeInfo()
140+
var runtimeInfo = new RuntimeInfo()
129141
{
130142
Version = Environment.Version.ToString(),
131143
ProcessorCount = Environment.ProcessorCount,
@@ -144,33 +156,45 @@ private static RuntimeInfo GetRuntimeInfo()
144156
OSDescription = RuntimeInformation.OSDescription,
145157
OSVersion = Environment.OSVersion.ToString(),
146158
MachineName = Environment.MachineName,
159+
UserName = Environment.UserName,
147160

148161
IsInContainer = IsInContainer(),
149162
IsInKubernetes = IsInKubernetesCluster(),
163+
KubernetesNamespace = GetKubernetesNamespace(),
150164

151165
LibraryVersion = libInfo.LibraryVersion,
152166
LibraryHash = libInfo.LibraryHash,
153167
RepositoryUrl = libInfo.RepositoryUrl,
154168
};
169+
return runtimeInfo;
155170
}
156171

157172
#region ContainerEnvironment
173+
// container environment
174+
// https://github.com/dotnet/dotnet-docker/blob/d90d458deada9057d7889f76d58fc0a7194a0c06/src/runtime-deps/6.0/alpine3.20/amd64/Dockerfile#L7
175+
176+
/// <summary>
177+
/// Whether running inside a container
178+
/// </summary>
158179
private static bool IsInContainer()
159180
{
160-
// https://github.com/dotnet/dotnet-docker/blob/9b731e901dd4a343fc30da7b8b3ab7d305a4aff9/src/runtime-deps/7.0/cbl-mariner2.0/amd64/Dockerfile#L18
161181
return "true".Equals(Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER"),
162182
StringComparison.OrdinalIgnoreCase);
163183
}
164184

185+
// Kubernetes environment
186+
// https://github.com/kubernetes-client/csharp/blob/36a02046439d01f1256aed4e5071cb7f1b57d6eb/src/KubernetesClient/KubernetesClientConfiguration.InCluster.cs#L41
165187
private static readonly string ServiceAccountPath =
166188
Path.Combine(
167189
[
168190
$"{Path.DirectorySeparatorChar}var", "run", "secrets", "kubernetes.io", "serviceaccount",
169191
]);
170192
private const string ServiceAccountTokenKeyFileName = "token";
171193
private const string ServiceAccountRootCAKeyFileName = "ca.crt";
194+
private const string ServiceAccountNamespaceFileName = "namespace";
195+
172196
/// <summary>
173-
/// Whether running in k8s cluster
197+
/// Whether running inside a k8s cluster
174198
/// </summary>
175199
/// <returns></returns>
176200
private static bool IsInKubernetesCluster()
@@ -191,8 +215,17 @@ private static bool IsInKubernetesCluster()
191215
var certPath = Path.Combine(ServiceAccountPath, ServiceAccountRootCAKeyFileName);
192216
return File.Exists(certPath);
193217
}
194-
#endregion ContainerEnvironment
195218

219+
/// <summary>
220+
/// Get Kubernetes namespace
221+
/// </summary>
222+
/// <returns>The namespace current workload in</returns>
223+
private static string? GetKubernetesNamespace()
224+
{
225+
var namespaceFilePath = Path.Combine(ServiceAccountPath, ServiceAccountNamespaceFileName);
226+
return File.Exists(namespaceFilePath) ? File.ReadAllText(namespaceFilePath).Trim() : null;
227+
}
228+
#endregion ContainerEnvironment
196229
}
197230

198231
public class LibraryInfo
@@ -202,7 +235,7 @@ public class LibraryInfo
202235
public required string RepositoryUrl { get; init; }
203236
}
204237

205-
public sealed class RuntimeInfo : LibraryInfo
238+
public class RuntimeInfo : LibraryInfo
206239
{
207240
public required string Version { get; init; }
208241
public required string FrameworkDescription { get; init; }
@@ -211,6 +244,7 @@ public sealed class RuntimeInfo : LibraryInfo
211244
public required string OSDescription { get; init; }
212245
public required string OSVersion { get; init; }
213246
public required string MachineName { get; init; }
247+
public required string UserName { get; init; }
214248

215249
#if NET6_0_OR_GREATER
216250
public required string RuntimeIdentifier { get; init; }
@@ -229,4 +263,9 @@ public sealed class RuntimeInfo : LibraryInfo
229263
/// Is running in a Kubernetes cluster
230264
/// </summary>
231265
public required bool IsInKubernetes { get; init; }
266+
267+
/// <summary>
268+
/// Kubernetes namespace when running in a Kubernetes cluster
269+
/// </summary>
270+
public string? KubernetesNamespace { get; init; }
232271
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Weihan Li. All rights reserved.
2+
// Licensed under the Apache license.
3+
4+
using WeihanLi.Common.Helpers;
5+
using Xunit;
6+
7+
namespace WeihanLi.Common.Test.HelpersTest;
8+
public class ApplicationHelperTest
9+
{
10+
[Fact]
11+
public void DotnetPathTest()
12+
{
13+
var dotnetPath = ApplicationHelper.GetDotnetPath();
14+
Assert.NotNull(dotnetPath);
15+
Assert.NotEmpty(dotnetPath);
16+
Assert.True(File.Exists(dotnetPath));
17+
}
18+
}

0 commit comments

Comments
 (0)