diff --git a/src/Tgstation.Server.Host/Components/Configuration.cs b/src/Tgstation.Server.Host/Components/Configuration.cs index 23af8efb62..41f1f34977 100644 --- a/src/Tgstation.Server.Host/Components/Configuration.cs +++ b/src/Tgstation.Server.Host/Components/Configuration.cs @@ -17,7 +17,7 @@ namespace Tgstation.Server.Host.Components sealed class Configuration : IConfiguration { const string CodeModificationsSubdirectory = "CodeModifications"; - //const string EventScriptsSubdirectory = "EventScripts"; + const string EventScriptsSubdirectory = "EventScripts"; const string GameStaticFilesSubdirectory = "GameStaticFiles"; const string CodeModificationsHeadFile = "HeadInclude.dm"; @@ -58,9 +58,13 @@ namespace Tgstation.Server.Host.Components this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } + Task EnsureDirectories(CancellationToken cancellationToken) => Task.WhenAll(ioManager.CreateDirectory(CodeModificationsSubdirectory, cancellationToken), ioManager.CreateDirectory(EventScriptsSubdirectory, cancellationToken), ioManager.CreateDirectory(GameStaticFilesSubdirectory, cancellationToken)); + /// public async Task CopyDMFilesTo(string dmeFile, string destination, CancellationToken cancellationToken) { + await EnsureDirectories(cancellationToken).ConfigureAwait(false); + //just assume no other fs race conditions here var dmeExistsTask = ioManager.FileExists(ioManager.ConcatPath(CodeModificationsSubdirectory, dmeFile), cancellationToken); var headFileExistsTask = ioManager.FileExists(ioManager.ConcatPath(CodeModificationsSubdirectory, CodeModificationsHeadFile), cancellationToken); @@ -101,6 +105,7 @@ namespace Tgstation.Server.Host.Components /// public async Task> ListDirectory(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) { + await EnsureDirectories(cancellationToken).ConfigureAwait(false); var path = ValidateConfigRelativePath(configurationRelativePath); List result = new List(); @@ -132,6 +137,7 @@ namespace Tgstation.Server.Host.Components /// public async Task Read(string configurationRelativePath, ISystemIdentity systemIdentity, CancellationToken cancellationToken) { + await EnsureDirectories(cancellationToken).ConfigureAwait(false); var path = ValidateConfigRelativePath(configurationRelativePath); ConfigurationFile result = null; @@ -176,8 +182,9 @@ namespace Tgstation.Server.Host.Components } /// - public Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) + public async Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken) { + await EnsureDirectories(cancellationToken).ConfigureAwait(false); async Task SymlinkBase(bool files) { Task> task; @@ -189,12 +196,13 @@ namespace Tgstation.Server.Host.Components await Task.WhenAll(entries.Select(x => symlinkFactory.CreateSymbolicLink(ioManager.ResolvePath(x), ioManager.ConcatPath(destination, x), cancellationToken))).ConfigureAwait(false); } - return Task.WhenAll(SymlinkBase(true), SymlinkBase(false)); + await Task.WhenAll(SymlinkBase(true), SymlinkBase(false)).ConfigureAwait(false); } /// public async Task Write(string configurationRelativePath, ISystemIdentity systemIdentity, byte[] data, string previousHash, CancellationToken cancellationToken) { + await EnsureDirectories(cancellationToken).ConfigureAwait(false); var path = ValidateConfigRelativePath(configurationRelativePath); ConfigurationFile result = null; @@ -239,5 +247,11 @@ namespace Tgstation.Server.Host.Components return result; } + + /// + public Task StartAsync(CancellationToken cancellationToken) => EnsureDirectories(cancellationToken); + + /// + public Task StopAsync(CancellationToken cancellationToken) => EnsureDirectories(cancellationToken); } } diff --git a/src/Tgstation.Server.Host/Components/IConfiguration.cs b/src/Tgstation.Server.Host/Components/IConfiguration.cs index f1734e028d..e972f8e508 100644 --- a/src/Tgstation.Server.Host/Components/IConfiguration.cs +++ b/src/Tgstation.Server.Host/Components/IConfiguration.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Microsoft.Extensions.Hosting; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Tgstation.Server.Api.Models; @@ -9,7 +10,7 @@ namespace Tgstation.Server.Host.Components /// /// For managing the Configuration directory /// - public interface IConfiguration + public interface IConfiguration : IHostedService { /// /// Copies all files in the CodeModifications directory to diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index fea1f1b57f..8c4b30f05c 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -125,10 +125,10 @@ namespace Tgstation.Server.Host.Components } /// - public Task StartAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(metadata.AutoUpdateInterval), ByondManager.StartAsync(cancellationToken), Watchdog.StartAsync(cancellationToken), Chat.StartAsync(cancellationToken), compileJobConsumer.StartAsync(cancellationToken), Watchdog.StartAsync(cancellationToken)); + public Task StartAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(metadata.AutoUpdateInterval), Configuration.StartAsync(cancellationToken), ByondManager.StartAsync(cancellationToken), Watchdog.StartAsync(cancellationToken), Chat.StartAsync(cancellationToken), compileJobConsumer.StartAsync(cancellationToken), Watchdog.StartAsync(cancellationToken)); /// - public Task StopAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(null), ByondManager.StopAsync(cancellationToken), Watchdog.StopAsync(cancellationToken), Chat.StopAsync(cancellationToken), compileJobConsumer.StopAsync(cancellationToken), Watchdog.StopAsync(cancellationToken)); + public Task StopAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(null), Configuration.StopAsync(cancellationToken), ByondManager.StopAsync(cancellationToken), Watchdog.StopAsync(cancellationToken), Chat.StopAsync(cancellationToken), compileJobConsumer.StopAsync(cancellationToken), Watchdog.StopAsync(cancellationToken)); /// public async Task SetAutoUpdateInterval(int? newInterval) diff --git a/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs b/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs index e6a3b4d81c..fb3abd7ba4 100644 --- a/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs +++ b/src/Tgstation.Server.Host/Controllers/ConfigurationController.cs @@ -65,10 +65,6 @@ namespace Tgstation.Server.Host.Controllers return Json(newFile); } - catch (InvalidOperationException) - { - return BadRequest(new { message = "Attempted to delete required folder!" }); - } catch(NotImplementedException e) { return StatusCode((int)HttpStatusCode.NotImplemented, new { message = e.Message });