More ByondManager stuff

This commit is contained in:
Cyberboss
2018-07-23 16:14:04 -04:00
parent 7f77d7f9ab
commit 9023336744
4 changed files with 104 additions and 27 deletions
@@ -0,0 +1,17 @@
using System;
namespace Tgstation.Server.Host.Components
{
sealed class ByondExecutableLock : IByondExecutableLock
{
public Version Version { get; set; }
public string DreamDaemonPath { get; set; }
public string DreamMakerPath { get; set; }
public void Dispose() { }
public void DoNotDeleteThisSession() { }
}
}
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -13,6 +14,12 @@ namespace Tgstation.Server.Host.Components
sealed class ByondManager : IByondManager
{
const string VersionFileName = "Version.txt";
const string ActiveVersionFileName = "ActiveVersion.txt";
const string BinPath = "byond/bin";
/// <inheritdoc />
public Version ActiveVersion { get; private set; }
/// <summary>
/// The <see cref="IIOManager"/> for the <see cref="ByondManager"/>
@@ -87,27 +94,69 @@ namespace Tgstation.Server.Host.Components
}
/// <inheritdoc />
public Task ChangeVersion(Version version, CancellationToken cancellationToken)
public async Task ChangeVersion(Version version, CancellationToken cancellationToken)
{
throw new NotImplementedException();
await InstallVersion(version, cancellationToken).ConfigureAwait(false);
await ioManager.WriteAllBytes(ActiveVersionFileName, Encoding.UTF8.GetBytes(version.ToString()), cancellationToken).ConfigureAwait(false);
ActiveVersion = version;
}
/// <inheritdoc />
public Task ClearCache(CancellationToken cancellationToken)
public async Task<IByondExecutableLock> UseExecutables(Version requiredVersion, CancellationToken cancellationToken)
{
throw new NotImplementedException();
var versionToUse = requiredVersion ?? ActiveVersion;
if (versionToUse == null)
throw new InvalidOperationException("No BYOND versions installed!");
await InstallVersion(requiredVersion, cancellationToken).ConfigureAwait(false);
var versionKey = VersionKey(versionToUse);
return new ByondExecutableLock
{
DreamDaemonPath = ioManager.ResolvePath(ioManager.ConcatPath(versionKey, byondInstaller.DreamDaemonName)),
DreamMakerPath = ioManager.ResolvePath(ioManager.ConcatPath(versionKey, byondInstaller.DreamMakerName)),
Version = versionToUse
};
}
/// <inheritdoc />
public Task<Version> GetVersion(CancellationToken cancellationToken)
public async Task StartAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
var cacheCleanTask = byondInstaller.CleanCache(cancellationToken);
var activeVersionBytesTask = ioManager.ReadAllBytes(ActiveVersionFileName, cancellationToken);
var directories = await ioManager.GetDirectories(".", cancellationToken).ConfigureAwait(false);
async Task ReadVersion(string path)
{
var bytes = await ioManager.ReadAllBytes(ioManager.ConcatPath(path, VersionFileName), cancellationToken).ConfigureAwait(false);
var text = Encoding.UTF8.GetString(bytes);
if (Version.TryParse(text, out var version))
{
var key = VersionKey(version);
lock (installedVersions)
if (!installedVersions.ContainsKey(key))
{
installedVersions.Add(key, Task.CompletedTask);
return;
}
}
await ioManager.DeleteDirectory(path, cancellationToken).ConfigureAwait(false);
};
await Task.WhenAll(directories.Select(x => ReadVersion(x))).ConfigureAwait(false);
var activeVersionString = Encoding.UTF8.GetString(await activeVersionBytesTask.ConfigureAwait(false));
if (Version.TryParse(activeVersionString, out var activeVersion))
ActiveVersion = activeVersion;
else
await ioManager.DeleteFile(ActiveVersionFileName, cancellationToken).ConfigureAwait(false);
await cacheCleanTask.ConfigureAwait(false);
}
/// <inheritdoc />
public IByondExecutableLock UseExecutables(Version requiredVersion)
{
throw new NotImplementedException();
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
}
@@ -7,10 +7,20 @@ using Stream = System.IO.Stream;
namespace Tgstation.Server.Host.Components
{
/// <summary>
/// For downloading and installing BYOND extractions
/// For downloading and installing BYOND extractions for a given system
/// </summary>
interface IByondInstaller
{
/// <summary>
/// Get the file name of the DreamDaemon executable
/// </summary>
string DreamDaemonName { get; }
/// <summary>
/// Get the file name of the DreamMaker executable
/// </summary>
string DreamMakerName { get; }
/// <summary>
/// Download a given BYOND <paramref name="version"/>
/// </summary>
@@ -26,5 +36,12 @@ namespace Tgstation.Server.Host.Components
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns></returns>
Task InstallByond(string path, CancellationToken cancellationToken);
/// <summary>
/// Attempts to cleans the BYOND cache folder for the system
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task CleanCache(CancellationToken cancellationToken);
}
}
@@ -1,4 +1,5 @@
using System;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;
@@ -7,8 +8,13 @@ namespace Tgstation.Server.Host.Components
/// <summary>
/// For managing the BYOND installation
/// </summary>
public interface IByondManager
public interface IByondManager : IHostedService
{
/// <summary>
/// The currently active BYOND version
/// </summary>
Version ActiveVersion { get; }
/// <summary>
/// Change the active BYOND version
/// </summary>
@@ -16,24 +22,12 @@ namespace Tgstation.Server.Host.Components
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
Task ChangeVersion(Version version, CancellationToken cancellationToken);
/// <summary>
/// Get the currently active BYOND version
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>The current BYOND version</returns>
Task<Version> GetVersion(CancellationToken cancellationToken);
/// <summary>
/// Lock the current installation's location and return a <see cref="IByondExecutableLock"/>
/// </summary>
/// <param name="requiredVersion">The BYOND <see cref="Version"/> required</param>
IByondExecutableLock UseExecutables(Version requiredVersion);
/// <summary>
/// Clears the cache folder
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
Task ClearCache(CancellationToken cancellationToken);
/// <returns>A <see cref="Task{TResult}"/> resulting in the requested <see cref="IByondExecutableLock"/></returns>
Task<IByondExecutableLock> UseExecutables(Version requiredVersion, CancellationToken cancellationToken);
}
}