diff --git a/src/Tgstation.Server.Client/Components/DreamMakerClient.cs b/src/Tgstation.Server.Client/Components/DreamMakerClient.cs index 496872d60f..dafa049834 100644 --- a/src/Tgstation.Server.Client/Components/DreamMakerClient.cs +++ b/src/Tgstation.Server.Client/Components/DreamMakerClient.cs @@ -35,7 +35,7 @@ namespace Tgstation.Server.Client.Components public Task Compile(CancellationToken cancellationToken) => apiClient.Create(Routes.DreamMaker, instance.Id, cancellationToken); /// - public Task GetCompileJob(CompileJob compileJob, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.DreamMaker, compileJob?.Id ?? throw new ArgumentNullException(nameof(compileJob))), instance.Id, cancellationToken); + public Task GetCompileJob(EntityId compileJob, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.DreamMaker, compileJob?.Id ?? throw new ArgumentNullException(nameof(compileJob))), instance.Id, cancellationToken); /// public Task> GetJobIds(CancellationToken cancellationToken) => apiClient.Read>(Routes.ListRoute(Routes.DreamMaker), instance.Id, cancellationToken); diff --git a/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs b/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs index 87a3d0fb54..174634bdb4 100644 --- a/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs +++ b/src/Tgstation.Server.Client/Components/IDreamMakerClient.cs @@ -42,9 +42,9 @@ namespace Tgstation.Server.Client.Components /// /// Get a /// - /// The to get + /// The to get /// The for the operation /// A resulting in the - Task GetCompileJob(CompileJob compileJob, CancellationToken cancellationToken); + Task GetCompileJob(EntityId compileJob, CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Client/Components/IJobsClient.cs b/src/Tgstation.Server.Client/Components/IJobsClient.cs index f53b0dd612..ae879f485e 100644 --- a/src/Tgstation.Server.Client/Components/IJobsClient.cs +++ b/src/Tgstation.Server.Client/Components/IJobsClient.cs @@ -27,10 +27,10 @@ namespace Tgstation.Server.Client.Components /// /// Get a /// - /// The to get + /// The 's to get /// The for the operation /// A resulting in the - Task GetId(Job job, CancellationToken cancellationToken); + Task GetId(EntityId job, CancellationToken cancellationToken); /// /// Cancels a diff --git a/src/Tgstation.Server.Client/Components/JobsClient.cs b/src/Tgstation.Server.Client/Components/JobsClient.cs index 00c043ae0e..228a2c4a9b 100644 --- a/src/Tgstation.Server.Client/Components/JobsClient.cs +++ b/src/Tgstation.Server.Client/Components/JobsClient.cs @@ -41,6 +41,6 @@ namespace Tgstation.Server.Client.Components public Task> ListActive(CancellationToken cancellationToken) => apiClient.Read>(Routes.Jobs, instance.Id, cancellationToken); /// - public Task GetId(Job job, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id, cancellationToken); + public Task GetId(EntityId job, CancellationToken cancellationToken) => apiClient.Read(Routes.SetID(Routes.Jobs, job?.Id ?? throw new ArgumentNullException(nameof(job))), instance.Id, cancellationToken); } } \ No newline at end of file diff --git a/src/Tgstation.Server.Host/Core/SetupWizard.cs b/src/Tgstation.Server.Host/Core/SetupWizard.cs index bc3a0759b8..dff6446387 100644 --- a/src/Tgstation.Server.Host/Core/SetupWizard.cs +++ b/src/Tgstation.Server.Host/Core/SetupWizard.cs @@ -638,41 +638,60 @@ namespace Tgstation.Server.Host.Core } var userConfigFileName = String.Format(CultureInfo.InvariantCulture, "appsettings.{0}.json", hostingEnvironment.EnvironmentName); - var exists = await ioManager.FileExists(userConfigFileName, cancellationToken).ConfigureAwait(false); - bool shouldRunBasedOnAutodetect; - if (exists) + async Task HandleSetupCancel() { - var bytes = await ioManager.ReadAllBytes(userConfigFileName, cancellationToken).ConfigureAwait(false); - var contents = Encoding.UTF8.GetString(bytes); - var existingConfigIsEmpty = String.IsNullOrWhiteSpace(contents) || contents.Trim() == "{}"; - logger.LogTrace("Configuration json detected. Empty: {0}", existingConfigIsEmpty); - shouldRunBasedOnAutodetect = existingConfigIsEmpty; - } - else - { - shouldRunBasedOnAutodetect = true; - logger.LogTrace("No configuration json detected"); + await console.WriteAsync(String.Empty, true, default).ConfigureAwait(false); + await console.WriteAsync("Aborting setup!", true, default).ConfigureAwait(false); } - if (!shouldRunBasedOnAutodetect) - { - if (forceRun) + // Link passed cancellationToken with cancel key press + Task finalTask = Task.CompletedTask; + using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, console.CancelKeyPress)) + using ((cancellationToken = cts.Token).Register(() => finalTask = HandleSetupCancel())) + try { - logger.LogTrace("Asking user to bypass due to force run request..."); - await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "The configuration settings are requesting the setup wizard be run, but you already appear to have a configuration file ({0})!", userConfigFileName), true, cancellationToken).ConfigureAwait(false); + var exists = await ioManager.FileExists(userConfigFileName, cancellationToken).ConfigureAwait(false); - forceRun = await PromptYesNo("Continue running setup wizard? (y/n): ", cancellationToken).ConfigureAwait(false); + bool shouldRunBasedOnAutodetect; + if (exists) + { + var bytes = await ioManager.ReadAllBytes(userConfigFileName, cancellationToken).ConfigureAwait(false); + var contents = Encoding.UTF8.GetString(bytes); + var existingConfigIsEmpty = String.IsNullOrWhiteSpace(contents) || contents.Trim() == "{}"; + logger.LogTrace("Configuration json detected. Empty: {0}", existingConfigIsEmpty); + shouldRunBasedOnAutodetect = existingConfigIsEmpty; + } + else + { + shouldRunBasedOnAutodetect = true; + logger.LogTrace("No configuration json detected"); + } + + if (!shouldRunBasedOnAutodetect) + { + if (forceRun) + { + logger.LogTrace("Asking user to bypass due to force run request..."); + await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "The configuration settings are requesting the setup wizard be run, but you already appear to have a configuration file ({0})!", userConfigFileName), true, cancellationToken).ConfigureAwait(false); + + forceRun = await PromptYesNo("Continue running setup wizard? (y/n): ", cancellationToken).ConfigureAwait(false); + } + + if (!forceRun) + return false; + } + + // flush the logs to prevent console conflicts + await asyncDelayer.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false); + + await RunWizard(userConfigFileName, cancellationToken).ConfigureAwait(false); + } + finally + { + await finalTask.ConfigureAwait(false); } - if (!forceRun) - return false; - } - - // flush the logs to prevent console conflicts - await asyncDelayer.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false); - - await RunWizard(userConfigFileName, cancellationToken).ConfigureAwait(false); return true; } } diff --git a/src/Tgstation.Server.Host/IO/Console.cs b/src/Tgstation.Server.Host/IO/Console.cs index 9f1fceba80..0d90d54c25 100644 --- a/src/Tgstation.Server.Host/IO/Console.cs +++ b/src/Tgstation.Server.Host/IO/Console.cs @@ -6,11 +6,50 @@ using System.Threading.Tasks; namespace Tgstation.Server.Host.IO { /// - sealed class Console : IConsole + sealed class Console : IConsole, IDisposable { /// public bool Available => Environment.UserInteractive; + /// + public CancellationToken CancelKeyPress => cancelKeyCts.Token; + + /// + /// The for . + /// + readonly CancellationTokenSource cancelKeyCts; + + /// + /// If the was disposed; + /// + bool disposed; + + /// + /// Initializes a new instance of the . + /// + public Console() + { + cancelKeyCts = new CancellationTokenSource(); + System.Console.CancelKeyPress += (sender, e) => + { + lock (cancelKeyCts) + { + if (!disposed) + cancelKeyCts.Cancel(); + } + }; + } + + /// + public void Dispose() + { + lock (cancelKeyCts) + { + cancelKeyCts.Dispose(); + disposed = true; + } + } + void CheckAvailable() { if (!Available) diff --git a/src/Tgstation.Server.Host/IO/IConsole.cs b/src/Tgstation.Server.Host/IO/IConsole.cs index 119b19d5dc..405ffb425b 100644 --- a/src/Tgstation.Server.Host/IO/IConsole.cs +++ b/src/Tgstation.Server.Host/IO/IConsole.cs @@ -13,6 +13,11 @@ namespace Tgstation.Server.Host.IO /// bool Available { get; } + /// + /// Gets a that triggers if Crtl+C or an equivalent is pressed. + /// + CancellationToken CancelKeyPress { get; } + /// /// Write some to the ///