From 326549c026ba0693b28f951a1cefd6ff9a3b2a73 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 3 Jun 2023 22:15:06 -0400 Subject: [PATCH 1/4] Fix bad semi-colons --- .../Controllers/DreamDaemonController.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs index 068b65d825c..856cb5d26ca 100644 --- a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs +++ b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs @@ -170,8 +170,7 @@ public async Task Update([FromBody] DreamDaemonRequest model, Can .AsQueryable() .Where(x => x.Id == Instance.Id) .Select(x => x.DreamDaemonSettings) - .FirstOrDefaultAsync(cancellationToken) - ; + .FirstOrDefaultAsync(cancellationToken); if (current == default) return Gone(); @@ -182,8 +181,8 @@ public async Task Update([FromBody] DreamDaemonRequest model, Can .GetAvailablePort( model.Port.Value, true, - cancellationToken) - ; + cancellationToken); + if (verifiedPort != model.Port) return Conflict(new ErrorMessageResponse(ErrorCode.PortNotAvailable)); } From 6577f55f659ac4ad3da69c79951302fbac6359e3 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 3 Jun 2023 22:19:48 -0400 Subject: [PATCH 2/4] Add `--staged` parameter for `prs` command. --- .../Chat/Commands/CommandFactory.cs | 11 +++- .../Chat/Commands/PullRequestsCommand.cs | 51 ++++++++++++--- .../Components/InstanceFactory.cs | 65 ++++++++++--------- .../Live/DummyChatProviderFactory.cs | 2 + 4 files changed, 87 insertions(+), 42 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/CommandFactory.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/CommandFactory.cs index 6159a2cc20f..06eb90dd758 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/CommandFactory.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/CommandFactory.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Tgstation.Server.Host.Components.Byond; +using Tgstation.Server.Host.Components.Deployment; using Tgstation.Server.Host.Components.Repository; using Tgstation.Server.Host.Components.Watchdog; using Tgstation.Server.Host.Database; @@ -32,6 +33,11 @@ sealed class CommandFactory : ICommandFactory /// readonly IDatabaseContextFactory databaseContextFactory; + /// + /// The for the . + /// + readonly ILatestCompileJobProvider compileJobProvider; + /// /// The for the . /// @@ -49,18 +55,21 @@ sealed class CommandFactory : ICommandFactory /// The value of . /// The value of . /// The value of . + /// The value of . /// The value of . public CommandFactory( IAssemblyInformationProvider assemblyInformationProvider, IByondManager byondManager, IRepositoryManager repositoryManager, IDatabaseContextFactory databaseContextFactory, + ILatestCompileJobProvider compileJobProvider, Models.Instance instance) { this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); this.byondManager = byondManager ?? throw new ArgumentNullException(nameof(byondManager)); this.repositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager)); this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); + this.compileJobProvider = compileJobProvider ?? throw new ArgumentNullException(nameof(compileJobProvider)); this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); } @@ -85,7 +94,7 @@ public IReadOnlyList GenerateCommands() new VersionCommand(assemblyInformationProvider), new ByondCommand(byondManager, watchdog), new RevisionCommand(watchdog, repositoryManager), - new PullRequestsCommand(watchdog, repositoryManager, databaseContextFactory, instance), + new PullRequestsCommand(watchdog, repositoryManager, databaseContextFactory, compileJobProvider, instance), new KekCommand(), }; } diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs index fab5b12b35e..25e5186c41d 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore; using Tgstation.Server.Api.Models; +using Tgstation.Server.Host.Components.Deployment; using Tgstation.Server.Host.Components.Interop; using Tgstation.Server.Host.Components.Repository; using Tgstation.Server.Host.Components.Watchdog; @@ -23,7 +24,7 @@ sealed class PullRequestsCommand : ICommand public string Name => "prs"; /// - public string HelpText => "Display live test merge numbers. Add --repo to view test merges in the repository as opposed to live."; + public string HelpText => "Display live test merge numbers. Add --repo to view test merges in the repository as opposed to live. Add --staged to view PRs in the upcoming deployment."; /// public bool AdminOnly => false; @@ -43,6 +44,11 @@ sealed class PullRequestsCommand : ICommand /// readonly IDatabaseContextFactory databaseContextFactory; + /// + /// The for the . + /// + readonly ILatestCompileJobProvider compileJobProvider; + /// /// The for the . /// @@ -54,12 +60,19 @@ sealed class PullRequestsCommand : ICommand /// The value of . /// The value of . /// The value of . + /// The value of . /// The value of . - public PullRequestsCommand(IWatchdog watchdog, IRepositoryManager repositoryManager, IDatabaseContextFactory databaseContextFactory, Models.Instance instance) + public PullRequestsCommand( + IWatchdog watchdog, + IRepositoryManager repositoryManager, + IDatabaseContextFactory databaseContextFactory, + ILatestCompileJobProvider compileJobProvider, + Models.Instance instance) { this.watchdog = watchdog ?? throw new ArgumentNullException(nameof(watchdog)); this.repositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager)); this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); + this.compileJobProvider = compileJobProvider ?? throw new ArgumentNullException(nameof(compileJobProvider)); this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); } @@ -69,7 +82,17 @@ public PullRequestsCommand(IWatchdog watchdog, IRepositoryManager repositoryMana public async Task Invoke(string arguments, ChatUser user, CancellationToken cancellationToken) { IEnumerable results = null; - if (arguments.Split(' ').Any(x => x.ToUpperInvariant() == "--REPO")) + var splits = arguments.Split(' '); + var hasRepo = splits.Any(x => x.Equals("--repo", StringComparison.OrdinalIgnoreCase)); + var hasStaged = splits.Any(x => x.Equals("--staged", StringComparison.OrdinalIgnoreCase)); + + if (hasStaged && hasRepo) + return new MessageContent + { + Text = "Please use only one of `--staged` or `--repo`", + }; + + if (hasRepo) { string head; using (var repo = await repositoryManager.LoadRepository(cancellationToken)) @@ -97,14 +120,24 @@ public async Task Invoke(string arguments, ChatUser user, Cancel }) .ToListAsync(cancellationToken)); } + else if (watchdog.Status == WatchdogStatus.Offline) + return new MessageContent + { + Text = "Server offline!", + }; else { - if (watchdog.Status == WatchdogStatus.Offline) - return new MessageContent - { - Text = "Server offline!", - }; - results = watchdog.ActiveCompileJob?.RevisionInformation.ActiveTestMerges.Select(x => x.TestMerge).ToList() ?? new List(); + var compileJobToUse = watchdog.ActiveCompileJob; + if (hasStaged) + { + var latestCompileJob = compileJobProvider.LatestCompileJob(); + if (latestCompileJob?.Id != compileJobToUse?.Id) + compileJobToUse = latestCompileJob; + else + compileJobToUse = null; + } + + results = compileJobToUse?.RevisionInformation.ActiveTestMerges.Select(x => x.TestMerge).ToList() ?? Enumerable.Empty(); } return new MessageContent diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index 6d78a4edd08..5c7c24929f7 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -300,38 +300,18 @@ public async Task CreateInstance(IBridgeRegistrar bridgeRegistrar, Mo { var byond = new ByondManager(byondIOManager, byondInstaller, eventConsumer, loggerFactory.CreateLogger()); - var commandFactory = new CommandFactory(assemblyInformationProvider, byond, repoManager, databaseContextFactory, metadata); - - var chatManager = chatFactory.CreateChatManager(commandFactory, metadata.ChatSettings); + var dmbFactory = new DmbFactory( + databaseContextFactory, + gameIoManager, + remoteDeploymentManagerFactory, + eventConsumer, + loggerFactory.CreateLogger(), + metadata); try { - var sessionControllerFactory = new SessionControllerFactory( - processExecutor, - byond, - topicClientFactory, - cryptographySuite, - assemblyInformationProvider, - gameIoManager, - diagnosticsIOManager, - chatManager, - networkPromptReaper, - platformIdentifier, - bridgeRegistrar, - serverPortProvider, - eventConsumer, - asyncDelayer, - loggerFactory, - loggerFactory.CreateLogger(), - sessionConfiguration, - metadata); - - var dmbFactory = new DmbFactory( - databaseContextFactory, - gameIoManager, - remoteDeploymentManagerFactory, - eventConsumer, - loggerFactory.CreateLogger(), - metadata); + var commandFactory = new CommandFactory(assemblyInformationProvider, byond, repoManager, databaseContextFactory, dmbFactory, metadata); + + var chatManager = chatFactory.CreateChatManager(commandFactory, metadata.ChatSettings); try { var reattachInfoHandler = new SessionPersistor( @@ -340,6 +320,27 @@ public async Task CreateInstance(IBridgeRegistrar bridgeRegistrar, Mo processExecutor, loggerFactory.CreateLogger(), metadata); + + var sessionControllerFactory = new SessionControllerFactory( + processExecutor, + byond, + topicClientFactory, + cryptographySuite, + assemblyInformationProvider, + gameIoManager, + diagnosticsIOManager, + chatManager, + networkPromptReaper, + platformIdentifier, + bridgeRegistrar, + serverPortProvider, + eventConsumer, + asyncDelayer, + loggerFactory, + loggerFactory.CreateLogger(), + sessionConfiguration, + metadata); + var watchdog = watchdogFactory.CreateWatchdog( chatManager, dmbFactory, @@ -398,13 +399,13 @@ public async Task CreateInstance(IBridgeRegistrar bridgeRegistrar, Mo } catch { - dmbFactory.Dispose(); + await chatManager.DisposeAsync(); throw; } } catch { - await chatManager.DisposeAsync(); + dmbFactory.Dispose(); throw; } } diff --git a/tests/Tgstation.Server.Tests/Live/DummyChatProviderFactory.cs b/tests/Tgstation.Server.Tests/Live/DummyChatProviderFactory.cs index 3f6fd02275a..762ad7294ce 100644 --- a/tests/Tgstation.Server.Tests/Live/DummyChatProviderFactory.cs +++ b/tests/Tgstation.Server.Tests/Live/DummyChatProviderFactory.cs @@ -9,6 +9,7 @@ using Tgstation.Server.Host.Components.Byond; using Tgstation.Server.Host.Components.Chat.Commands; using Tgstation.Server.Host.Components.Chat.Providers; +using Tgstation.Server.Host.Components.Deployment; using Tgstation.Server.Host.Components.Repository; using Tgstation.Server.Host.Components.Watchdog; using Tgstation.Server.Host.Database; @@ -42,6 +43,7 @@ public DummyChatProviderFactory(IJobManager jobManager, ICryptographySuite crypt Mock.Of(), Mock.Of(), Mock.Of(), + Mock.Of(), new Host.Models.Instance()); commandFactory.SetWatchdog(Mock.Of()); From 08ae7a31bdd1a71aa763b212eff943b47c672061 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 3 Jun 2023 22:34:20 -0400 Subject: [PATCH 3/4] `prs` command no longer waits for the repository --- .../Components/Chat/Commands/PullRequestsCommand.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs index 25e5186c41d..409c989a644 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs @@ -94,6 +94,12 @@ public async Task Invoke(string arguments, ChatUser user, Cancel if (hasRepo) { + if (repositoryManager.CloneInProgress || repositoryManager.InUse) + return new MessageContent + { + Text = "Repository busy! Try again later", + }; + string head; using (var repo = await repositoryManager.LoadRepository(cancellationToken)) { From 3991b855d53b9578422ce3bdf676d5707c22d242 Mon Sep 17 00:00:00 2001 From: Dominion Date: Sat, 3 Jun 2023 22:36:38 -0400 Subject: [PATCH 4/4] `revision` command no longer waits for repository --- .../Components/Chat/Commands/RevisionCommand.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs index 8bf6ab34320..c0028964e2a 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/RevisionCommand.cs @@ -51,6 +51,13 @@ public async Task Invoke(string arguments, ChatUser user, Cancel { string result; if (arguments.Split(' ').Any(x => x.ToUpperInvariant() == "--REPO")) + { + if (repositoryManager.CloneInProgress || repositoryManager.InUse) + return new MessageContent + { + Text = "Repository busy! Try again later", + }; + using (var repo = await repositoryManager.LoadRepository(cancellationToken)) { if (repo == null) @@ -60,6 +67,7 @@ public async Task Invoke(string arguments, ChatUser user, Cancel }; result = repo.Head; } + } else { if (watchdog.Status == WatchdogStatus.Offline)