Merge branch '714-StaticIgnore' into 4.0.1.0

This commit is contained in:
Jordan Brown
2018-10-11 12:34:08 -04:00
3 changed files with 63 additions and 4 deletions
+1 -1
View File
@@ -315,7 +315,7 @@ This folder can contain anything. But, when certain events occur in the instance
#### GameStaticFiles
Any files and folders contained in this root level of this folder will be symbolically linked to all deployments at the time they are created. This allows persistent game data (BYOND `.sav`s or code configuration files for example) to persist across all deployments.
Any files and folders contained in this root level of this folder will be symbolically linked to all deployments at the time they are created. This allows persistent game data (BYOND `.sav`s or code configuration files for example) to persist across all deployments. This folder contains a .tgsignore file which can be used to prevent symlinks from being generated by entering the names of files and folders (1 per line)
### Updating
@@ -124,7 +124,7 @@ namespace Tgstation.Server.Host.Components.Byond
//after this version lummox made DD depend of directx lol
//but then he became amazing and not only fixed it but also gave us 30s compiles \[T]/
if (version.Major == 512 && version.Minor >= 1427 && version.Major < 1452 && !installedDirectX)
if (version.Major == 512 && version.Minor >= 1427 && version.Minor < 1452 && !installedDirectX)
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
//check again because race conditions
if (!installedDirectX)
@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api.Models;
@@ -22,6 +23,11 @@ namespace Tgstation.Server.Host.Components.StaticFiles
const string EventScriptsSubdirectory = "EventScripts";
const string GameStaticFilesSubdirectory = "GameStaticFiles";
/// <summary>
/// Name of the ignore file in <see cref="GameStaticFilesSubdirectory"/>
/// </summary>
const string StaticIgnoreFile = ".tgsignore";
const string CodeModificationsHeadFile = "HeadInclude.dm";
const string CodeModificationsTailFile = "TailInclude.dm";
@@ -93,12 +99,29 @@ namespace Tgstation.Server.Host.Components.StaticFiles
/// <inheritdoc />
public void Dispose() => semaphore.Dispose();
/// <summary>
/// Get the proper path to <see cref="StaticIgnoreFile"/>
/// </summary>
/// <returns>The <see cref="ioManager"/> relative path to <see cref="StaticIgnoreFile"/></returns>
string StaticIgnorePath() => ioManager.ConcatPath(GameStaticFilesSubdirectory, StaticIgnoreFile);
/// <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));
async Task EnsureDirectories(CancellationToken cancellationToken)
{
async Task ValidateStaticFolder()
{
await ioManager.CreateDirectory(GameStaticFilesSubdirectory, cancellationToken).ConfigureAwait(false);
var staticIgnorePath = StaticIgnorePath();
if(!await ioManager.FileExists(staticIgnorePath, cancellationToken).ConfigureAwait(false))
await ioManager.WriteAllBytes(staticIgnorePath, Array.Empty<byte>(), cancellationToken).ConfigureAwait(false);
}
await Task.WhenAll(ioManager.CreateDirectory(CodeModificationsSubdirectory, cancellationToken), ioManager.CreateDirectory(EventScriptsSubdirectory, cancellationToken), ValidateStaticFolder()).ConfigureAwait(false);
}
/// <inheritdoc />
public async Task<ServerSideModifications> CopyDMFilesTo(string dmeFile, string destination, CancellationToken cancellationToken)
@@ -254,6 +277,26 @@ namespace Tgstation.Server.Host.Components.StaticFiles
/// <inheritdoc />
public async Task SymlinkStaticFilesTo(string destination, CancellationToken cancellationToken)
{
async Task<IReadOnlyList<string>> GetIgnoreFiles()
{
var ignoreFileBytes = await ioManager.ReadAllBytes(StaticIgnorePath(), cancellationToken).ConfigureAwait(false);
var ignoreFileText = Encoding.UTF8.GetString(ignoreFileBytes);
//we don't want to lose trailing whitespace on linux
var results = new List<string> { StaticIgnoreFile };
using (var reader = new StringReader(ignoreFileText)) {
cancellationToken.ThrowIfCancellationRequested();
var line = await reader.ReadLineAsync().ConfigureAwait(false);
if (!String.IsNullOrEmpty(line))
results.Add(line);
}
return results;
};
IReadOnlyList<string> ignoreFiles;
async Task SymlinkBase(bool files)
{
Task<IReadOnlyList<string>> task;
@@ -265,7 +308,22 @@ namespace Tgstation.Server.Host.Components.StaticFiles
await Task.WhenAll(task.Result.Select(async x =>
{
var destPath = ioManager.ConcatPath(destination, ioManager.GetFileName(x));
var fileName = ioManager.GetFileName(x);
bool ignored;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
//need to normalize
ignored = ignoreFiles.Any(y => fileName.ToUpperInvariant() == y.ToUpperInvariant());
else
ignored = ignoreFiles.Any(y => fileName == y);
if (ignored)
{
logger.LogTrace("Ignoring static file {0}...", fileName);
return;
}
var destPath = ioManager.ConcatPath(destination, fileName);
logger.LogTrace("Symlinking {0} to {1}...", x, destPath);
var fileExistsTask = ioManager.FileExists(destPath, cancellationToken);
if (await ioManager.DirectoryExists(destPath, cancellationToken).ConfigureAwait(false))
@@ -280,6 +338,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
{
await EnsureDirectories(cancellationToken).ConfigureAwait(false);
ignoreFiles = await GetIgnoreFiles().ConfigureAwait(false);
await Task.WhenAll(SymlinkBase(true), SymlinkBase(false)).ConfigureAwait(false);
}
}