using Docker.DotNet; using Docker.DotNet.Models; using DashCaddy.Desktop.Models; using System.Text.Json; namespace DashCaddy.Desktop.Services; public class DockerService { private readonly DockerClient _client; public DockerService(string endpoint) { _client = new DockerClientConfiguration(new Uri(endpoint)).CreateClient(); } public async Task> GetContainersAsync(string labelFilter = null) { var parameters = new ContainersListParameters { All = true, Filters = new Dictionary> { ["label"] = new Dictionary { ["dashcaddy.managed"] = true } } }; if (!string.IsNullOrEmpty(labelFilter)) { parameters.Filters["name"] = new Dictionary { [labelFilter] = true }; } return await _client.Containers.ListContainersAsync(parameters); } public async Task GetContainerAsync(string id) { return await _client.Containers.InspectContainerAsync(id); } public async Task StartContainerAsync(string id) { await _client.Containers.StartContainerAsync(id, null); } public async Task StopContainerAsync(string id) { await _client.Containers.StopContainerAsync(id, new ContainerStopParameters { WaitBeforeKillSeconds = 10 }); } public async Task RestartContainerAsync(string id) { await _client.Containers.RestartContainerAsync(id, new ContainerRestartParameters { WaitBeforeKillSeconds = 10 }); } public async Task RemoveContainerAsync(string id) { await _client.Containers.RemoveContainerAsync(id, new ContainerRemoveParameters { Force = true, RemoveVolumes = false }); } public async Task CreateContainerAsync(ServiceModel service) { var createParams = new CreateContainerParameters { Image = service.Image, Name = $"dashcaddy-{service.Id}", Labels = new Dictionary { ["dashcaddy.managed"] = "true", ["dashcaddy.service-id"] = service.Id, ["dashcaddy.service-name"] = service.Name }, Env = service.Environment.Select(kvp => $"{kvp.Key}={kvp.Value}").ToList(), HostConfig = new HostConfig { PortBindings = service.Environment.TryGetValue("PORT", out var port) && int.TryParse(port, out var p) ? new Dictionary> { [$"{p}/tcp"] = new List { new PortBinding { HostPort = p.ToString() } } } : new Dictionary>(), RestartPolicy = new RestartPolicy { Name = "unless-stopped" } } }; if (service.Volumes != null) { createParams.HostConfig.Binds = service.Volumes.ToList(); } await _client.Containers.CreateContainerAsync(createParams); } public async Task GetContainerLogsAsync(string id, int tailLines = 100) { var parameters = new ContainerLogsParameters { ShowStdout = true, ShowStderr = true, Tail = tailLines.ToString() }; using var stream = await _client.Containers.GetContainerLogsAsync(id, false, parameters); using var reader = new StreamReader(stream); return await reader.ReadToEndAsync(); } public async Task IsDockerRunningAsync() { try { await _client.System.PingAsync(); return true; } catch { return false; } } public async Task GetVersionAsync() { return await _client.System.GetVersionAsync(); } }