Invoke OD with dotnet executable for nix friendliness

This commit is contained in:
Jordan Dominion
2024-11-26 21:34:48 -05:00
parent 526f720d12
commit bd6d8b07c2
7 changed files with 72 additions and 49 deletions
@@ -74,29 +74,30 @@ namespace Tgstation.Server.Host.Components.Engine
}
/// <inheritdoc />
public override IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask)
public override ValueTask<IEngineInstallation> CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken)
{
CheckVersionValidity(version);
var installationIOManager = new ResolvingIOManager(IOManager, path);
var supportsMapThreads = version.Version >= MapThreadsVersion;
return new ByondInstallation(
installationIOManager,
installationTask,
version,
installationIOManager.ResolvePath(
installationIOManager.ConcatPath(
ByondBinPath,
GetDreamDaemonName(
version.Version!,
out var supportsCli))),
installationIOManager.ResolvePath(
installationIOManager.ConcatPath(
ByondBinPath,
DreamMakerName)),
supportsCli,
supportsMapThreads);
return ValueTask.FromResult<IEngineInstallation>(
new ByondInstallation(
installationIOManager,
installationTask,
version,
installationIOManager.ResolvePath(
installationIOManager.ConcatPath(
ByondBinPath,
GetDreamDaemonName(
version.Version!,
out var supportsCli))),
installationIOManager.ResolvePath(
installationIOManager.ConcatPath(
ByondBinPath,
DreamMakerName)),
supportsCli,
supportsMapThreads));
}
/// <inheritdoc />
@@ -33,8 +33,8 @@ namespace Tgstation.Server.Host.Components.Engine
=> Task.WhenAll(delegatedInstallers.Values.Select(installer => installer.CleanCache(cancellationToken)));
/// <inheritdoc />
public IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask)
=> DelegateCall(version, installer => installer.CreateInstallation(version, path, installationTask));
public ValueTask<IEngineInstallation> CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken)
=> DelegateCall(version, installer => installer.CreateInstallation(version, path, installationTask, cancellationToken));
/// <inheritdoc />
public ValueTask<IEngineInstallationData> DownloadVersion(EngineVersion version, JobProgressReporter jobProgressReporter, CancellationToken cancellationToken)
@@ -40,7 +40,7 @@ namespace Tgstation.Server.Host.Components.Engine
}
/// <inheritdoc />
public abstract IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask);
public abstract ValueTask<IEngineInstallation> CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken);
/// <inheritdoc />
public abstract Task CleanCache(CancellationToken cancellationToken);
@@ -337,7 +337,8 @@ namespace Tgstation.Server.Host.Components.Engine
try
{
AddInstallationContainer(version, path, Task.CompletedTask);
var installation = await engineInstaller.CreateInstallation(version, path, Task.CompletedTask, cancellationToken);
AddInstallationContainer(installation);
logger.LogDebug("Added detected BYOND version {versionKey}...", version);
}
catch (Exception ex)
@@ -410,6 +411,13 @@ namespace Tgstation.Server.Host.Components.Engine
IEngineInstallation installation;
EngineExecutableLock installLock;
bool installedOrInstalling;
var potentialInstallation = await engineInstaller.CreateInstallation(
version,
ioManager.ResolvePath(version.ToString()),
ourTcs.Task,
cancellationToken);
lock (installedVersions)
{
if (customVersionStream != null)
@@ -429,10 +437,7 @@ namespace Tgstation.Server.Host.Components.Engine
if (!allowInstallation)
throw new InvalidOperationException($"Engine version {version} not installed!");
installationContainer = AddInstallationContainer(
version,
ioManager.ResolvePath(version.ToString()),
ourTcs.Task);
installationContainer = AddInstallationContainer(potentialInstallation);
}
else
installationContainer = installationContainerNullable!;
@@ -616,18 +621,14 @@ namespace Tgstation.Server.Host.Components.Engine
/// <summary>
/// Create and add a new <see cref="IEngineInstallation"/> to <see cref="installedVersions"/>.
/// </summary>
/// <param name="version">The <see cref="Version"/> being added.</param>
/// <param name="installPath">The path to the installation.</param>
/// <param name="installationTask">The <see cref="ValueTask"/> representing the installation process.</param>
/// <returns>The new <see cref="IEngineInstallation"/>.</returns>
ReferenceCountingContainer<IEngineInstallation, EngineExecutableLock> AddInstallationContainer(EngineVersion version, string installPath, Task installationTask)
/// <param name="installation">The <see cref="IEngineInstallation"/> being added.</param>
/// <returns>A new <see cref="ReferenceCountingContainer{TWrapped, TReference}"/> for the <see cref="IEngineInstallation"/>/<see cref="EngineExecutableLock"/>.</returns>
ReferenceCountingContainer<IEngineInstallation, EngineExecutableLock> AddInstallationContainer(IEngineInstallation installation)
{
var installation = engineInstaller.CreateInstallation(version, installPath, installationTask);
var installationContainer = new ReferenceCountingContainer<IEngineInstallation, EngineExecutableLock>(installation);
lock (installedVersions)
installedVersions.Add(version, installationContainer);
installedVersions.Add(installation.Version, installationContainer);
return installationContainer;
}
@@ -17,8 +17,9 @@ namespace Tgstation.Server.Host.Components.Engine
/// <param name="version">The <see cref="EngineVersion"/> of the installation.</param>
/// <param name="path">The path to the installation.</param>
/// <param name="installationTask">The <see cref="Task"/> representing the installation process for the installation.</param>
/// <returns>The <see cref="IEngineInstallation"/>.</returns>
IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask);
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="IEngineInstallation"/>.</returns>
ValueTask<IEngineInstallation> CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken);
/// <summary>
/// Download a given engine <paramref name="version"/>.
@@ -60,30 +60,46 @@ namespace Tgstation.Server.Host.Components.Engine
/// </summary>
readonly IAbstractHttpClientFactory httpClientFactory;
/// <summary>
/// Path to the Robust.Server.dll.
/// </summary>
readonly string serverDllPath;
/// <summary>
/// Path to the DMCompiler.dll.
/// </summary>
readonly string compilerDllPath;
/// <summary>
/// Initializes a new instance of the <see cref="OpenDreamInstallation"/> class.
/// </summary>
/// <param name="installationIOManager">The <see cref="IIOManager"/> for the <see cref="EngineInstallationBase"/>.</param>
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/>.</param>
/// <param name="httpClientFactory">The value of <see cref="httpClientFactory"/>.</param>
/// <param name="serverExePath">The value of <see cref="ServerExePath"/>.</param>
/// <param name="compilerExePath">The value of <see cref="CompilerExePath"/>.</param>
/// <param name="dotnetPath">The path to the dotnet executable.</param>
/// <param name="serverDllPath">The value of <see cref="serverDllPath"/>.</param>
/// <param name="compilerDllPath">The value of <see cref="compilerDllPath"/>.</param>
/// <param name="installationTask">The value of <see cref="InstallationTask"/>.</param>
/// <param name="version">The value of <see cref="Version"/>.</param>
public OpenDreamInstallation(
IIOManager installationIOManager,
IAsyncDelayer asyncDelayer,
IAbstractHttpClientFactory httpClientFactory,
string serverExePath,
string compilerExePath,
string dotnetPath,
string serverDllPath,
string compilerDllPath,
Task installationTask,
EngineVersion version)
: base(installationIOManager)
{
this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
this.httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
ServerExePath = serverExePath ?? throw new ArgumentNullException(nameof(serverExePath));
CompilerExePath = compilerExePath ?? throw new ArgumentNullException(nameof(compilerExePath));
ServerExePath = dotnetPath ?? throw new ArgumentNullException(nameof(dotnetPath));
CompilerExePath = dotnetPath;
this.serverDllPath = serverDllPath ?? throw new ArgumentNullException(nameof(serverDllPath));
this.compilerDllPath = compilerDllPath ?? throw new ArgumentNullException(nameof(compilerDllPath));
InstallationTask = installationTask ?? throw new ArgumentNullException(nameof(installationTask));
Version = version ?? throw new ArgumentNullException(nameof(version));
@@ -107,7 +123,7 @@ namespace Tgstation.Server.Host.Components.Engine
var parametersString = EncodeParameters(parameters, launchParameters);
var arguments = $"--cvar {(logFilePath != null ? $"log.path=\"{InstallationIOManager.GetDirectoryName(logFilePath)}\" --cvar log.format=\"{InstallationIOManager.GetFileName(logFilePath)}\"" : "log.enabled=false")} --cvar watchdog.token={accessIdentifier} --cvar log.runtimelog=false --cvar net.port={launchParameters.Port!.Value} --cvar opendream.topic_port={launchParameters.OpenDreamTopicPort!.Value} --cvar opendream.world_params=\"{parametersString}\" --cvar opendream.json_path=\"./{dmbProvider.DmbName}\"";
var arguments = $"{serverDllPath} --cvar {(logFilePath != null ? $"log.path=\"{InstallationIOManager.GetDirectoryName(logFilePath)}\" --cvar log.format=\"{InstallationIOManager.GetFileName(logFilePath)}\"" : "log.enabled=false")} --cvar watchdog.token={accessIdentifier} --cvar log.runtimelog=false --cvar net.port={launchParameters.Port!.Value} --cvar opendream.topic_port={launchParameters.OpenDreamTopicPort!.Value} --cvar opendream.world_params=\"{parametersString}\" --cvar opendream.json_path=\"./{dmbProvider.DmbName}\"";
return arguments;
}
@@ -119,7 +135,7 @@ namespace Tgstation.Server.Host.Components.Engine
else
additionalArguments = $"{additionalArguments.Trim()} ";
return $"--suppress-unimplemented --notices-enabled {additionalArguments}\"{dmePath ?? throw new ArgumentNullException(nameof(dmePath))}\"";
return $"{compilerDllPath} --suppress-unimplemented --notices-enabled {additionalArguments}\"{dmePath ?? throw new ArgumentNullException(nameof(dmePath))}\"";
}
/// <inheritdoc />
@@ -118,14 +118,20 @@ namespace Tgstation.Server.Host.Components.Engine
public override Task CleanCache(CancellationToken cancellationToken) => Task.CompletedTask;
/// <inheritdoc />
public override IEngineInstallation CreateInstallation(EngineVersion version, string path, Task installationTask)
public override async ValueTask<IEngineInstallation> CreateInstallation(EngineVersion version, string path, Task installationTask, CancellationToken cancellationToken)
{
CheckVersionValidity(version);
GetExecutablePaths(path, out var serverExePath, out var compilerExePath);
var dotnetPath = await DotnetHelper.GetDotnetPath(platformIdentifier, IOManager, cancellationToken);
if (dotnetPath == null)
throw new JobException("Failed to find dotnet path!");
return new OpenDreamInstallation(
new ResolvingIOManager(IOManager, path),
asyncDelayer,
httpClientFactory,
dotnetPath,
serverExePath,
compilerExePath,
installationTask,
@@ -370,21 +376,19 @@ namespace Tgstation.Server.Host.Components.Engine
/// <param name="compilerExePath">The path to the DMCompiler executable.</param>
protected void GetExecutablePaths(string installationPath, out string serverExePath, out string compilerExePath)
{
var exeExtension = platformIdentifier.IsWindows
? ".exe"
: String.Empty;
const string DllExtension = ".dll";
serverExePath = IOManager.ConcatPath(
installationPath,
BinDir,
ServerDir,
$"Robust.Server{exeExtension}");
$"Robust.Server{DllExtension}");
compilerExePath = IOManager.ConcatPath(
installationPath,
BinDir,
InstallationCompilerDirectory,
$"DMCompiler{exeExtension}");
$"DMCompiler{DllExtension}");
}
}
}