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