All checks were successful
Caddy Manager CI build / docker (push) Successful in 11m33s
100 lines
3.5 KiB
C#
100 lines
3.5 KiB
C#
using Docker.DotNet;
|
|
using Docker.DotNet.Models;
|
|
using CaddyManager.Contracts.Configurations.Docker;
|
|
using CaddyManager.Contracts.Configurations;
|
|
using CaddyManager.Contracts.Docker;
|
|
|
|
namespace CaddyManager.Services.Docker;
|
|
|
|
/// <inheritdoc />
|
|
public class DockerService(IConfigurationsService configurationsService) : IDockerService
|
|
{
|
|
private DockerServiceConfiguration Configuration => configurationsService.Get<DockerServiceConfiguration>();
|
|
|
|
/// <summary>
|
|
/// Method to get the container id of the Caddy container by the name configured
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private async Task<string> GetCaddyContainerId(IDockerClient client)
|
|
{
|
|
var containers = await client.Containers.ListContainersAsync(new ContainersListParameters
|
|
{
|
|
All = true
|
|
});
|
|
|
|
return containers.FirstOrDefault(container => container.Names.Contains($"/{Configuration.CaddyContainerName}"))
|
|
?.ID ?? string.Empty;
|
|
|
|
}
|
|
|
|
private IDockerClient CreateClient() =>
|
|
new DockerClientConfiguration(new Uri(Configuration.DockerHostWithEnvCheck)).CreateClient();
|
|
|
|
/// <inheritdoc />
|
|
public async Task RestartCaddyContainerAsync()
|
|
{
|
|
using var client = CreateClient();
|
|
|
|
var containerId = await GetCaddyContainerId(client);
|
|
|
|
if (string.IsNullOrEmpty(containerId)) return;
|
|
|
|
await client.Containers.RestartContainerAsync(containerId, new ContainerRestartParameters());
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<CaddyReloadResponse> ReloadCaddyContainerAsync()
|
|
{
|
|
try
|
|
{
|
|
using var client = CreateClient();
|
|
|
|
var containerId = await GetCaddyContainerId(client);
|
|
|
|
if (string.IsNullOrEmpty(containerId))
|
|
{
|
|
return new CaddyReloadResponse
|
|
{
|
|
Message = $"Caddy container '{Configuration.CaddyContainerName}' was not found"
|
|
};
|
|
}
|
|
|
|
var exec = await client.Exec.ExecCreateContainerAsync(containerId, new ContainerExecCreateParameters
|
|
{
|
|
Cmd = ["caddy", "reload", "--config", Configuration.CaddyConfigPathInContainer],
|
|
AttachStdout = true,
|
|
AttachStderr = true
|
|
});
|
|
|
|
string stdout, stderr;
|
|
|
|
using (var stream = await client.Exec.StartAndAttachContainerExecAsync(exec.ID, false))
|
|
{
|
|
(stdout, stderr) = await stream.ReadOutputToEndAsync(CancellationToken.None);
|
|
}
|
|
|
|
var inspection = await client.Exec.InspectContainerExecAsync(exec.ID);
|
|
|
|
if (inspection.ExitCode == 0)
|
|
{
|
|
return new CaddyReloadResponse { Success = true };
|
|
}
|
|
|
|
// Caddy reports errors on stderr, interleaved with its structured JSON progress logs which are noise here
|
|
var output = string.Join(Environment.NewLine, $"{stderr}{Environment.NewLine}{stdout}"
|
|
.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
|
.Where(line => !line.StartsWith('{')));
|
|
|
|
return new CaddyReloadResponse
|
|
{
|
|
Message = string.IsNullOrWhiteSpace(output)
|
|
? $"Caddy reload failed with exit code {inspection.ExitCode}"
|
|
: output.Trim()
|
|
};
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return new CaddyReloadResponse { Message = e.Message };
|
|
}
|
|
}
|
|
} |