feat: initial release of headlamp-intel-gpu-plugin v0.1.0

Adds a Headlamp plugin for Intel GPU device plugin visibility:

- Dedicated sidebar section: Overview, Device Plugins, GPU Nodes, GPU Pods
- Native Node detail page injection: GPU capacity, allocatable, utilization, active pods
- Native Pod detail page injection: per-container GPU resource requests/limits
- Native Nodes table: GPU Type and GPU Devices columns
- App bar health badge (hidden when plugin not installed)
- GpuDevicePlugin CRD monitoring (deviceplugin.intel.com/v1) with graceful
  degradation when CRD is not present
- Supports discrete (i915), Xe, and integrated GPU nodes via node labels
- 48 unit tests, TypeScript clean, 28 kB production bundle

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
2026-02-18 17:58:49 -05:00
commit 41bf2aead4
18 changed files with 21053 additions and 0 deletions
@@ -0,0 +1,58 @@
/**
* NodeColumns — adds Intel GPU columns to the native Headlamp Nodes table.
*
* Injects two columns:
* - "GPU Type" — Discrete / Integrated / — for non-GPU nodes
* - "GPU Devices" — count of i915/xe devices available on the node
*
* The processor is registered via registerResourceTableColumnsProcessor
* in index.tsx, targeting the 'headlamp-nodes' table ID.
*/
import { StatusLabel } from '@kinvolk/headlamp-plugin/lib/CommonComponents';
import React from 'react';
import {
formatGpuType,
getNodeGpuCount,
getNodeGpuType,
isIntelGpuNode,
} from '../../api/k8s';
/** Build GPU columns to append to the native Nodes table. */
export function buildNodeGpuColumns() {
return [
{
label: 'GPU Type',
getter: (resource: unknown) => {
// resource is a Headlamp KubeObject — extract jsonData
const raw =
resource && typeof resource === 'object' && 'jsonData' in resource
? (resource as { jsonData: unknown }).jsonData
: resource;
if (!isIntelGpuNode(raw)) return '—';
const node = raw as Parameters<typeof getNodeGpuType>[0];
const type = getNodeGpuType(node);
return (
<StatusLabel status="success">
{formatGpuType(type)}
</StatusLabel>
);
},
},
{
label: 'GPU Devices',
getter: (resource: unknown) => {
const raw =
resource && typeof resource === 'object' && 'jsonData' in resource
? (resource as { jsonData: unknown }).jsonData
: resource;
if (!isIntelGpuNode(raw)) return '—';
const node = raw as Parameters<typeof getNodeGpuCount>[0];
const count = getNodeGpuCount(node);
return count > 0 ? String(count) : '—';
},
},
];
}