Owner decision pending (STATE.md DC-100 tick): adopt/ship/park. Preserved from fragile git stash to named branch 2026-08-23. NOTE: requires a Windows build machine (WinUI XAML compiler + MSIX do not cross-build on Linux) — see WINDOWS_APP_BUILD.md in this tree. Secret-scanned clean 2026-08-23 (no keys/tokens/PEM in tree).
125 lines
3.9 KiB
C#
125 lines
3.9 KiB
C#
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<List<ContainerListResponse>> GetContainersAsync(string labelFilter = null)
|
|
{
|
|
var parameters = new ContainersListParameters
|
|
{
|
|
All = true,
|
|
Filters = new Dictionary<string, IDictionary<string, bool>>
|
|
{
|
|
["label"] = new Dictionary<string, bool> { ["dashcaddy.managed"] = true }
|
|
}
|
|
};
|
|
|
|
if (!string.IsNullOrEmpty(labelFilter))
|
|
{
|
|
parameters.Filters["name"] = new Dictionary<string, bool> { [labelFilter] = true };
|
|
}
|
|
|
|
return await _client.Containers.ListContainersAsync(parameters);
|
|
}
|
|
|
|
public async Task<ContainerInspectResponse> 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<string, string>
|
|
{
|
|
["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<string, IList<PortBinding>>
|
|
{
|
|
[$"{p}/tcp"] = new List<PortBinding> { new PortBinding { HostPort = p.ToString() } }
|
|
}
|
|
: new Dictionary<string, IList<PortBinding>>(),
|
|
RestartPolicy = new RestartPolicy { Name = "unless-stopped" }
|
|
}
|
|
};
|
|
|
|
if (service.Volumes != null)
|
|
{
|
|
createParams.HostConfig.Binds = service.Volumes.ToList();
|
|
}
|
|
|
|
await _client.Containers.CreateContainerAsync(createParams);
|
|
}
|
|
|
|
public async Task<string> 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<bool> IsDockerRunningAsync()
|
|
{
|
|
try
|
|
{
|
|
await _client.System.PingAsync();
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<VersionResponse> GetVersionAsync()
|
|
{
|
|
return await _client.System.GetVersionAsync();
|
|
}
|
|
} |