Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
36 changes: 21 additions & 15 deletions internal/cli/node/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,6 @@ func runAdd(ctx context.Context, nodeName, controlPlane, nodeImage, role string,
return fmt.Errorf("ensuring cluster image: %w", err)
}

// Ensure images volume exists for this node image version
logger.Infof("Step 0: Ensuring cluster images volume...")
clusterMgr := cluster.New(cluster.Config{
Name: clusterName,
ControlPlane: controlPlane,
HostNetworkPopulator: hostNetworkPopulator,
Logger: logger,
})

clusterImagesVolume, err := clusterMgr.EnsureImagesVolume(ctx, nodeImage)
if err != nil {
return fmt.Errorf("ensuring images volume: %w", err)
}
logger.Info("")

// Step 1: Create the new node
logger.Infof("Step 1: Creating %s node...", role)
logger.Infof("Node image: %s", nodeImage)
Expand All @@ -140,6 +125,27 @@ func runAdd(ctx context.Context, nodeName, controlPlane, nodeImage, role string,
}
}

// Auto-detect the control-plane node name from container labels
discovered, err := findControlPlaneNode(ctx, podmanClient, clusterName, "")
if err == nil {
controlPlane = discovered
}
Comment thread
alicefr marked this conversation as resolved.

// Ensure images volume exists for this node image version
logger.Infof("Step 0: Ensuring cluster images volume...")
clusterMgr := cluster.New(cluster.Config{
Name: clusterName,
ControlPlane: controlPlane,
HostNetworkPopulator: hostNetworkPopulator,
Logger: logger,
})

clusterImagesVolume, err := clusterMgr.EnsureImagesVolume(ctx, nodeImage)
if err != nil {
return fmt.Errorf("ensuring images volume: %w", err)
}
logger.Info("")

// Discover DNS container IP for cloud-init config
dnsMgr, err := dns.NewManager(clusterName)
if err != nil {
Expand Down
8 changes: 8 additions & 0 deletions test/integration/helpers/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ func CreateCluster(name string) {
Expect(session.ExitCode()).To(Equal(0), "Failed to create cluster: %s", string(session.Err.Contents()))
}

// CreateClusterWithNodeName creates a cluster with a custom control-plane node name
func CreateClusterWithNodeName(name, nodeName string) {
GinkgoWriter.Printf("Creating cluster: %s with node name: %s (with auto-assigned API port)\n", name, nodeName)
cmd := BinkCmd("cluster", "start", "--cluster-name", name, "--node-name", nodeName, "--api-port", "0", "--memory", "1900", "--max-memory", "4096")
session := RunCommand(cmd, 10*time.Minute)
Expect(session.ExitCode()).To(Equal(0), "Failed to create cluster: %s", string(session.Err.Contents()))
}

// AddNode adds a node to the cluster
func AddNode(clusterName, nodeName string, extraArgs ...string) {
GinkgoWriter.Printf("Adding node %s to cluster %s\n", nodeName, clusterName)
Expand Down
25 changes: 25 additions & 0 deletions test/integration/multinode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,31 @@ var _ = Describe("Multi-Node Clusters", func() {
}
})

It("should add worker node when cluster uses custom node name", func() {
const customNodeName = "cp-custom"

By("Creating a cluster with a custom control-plane node name")
helpers.CreateClusterWithNodeName(clusterName, customNodeName)

By("Verifying control-plane container has the custom name")
containerName := helpers.NodeContainerName(clusterName, customNodeName)
container := helpers.GetContainer(containerName)
Expect(container).ToNot(BeNil(), "Container %s should exist", containerName)
Expect(container.State).To(Equal("running"))

By("Adding a worker node without specifying --control-plane")
helpers.AddNode(clusterName, node2, "--role", "worker")

By("Exposing API and creating Kubernetes client")
kubeClient, kubeconfigPath := helpers.SetupKubeClient(clusterName)
defer helpers.CleanupKubeconfig(kubeconfigPath)

By("Verifying both nodes are Ready in Kubernetes")
helpers.WaitForNodeReady(kubeClient, customNodeName, 5*time.Minute)
helpers.WaitForNodeReady(kubeClient, node2, 5*time.Minute)
Expect(helpers.GetNodeCount(kubeClient)).To(Equal(2))
})

It("should add control-plane nodes for HA configuration", Serial, func() {
By("Creating a single-node cluster")
helpers.CreateCluster(clusterName)
Expand Down
Loading