-
Notifications
You must be signed in to change notification settings - Fork 178
Add CommunityToolkit.Aspire.Hosting.Kind integration #1270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
andrey-noskov
wants to merge
32
commits into
CommunityToolkit:main
Choose a base branch
from
andrey-noskov:submission/kind-hosting-history
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+5,360
−0
Open
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
f0be4cb
feat: add Kind (Kubernetes in Docker) hosting integration
andrey-noskov 65d6999
Extract KindContainerImageTags as public constants class
Copilot 916c98f
Remove trivial constant-value tests for KindContainerImageTags
Copilot 580a91b
ci: add Hosting.Kind.Tests to test matrix
andrey-noskov 0acfab7
Replace tautological tests with KindConfigGenerator YAML wiring test
Copilot eed932a
feat: add cluster lifecycle management with WithClusterLifetime
andrey-noskov 0da2b16
feat: add pre-flight Kind CLI availability check
andrey-noskov 96b56c6
feat: make KindConfigGenerator async (#25) (#51)
andrey-noskov d8868e4
test: expand unit test coverage to 28 tests (#22) (#52)
andrey-noskov ae89f58
docs: add README for Kind hosting integration (#23) (#53)
andrey-noskov c82a785
refactor: replace StringBuilder with YamlDotNet in KindConfigGenerato…
andrey-noskov 832a16e
feat: add Helm chart support for Kind clusters (#37) (#54)
andrey-noskov a79e8f7
fix: make ProcessHelper tests cross-platform (Linux/Windows)
c6081ec
feat: replace Helm --wait with Kubernetes health check (#55)
andrey-noskov 8771457
Replace ProcessHelper static with IProcessRunner DI (#75)
MattKotsenas 5aa9770
feat: expose Kind config as extensible builder pattern
andrey-noskov 2f7d9db
Add Kind as a Kubernetes compute environment for aspire publish / asp…
MattKotsenas f8d24cb
feat: replace regex kubeconfig rewriting with YAML parser and improve…
andrey-noskov ef4b216
chore: align Kind submission with toolkit conventions
andrey-noskov ae12386
Merge branch 'main' into submission/kind-hosting-history
aaronpowell 988ceab
Bump Kind examples Aspire SDK
8d22333
Support Podman for Kind hosting
b1744bf
Use Aspire container runtime resolver for Kind
8792fee
Fix Kind runtime resolver test build
82329d2
Add comments for Kind Podman process behavior
8cccfa8
Merge pull request #1 from tamirdresher/tamir/sdk-bump-kind-examples
andrey-noskov 7e681f5
Address Kind PR review comments
aa58c20
Merge pull request #2 from tamirdresher/tamir/podman-kind-hosting-only
andrey-noskov 3cdc3a2
Apply suggestions from code review
aaronpowell fdd5fe4
Merge branch 'main' into submission/kind-hosting-history
aaronpowell f26b10f
Updating to 13.4.3 and adding polyglot exports
aaronpowell bde5923
Removing unneeded slnx
aaronpowell File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "version": 1, | ||
| "isRoot": true, | ||
| "tools": { | ||
| "verify.tool": { | ||
| "version": "0.7.0", | ||
| "commands": [ | ||
| "dotnet-verify" | ||
| ], | ||
| "rollForward": false | ||
| } | ||
| } | ||
| } |
14 changes: 14 additions & 0 deletions
14
...tyToolkit.Aspire.Hosting.Kind.AppHost/CommunityToolkit.Aspire.Hosting.Kind.AppHost.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <Project Sdk="Aspire.AppHost.Sdk/13.4.3"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\..\src\CommunityToolkit.Aspire.Hosting.Kind\CommunityToolkit.Aspire.Hosting.Kind.csproj" IsAspireProjectResource="false" /> | ||
| </ItemGroup> | ||
|
|
||
|
aaronpowell marked this conversation as resolved.
|
||
| <ItemGroup> | ||
| <PackageReference Include="MessagePack" /> | ||
| </ItemGroup> | ||
| </Project> | ||
30 changes: 30 additions & 0 deletions
30
examples/kind/CommunityToolkit.Aspire.Hosting.Kind.AppHost/Program.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| var builder = DistributedApplication.CreateBuilder(args); | ||
|
|
||
| // Kind cluster as a managed dependency (F5 mode). | ||
| // The cluster appears in the Aspire dashboard, your apps get KUBECONFIG injected. | ||
| var cluster = builder.AddKindCluster("kind-cluster") | ||
| .WithKubernetesVersion("v1.32.2"); | ||
|
|
||
| // Run Headlamp (a lightweight Kubernetes web UI) as an Aspire-managed container | ||
| // connected to the Kind cluster. | ||
| var dashboard = builder.AddContainer("headlamp", "ghcr.io/headlamp-k8s/headlamp:latest") | ||
| .WithHttpEndpoint(targetPort: 4466) | ||
| .WithReference(cluster); | ||
|
|
||
| // Deploy a Helm chart to the Kind cluster, exposed via NodePort so containers | ||
| // on the Kind container network can reach it. | ||
| var redis = cluster.AddHelmChart("redis", "oci://registry-1.docker.io/bitnamicharts/redis") | ||
| .WithHelmValue("replica.replicaCount", "0") | ||
| .WithHelmValue("master.service.type", "NodePort") | ||
| .WithHelmValue("master.service.nodePorts.redis", "30379") | ||
| .WithNamespace("cache"); | ||
|
|
||
| // Test Aspire-container → Kind-workload connectivity by pinging Redis | ||
| // through the Kind container network on the NodePort. | ||
| builder.AddContainer("redis-ping", "nicolaka/netshoot") | ||
| .WithKindNetwork() | ||
| .WaitFor(cluster) | ||
| .WithEntrypoint("sh") | ||
| .WithArgs("-c", "while true; do nc -zv kind-cluster-control-plane 30379; sleep 5; done"); | ||
|
|
||
| builder.Build().Run(); |
30 changes: 30 additions & 0 deletions
30
examples/kind/CommunityToolkit.Aspire.Hosting.Kind.AppHost/Properties/launchSettings.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| { | ||
| "$schema": "https://json.schemastore.org/launchsettings.json", | ||
| "profiles": { | ||
| "https": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "https://localhost:17220;http://localhost:15180", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development", | ||
| "DOTNET_ENVIRONMENT": "Development", | ||
| "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21176", | ||
| "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22301" | ||
| } | ||
| }, | ||
| "http": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "http://localhost:15180", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development", | ||
| "DOTNET_ENVIRONMENT": "Development", | ||
| "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19125", | ||
| "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20372", | ||
| "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" | ||
| } | ||
| } | ||
| } | ||
| } |
14 changes: 14 additions & 0 deletions
14
....Hosting.Kind.Publish.AppHost/CommunityToolkit.Aspire.Hosting.Kind.Publish.AppHost.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <Project Sdk="Aspire.AppHost.Sdk/13.4.3"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\..\src\CommunityToolkit.Aspire.Hosting.Kind\CommunityToolkit.Aspire.Hosting.Kind.csproj" IsAspireProjectResource="false" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="MessagePack" /> | ||
| </ItemGroup> | ||
| </Project> |
17 changes: 17 additions & 0 deletions
17
examples/kind/CommunityToolkit.Aspire.Hosting.Kind.Publish.AppHost/Program.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #pragma warning disable ASPIREPIPELINES001 | ||
|
|
||
| var builder = DistributedApplication.CreateBuilder(args); | ||
|
|
||
| // Kind as a compute environment (aspire publish / aspire deploy). | ||
| // Generates Helm charts and deploys to a local Kind cluster. | ||
| // | ||
| // aspire publish --output-path ./charts # generate Helm chart | ||
| // aspire deploy # deploy directly to Kind | ||
| builder.AddKubernetesEnvironment("kind-deploy") | ||
| .WithKind() | ||
| .WithKubernetesVersion("v1.32.2") | ||
| .WithWorkerNodes(1); | ||
|
|
||
| builder.AddContainer("redis", "redis", "7"); | ||
|
|
||
| builder.Build().Run(); |
30 changes: 30 additions & 0 deletions
30
.../kind/CommunityToolkit.Aspire.Hosting.Kind.Publish.AppHost/Properties/launchSettings.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| { | ||
| "$schema": "https://json.schemastore.org/launchsettings.json", | ||
| "profiles": { | ||
| "https": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "https://localhost:17221;http://localhost:15181", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development", | ||
| "DOTNET_ENVIRONMENT": "Development", | ||
| "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21177", | ||
| "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22302" | ||
| } | ||
| }, | ||
| "http": { | ||
| "commandName": "Project", | ||
| "dotnetRunMessages": true, | ||
| "launchBrowser": true, | ||
| "applicationUrl": "http://localhost:15181", | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development", | ||
| "DOTNET_ENVIRONMENT": "Development", | ||
| "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19126", | ||
| "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20373", | ||
| "ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true" | ||
| } | ||
| } | ||
| } | ||
| } |
21 changes: 21 additions & 0 deletions
21
src/CommunityToolkit.Aspire.Hosting.Kind/ClusterLifetime.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace Aspire.Hosting; | ||
|
|
||
| /// <summary> | ||
| /// Specifies the lifetime behavior of a Kind cluster relative to the AppHost session. | ||
| /// </summary> | ||
| public enum ClusterLifetime | ||
| { | ||
| /// <summary> | ||
| /// The cluster is deleted when the AppHost shuts down. | ||
| /// This is the default behavior. | ||
| /// </summary> | ||
| Session, | ||
|
|
||
| /// <summary> | ||
| /// The cluster survives AppHost restarts and is reused on the next startup. | ||
| /// </summary> | ||
| Persistent | ||
| } |
17 changes: 17 additions & 0 deletions
17
src/CommunityToolkit.Aspire.Hosting.Kind/ClusterLifetimeAnnotation.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using Aspire.Hosting.ApplicationModel; | ||
|
|
||
| namespace Aspire.Hosting; | ||
|
|
||
| /// <summary> | ||
| /// Annotation that stores the <see cref="ClusterLifetime"/> for a Kind cluster resource. | ||
| /// </summary> | ||
| internal sealed class ClusterLifetimeAnnotation : IResourceAnnotation | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the cluster lifetime. | ||
| /// </summary> | ||
| public required ClusterLifetime Lifetime { get; set; } | ||
| } |
22 changes: 22 additions & 0 deletions
22
src/CommunityToolkit.Aspire.Hosting.Kind/CommunityToolkit.Aspire.Hosting.Kind.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <Description>An Aspire hosting integration for Kind that manages local Kind clusters for development with Docker or Podman.</Description> | ||
| <AdditionalPackageTags>hosting kind kubernetes k8s docker podman</AdditionalPackageTags> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Aspire.Hosting" /> | ||
| <PackageReference Include="Aspire.Hosting.Kubernetes" /> | ||
| <PackageReference Include="KubernetesClient" /> | ||
| <PackageReference Include="YamlDotNet" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <InternalsVisibleTo Include="CommunityToolkit.Aspire.Hosting.Kind.Tests" /> | ||
| </ItemGroup> | ||
|
|
||
|
aaronpowell marked this conversation as resolved.
|
||
| <ItemGroup> | ||
| <PackageReference Include="MessagePack" /> | ||
| </ItemGroup> | ||
| </Project> | ||
102 changes: 102 additions & 0 deletions
102
src/CommunityToolkit.Aspire.Hosting.Kind/DefaultProcessRunner.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System.Diagnostics; | ||
| using System.Text; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
||
| namespace CommunityToolkit.Aspire.Hosting.Kind; | ||
|
|
||
| /// <summary> | ||
| /// Default <see cref="IProcessRunner"/> implementation that runs real | ||
| /// external processes and captures stdout/stderr. | ||
| /// </summary> | ||
| internal sealed class DefaultProcessRunner : IProcessRunner | ||
| { | ||
| /// <inheritdoc /> | ||
| public async Task<ProcessResult> RunAsync( | ||
| ILogger logger, | ||
| string fileName, | ||
| IReadOnlyList<string> arguments, | ||
| string? workingDirectory = null, | ||
| IReadOnlyDictionary<string, string>? environmentVariables = null, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| logger.LogDebug("Executing: {FileName} {Arguments}", fileName, string.Join(' ', arguments)); | ||
|
|
||
| var psi = new ProcessStartInfo | ||
| { | ||
| FileName = fileName, | ||
| RedirectStandardOutput = true, | ||
| RedirectStandardError = true, | ||
| UseShellExecute = false, | ||
| CreateNoWindow = true | ||
| }; | ||
|
|
||
| foreach (string argument in arguments) | ||
| { | ||
| psi.ArgumentList.Add(argument); | ||
| } | ||
|
|
||
| if (workingDirectory is not null) | ||
| { | ||
| psi.WorkingDirectory = workingDirectory; | ||
| } | ||
|
|
||
| if (environmentVariables is not null) | ||
| { | ||
| foreach (var (key, value) in environmentVariables) | ||
| { | ||
| psi.Environment[key] = value; | ||
| } | ||
| } | ||
|
|
||
| using var process = new Process { StartInfo = psi }; | ||
| var stdout = new StringBuilder(); | ||
| var stderr = new StringBuilder(); | ||
|
|
||
| process.OutputDataReceived += (_, e) => | ||
| { | ||
| if (e.Data is not null) | ||
| { | ||
| stdout.AppendLine(e.Data); | ||
| logger.LogDebug("[{FileName}] {Data}", fileName, e.Data); | ||
| } | ||
| }; | ||
|
|
||
| process.ErrorDataReceived += (_, e) => | ||
| { | ||
| if (e.Data is not null) | ||
| { | ||
| stderr.AppendLine(e.Data); | ||
| logger.LogDebug("[{FileName}] stderr: {Data}", fileName, e.Data); | ||
| } | ||
| }; | ||
|
|
||
| process.Start(); | ||
| process.BeginOutputReadLine(); | ||
| process.BeginErrorReadLine(); | ||
|
|
||
| try | ||
| { | ||
| // WaitForExitAsync observes process termination; WaitForExit() then lets async stdout/stderr event handlers finish draining redirected output. | ||
| await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false); | ||
| process.WaitForExit(); | ||
| } | ||
| catch | ||
| { | ||
| try | ||
| { | ||
| process.Kill(entireProcessTree: true); | ||
| } | ||
| catch (InvalidOperationException) | ||
| { | ||
| // Process already exited. | ||
| } | ||
|
|
||
| throw; | ||
| } | ||
|
|
||
| return new ProcessResult(process.ExitCode, stdout.ToString().TrimEnd(), stderr.ToString().TrimEnd()); | ||
| } | ||
|
aaronpowell marked this conversation as resolved.
|
||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocker — solution files inconsistent. The main solution only adds
examples/kind/CommunityToolkit.Aspire.Hosting.Kind.AppHost, but the focusedCommunityToolkit.Aspire.Hosting.Kind.slnxadds both...AppHostand...Publish.AppHost. Please also addexamples/kind/CommunityToolkit.Aspire.Hosting.Kind.Publish.AppHost/CommunityToolkit.Aspire.Hosting.Kind.Publish.AppHost.csprojhere so the publish/deploy example builds as part of the main solution and gets covered by repo-wide build/format checks.