fix(e2e): use Job with base64 tarball instead of kubectl run stdin

The kubectl run --rm -i stdin pipe times out in the ARC runner
environment. Replace with a Kubernetes Job that receives the plugin
tarball as base64-encoded data in the container command. This avoids
the unreliable attach/stdin mechanism entirely.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-03-17 17:15:27 +00:00
parent 77d87db614
commit 2fb60c60f3
+59 -37
View File
@@ -43,53 +43,75 @@ HEADLAMP_NODE=$(kubectl get pods -n "$HEADLAMP_NAMESPACE" \
-l "app.kubernetes.io/name=headlamp" \ -l "app.kubernetes.io/name=headlamp" \
-o jsonpath='{.items[0].spec.nodeName}' 2>/dev/null || true) -o jsonpath='{.items[0].spec.nodeName}' 2>/dev/null || true)
if [ -z "$HEADLAMP_NODE" ]; then if [ -z "$HEADLAMP_NODE" ]; then
# Fallback: try by deployment label
HEADLAMP_NODE=$(kubectl get pods -n "$HEADLAMP_NAMESPACE" \ HEADLAMP_NODE=$(kubectl get pods -n "$HEADLAMP_NAMESPACE" \
-l "app.kubernetes.io/instance=headlamp" \ -l "app.kubernetes.io/instance=headlamp" \
-o jsonpath='{.items[0].spec.nodeName}' 2>/dev/null || true) -o jsonpath='{.items[0].spec.nodeName}' 2>/dev/null || true)
fi fi
if [ -n "$HEADLAMP_NODE" ]; then if [ -n "$HEADLAMP_NODE" ]; then
echo " Headlamp node: $HEADLAMP_NODE (scheduling deploy pod there)" echo " Headlamp node: $HEADLAMP_NODE (scheduling deploy job there)"
NODE_OVERRIDE="\"nodeName\": \"$HEADLAMP_NODE\"," NODE_SELECTOR="\"nodeName\": \"$HEADLAMP_NODE\","
else else
echo " WARNING: Could not determine Headlamp node, deploy pod may fail if PVC is ReadWriteOnce" echo " WARNING: Could not determine Headlamp node"
NODE_OVERRIDE="" NODE_SELECTOR=""
fi fi
# Clean up any previous deploy pod # Base64-encode the tarball so we can embed it in the pod command
kubectl delete pod plugin-deploy -n "$HEADLAMP_NAMESPACE" --ignore-not-found --wait=false 2>/dev/null || true # (avoids unreliable kubectl run --rm -i stdin piping)
TARBALL_B64=$(base64 -w0 "$TAR_FILE")
echo " Encoded size: $(echo -n "$TARBALL_B64" | wc -c) bytes"
# Clean up any previous deploy job/pod
kubectl delete job plugin-deploy -n "$HEADLAMP_NAMESPACE" --ignore-not-found 2>/dev/null || true
kubectl delete pod plugin-deploy -n "$HEADLAMP_NAMESPACE" --ignore-not-found 2>/dev/null || true
sleep 2 sleep 2
# Run a temporary pod that mounts the PVC and receives the tarball via stdin # Create a Job that decodes the tarball and extracts to the PVC
echo "Starting deploy pod..." echo "Starting deploy job..."
kubectl run plugin-deploy \ cat <<JOBEOF | kubectl apply -n "$HEADLAMP_NAMESPACE" -f -
--rm -i \ apiVersion: batch/v1
--restart=Never \ kind: Job
--image=busybox:1.36 \ metadata:
--namespace="$HEADLAMP_NAMESPACE" \ name: plugin-deploy
--overrides="{ spec:
\"spec\": { backoffLimit: 0
${NODE_OVERRIDE} ttlSecondsAfterFinished: 60
\"containers\": [{ template:
\"name\": \"plugin-deploy\", spec:
\"image\": \"busybox:1.36\", ${NODE_SELECTOR}
\"stdin\": true, restartPolicy: Never
\"command\": [\"sh\", \"-c\", containers:
\"rm -rf /plugins/${PLUGIN_DIR_NAME} && mkdir -p /plugins/${PLUGIN_DIR_NAME} && tar -xzf - -C /plugins/${PLUGIN_DIR_NAME} && echo Files deployed: && ls -la /plugins/${PLUGIN_DIR_NAME}/\" - name: deploy
], image: busybox:1.36
\"volumeMounts\": [{ command:
\"name\": \"plugins\", - sh
\"mountPath\": \"/plugins\" - -c
}] - |
}], echo "Decoding and extracting plugin..."
\"volumes\": [{ echo "${TARBALL_B64}" | base64 -d > /tmp/plugin.tar.gz
\"name\": \"plugins\", rm -rf /plugins/${PLUGIN_DIR_NAME}
\"persistentVolumeClaim\": { mkdir -p /plugins/${PLUGIN_DIR_NAME}
\"claimName\": \"headlamp-plugins\" tar -xzf /tmp/plugin.tar.gz -C /plugins/${PLUGIN_DIR_NAME}
} echo "Files deployed:"
}] ls -la /plugins/${PLUGIN_DIR_NAME}/
} volumeMounts:
}" < "$TAR_FILE" - name: plugins
mountPath: /plugins
volumes:
- name: plugins
persistentVolumeClaim:
claimName: headlamp-plugins
JOBEOF
# Wait for the job to complete
echo "Waiting for deploy job to complete..."
kubectl wait --for=condition=complete job/plugin-deploy \
-n "$HEADLAMP_NAMESPACE" --timeout=120s
# Show logs
kubectl logs job/plugin-deploy -n "$HEADLAMP_NAMESPACE" 2>/dev/null || true
# Clean up
kubectl delete job plugin-deploy -n "$HEADLAMP_NAMESPACE" --ignore-not-found 2>/dev/null || true
rm -f "$TAR_FILE" rm -f "$TAR_FILE"