using Docker.DotNet; using MoonlightServers.Daemon.Models; using MoonlightServers.Daemon.ServerSystem.Abstractions; namespace MoonlightServers.Daemon.ServerSystem.Implementations.Docker; public class DockerInstallEnvService : IInstallEnvironmentService { private readonly DockerClient DockerClient; private readonly ILoggerFactory LoggerFactory; private readonly DockerEventService DockerEventService; private readonly ContainerConfigMapper ConfigMapper; private const string NameTemplate = "ml-install-{0}"; public DockerInstallEnvService( DockerClient dockerClient, ILoggerFactory loggerFactory, DockerEventService dockerEventService, ContainerConfigMapper configMapper ) { DockerClient = dockerClient; LoggerFactory = loggerFactory; DockerEventService = dockerEventService; ConfigMapper = configMapper; } public async Task FindAsync(string id) { try { var dockerInspect = await DockerClient.Containers.InspectContainerAsync( string.Format(NameTemplate, id) ); var logger = LoggerFactory.CreateLogger($"MoonlightServers.Daemon.ServerSystem.Implementations.Docker({id})"); return new DockerInstallEnv(dockerInspect.ID, DockerClient, logger, DockerEventService); } catch (DockerContainerNotFoundException) { return null; } } public async Task CreateAsync( string id, RuntimeConfiguration runtimeConfiguration, InstallConfiguration installConfiguration, IInstallStorage installStorage, IRuntimeStorage runtimeStorage ) { try { var dockerInspect = await DockerClient.Containers.InspectContainerAsync( string.Format(NameTemplate, id) ); if (dockerInspect.State.Running) await DockerClient.Containers.KillContainerAsync(dockerInspect.ID, new()); await DockerClient.Containers.RemoveContainerAsync(dockerInspect.ID, new()); } catch (DockerContainerNotFoundException) { // Ignored } var runtimeStoragePath = await runtimeStorage.GetBindPathAsync(); var installStoragePath = await installStorage.GetBindPathAsync(); var parameters = ConfigMapper.GetInstallConfig( id, string.Format(NameTemplate, id), runtimeConfiguration, installConfiguration, runtimeStoragePath, installStoragePath ); var container = await DockerClient.Containers.CreateContainerAsync(parameters); var logger = LoggerFactory.CreateLogger($"MoonlightServers.Daemon.ServerSystem.Implementations.Docker({id})"); return new DockerInstallEnv(container.ID, DockerClient, logger, DockerEventService); } public async Task DeleteAsync(IInstallEnvironment environment) { if (environment is not DockerInstallEnv dockerInstallEnv) throw new ArgumentException( $"You cannot delete runtime environments which haven't been created by {nameof(DockerInstallEnv)}"); await dockerInstallEnv.DisposeAsync(); try { var dockerInspect = await DockerClient.Containers.InspectContainerAsync( dockerInstallEnv.ContainerId ); if (dockerInspect.State.Running) await DockerClient.Containers.KillContainerAsync(dockerInspect.ID, new()); await DockerClient.Containers.RemoveContainerAsync(dockerInspect.ID, new()); } catch (DockerContainerNotFoundException) { // Ignored } } }