From 4bd68bba72290e306c19246e0fdda5bb99da62ec Mon Sep 17 00:00:00 2001 From: Luca Consalvi Date: Thu, 16 Jul 2026 09:50:46 +0200 Subject: [PATCH 1/5] OCPEDGE-2118: Record Kubernetes events for etcd transition lifecycle Add event recording to the TNF setup runner and etcd transition code so the full CEO-to-pacemaker handoff is observable via `kubectl get events -n openshift-etcd`. Nine events are emitted across the transition lifecycle: - runner.go: auth, cluster, fencing, etcd resource, constraints - etcd.go: transition started, waiting, static pod removed, completed Events use the direct K8s API (not library-go Recorder) since the setup runner is a short-lived Job. Failures are logged but never block the transition. Co-Authored-By: Claude Opus 4.6 --- hack/test-transition-events.sh | 64 +++++++++++++++++++++++++++++ pkg/tnf/pkg/etcd/etcd.go | 26 ++++++++++-- pkg/tnf/pkg/etcd/etcd_test.go | 74 ++++++++++++++-------------------- pkg/tnf/pkg/tools/events.go | 49 ++++++++++++++++++++++ pkg/tnf/setup/runner.go | 17 +++++++- 5 files changed, 182 insertions(+), 48 deletions(-) create mode 100755 hack/test-transition-events.sh create mode 100644 pkg/tnf/pkg/tools/events.go diff --git a/hack/test-transition-events.sh b/hack/test-transition-events.sh new file mode 100755 index 0000000000..0c31b1cf0c --- /dev/null +++ b/hack/test-transition-events.sh @@ -0,0 +1,64 @@ +#!/usr/bin/bash +# Test script to validate transition event format on a live cluster. +# Creates mock events identical to what our code produces, then verifies +# they appear correctly in `oc get events`. +# +# Usage: ./hack/test-transition-events.sh +# Requires: oc/kubectl with cluster-admin access + +set -euo pipefail + +NAMESPACE="openshift-etcd" +TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") + +events=( + "EtcdTransitionAuthCompleted|PCS authentication completed on all nodes" + "EtcdTransitionClusterConfigured|Pacemaker cluster configured successfully" + "EtcdTransitionFencingConfigured|STONITH fencing configured successfully" + "EtcdTransitionEtcdResourceCreated|Pacemaker etcd resource agent (podman-etcd) configured" + "EtcdTransitionConstraintsConfigured|Pacemaker ordering and colocation constraints configured" + "EtcdTransitionStarted|Etcd transition from CEO-controlled to pacemaker-controlled has started" + "EtcdTransitionWaitingForRemoval|Waiting for CEO to remove static etcd container from all nodes" + "EtcdTransitionStaticContainerRemoved|Static etcd container removed from all nodes, revision is stable" + "EtcdTransitionCompleted|Etcd transition to pacemaker-controlled has completed" +) + +echo "Creating ${#events[@]} test transition events in ${NAMESPACE}..." + +for entry in "${events[@]}"; do + reason="${entry%%|*}" + message="${entry#*|}" + name="test-${reason,,}-$(date +%s%N)" + + oc apply -f - < Date: Thu, 16 Jul 2026 14:25:51 +0200 Subject: [PATCH 2/5] Lowercase event name to comply with RFC 1123 subdomain rules The event reason (e.g. EtcdTransitionAuthCompleted) was used directly in metadata.name which should be a valid lowercase DNS subdomain. Co-Authored-By: Claude Opus 4.6 --- pkg/tnf/pkg/tools/events.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/tnf/pkg/tools/events.go b/pkg/tnf/pkg/tools/events.go index c87c021a3c..ecbc57ff92 100644 --- a/pkg/tnf/pkg/tools/events.go +++ b/pkg/tnf/pkg/tools/events.go @@ -3,6 +3,7 @@ package tools import ( "context" "fmt" + "strings" "time" corev1 "k8s.io/api/core/v1" @@ -23,7 +24,7 @@ const ( func RecordSetupEvent(ctx context.Context, kubeClient kubernetes.Interface, reason, message string) { event := &corev1.Event{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("tnf-%s-%d", reason, time.Now().UnixNano()), + Name: fmt.Sprintf("tnf-%s-%d", strings.ToLower(reason), time.Now().UnixNano()), Namespace: setupEventNamespace, }, InvolvedObject: corev1.ObjectReference{ From d75bdc7a50d8307ca642bdec8fc3d03dd4279d1d Mon Sep 17 00:00:00 2001 From: Luca Consalvi Date: Thu, 16 Jul 2026 16:20:25 +0200 Subject: [PATCH 3/5] Fix gofmt alignment in const block Co-Authored-By: Claude Opus 4.6 --- pkg/tnf/pkg/tools/events.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/tnf/pkg/tools/events.go b/pkg/tnf/pkg/tools/events.go index ecbc57ff92..e3cf095321 100644 --- a/pkg/tnf/pkg/tools/events.go +++ b/pkg/tnf/pkg/tools/events.go @@ -13,8 +13,8 @@ import ( ) const ( - setupEventNamespace = "openshift-etcd" - setupJobName = "tnf-setup-job" + setupEventNamespace = "openshift-etcd" + setupJobName = "tnf-setup-job" setupSourceComponent = "tnf-setup-runner" ) From 76d363dae2d09ff5c46e241c8fb440c45b24f722 Mon Sep 17 00:00:00 2001 From: Luca Consalvi Date: Tue, 21 Jul 2026 15:43:40 +0200 Subject: [PATCH 4/5] Move test-transition-events.sh to pkg/tnf/hack/ TNF-specific manual validation script belongs under the TNF directory tree rather than the repo-wide hack/ directory. Co-Authored-By: Claude Opus 4.6 --- {hack => pkg/tnf/hack}/test-transition-events.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {hack => pkg/tnf/hack}/test-transition-events.sh (100%) diff --git a/hack/test-transition-events.sh b/pkg/tnf/hack/test-transition-events.sh similarity index 100% rename from hack/test-transition-events.sh rename to pkg/tnf/hack/test-transition-events.sh From d31a9b2d1e79ee2809d8ea20093653f7efd15472 Mon Sep 17 00:00:00 2001 From: Luca Consalvi Date: Tue, 21 Jul 2026 15:50:37 +0200 Subject: [PATCH 5/5] Label mock events for safe cleanup in test script Add tnf-test=true label to mock events so the cleanup command only targets test events, not real cluster diagnostic data. Co-Authored-By: Claude Opus 4.6 --- pkg/tnf/hack/test-transition-events.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/tnf/hack/test-transition-events.sh b/pkg/tnf/hack/test-transition-events.sh index 0c31b1cf0c..9e670c94bf 100755 --- a/pkg/tnf/hack/test-transition-events.sh +++ b/pkg/tnf/hack/test-transition-events.sh @@ -36,6 +36,8 @@ kind: Event metadata: name: ${name} namespace: ${NAMESPACE} + labels: + tnf-test: "true" involvedObject: kind: Job name: tnf-setup-job @@ -60,5 +62,5 @@ echo "" oc get events -n "${NAMESPACE}" --field-selector reason!=="" --sort-by='.lastTimestamp' | grep -i "EtcdTransition" || echo "No EtcdTransition events found!" echo "" -echo "Cleanup: oc delete events -n ${NAMESPACE} -l ''" +echo "Cleanup: oc delete events -n ${NAMESPACE} -l tnf-test=true" echo " (events auto-expire after ~1 hour)"