using Docker.DotNet; using MoonlightServers.Daemon.Models; using MoonlightServers.Daemon.ServerSystem.Abstractions; namespace MoonlightServers.Daemon.ServerSystem.Implementations.Docker; public class DockerRuntimeEnvService : IRuntimeEnvironmentService { private readonly DockerClient DockerClient; private readonly ILoggerFactory LoggerFactory; private readonly DockerEventService DockerEventService; private const string NameTemplate = "ml-runtime-{0}"; public DockerRuntimeEnvService(DockerClient dockerClient, ILoggerFactory loggerFactory, DockerEventService dockerEventService) { DockerClient = dockerClient; LoggerFactory = loggerFactory; DockerEventService = dockerEventService; } 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 DockerRuntimeEnv(dockerInspect.ID, DockerClient, logger, DockerEventService); } catch (DockerContainerNotFoundException) { return null; } } public async Task CreateAsync( string id, RuntimeConfiguration configuration, IRuntimeStorage storage ) { 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 storagePath = await storage.GetHostPathAsync(); var parameters = ConfigMapper.GetRuntimeConfig( id, string.Format(NameTemplate, id), configuration, storagePath ); var container = await DockerClient.Containers.CreateContainerAsync(parameters); var logger = LoggerFactory.CreateLogger($"MoonlightServers.Daemon.ServerSystem.Implementations.Docker({id})"); return new DockerRuntimeEnv(container.ID, DockerClient, logger, DockerEventService); } public Task UpdateAsync(IRuntimeEnvironment environment, RuntimeConfiguration configuration) { throw new NotImplementedException(); } public async Task DeleteAsync(IRuntimeEnvironment environment) { if (environment is not DockerRuntimeEnv dockerRuntimeEnv) { throw new ArgumentException( $"You cannot delete runtime environments which haven't been created by {nameof(DockerRuntimeEnvService)}" ); } await dockerRuntimeEnv.DisposeAsync(); try { var dockerInspect = await DockerClient.Containers.InspectContainerAsync( dockerRuntimeEnv.ContainerId ); if (dockerInspect.State.Running) await DockerClient.Containers.KillContainerAsync(dockerInspect.ID, new()); await DockerClient.Containers.RemoveContainerAsync(dockerInspect.ID, new()); } catch (DockerContainerNotFoundException) { // Ignored } } }