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" \
-o jsonpath='{.items[0].spec.nodeName}' 2>/dev/null || true)
if [ -z "$HEADLAMP_NODE" ]; then
# Fallback: try by deployment label
HEADLAMP_NODE=$(kubectl get pods -n "$HEADLAMP_NAMESPACE" \
-l "app.kubernetes.io/instance=headlamp" \
-o jsonpath='{.items[0].spec.nodeName}' 2>/dev/null || true)
fi
if [ -n "$HEADLAMP_NODE" ]; then
echo " Headlamp node: $HEADLAMP_NODE (scheduling deploy pod there)"
NODE_OVERRIDE="\"nodeName\": \"$HEADLAMP_NODE\","
echo " Headlamp node: $HEADLAMP_NODE (scheduling deploy job there)"
NODE_SELECTOR="\"nodeName\": \"$HEADLAMP_NODE\","
else
echo " WARNING: Could not determine Headlamp node, deploy pod may fail if PVC is ReadWriteOnce"
NODE_OVERRIDE=""
echo " WARNING: Could not determine Headlamp node"
NODE_SELECTOR=""
fi
# Clean up any previous deploy pod
kubectl delete pod plugin-deploy -n "$HEADLAMP_NAMESPACE" --ignore-not-found --wait=false 2>/dev/null || true
# Base64-encode the tarball so we can embed it in the pod command
# (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
# Run a temporary pod that mounts the PVC and receives the tarball via stdin
echo "Starting deploy pod..."
kubectl run plugin-deploy \
--rm -i \
--restart=Never \
--image=busybox:1.36 \
--namespace="$HEADLAMP_NAMESPACE" \
--overrides="{
\"spec\": {
${NODE_OVERRIDE}
\"containers\": [{
\"name\": \"plugin-deploy\",
\"image\": \"busybox:1.36\",
\"stdin\": true,
\"command\": [\"sh\", \"-c\",
\"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}/\"
],
\"volumeMounts\": [{
\"name\": \"plugins\",
\"mountPath\": \"/plugins\"
}]
}],
\"volumes\": [{
\"name\": \"plugins\",
\"persistentVolumeClaim\": {
\"claimName\": \"headlamp-plugins\"
}
}]
}
}" < "$TAR_FILE"
# Create a Job that decodes the tarball and extracts to the PVC
echo "Starting deploy job..."
cat <<JOBEOF | kubectl apply -n "$HEADLAMP_NAMESPACE" -f -
apiVersion: batch/v1
kind: Job
metadata:
name: plugin-deploy
spec:
backoffLimit: 0
ttlSecondsAfterFinished: 60
template:
spec:
${NODE_SELECTOR}
restartPolicy: Never
containers:
- name: deploy
image: busybox:1.36
command:
- sh
- -c
- |
echo "Decoding and extracting plugin..."
echo "${TARBALL_B64}" | base64 -d > /tmp/plugin.tar.gz
rm -rf /plugins/${PLUGIN_DIR_NAME}
mkdir -p /plugins/${PLUGIN_DIR_NAME}
tar -xzf /tmp/plugin.tar.gz -C /plugins/${PLUGIN_DIR_NAME}
echo "Files deployed:"
ls -la /plugins/${PLUGIN_DIR_NAME}/
volumeMounts:
- 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"