Implemented support for authentication dependent docker registries

This commit is contained in:
2025-04-15 14:16:02 +02:00
parent 144d9141c9
commit 0bca85d775
2 changed files with 51 additions and 5 deletions

View File

@@ -18,6 +18,15 @@ public class AppConfiguration
public class DockerData public class DockerData
{ {
public string Uri { get; set; } = "unix:///var/run/docker.sock"; public string Uri { get; set; } = "unix:///var/run/docker.sock";
public DockerCredentialData[] Credentials { get; set; } = [];
public class DockerCredentialData
{
public string Domain { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Email { get; set; }
}
} }
public class SecurityData public class SecurityData

View File

@@ -1,6 +1,7 @@
using Docker.DotNet; using Docker.DotNet;
using Docker.DotNet.Models; using Docker.DotNet.Models;
using MoonCore.Attributes; using MoonCore.Attributes;
using MoonlightServers.Daemon.Configuration;
namespace MoonlightServers.Daemon.Services; namespace MoonlightServers.Daemon.Services;
@@ -8,21 +9,43 @@ namespace MoonlightServers.Daemon.Services;
public class DockerImageService public class DockerImageService
{ {
private readonly DockerClient DockerClient; private readonly DockerClient DockerClient;
private readonly AppConfiguration Configuration;
private readonly ILogger<DockerImageService> Logger; private readonly ILogger<DockerImageService> Logger;
public DockerImageService(DockerClient dockerClient, ILogger<DockerImageService> logger) public DockerImageService(
DockerClient dockerClient,
ILogger<DockerImageService> logger,
AppConfiguration configuration
)
{ {
Configuration = configuration;
DockerClient = dockerClient; DockerClient = dockerClient;
Logger = logger; Logger = logger;
} }
public async Task Ensure(string name, Action<string>? onProgressUpdated) public async Task Ensure(string name, Action<string>? onProgressUpdated)
{ {
// Figure out if and which credentials to use by checking for the domain
AuthConfig credentials = new();
var domain = GetDomainFromDockerImageName(name);
var configuredCredentials = Configuration.Docker.Credentials
.FirstOrDefault(x => x.Domain.Equals(domain, StringComparison.InvariantCultureIgnoreCase));
if (configuredCredentials != null)
{
credentials.Username = configuredCredentials.Username;
credentials.Password = configuredCredentials.Password;
credentials.Email = configuredCredentials.Email;
}
// Now we want to pull the image
await DockerClient.Images.CreateImageAsync(new() await DockerClient.Images.CreateImageAsync(new()
{ {
FromImage = name FromImage = name
}, },
new AuthConfig(), // TODO: Config for custom registries credentials,
new Progress<JSONMessage>(async message => new Progress<JSONMessage>(async message =>
{ {
if (message.Progress == null) if (message.Progress == null)
@@ -37,4 +60,18 @@ public class DockerImageService
}) })
); );
} }
private string GetDomainFromDockerImageName(string name) // Method names are my passion ;)
{
var nameParts = name.Split("/");
// If it has 1 part -> just the image name (e.g., "ubuntu")
// If it has 2 parts -> usually "user/image" (e.g., "library/ubuntu")
// If it has 3 or more -> assume first part is the registry domain
if (nameParts.Length >= 3 || (nameParts.Length >= 2 && nameParts[0].Contains('.') || nameParts[0].Contains(':')))
return nameParts[0]; // Registry domain is explicitly specified
return "docker.io"; // Default Docker registry
}
} }