Fix OD build paths being too long on Windows

This commit is contained in:
Jordan Dominion
2023-10-14 22:47:14 -04:00
parent 0544c0241c
commit 1f2e4494a2
2 changed files with 54 additions and 14 deletions
@@ -206,21 +206,25 @@ namespace Tgstation.Server.Host.Components.Engine
var dotnetPath = dotnetPaths[selectedPathIndex];
await using (var buildProcess = ProcessExecutor.LaunchProcess(
dotnetPath,
int? buildExitCode = null;
await HandleExtremelyLongPathOperation(
async shortenedPath =>
{
await using var buildProcess = ProcessExecutor.LaunchProcess(
dotnetPath,
shortenedPath,
"build -c Release /p:TgsEngineBuild=true",
null,
true,
true);
buildExitCode = await buildProcess.Lifetime;
Logger.LogDebug("Build output:{newLine}{output}", Environment.NewLine, await buildProcess.GetCombinedOutput(cancellationToken));
},
sourcePath,
"build -c Release /p:TgsEngineBuild=true",
null,
true,
true))
{
var buildExitCode = await buildProcess.Lifetime;
cancellationToken);
Logger.LogDebug("Build output:{newLine}{output}", Environment.NewLine, await buildProcess.GetCombinedOutput(cancellationToken));
if (buildExitCode != 0)
throw new JobException("OpenDream build failed!");
}
if (buildExitCode != 0)
throw new JobException("OpenDream build failed!");
await IOManager.MoveDirectory(
IOManager.ConcatPath(
@@ -250,6 +254,19 @@ namespace Tgstation.Server.Host.Components.Engine
return ValueTask.CompletedTask;
}
/// <summary>
/// Perform an operation on a very long path.
/// </summary>
/// <param name="shortenedPathOperation">A <see cref="Func{T, TResult}"/> taking a shortened path and resulting in a <see cref="ValueTask"/> representing the running operation.</param>
/// <param name="originalPath">The original path to the directory.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
protected virtual ValueTask HandleExtremelyLongPathOperation(
Func<string, ValueTask> shortenedPathOperation,
string originalPath,
CancellationToken cancellationToken)
=> shortenedPathOperation(originalPath); // based god linux has no such weakness
/// <summary>
/// Gets the paths to the server and client executables.
/// </summary>
@@ -21,6 +21,11 @@ namespace Tgstation.Server.Host.Components.Engine
/// </summary>
sealed class WindowsOpenDreamInstaller : OpenDreamInstaller
{
/// <summary>
/// The <see cref="ISymlinkFactory"/> for the <see cref="WindowsOpenDreamInstaller"/>.
/// </summary>
readonly ISymlinkFactory symlinkFactory;
/// <summary>
/// Initializes a new instance of the <see cref="WindowsOpenDreamInstaller"/> class.
/// </summary>
@@ -30,13 +35,15 @@ namespace Tgstation.Server.Host.Components.Engine
/// <param name="processExecutor">The <see cref="IProcessExecutor"/> for the <see cref="OpenDreamInstaller"/>.</param>
/// <param name="repositoryManager">The <see cref="IRepositoryManager"/> for the <see cref="OpenDreamInstaller"/>.</param>
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> of <see cref="GeneralConfiguration"/> for the <see cref="OpenDreamInstaller"/>.</param>
/// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/>.</param>
public WindowsOpenDreamInstaller(
IIOManager ioManager,
ILogger<WindowsOpenDreamInstaller> logger,
IPlatformIdentifier platformIdentifier,
IProcessExecutor processExecutor,
IRepositoryManager repositoryManager,
IOptions<GeneralConfiguration> generalConfigurationOptions)
IOptions<GeneralConfiguration> generalConfigurationOptions,
ISymlinkFactory symlinkFactory)
: base(
ioManager,
logger,
@@ -45,6 +52,7 @@ namespace Tgstation.Server.Host.Components.Engine
repositoryManager,
generalConfigurationOptions)
{
this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
}
/// <inheritdoc />
@@ -59,6 +67,21 @@ namespace Tgstation.Server.Host.Components.Engine
installPath,
cancellationToken));
/// <inheritdoc />
protected override async ValueTask HandleExtremelyLongPathOperation(Func<string, ValueTask> shortenedPathOperation, string originalPath, CancellationToken cancellationToken)
{
var shortPath = $"C:/{Guid.NewGuid()}";
await symlinkFactory.CreateSymbolicLink(originalPath, shortPath, cancellationToken);
try
{
await shortenedPathOperation(shortPath);
}
finally
{
await IOManager.DeleteDirectory(shortPath, CancellationToken.None); // DCT: Should always run.
}
}
/// <summary>
/// Attempt to add the DreamDaemon executable as an exception to the Windows firewall.
/// </summary>