mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-30 08:33:19 +01:00
Merge branch '714-StaticIgnore' into 4.0.1.0
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user