From 670314db6912351b555cf937a4c6dd60ff0295be Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Tue, 2 Jun 2026 10:03:34 +0000 Subject: [PATCH 1/2] fix: include pod clique pod index in pod name Pod names are generated using GenerateName, which appends a random suffix. Before this change, two pods for the same PodClique were named e.g. ubuntu-0-worker-2tnab and ubuntu-0-worker-5mfde, making it impossible to correlate the hostname seen in logs with a specific pod without querying custom columns. Include the per-pod index (LabelPodCliquePodIndex) directly in the GenerateName prefix so that names become ubuntu-0-worker-0-2tnab and ubuntu-0-worker-1-5mfde. This mirrors the existing convention used for PCS and PCSG replica indices and requires no label lookup to identify which pod is which. Closes #635 Signed-off-by: OpenClaw Agent --- .../podclique/components/pod/pod.go | 2 +- .../podclique/components/pod/pod_test.go | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/operator/internal/controller/podclique/components/pod/pod.go b/operator/internal/controller/podclique/components/pod/pod.go index 50c28635d..1d2b58791 100644 --- a/operator/internal/controller/podclique/components/pod/pod.go +++ b/operator/internal/controller/podclique/components/pod/pod.go @@ -150,7 +150,7 @@ func (r _resource) buildResource(pcs *grovecorev1alpha1.PodCliqueSet, pclq *grov labels := getLabels(pclq.ObjectMeta, pcsName, podGangName, pcsReplicaIndex, podIndex) pod.ObjectMeta = metav1.ObjectMeta{ - GenerateName: fmt.Sprintf("%s-", pclq.Name), + GenerateName: fmt.Sprintf("%s-%d-", pclq.Name, podIndex), Namespace: pclq.Namespace, Labels: labels, Annotations: pclq.Annotations, diff --git a/operator/internal/controller/podclique/components/pod/pod_test.go b/operator/internal/controller/podclique/components/pod/pod_test.go index 9da32fa8d..9e547f278 100644 --- a/operator/internal/controller/podclique/components/pod/pod_test.go +++ b/operator/internal/controller/podclique/components/pod/pod_test.go @@ -554,3 +554,51 @@ func filterOutEnvVar(envVars []string, exclude string) []string { } return result } + +func TestGetLabels_PodIndexLabel(t *testing.T) { + tests := []struct { + name string + pclqName string + podIndex int + expectedLabelVal string + }{ + {name: "pod index 0", pclqName: "workload1-0-pc-worker", podIndex: 0, expectedLabelVal: "0"}, + {name: "pod index 1", pclqName: "workload1-0-pc-worker", podIndex: 1, expectedLabelVal: "1"}, + {name: "pod index 5", pclqName: "workload1-0-pc-worker", podIndex: 5, expectedLabelVal: "5"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pclqObjectMeta := metav1.ObjectMeta{ + Name: tt.pclqName, + Namespace: "default", + Labels: map[string]string{ + common.LabelManagedByKey: common.LabelManagedByValue, + }, + } + labels := getLabels(pclqObjectMeta, "workload1", "gang-0", 0, tt.podIndex) + assert.Equal(t, tt.expectedLabelVal, labels[common.LabelPodCliquePodIndex], + "LabelPodCliquePodIndex should match podIndex") + }) + } +} + +// TestPodGenerateNameIncludesPodIndex verifies that each pod's GenerateName embeds the +// pod index so that the Kubernetes-generated suffix yields names like +// "--" (e.g. ubuntu-0-worker-0-2tnab). +func TestPodGenerateNameIncludesPodIndex(t *testing.T) { + tests := []struct { + pclqName string + podIndex int + expectedPrefix string + }{ + {pclqName: "ubuntu-0-worker", podIndex: 0, expectedPrefix: "ubuntu-0-worker-0-"}, + {pclqName: "ubuntu-0-worker", podIndex: 1, expectedPrefix: "ubuntu-0-worker-1-"}, + {pclqName: "workload1-2-pc-server", podIndex: 3, expectedPrefix: "workload1-2-pc-server-3-"}, + } + for _, tt := range tests { + t.Run(tt.expectedPrefix, func(t *testing.T) { + got := fmt.Sprintf("%s-%d-", tt.pclqName, tt.podIndex) + assert.Equal(t, tt.expectedPrefix, got) + }) + } +} From 2c883ccf9c549f254320ae630f92a6be90b1e1ed Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Tue, 2 Jun 2026 18:12:31 +0000 Subject: [PATCH 2/2] fix: update extractPCLQNameFromPodName for new pod name format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pod names now have the format -- after the previous commit added the pod clique index to GenerateName. The helper function extractPCLQNameFromPodName only stripped one trailing segment, returning - instead of , which broke the PodGang→PodClique reconcile mapping and left all pods permanently ScheduleGated. Strip two segments (random suffix then pod index) to correctly recover the PodClique FQN. Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: OpenClaw Agent --- operator/internal/controller/podclique/register.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/operator/internal/controller/podclique/register.go b/operator/internal/controller/podclique/register.go index 05073841e..66a31ffeb 100644 --- a/operator/internal/controller/podclique/register.go +++ b/operator/internal/controller/podclique/register.go @@ -327,10 +327,12 @@ func mapPodGangToPCLQs() handler.MapFunc { } } -// extractPCLQNameFromPodName extracts the PodClique name from a Pod name by removing the replica index suffix +// extractPCLQNameFromPodName extracts the PodClique name from a Pod name. +// Pod names have the format --, so two trailing +// segments must be stripped: first the Kubernetes-generated random suffix, then the pod index. func extractPCLQNameFromPodName(podName string) string { - endIndex := strings.LastIndex(podName, "-") - return podName[:endIndex] + withoutRandom := podName[:strings.LastIndex(podName, "-")] + return withoutRandom[:strings.LastIndex(withoutRandom, "-")] } // podGangPredicate filters PodGang events to trigger on initialization and spec updates