Files
Servers/MoonlightServers.Daemon/ServerSystem/Server.Install.cs

157 lines
5.7 KiB
C#

namespace MoonlightServers.Daemon.ServerSystem;
public partial class Server
{
public async Task InstallAsync()
{
await Lock.WaitAsync();
try
{
if (State != ServerState.Offline)
throw new InvalidOperationException("Server is not offline");
// Check if any pre-existing install env exists, if we don't have a reference to it already
InstallEnvironment ??= await InstallEnvironmentService.FindAsync(Uuid);
// Check if storages exist
InstallStorage ??= await InstallStorageService.FindAsync(Uuid);
RuntimeStorage ??= await RuntimeStorageService.FindAsync(Uuid);
// Remove any pre-existing installation env
if (InstallEnvironment != null)
{
Logger.LogTrace("Destroying pre-existing install environment");
if (await InstallEnvironment.IsRunningAsync())
{
Logger.LogTrace("Pre-existing install environment is still running, killing it");
await InstallEnvironment.KillAsync();
}
// Remove any event handlers if existing
InstallEnvironment.Console.OnOutput -= OnConsoleMessageAsync;
InstallEnvironment.Statistics.OnStatisticsReceived -= OnStatisticsReceivedAsync;
InstallEnvironment.OnExited -= OnInstallExitedAsync;
// Now remove it
// Finally remove it
await InstallEnvironmentService.DeleteAsync(InstallEnvironment);
InstallEnvironment = null;
Logger.LogTrace("Pre-existing install environment destroyed");
}
// Remove pre-existing installation storage
if (InstallStorage != null)
{
Logger.LogTrace("Destroying pre-existing installation storage");
await InstallStorageService.DeleteAsync(InstallStorage);
InstallStorage = null;
}
// Fetch the latest configuration
Logger.LogTrace("Fetching latest configuration");
RuntimeConfiguration = await ConfigurationService.GetRuntimeConfigurationAsync(Uuid);
InstallConfiguration = await ConfigurationService.GetInstallConfigurationAsync(Uuid);
// Ensure runtime storage
if (RuntimeStorage == null)
{
Logger.LogTrace("Creating runtime storage");
RuntimeStorage = await RuntimeStorageService.CreateAsync(Uuid, RuntimeConfiguration);
}
else
{
Logger.LogTrace("Updating runtime storage");
await RuntimeStorageService.UpdateAsync(RuntimeStorage, RuntimeConfiguration);
}
// Create installation storage
Logger.LogTrace("Creating installation storage");
InstallStorage = await InstallStorageService.CreateAsync(Uuid, RuntimeConfiguration, InstallConfiguration);
// Write install script
var installStoragePath = await InstallStorage.GetHostPathAsync();
await File.WriteAllTextAsync(
Path.Combine(installStoragePath, "install.sh"),
InstallConfiguration.Script
);
// Create env
Logger.LogTrace("Creating install environment");
InstallEnvironment = await InstallEnvironmentService.CreateAsync(
Uuid,
RuntimeConfiguration,
InstallConfiguration,
InstallStorage,
RuntimeStorage
);
// Add event handlers
Logger.LogTrace("Attaching to install environment");
InstallEnvironment.Console.OnOutput += OnConsoleMessageAsync;
InstallEnvironment.Statistics.OnStatisticsReceived += OnStatisticsReceivedAsync;
InstallEnvironment.OnExited += OnInstallExitedAsync;
// Attach console and statistics
await InstallEnvironment.Console.AttachAsync();
await InstallEnvironment.Statistics.AttachAsync();
// Finally start the env
Logger.LogTrace("Starting install environment");
await InstallEnvironment.StartAsync();
await ChangeStateAsync(ServerState.Installing);
}
finally
{
Lock.Release();
}
}
private async Task OnInstallExitedAsync()
{
Logger.LogTrace("Install environment exited, checking result and cleaning up");
await Lock.WaitAsync();
try
{
// TODO: Handle crash
if (InstallEnvironment == null)
throw new InvalidOperationException("Install environment is not set");
// Make sure no event handler is there
InstallEnvironment.Console.OnOutput -= OnConsoleMessageAsync;
InstallEnvironment.Statistics.OnStatisticsReceived -= OnStatisticsReceivedAsync;
InstallEnvironment.OnExited -= OnInstallExitedAsync;
// Remove env
await InstallEnvironmentService.DeleteAsync(InstallEnvironment);
InstallEnvironment = null;
Logger.LogTrace("Install environment cleaned up");
if(InstallStorage == null)
throw new InvalidOperationException("Install storage is not set");
Logger.LogTrace("Cleaned up install storage");
await InstallStorageService.DeleteAsync(InstallStorage);
InstallStorage = null;
}
finally
{
Lock.Release();
}
await ChangeStateAsync(ServerState.Offline);
}
}