157 lines
5.7 KiB
C#
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);
|
|
}
|
|
} |