Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Address all feedback comments: Remove DockerTar enum, fix MSBuild map…
…pings, enhance Docker/Podman runtime support

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
  • Loading branch information
Copilot and captainsafia committed Jul 8, 2025
commit 9125a8f06f4e52424a0a0f12c34ad8c19be74146
25 changes: 16 additions & 9 deletions src/Aspire.Hosting/Publishing/DockerContainerRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,25 @@ private async Task<int> RunDockerBuildAsync(string contextPath, string dockerfil
// Add output format support if specified
if (options?.ImageFormat.HasValue == true || !string.IsNullOrEmpty(options?.OutputPath))
{
var outputType = options.ImageFormat switch
// Validate that OutputPath is provided when ImageFormat is Oci
if (options?.ImageFormat == ContainerImageFormat.Oci && string.IsNullOrEmpty(options?.OutputPath))
{
ContainerImageFormat.OciTar => "type=oci",
ContainerImageFormat.DockerTar => "type=docker",
ContainerImageFormat.Docker => "type=docker",
throw new ArgumentException("OutputPath must be provided when ImageFormat is Oci.", nameof(options));
}

var outputType = options?.ImageFormat switch
{
ContainerImageFormat.Oci => "type=oci",
ContainerImageFormat.Docker => "type=docker,compression=gzip",
null => "type=docker",
_ => throw new ArgumentOutOfRangeException(nameof(options), options.ImageFormat, "Invalid container image format")
};

if (!string.IsNullOrEmpty(options?.OutputPath))
{
outputType += $",dest=\"{options.OutputPath}\"";
// Extract resource name from imageName for the file name
var resourceName = imageName.Split('/').Last().Split(':').First();
outputType += $",dest=\"{options.OutputPath}/{resourceName}.tar\"";
}

arguments += $" --output \"{outputType}\"";
Expand All @@ -48,11 +55,11 @@ private async Task<int> RunDockerBuildAsync(string contextPath, string dockerfil
Arguments = arguments,
OnOutputData = output =>
{
logger.LogInformation("docker build (stdout): {Output}", output);
logger.LogInformation("docker builds (stdout): {Output}", output);
},
OnErrorData = error =>
{
logger.LogInformation("docker build (stderr): {Error}", error);
logger.LogInformation("docker builds (stderr): {Error}", error);
},
ThrowOnNonZeroReturnCode = false,
InheritEnv = true
Expand All @@ -69,11 +76,11 @@ private async Task<int> RunDockerBuildAsync(string contextPath, string dockerfil

if (processResult.ExitCode != 0)
{
logger.LogError("Docker build for {ImageName} failed with exit code {ExitCode}.", imageName, processResult.ExitCode);
logger.LogError("Docker builds for {ImageName} failed with exit code {ExitCode}.", imageName, processResult.ExitCode);
return processResult.ExitCode;
}

logger.LogInformation("Docker build for {ImageName} succeeded.", imageName);
logger.LogInformation("Docker builds for {ImageName} succeeded.", imageName);
return processResult.ExitCode;
}
}
Expand Down
22 changes: 11 additions & 11 deletions src/Aspire.Hosting/Publishing/PodmanContainerRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,33 @@ private async Task<int> RunPodmanBuildAsync(string contextPath, string dockerfil
{
var format = options.ImageFormat.Value switch
{
ContainerImageFormat.OciTar => "oci",
ContainerImageFormat.DockerTar => "docker-archive",
ContainerImageFormat.Oci => "oci",
ContainerImageFormat.Docker => "docker",
_ => throw new ArgumentOutOfRangeException(nameof(options), options.ImageFormat, "Invalid container image format")
};
arguments += $" --format \"{format}\"";
}

arguments += $" \"{contextPath}\"";

// Note: Podman doesn't support --output like Docker buildx, so OutputPath is not directly supported
// For Podman, users would need to save/export the image separately after building
// Add output support if specified
if (!string.IsNullOrEmpty(options?.OutputPath))
{
logger.LogWarning("OutputPath is not directly supported by Podman build. The image will be built and tagged, but not exported to the specified path.");
// Extract resource name from imageName for the file name
var resourceName = imageName.Split('/').Last().Split(':').First();
arguments += $" --output \"{options.OutputPath}/{resourceName}.tar\"";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.Combine

}

arguments += $" \"{contextPath}\"";

var spec = new ProcessSpec("podman")
{
Arguments = arguments,
OnOutputData = output =>
{
logger.LogInformation("podman build (stdout): {Output}", output);
logger.LogInformation("podman builds (stdout): {Output}", output);
},
OnErrorData = error =>
{
logger.LogInformation("podman build (stderr): {Error}", error);
logger.LogInformation("podman builds (stderr): {Error}", error);
},
ThrowOnNonZeroReturnCode = false,
InheritEnv = true
Expand All @@ -69,11 +69,11 @@ private async Task<int> RunPodmanBuildAsync(string contextPath, string dockerfil

if (processResult.ExitCode != 0)
{
logger.LogError("Podman build for {ImageName} failed with exit code {ExitCode}.", imageName, processResult.ExitCode);
logger.LogError("Podman builds for {ImageName} failed with exit code {ExitCode}.", imageName, processResult.ExitCode);
return processResult.ExitCode;
}

logger.LogInformation("Podman build for {ImageName} succeeded.", imageName);
logger.LogInformation("Podman builds for {ImageName} succeeded.", imageName);
return processResult.ExitCode;
}
}
Expand Down
15 changes: 4 additions & 11 deletions src/Aspire.Hosting/Publishing/ResourceContainerImageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,9 @@ public enum ContainerImageFormat
Docker,

/// <summary>
/// OCI tar format.
/// OCI format.
/// </summary>
OciTar,

/// <summary>
/// Docker tar format.
/// </summary>
DockerTar
Oci
}

/// <summary>
Expand Down Expand Up @@ -247,8 +242,7 @@ private async Task BuildProjectContainerImageAsync(IResource resource, IPublishi
var format = options.ImageFormat.Value switch
{
ContainerImageFormat.Docker => "Docker",
ContainerImageFormat.OciTar => "OciTar",
ContainerImageFormat.DockerTar => "DockerTar",
ContainerImageFormat.Oci => "OCI",
_ => throw new ArgumentOutOfRangeException(nameof(options), options.ImageFormat, "Invalid container image format")
};
arguments += $" /p:ContainerImageFormat=\"{format}\"";
Expand Down Expand Up @@ -328,8 +322,7 @@ private async Task BuildProjectContainerImageAsync(IResource resource, IPublishi
var format = options.ImageFormat.Value switch
{
ContainerImageFormat.Docker => "Docker",
ContainerImageFormat.OciTar => "OciTar",
ContainerImageFormat.DockerTar => "DockerTar",
ContainerImageFormat.Oci => "OCI",
_ => throw new ArgumentOutOfRangeException(nameof(options), options.ImageFormat, "Invalid container image format")
};
arguments += $" /p:ContainerImageFormat=\"{format}\"";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public async Task CanBuildImageFromProjectResourceWithOptions()

var options = new ContainerBuildOptions
{
ImageFormat = ContainerImageFormat.OciTar,
ImageFormat = ContainerImageFormat.Oci,
OutputPath = "/tmp/test-output",
TargetPlatform = ContainerTargetPlatform.LinuxAmd64
};
Expand All @@ -71,28 +71,26 @@ public void ContainerBuildOptions_CanSetAllProperties()
{
var options = new ContainerBuildOptions
{
ImageFormat = ContainerImageFormat.DockerTar,
ImageFormat = ContainerImageFormat.Oci,
OutputPath = "/custom/path",
TargetPlatform = ContainerTargetPlatform.LinuxArm64
};

Assert.Equal(ContainerImageFormat.DockerTar, options.ImageFormat);
Assert.Equal(ContainerImageFormat.Oci, options.ImageFormat);
Assert.Equal("/custom/path", options.OutputPath);
Assert.Equal(ContainerTargetPlatform.LinuxArm64, options.TargetPlatform);
}

[Theory]
[InlineData(ContainerImageFormat.Docker, "Docker")]
[InlineData(ContainerImageFormat.OciTar, "OciTar")]
[InlineData(ContainerImageFormat.DockerTar, "DockerTar")]
[InlineData(ContainerImageFormat.Oci, "OCI")]
public void ContainerImageFormat_EnumValues_AreCorrect(ContainerImageFormat format, string expectedValue)
{
// This test ensures that the enum values match what's expected for MSBuild properties
var formatString = format switch
{
ContainerImageFormat.Docker => "Docker",
ContainerImageFormat.OciTar => "OciTar",
ContainerImageFormat.DockerTar => "DockerTar",
ContainerImageFormat.Oci => "OCI",
_ => throw new ArgumentOutOfRangeException(nameof(format))
};

Expand Down