diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 271cd0c..86aa19f 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -8,7 +8,6 @@ on: workflow_dispatch: env: - PLUGIN_VOLUME_PATH: /mnt/headlamp-plugins HEADLAMP_NAMESPACE: kube-system HEADLAMP_DEPLOY: headlamp @@ -33,6 +32,17 @@ jobs: - name: Build plugin run: npm run build + - name: Ensure PVC exists + run: kubectl apply -f deployment/headlamp-plugins-pvc.yaml + + - name: Upgrade Headlamp with shared volume mount + run: | + helm upgrade headlamp headlamp/headlamp \ + --namespace "$HEADLAMP_NAMESPACE" \ + --reuse-values \ + -f deployment/headlamp-e2e-values.yaml \ + --wait --timeout 120s + - name: Deploy plugin via shared volume run: scripts/deploy-plugin-via-volume.sh diff --git a/scripts/deploy-plugin-via-volume.sh b/scripts/deploy-plugin-via-volume.sh index c89c719..881cb62 100755 --- a/scripts/deploy-plugin-via-volume.sh +++ b/scripts/deploy-plugin-via-volume.sh @@ -2,19 +2,18 @@ # deploy-plugin-via-volume.sh # # Copies the built plugin into the shared PVC so Headlamp picks it up. -# The PVC must already be mounted on the CI runner at PLUGIN_VOLUME_PATH. +# Uses a temporary Kubernetes pod to write to the PVC — the CI runner +# does NOT need the PVC mounted locally. # # Usage: -# scripts/deploy-plugin-via-volume.sh [plugin-volume-path] +# scripts/deploy-plugin-via-volume.sh # # Environment: -# PLUGIN_VOLUME_PATH — mount point of the shared PVC (default: /mnt/headlamp-plugins) # HEADLAMP_NAMESPACE — namespace where Headlamp runs (default: kube-system) # HEADLAMP_DEPLOY — Headlamp deployment name (default: headlamp) set -euo pipefail REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" -PLUGIN_VOLUME_PATH="${1:-${PLUGIN_VOLUME_PATH:-/mnt/headlamp-plugins}}" HEADLAMP_NAMESPACE="${HEADLAMP_NAMESPACE:-kube-system}" HEADLAMP_DEPLOY="${HEADLAMP_DEPLOY:-headlamp}" @@ -28,18 +27,51 @@ if [ ! -d "$DIST_DIR" ]; then exit 1 fi -echo "Deploying plugin to shared volume..." -echo " Source: $DIST_DIR" -echo " Destination: $PLUGIN_VOLUME_PATH/$PLUGIN_DIR_NAME" +echo "Deploying plugin to shared volume via temporary pod..." +echo " Source: $DIST_DIR" +echo " PVC: headlamp-plugins" +echo " Plugin: $PLUGIN_DIR_NAME" -# Clean any previous version and copy fresh build -rm -rf "${PLUGIN_VOLUME_PATH:?}/${PLUGIN_DIR_NAME}" -mkdir -p "$PLUGIN_VOLUME_PATH/$PLUGIN_DIR_NAME" -cp -a "$DIST_DIR"/. "$PLUGIN_VOLUME_PATH/$PLUGIN_DIR_NAME/" -cp "$REPO_ROOT/package.json" "$PLUGIN_VOLUME_PATH/$PLUGIN_DIR_NAME/" +# Create tarball of plugin dist + package.json +TAR_FILE=$(mktemp /tmp/plugin-XXXXXX.tar.gz) +tar -czf "$TAR_FILE" -C "$DIST_DIR" . -C "$REPO_ROOT" package.json +echo " Tarball: $TAR_FILE ($(du -h "$TAR_FILE" | cut -f1))" -echo "Plugin files deployed:" -ls -la "$PLUGIN_VOLUME_PATH/$PLUGIN_DIR_NAME/" +# Clean up any previous deploy pod +kubectl delete pod plugin-deploy -n "$HEADLAMP_NAMESPACE" --ignore-not-found --wait=false 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\": { + \"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" + +rm -f "$TAR_FILE" # Restart Headlamp to pick up the new plugin echo "Restarting Headlamp deployment to load plugin..."