Started implementing server installation

This commit is contained in:
2025-02-13 21:23:35 +01:00
parent f45699f300
commit 761ab455f0
11 changed files with 179 additions and 19 deletions

View File

@@ -30,6 +30,8 @@ public partial class Server
await LogToConsole("Removing container");
await dockerClient.Containers.RemoveContainerAsync(container.ID, new());
RuntimeContainerId = null;
}
catch (DockerContainerNotFoundException){}

View File

@@ -53,7 +53,8 @@ public partial class Server
.OnEntryAsync(InternalStop);
StateMachine.Configure(ServerState.Installing)
.Permit(ServerTrigger.NotifyInstallContainerDied, ServerState.Offline);
.Permit(ServerTrigger.NotifyContainerDied, ServerState.Offline)
.OnEntryAsync(InternalInstall);
return Task.CompletedTask;
}

View File

@@ -0,0 +1,59 @@
using Docker.DotNet;
using MoonCore.Helpers;
using MoonlightServers.Daemon.Enums;
using MoonlightServers.Daemon.Extensions;
using MoonlightServers.Daemon.Services;
using MoonlightServers.DaemonShared.PanelSide.Http.Responses;
namespace MoonlightServers.Daemon.Abstractions;
public partial class Server
{
public async Task Install() => await StateMachine.FireAsync(ServerTrigger.Reinstall);
private async Task InternalInstall()
{
// TODO: Consider if checking for existing install containers is actually useful, because
// when the daemon is starting and a installation is still ongoing it will reattach anyways
// and the container has the auto remove flag enabled by default (maybe also consider this for the normal runtime container)
await LogToConsole("Fetching installation configuration");
// Fetching remote configuration
var remoteService = ServiceProvider.GetRequiredService<RemoteService>();
using var remoteHttpClient = await remoteService.CreateHttpClient();
var installData = await remoteHttpClient.GetJson<ServerInstallDataResponse>($"api/servers/remote/servers/{Configuration.Id}/install");
var dockerImageService = ServiceProvider.GetRequiredService<DockerImageService>();
// We call an external service for that, as we want to have a central management point of images
// for analytics and automatic deletion
await dockerImageService.Ensure(installData.DockerImage, async message => { await LogToConsole(message); });
// Ensuring storage configuration
var installationHostPath = await EnsureInstallationVolume();
var runtimeHostPath = await EnsureRuntimeVolume();
// Write installation script to path
await File.WriteAllTextAsync(PathBuilder.File(installationHostPath, "install.sh"), installData.Script.Replace("\n\r", "\n") + "\n\n");
// Creating container configuration
var parameters = Configuration.ToInstallationCreateParameters(
runtimeHostPath,
installationHostPath,
InstallationContainerName,
installData.DockerImage,
installData.Shell
);
var dockerClient = ServiceProvider.GetRequiredService<DockerClient>();
var container = await dockerClient.Containers.CreateContainerAsync(parameters);
InstallationContainerId = container.ID;
await AttachConsole(InstallationContainerId);
await dockerClient.Containers.StartContainerAsync(InstallationContainerId, new());
}
}

View File

@@ -35,11 +35,11 @@ public partial class Server
var appConfiguration = ServiceProvider.GetRequiredService<AppConfiguration>();
var hostPath = PathBuilder.Dir(
appConfiguration.Storage.Volumes,
appConfiguration.Storage.Install,
Configuration.Id.ToString()
);
await LogToConsole("Creating storage");
await LogToConsole("Creating installation storage");
// Create volume if missing
if (!Directory.Exists(hostPath))