fix: resolve E2E settings + badge navigation failures #52
@@ -65,6 +65,39 @@ jobs:
|
||||
echo "::warning::Version mismatch — repo has $EXPECTED but Headlamp runs $DEPLOYED_VERSION. Tests may fail due to stale plugin."
|
||||
fi
|
||||
|
||||
- name: Build plugin
|
||||
run: npm run build
|
||||
|
||||
- name: Setup kubectl
|
||||
uses: azure/setup-kubectl@v4
|
||||
|
||||
- name: Configure kubeconfig
|
||||
env:
|
||||
KUBECONFIG_DATA: ${{ secrets.KUBECONFIG }}
|
||||
run: |
|
||||
if [ -n "$KUBECONFIG_DATA" ]; then
|
||||
mkdir -p ~/.kube
|
||||
echo "$KUBECONFIG_DATA" | base64 -d > ~/.kube/config
|
||||
chmod 600 ~/.kube/config
|
||||
elif [ -f /var/run/secrets/kubernetes.io/serviceaccount/token ]; then
|
||||
SA_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
|
||||
CA_CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
|
||||
kubectl config set-cluster in-cluster --server=https://kubernetes.default.svc --certificate-authority="$CA_CERT"
|
||||
kubectl config set-credentials sa-user --token="$SA_TOKEN"
|
||||
kubectl config set-context in-cluster --cluster=in-cluster --user=sa-user --namespace="$NAMESPACE"
|
||||
kubectl config use-context in-cluster
|
||||
fi
|
||||
kubectl version --client
|
||||
kubectl cluster-info || echo "::warning::Cannot reach cluster API — deploy step may fail"
|
||||
|
||||
- name: Deploy plugin to Headlamp
|
||||
env:
|
||||
HEADLAMP_URL: ${{ secrets.HEADLAMP_URL || 'http://headlamp.kube-system.svc.cluster.local' }}
|
||||
HEADLAMP_NS: ${{ secrets.HEADLAMP_NS || 'kube-system' }}
|
||||
HEADLAMP_PLUGIN_DIR: ${{ secrets.HEADLAMP_PLUGIN_DIR || '/headlamp/static-plugins/polaris' }}
|
||||
run: ./scripts/deploy-plugin-to-headlamp.sh
|
||||
|
||||
- name: Install Playwright browsers
|
||||
run: npx playwright install --with-deps chromium
|
||||
|
||||
|
||||
+2
-2
@@ -6,5 +6,5 @@ COPY src/ src/
|
||||
RUN npx @kinvolk/headlamp-plugin build
|
||||
|
||||
FROM alpine:3.20
|
||||
COPY --from=build /app/dist/ /plugins/headlamp-polaris-plugin/
|
||||
COPY --from=build /app/package.json /plugins/headlamp-polaris-plugin/
|
||||
COPY --from=build /app/dist/ /plugins/polaris/
|
||||
COPY --from=build /app/package.json /plugins/polaris/
|
||||
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deploy the built plugin to a live Headlamp instance via kubectl.
|
||||
#
|
||||
# Prerequisites:
|
||||
# - kubectl configured with access to the Headlamp namespace
|
||||
# - Plugin already built (npm run build → dist/)
|
||||
#
|
||||
# Environment variables (all optional, with defaults):
|
||||
# HEADLAMP_URL — Headlamp URL for readiness check
|
||||
# HEADLAMP_NS — Kubernetes namespace (default: kube-system)
|
||||
# HEADLAMP_PLUGIN_DIR — Plugin path inside the pod (default: /headlamp/static-plugins/polaris)
|
||||
#
|
||||
# Usage:
|
||||
# npm run build
|
||||
# ./scripts/deploy-plugin-to-headlamp.sh
|
||||
#
|
||||
# Intended to be called from the E2E workflow before running Playwright tests,
|
||||
# so that E2E always tests the current commit's plugin code rather than whatever
|
||||
# was previously deployed.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
HEADLAMP_URL="${HEADLAMP_URL:-http://headlamp.kube-system.svc.cluster.local}"
|
||||
HEADLAMP_NS="${HEADLAMP_NS:-kube-system}"
|
||||
HEADLAMP_PLUGIN_DIR="${HEADLAMP_PLUGIN_DIR:-/headlamp/static-plugins/polaris}"
|
||||
|
||||
if [ ! -d "dist" ]; then
|
||||
echo "Error: dist/ not found. Run 'npm run build' first." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find the Headlamp pod
|
||||
POD=$(kubectl get pod -n "$HEADLAMP_NS" -l app.kubernetes.io/name=headlamp \
|
||||
-o jsonpath='{.items[0].metadata.name}')
|
||||
echo "Headlamp pod: $POD"
|
||||
|
||||
# Remove stale plugin and copy current build
|
||||
kubectl exec -n "$HEADLAMP_NS" "$POD" -c headlamp -- \
|
||||
rm -rf "$HEADLAMP_PLUGIN_DIR" 2>/dev/null || true
|
||||
kubectl cp dist/. "$HEADLAMP_NS/$POD:$HEADLAMP_PLUGIN_DIR" -c headlamp
|
||||
|
||||
# Copy package.json so Headlamp can read plugin metadata
|
||||
kubectl cp package.json "$HEADLAMP_NS/$POD:$HEADLAMP_PLUGIN_DIR/package.json" -c headlamp
|
||||
|
||||
# Verify the copy
|
||||
echo "Deployed files:"
|
||||
kubectl exec -n "$HEADLAMP_NS" "$POD" -c headlamp -- \
|
||||
ls -la "$HEADLAMP_PLUGIN_DIR"
|
||||
|
||||
# Restart the Headlamp process to reload plugins.
|
||||
# Killing PID 1 restarts the container without replacing the pod,
|
||||
# so the emptyDir volume (and our copied files) is preserved.
|
||||
echo "Restarting Headlamp process..."
|
||||
kubectl exec -n "$HEADLAMP_NS" "$POD" -c headlamp -- kill 1 || true
|
||||
|
||||
# Wait for Headlamp to come back
|
||||
echo "Waiting for Headlamp to restart..."
|
||||
sleep 10
|
||||
for i in $(seq 1 30); do
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 "$HEADLAMP_URL" || true)
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "Headlamp is ready"
|
||||
exit 0
|
||||
fi
|
||||
echo " attempt $i/30 — HTTP $HTTP_CODE"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "Error: Headlamp did not recover after plugin deploy" >&2
|
||||
exit 1
|
||||
@@ -1,4 +1,4 @@
|
||||
import { K8s, Router } from '@kinvolk/headlamp-plugin/lib';
|
||||
import { K8s } from '@kinvolk/headlamp-plugin/lib';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
@@ -36,7 +36,8 @@ export default function AppBarScoreBadge() {
|
||||
};
|
||||
|
||||
const handleClick = () => {
|
||||
history.push(Router.createRouteURL('polaris', { cluster: cluster ?? '' }));
|
||||
const prefix = cluster ? `/c/${cluster}` : '';
|
||||
history.push(`${prefix}/polaris`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ registerRoute({
|
||||
});
|
||||
|
||||
// Register plugin settings
|
||||
registerPluginSettings('headlamp-polaris', PolarisSettings, true);
|
||||
registerPluginSettings('polaris', PolarisSettings, true);
|
||||
|
||||
// Register details view section for supported controller types
|
||||
registerDetailsViewSection(({ resource }) => {
|
||||
|
||||
Reference in New Issue
Block a user