From 515a1434db765d496f8d451c3496f36dd0f76a7a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 29 Jul 2018 19:21:12 -0400 Subject: [PATCH] More repo stuff + serialize config script execution --- .../Components/Instance.cs | 7 +++-- .../Components/Repository/IRepository.cs | 15 +++++++++ .../Components/Repository/Repository.cs | 12 +++++++ .../Components/StaticFiles/Configuration.cs | 31 ++++++++++++++++--- .../Components/StaticFiles/IConfiguration.cs | 3 +- .../Components/StaticFiles/ScriptExecutor.cs | 4 ++- 6 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index 2695689f01..9a22a5ea9a 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -94,10 +94,11 @@ namespace Tgstation.Server.Host.Components public void Dispose() { timerCts?.Dispose(); - Watchdog.Dispose(); - Chat.Dispose(); - RepositoryManager.Dispose(); compileJobConsumer.Dispose(); + Configuration.Dispose(); + Chat.Dispose(); + Watchdog.Dispose(); + RepositoryManager.Dispose(); } /// diff --git a/src/Tgstation.Server.Host/Components/Repository/IRepository.cs b/src/Tgstation.Server.Host/Components/Repository/IRepository.cs index cb46b4a9d1..d134a34639 100644 --- a/src/Tgstation.Server.Host/Components/Repository/IRepository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/IRepository.cs @@ -65,6 +65,13 @@ namespace Tgstation.Server.Host.Components.Repository /// A resulting in the SHA of the new HEAD Task ResetToOrigin(CancellationToken cancellationToken); + /// + /// Requires the current HEAD to be a tracked reference. Merges the reference to what it tracks on the origin repository + /// + /// The for the operation + /// A resulting in the SHA of the new HEAD. if the merge resulted in conflict + Task MergeOrigin(CancellationToken cancellationToken); + /// /// Force push the current repository HEAD to ; /// @@ -73,6 +80,14 @@ namespace Tgstation.Server.Host.Components.Repository /// A representing the running operation Task PushHeadToTemporaryBranch(string accessString, CancellationToken cancellationToken); + /// + /// Runs the synchronize event script and attempts to push any changes made to the if on a tracked branch + /// + /// The access string to push to the origin repository + /// The for the operation + /// A representing the running operation + Task Sychronize(string accessString, CancellationToken cancellationToken); + /// /// Copies the current working directory to a given /// diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs index 4696bb66bb..52565c0a34 100644 --- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs @@ -229,5 +229,17 @@ namespace Tgstation.Server.Host.Components.Repository throw new ArgumentNullException(nameof(path)); await ioMananger.CopyDirectory(".", path, new List { ".git" }, cancellationToken).ConfigureAwait(false); } + + /// + public Task MergeOrigin(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + /// + public Task Sychronize(string accessString, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } } } diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs index 6442c22e7c..6ff0183354 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs @@ -9,6 +9,7 @@ using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using Tgstation.Server.Api.Models; +using Tgstation.Server.Host.Core; using Tgstation.Server.Host.IO; using Tgstation.Server.Host.Security; @@ -55,6 +56,11 @@ namespace Tgstation.Server.Host.Components.StaticFiles /// readonly ILogger logger; + /// + /// The for + /// + readonly SemaphoreSlim semaphore; + /// /// Construct /// @@ -70,8 +76,18 @@ namespace Tgstation.Server.Host.Components.StaticFiles this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory)); this.scriptExecutor = scriptExecutor ?? throw new ArgumentNullException(nameof(scriptExecutor)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + semaphore = new SemaphoreSlim(1); } + /// + public void Dispose() => semaphore.Dispose(); + + /// + /// Ensures standard configuration directories exist + /// + /// The for the operation + /// A representing the running operation Task EnsureDirectories(CancellationToken cancellationToken) => Task.WhenAll(ioManager.CreateDirectory(CodeModificationsSubdirectory, cancellationToken), ioManager.CreateDirectory(EventScriptsSubdirectory, cancellationToken), ioManager.CreateDirectory(GameStaticFilesSubdirectory, cancellationToken)); /// @@ -276,11 +292,16 @@ namespace Tgstation.Server.Host.Components.StaticFiles if (!EventTypeScriptFileNameMap.TryGetValue(eventType, out var scriptName)) return true; - var files = await ioManager.GetFilesWithExtension(EventScriptsSubdirectory, SystemScriptFileExtension, cancellationToken).ConfigureAwait(false); - var resolvedScriptsDir = ioManager.ResolvePath(EventScriptsSubdirectory); - foreach (var I in files.Where(x => x.StartsWith(scriptName, StringComparison.Ordinal))) - if ((await scriptExecutor.ExecuteScript(ioManager.ConcatPath(resolvedScriptsDir, I), parameters, cancellationToken).ConfigureAwait(false)) != 0) - return false; + //always execute in serial + using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false)) + { + var files = await ioManager.GetFilesWithExtension(EventScriptsSubdirectory, SystemScriptFileExtension, cancellationToken).ConfigureAwait(false); + var resolvedScriptsDir = ioManager.ResolvePath(EventScriptsSubdirectory); + + foreach (var I in files.Where(x => x.StartsWith(scriptName, StringComparison.Ordinal))) + if ((await scriptExecutor.ExecuteScript(ioManager.ConcatPath(resolvedScriptsDir, I), parameters, cancellationToken).ConfigureAwait(false)) != 0) + return false; + } return true; } } diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs index 883568558e..3fdce2aa9b 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/IConfiguration.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.Hosting; +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -10,7 +11,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles /// /// For managing the Configuration directory /// - public interface IConfiguration : IHostedService, IEventConsumer + public interface IConfiguration : IHostedService, IEventConsumer, IDisposable { /// /// Copies all files in the CodeModifications directory to diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/ScriptExecutor.cs b/src/Tgstation.Server.Host/Components/StaticFiles/ScriptExecutor.cs index 7aa7409d4c..14a2a97805 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/ScriptExecutor.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/ScriptExecutor.cs @@ -35,13 +35,15 @@ namespace Tgstation.Server.Host.Components.StaticFiles /// public async Task ExecuteScript(string scriptPath, IEnumerable parameters, CancellationToken cancellationToken) { + var joinedParams = String.Join(" ", parameters); + logger.LogInformation("Running script {0} {1}", scriptPath, joinedParams); try { using (var process = new Process()) { process.StartInfo.FileName = scriptPath; process.StartInfo.WorkingDirectory = ioManager.GetDirectoryName(scriptPath); - process.StartInfo.Arguments = String.Join(" ", parameters); + process.StartInfo.Arguments = joinedParams; process.EnableRaisingEvents = true; var tcs = new TaskCompletionSource();