Skip to content

Hotfix/dockerhub local#50

Merged
ewassef merged 2 commits intomainfrom
hotfix/dockerhub-local
Jan 27, 2026
Merged

Hotfix/dockerhub local#50
ewassef merged 2 commits intomainfrom
hotfix/dockerhub-local

Conversation

@ewassef
Copy link
Contributor

@ewassef ewassef commented Jan 27, 2026

This pull request introduces improvements to the Kubernetes cluster creation process and enhances the robustness of the Flux deployment workflow. The main changes include updating the default Kubernetes version, ensuring proper configuration file handling for containerd, and adding a mechanism to wait for all Flux kustomizations to be ready before proceeding.

Cluster creation and configuration improvements:

  • The default Kubernetes API version used in the CreateClusterCommand has been updated from 1.29 to 1.32 to ensure clusters are created with a more recent version.
  • The hosts.toml file for containerd registry configuration is now written to a temporary file location, ensuring Docker can reliably access it regardless of the working directory. All references to this file in the cluster setup process have been updated to use the temporary path. [1] [2] [3]

Flux deployment reliability:

  • A new method, WaitForKustomizations, has been added to the FluxClient service. This method polls the Flux API to ensure all kustomizations are reconciled and ready before proceeding, improving the reliability of post-deployment configuration steps. The CreateClusterCommand now calls this method after bootstrapping Flux. [1] [2] [3]

Development tooling:

  • The .claude/settings.local.json file has been updated to allow additional Bash commands related to Docker, Kubernetes, and shell scripting, supporting more flexible local development and automation.

Bumps the default Kubernetes API version to 1.32 in CreateClusterCommand. Hosts.toml is now written to a temporary file to ensure accessibility for Docker, replacing the previous static path usage.
Introduces a WaitForKustomizations method to FluxClient and IFluxClient, and calls it in CreateClusterCommand after bootstrapping Flux. This ensures all Flux kustomizations are reconciled before proceeding with reverse proxy configuration, improving cluster setup reliability.
Copilot AI review requested due to automatic review settings January 27, 2026 13:55
@ewassef ewassef merged commit 7584d40 into main Jan 27, 2026
6 checks passed
@ewassef ewassef deleted the hotfix/dockerhub-local branch January 27, 2026 13:57
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Kubernetes cluster creation process by upgrading the default Kubernetes version from 1.29 to 1.32, relocating the containerd hosts.toml configuration to a temporary file for improved accessibility, and introducing a waiting mechanism to ensure Flux kustomizations are ready before proceeding with cluster configuration.

Changes:

  • Updated default Kubernetes API version from 1.29 to 1.32
  • Moved hosts.toml file generation from static ConfigMounts directory to a dynamically created temporary file
  • Added WaitForKustomizations method to FluxClient to poll and verify Flux kustomization reconciliation status before continuing

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
cli/src/Vdk/Commands/CreateClusterCommand.cs Updated default Kubernetes version to 1.32; changed hosts.toml to be written to temp file; added call to WaitForKustomizations after Flux bootstrap
cli/src/Vdk/Services/FluxClient.cs Added WaitForKustomizations method to poll Flux API and verify all kustomizations are ready; added System.Text.Json import
cli/src/Vdk/Services/IFluxClient.cs Added WaitForKustomizations method signature to interface
.claude/settings.local.json Added additional Bash command permissions for Docker, Kubernetes, and shell scripting operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +121 to +122
public bool WaitForKustomizations(string clusterName, int maxAttempts = 60, int delaySeconds = 5)
{
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This synchronous method uses Thread.Sleep which blocks the calling thread. Since it's called from InvokeAsync (an async method at line 209), this creates a blocking call in an async context. Consider making this method async and using Task.Delay instead of Thread.Sleep. This would improve responsiveness and follow async/await best practices. The pattern should be: public async Task<bool> WaitForKustomizations(...) with await Task.Delay(delaySeconds * 1000) instead of Thread.Sleep.

Copilot uses AI. Check for mistakes.
public interface IFluxClient
{
void Bootstrap(string clusterName, string path, string branch = FluxClient.DefaultBranch);
bool WaitForKustomizations(string clusterName, int maxAttempts = 60, int delaySeconds = 5);
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The interface should be updated to return Task<bool> instead of bool to properly support async operations. Since this method performs network I/O and waits (currently with Thread.Sleep), it should be async to avoid blocking the calling thread.

Copilot uses AI. Check for mistakes.
Comment on lines +151 to +161
var name = item.GetProperty("metadata").GetProperty("name").GetString();
bool isReady = false;

if (item.TryGetProperty("status", out var status) &&
status.TryGetProperty("conditions", out var conditions))
{
foreach (var condition in conditions.EnumerateArray())
{
if (condition.GetProperty("type").GetString() == "Ready")
{
var condStatus = condition.GetProperty("status").GetString();
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The GetString() calls on lines 151, 159, and 161 could potentially return null if the JSON property values are null. This could lead to NullReferenceException when these values are used. Consider using null-conditional operators or null-coalescing operators to handle potential null values, e.g., GetString() ?? "unknown" for name comparisons.

Copilot uses AI. Check for mistakes.
var workers = new Option<int>("--Workers") { DefaultValueFactory = _ => Defaults.WorkerNodes, Description = "The number of worker nodes in the cluster." };
workers.Aliases.Add("-w");
var kubeVersion = new Option<string>("--KubeVersion") { DefaultValueFactory = _ => "1.29", Description = "The kubernetes api version." };
var kubeVersion = new Option<string>("--KubeVersion") { DefaultValueFactory = _ => "1.32", Description = "The kubernetes api version." };
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The documentation still references Kubernetes version 1.29 as the default, but the code has been updated to use 1.32. The documentation files docs/usage/command-reference.md (line 39) and docs/usage/creating-clusters.md (line 31) should be updated to reflect the new default version of 1.32.

Copilot uses AI. Check for mistakes.
[host."http://host.docker.internal:5000"]
capabilities = ["pull", "resolve"]
""";
var hostsTomlPath = _fileSystem.Path.Combine(_fileSystem.Path.GetTempPath(), $"hosts-{Guid.NewGuid()}.toml");
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The temporary hosts.toml file created at this location is never cleaned up after the cluster is created. This will lead to accumulation of orphaned files in the temp directory over time. Consider using a try-finally block or ensuring the file is deleted after the Kind cluster creation completes, or use a deterministic naming scheme that allows reuse of the same file.

Suggested change
var hostsTomlPath = _fileSystem.Path.Combine(_fileSystem.Path.GetTempPath(), $"hosts-{Guid.NewGuid()}.toml");
var hostsTomlPath = _fileSystem.Path.Combine(_fileSystem.Path.GetTempPath(), "vdk-hosts-hub.dev-k8s.cloud.toml");

Copilot uses AI. Check for mistakes.
Comment on lines +157 to +177
foreach (var condition in conditions.EnumerateArray())
{
if (condition.GetProperty("type").GetString() == "Ready")
{
var condStatus = condition.GetProperty("status").GetString();
if (condStatus == "True")
{
isReady = true;
}
else if (attempt % 5 == 0)
{
var reason = condition.TryGetProperty("reason", out var r)
? r.GetString() : "Unknown";
var message = condition.TryGetProperty("message", out var m)
? m.GetString() : "";
_console.WriteLine(
$" Kustomization '{name}' not ready: {reason} - {message}");
}
break;
}
}
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
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.

1 participant