fix: deploy plugin via temporary pod instead of assuming local PVC mount

The deploy script assumed the PVC was mounted on the CI runner at
/mnt/headlamp-plugins, but the runner pod doesn't have that mount.
Fix by using a temporary pod (kubectl run) that mounts the PVC,
receives the plugin tarball via stdin, and extracts it.

Also adds missing workflow steps to create the PVC and upgrade
Headlamp with the shared volume helm values before deploying.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Hugh Hackman
2026-03-17 09:10:09 +00:00
parent 0de500221b
commit 813a9e1fcd
2 changed files with 57 additions and 15 deletions
+11 -1
View File
@@ -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
+46 -14
View File
@@ -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..."