From 2d9c44746767042d56d5750d97f10bb915d6b892 Mon Sep 17 00:00:00 2001 From: Chris Farhood Date: Tue, 5 May 2026 15:35:48 +0000 Subject: [PATCH] fix(e2e): keep ServiceAccount across deploy cycles to avoid token fetch race The deploy script was deleting serviceaccount/headlamp-e2e before recreating it via kubectl apply. This causes a race: the new deployment pod tries to mount its service account token before the token is available, resulting in: Warning FailedMount: failed to fetch token: serviceaccounts "headlamp-e2e" not found Fix by removing the kubectl delete serviceaccount line and replacing it with an idempotent create (--dry-run=client | kubectl apply). This ensures the ServiceAccount persists across deploy cycles and tokens are available when pods start. Co-Authored-By: Paperclip --- scripts/deploy-e2e-headlamp.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/deploy-e2e-headlamp.sh b/scripts/deploy-e2e-headlamp.sh index 783c758..7948bb3 100755 --- a/scripts/deploy-e2e-headlamp.sh +++ b/scripts/deploy-e2e-headlamp.sh @@ -60,15 +60,20 @@ kubectl create configmap headlamp-intel-gpu-plugin \ # --- Tear down any existing E2E deployment for a clean start --- # Deleting the Deployment forces a fresh pod (new ReplicaSet) regardless of -# whether the pod spec changed. The ServiceAccount is also deleted for a clean -# token state. The Service is NOT deleted — leaving it in place avoids an +# whether the pod spec changed. We do NOT delete the ServiceAccount — keeping +# it avoids a token-race condition where kubelet tries to mount a volume using a +# token that has been deleted but the new one isn't ready yet. +# The Service is NOT deleted — leaving it in place avoids an # Endpoints UID race (FailedToUpdateEndpoint) that causes DNS resolution # failures. kubectl apply below upserts the Service in-place, and the new # pod's IP is added to the existing Endpoints automatically. echo "" echo "Removing any existing E2E deployment (clean-start)..." kubectl delete deployment "${E2E_RELEASE}" -n "$E2E_NAMESPACE" --ignore-not-found --wait -kubectl delete serviceaccount "${E2E_RELEASE}" -n "$E2E_NAMESPACE" --ignore-not-found --wait +# ServiceAccount is kept — create it idempotently so the first run works too +kubectl create serviceaccount "${E2E_RELEASE}" \ + -n "$E2E_NAMESPACE" \ + --dry-run=client -o yaml | kubectl apply -f - # --- Deploy Headlamp via kubectl apply --- echo "" -- 2.52.0