Skip to content

Comments

Container v1 support#309

Merged
prom3theu5 merged 7 commits intoprom3theu5:mainfrom
John-Leitch:container-v1-support
Mar 7, 2025
Merged

Container v1 support#309
prom3theu5 merged 7 commits intoprom3theu5:mainfrom
John-Leitch:container-v1-support

Conversation

@John-Leitch
Copy link
Contributor

@John-Leitch John-Leitch commented Mar 6, 2025

As discussed in #264 and #300, Aspire now generates container.v1 resources in cases that were previously dockerfile.v0. This PR adds fairly complete support for container.v1, reusing existing logic container.v0 and dockerfile.v0 depending on whether an image or build is specified. Only two container.v1 properties are unsupported: deployment and build.secrets, with the former appearing to be Azure specific and potentially irrelevant.

@John-Leitch John-Leitch marked this pull request as ready for review March 6, 2025 05:39
@qodo-code-review
Copy link

Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis ✅

264 - PR Code Verified

Compliant requirements:

• Support for container.v1 resources generated by Aspire when using WithDockerfile
• Handle the new build entry in docker-compose

Requires further human verification:

• Ensure compatibility with Kubernetes manifests

300 - Fully compliant

Compliant requirements:

• Fix crash when Aspir8 tries to read manifest.json it just generated with container.v1 resources
• Handle the build section in the manifest.json properly
• Support containers modified with a Dockerfile in Aspire

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Error Handling

The GetImageFromContainerResource method might throw an exception if a ContainerV1Resource has neither Image nor Build properties set. Consider adding validation or more graceful error handling.

private string GetImageFromContainerResource(KeyValuePair<string, Resource> resource)
{
    switch (resource.Value)
    {
        case ContainerResource containerV0:
            return containerV0.Image;

        case ContainerV1Resource containerV1:
            if (containerV1.Image != null)
            {
                return containerV1.Image;
            }
            else if (containerV1.Build != null)
            {
                return GetCachedImages(resource.Key).First();
            }
            else
            {
                throw new InvalidOperationException($"{AspireComponentLiterals.ContainerV1} must have image or build property.");
            }

        default:
            throw new InvalidOperationException($"Unexpected resource type {resource.Value?.GetType().Name}");
    }
}
Null Reference Risk

The CreateComposeEntry method assumes container is not null when casting to specific types. Consider adding null checks to prevent potential runtime exceptions.

public override ComposeService CreateComposeEntry(CreateComposeEntryOptions options)
{
    var response = new ComposeService();

    var container = options.Resource.Value as TContainerResource;

    var service = Builder.MakeService(options.Resource.Key);

    if (container is ContainerResource containerV0)
    {
        service.WithImage(containerV0.Image.ToLowerInvariant());
    }
    else if (container is ContainerV1Resource containerV1)
    {
        if (containerV1.Image != null)
        {
            service.WithImage(containerV1.Image.ToLowerInvariant());
        }
        else if (containerV1.Build != null && options.ComposeBuilds == true)
        {
            service.WithBuild(builder =>
                builder
                    .WithContext(_fileSystem.GetFullPath(containerV1.Build.Context))
                    .WithDockerfile(_fileSystem.GetFullPath(containerV1.Build.Dockerfile))
                    .Build());
        }
    }
Resource Selection Logic

The SelectComposeItemsToIncludeAsComposeBuilds method now filters resources differently, which might affect which resources are included in the build process. Verify this change doesn't exclude valid resources.

var dockerFileEntries = CurrentState.LoadedAspireManifestResources
    .Where(x => x.Value is DockerfileResource || (x.Value is ContainerV1Resource c && c.Build != null))
    .Select(x => x.Key)
    .ToList();

@qodo-code-review
Copy link

Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

PR Code Suggestions ✨

No code suggestions found for the PR.

@prom3theu5
Copy link
Owner

Awesome - thanks John, looks good and will close off the issues that have started trickling in related to the v1 resource
I'd completely missed that that had been implemented

@prom3theu5 prom3theu5 merged commit acc1689 into prom3theu5:main Mar 7, 2025
2 checks passed
prom3theu5 added a commit that referenced this pull request Mar 7, 2025
prom3theu5 pushed a commit that referenced this pull request Mar 7, 2025
* feat: Started implementing container.v1 support.

* feat: Container.v1 build support.

* refactor: Moved classes to separate files, cleaned up usings.

* feat: Container.v1 compose support.

* docs: Commented IImageProcessor interface.

* refactor: Cleaned up usings.

* refactor: Cleaned up usings.
prom3theu5 added a commit that referenced this pull request Mar 7, 2025
* feat: Improve warnings and errors related to missing/unsupported resources.

* Container v1 support (#309)

* feat: Started implementing container.v1 support.

* feat: Container.v1 build support.

* refactor: Moved classes to separate files, cleaned up usings.

* feat: Container.v1 compose support.

* docs: Commented IImageProcessor interface.

* refactor: Cleaned up usings.

* refactor: Cleaned up usings.

---------

Co-authored-by: David Sekula <dave.sekula@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants