More repo stuff + serialize config script execution

This commit is contained in:
Jordan Brown
2018-07-29 19:21:12 -04:00
parent 9a789ed76c
commit 515a1434db
6 changed files with 62 additions and 10 deletions
@@ -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();
}
/// <summary>
@@ -65,6 +65,13 @@ namespace Tgstation.Server.Host.Components.Repository
/// <returns>A <see cref="Task{TResult}"/> resulting in the SHA of the new HEAD</returns>
Task<string> ResetToOrigin(CancellationToken cancellationToken);
/// <summary>
/// Requires the current HEAD to be a tracked reference. Merges the reference to what it tracks on the origin repository
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the SHA of the new HEAD. <see langword="null"/> if the merge resulted in conflict</returns>
Task<string> MergeOrigin(CancellationToken cancellationToken);
/// <summary>
/// Force push the current repository HEAD to <see cref="Repository.RemoteTemporaryBranchName"/>;
/// </summary>
@@ -73,6 +80,14 @@ namespace Tgstation.Server.Host.Components.Repository
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task PushHeadToTemporaryBranch(string accessString, CancellationToken cancellationToken);
/// <summary>
/// Runs the synchronize event script and attempts to push any changes made to the <see cref="IRepository"/> if on a tracked branch
/// </summary>
/// <param name="accessString">The access string to push to the origin repository</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task Sychronize(string accessString, CancellationToken cancellationToken);
/// <summary>
/// Copies the current working directory to a given <paramref name="path"/>
/// </summary>
@@ -229,5 +229,17 @@ namespace Tgstation.Server.Host.Components.Repository
throw new ArgumentNullException(nameof(path));
await ioMananger.CopyDirectory(".", path, new List<string> { ".git" }, cancellationToken).ConfigureAwait(false);
}
/// <inheritdoc />
public Task<string> MergeOrigin(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task Sychronize(string accessString, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
}
@@ -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
/// </summary>
readonly ILogger<Configuration> logger;
/// <summary>
/// The <see cref="SemaphoreSlim"/> for <see cref="Configuration"/>
/// </summary>
readonly SemaphoreSlim semaphore;
/// <summary>
/// Construct <see cref="Configuration"/>
/// </summary>
@@ -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);
}
/// <inheritdoc />
public void Dispose() => semaphore.Dispose();
/// <summary>
/// Ensures standard configuration directories exist
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task EnsureDirectories(CancellationToken cancellationToken) => Task.WhenAll(ioManager.CreateDirectory(CodeModificationsSubdirectory, cancellationToken), ioManager.CreateDirectory(EventScriptsSubdirectory, cancellationToken), ioManager.CreateDirectory(GameStaticFilesSubdirectory, cancellationToken));
/// <inheritdoc />
@@ -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;
}
}
@@ -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
/// <summary>
/// For managing the Configuration directory
/// </summary>
public interface IConfiguration : IHostedService, IEventConsumer
public interface IConfiguration : IHostedService, IEventConsumer, IDisposable
{
/// <summary>
/// Copies all files in the CodeModifications directory to <paramref name="destination"/>
@@ -35,13 +35,15 @@ namespace Tgstation.Server.Host.Components.StaticFiles
/// <inheritdoc />
public async Task<int?> ExecuteScript(string scriptPath, IEnumerable<string> 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<object>();