diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs
index 34cda5315b1e..c27d1ea25874 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs
@@ -9,6 +9,7 @@
using System.Diagnostics.CodeAnalysis;
#endif
using System.Text;
+using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using Microsoft.NET.Build.Containers.Resources;
@@ -143,13 +144,27 @@ internal static bool IsValidImageTag(string imageTag)
return ReferenceParser.anchoredTagRegexp.IsMatch(imageTag);
}
+
///
/// Given an already-validated registry domain, this is our hueristic to determine what HTTP protocol should be used to interact with it.
+ /// If the domain is localhost, we default to HTTP. Otherwise, we check the Docker config to see if the registry is marked as insecure.
/// This is primarily for testing - in the real world almost all usage should be through HTTPS!
///
internal static Uri TryExpandRegistryToUri(string alreadyValidatedDomain)
{
- var prefix = alreadyValidatedDomain.StartsWith("localhost", StringComparison.Ordinal) ? "http" : "https";
+ string prefix = "https";
+ if (alreadyValidatedDomain.StartsWith("localhost", StringComparison.Ordinal))
+ {
+ prefix = "http";
+ }
+
+ //check the docker config to see if the registry is marked as insecure
+ else if (DockerCli.IsInsecureRegistry(alreadyValidatedDomain))
+ {
+ prefix = "http";
+ }
+
+
return new Uri($"{prefix}://{alreadyValidatedDomain}");
}
diff --git a/src/Containers/Microsoft.NET.Build.Containers/LocalDaemons/DockerCli.cs b/src/Containers/Microsoft.NET.Build.Containers/LocalDaemons/DockerCli.cs
index b7b0733ad52a..fb0e09b87d5a 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/LocalDaemons/DockerCli.cs
+++ b/src/Containers/Microsoft.NET.Build.Containers/LocalDaemons/DockerCli.cs
@@ -2,7 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
+#if NET
using System.Formats.Tar;
+#endif
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.DotNet.Cli.Utils;
@@ -12,7 +14,10 @@
namespace Microsoft.NET.Build.Containers;
// Wraps the 'docker'/'podman' cli.
-internal sealed class DockerCli : ILocalRegistry
+internal sealed class DockerCli
+#if NET
+: ILocalRegistry
+#endif
{
public const string DockerCommand = "docker";
public const string PodmanCommand = "podman";
@@ -21,7 +26,10 @@ internal sealed class DockerCli : ILocalRegistry
private readonly ILogger _logger;
private string? _command;
+
+#if NET
private string? _fullCommandPath;
+#endif
public DockerCli(string? command, ILoggerFactory loggerFactory)
{
@@ -53,6 +61,7 @@ private static string FindFullPathFromPath(string command)
return command;
}
+#if NET
private async ValueTask FindFullCommandPath(CancellationToken cancellationToken)
{
if (_fullCommandPath != null)
@@ -164,6 +173,7 @@ public bool IsAvailable()
public string? GetCommand()
=> GetCommandAsync(default).GetAwaiter().GetResult();
+#endif
///
/// Gets docker configuration.
@@ -185,7 +195,6 @@ internal static JsonDocument GetDockerConfig()
dockerCommand.CaptureStdErr();
CommandResult dockerCommandResult = dockerCommand.Execute();
-
if (dockerCommandResult.ExitCode != 0)
{
throw new DockerLoadException(Resource.FormatString(
@@ -196,17 +205,68 @@ internal static JsonDocument GetDockerConfig()
}
return JsonDocument.Parse(dockerCommandResult.StdOut);
-
-
}
catch (Exception e) when (e is not DockerLoadException)
{
throw new DockerLoadException(Resource.FormatString(nameof(Strings.DockerInfoFailed_Ex), e.Message));
}
}
+ ///
+ /// Checks if the registry is marked as insecure in the docker/podman config.
+ ///
+ ///
+ ///
+ public static bool IsInsecureRegistry(string registryDomain)
+ {
+ try
+ {
+ //check the docker config to see if the registry is marked as insecure
+ var rootElement = GetDockerConfig().RootElement;
+
+ //for docker
+ if (rootElement.TryGetProperty("RegistryConfig", out var registryConfig) && registryConfig.ValueKind == JsonValueKind.Object)
+ {
+ if (registryConfig.TryGetProperty("IndexConfigs", out var indexConfigs) && indexConfigs.ValueKind == JsonValueKind.Object)
+ {
+ foreach (var property in indexConfigs.EnumerateObject())
+ {
+ if (property.Value.ValueKind == JsonValueKind.Object && property.Value.TryGetProperty("Secure", out var secure) && !secure.GetBoolean())
+ {
+ if (property.Name.Equals(registryDomain, StringComparison.Ordinal))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ //for podman
+ if (rootElement.TryGetProperty("registries", out var registries) && registries.ValueKind == JsonValueKind.Object)
+ {
+ foreach (var property in registries.EnumerateObject())
+ {
+ if (property.Value.ValueKind == JsonValueKind.Object && property.Value.TryGetProperty("Insecure", out var insecure) && insecure.GetBoolean())
+ {
+ if (property.Name.Equals(registryDomain, StringComparison.Ordinal))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ catch (DockerLoadException)
+ {
+ //if docker load fails, we can't check the config so we assume the registry is secure
+ return false;
+ }
+ }
private static void Proc_OutputDataReceived(object sender, DataReceivedEventArgs e) => throw new NotImplementedException();
+#if NET
public static async Task WriteImageToStreamAsync(BuiltImage image, SourceImageReference sourceReference, DestinationImageReference destinationReference, Stream imageStream, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -312,6 +372,7 @@ await Task.WhenAll(
return _command;
}
+#endif
private static bool IsPodmanAlias()
{
@@ -333,6 +394,7 @@ private static bool IsPodmanAlias()
}
}
+#if NET
private async Task TryRunVersionCommandAsync(string command, CancellationToken cancellationToken)
{
try
@@ -355,6 +417,7 @@ private async Task TryRunVersionCommandAsync(string command, CancellationT
return false;
}
}
+#endif
public override string ToString()
{
diff --git a/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj b/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj
index 040677b24bf5..2c6b5818c1af 100644
--- a/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj
+++ b/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj
@@ -43,6 +43,8 @@
+
+