### Install Project Dependencies Source: https://github.com/project-hami/hami-webui/blob/main/packages/web/README.md Run this command to install all necessary project dependencies. ```bash pnpm install ``` -------------------------------- ### Install HAMi-WebUI Helm Chart Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/README.md Install the HAMi-WebUI Helm chart into a specified namespace. Ensure you have configured the `values.yaml` file before installation. ```console helm install my-hami-webui hami-webui/hami-webui --create-namespace --namespace hami -f values.yaml ``` -------------------------------- ### Install HAMi-WebUI with Default Settings Source: https://context7.com/project-hami/hami-webui/llms.txt Installs HAMi-WebUI using the Helm chart with default configurations, including the 'main' image tag. Ensure the target namespace exists or is created. ```bash helm install hami-webui ./charts/hami-webui \ --namespace hami-system \ --create-namespace ``` -------------------------------- ### Verify HAMi-WebUI Installation Source: https://github.com/project-hami/hami-webui/blob/main/docs/installation/helm/index.md Checks if the HAMi-WebUI pods are running in the specified namespace. Successful installation shows 'hami-webui' and 'hami-webui-dcgm-exporter' in a running state. ```bash kubectl get pods -n kube-system | grep webui ``` -------------------------------- ### Start Development Server Source: https://github.com/project-hami/hami-webui/blob/main/packages/web/README.md Compiles and hot-reloads the application for development. Access the running application via your browser. ```bash pnpm run start:dev ``` -------------------------------- ### Install macOS Dependencies with Homebrew Source: https://github.com/project-hami/hami-webui/blob/main/docs/contribute/developer-guide.md Use Homebrew to install Git, Go, and Node.js on macOS. Ensure the Go version meets the minimum requirement specified in go.mod. ```bash brew install git brew install go brew install node@20 ``` -------------------------------- ### Install HAMi-WebUI Helm Chart Source: https://github.com/project-hami/hami-webui/blob/main/docs/installation/helm/index.md Deploys HAMi-WebUI using the Helm chart. Ensure to replace 'externalPrometheus.address' with your Prometheus instance's address and specify the correct namespace. ```bash helm install my-hami-webui hami-webui/hami-webui --set externalPrometheus.enabled=true --set externalPrometheus.address="http://prometheus-kube-prometheus-prometheus.monitoring.svc.cluster.local:9090" -n kube-system ``` -------------------------------- ### Production Install with Specific Configurations Source: https://context7.com/project-hami/hami-webui/llms.txt Deploys HAMi-WebUI for production with specific image tags, Prometheus integration, and Ingress settings. This command overrides default values in the Helm chart. ```bash helm install hami-webui ./charts/hami-webui \ --namespace hami-system \ --create-namespace \ --set image.frontend.tag=v1.1.0 \ --set image.backend.tag=v1.1.0 \ --set externalPrometheus.enabled=true \ --set externalPrometheus.address=http://prometheus.monitoring.svc.cluster.local:9090 \ --set ingress.enabled=true \ --set ingress.hosts[0].host=hami-webui.example.com \ --set ingress.hosts[0].paths[0].path=/ ``` -------------------------------- ### NestJS Server Entry Point Source: https://context7.com/project-hami/hami-webui/llms.txt Sets up the NestJS application, including static asset serving, cookie parsing, global interceptors, and starts the server on port 3000. The body-parser is disabled to allow the proxy middleware to handle raw request bodies. ```typescript import { NestFactory } from '@nestjs/core' import { NestExpressApplication } from '@nestjs/platform-express' import { AppModule } from './app.module' import { join } from 'path' import { TransformInterceptor } from './interceptors/transform.interceptor' import * as cookieParser from 'cookie-parser' async function bootstrap() { const app = await NestFactory.create(AppModule, { bodyParser: false // raw body kept for proxy re-serialisation }) app.useStaticAssets(join(__dirname, '..', 'public')) app.setBaseViewsDir(join(__dirname, '..', 'public')) app.setViewEngine('hbs') app.use(cookieParser()) app.useGlobalInterceptors(new TransformInterceptor()) await app.listen(3000) } bootstrap() ``` -------------------------------- ### SPA Fallback Route Source: https://context7.com/project-hami/hami-webui/llms.txt Configures a catch-all GET route to serve the Vue SPA's entry point (`public/index.html`) for client-side routing. This applies to any GET request not matching `/api/*` or `/health_check`. ```bash curl http://localhost:3000/admin/vgpu/monitor/overview # → serves public/index.html (Vue SPA entry) ``` -------------------------------- ### Deploy Prometheus using kube-prometheus-stack in HAMi-WebUI Chart Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/README.md Enable the kube-prometheus-stack to deploy Prometheus and its operator if no Prometheus is currently installed. Ensure CRDs are enabled. ```yaml kube-prometheus-stack: enabled: true crds: enabled: true ... prometheusOperator: enabled: true ... ``` -------------------------------- ### Fetching GPU Card List and Details Source: https://context7.com/project-hami/hami-webui/llms.txt Use cardApi to interact with GPU card operations. The base prefix for all requests is '/api/vgpu'. Supports filtering, getting types, and Prometheus queries. ```javascript // packages/web/projects/vgpu/api/card.js import cardApi from '~/vgpu/api/card' // List all GPU cards with optional filters const { list } = await cardApi.getCardListReq({ filters: { nodeName: 'gpu-node-01', type: 'NVIDIA-A100' } }) // list: [{ uuid, type, nodeName, health, mode, vgpuTotal, vgpuUsed, coreTotal, coreUsed, memoryTotal, memoryUsed, isExternal }] // Get distinct GPU card types const { list: types } = await request(cardApi.getCardType()) // types: [{ type: 'NVIDIA-A100' }, { type: 'NVIDIA-V100' }] // Get single card detail const card = await cardApi.getCardDetail({ uuid: 'GPU-abc123' }) // Prometheus instant-vector query (current values) const result = await cardApi.getInstantVector({ query: 'avg(sum(hami_container_vgpu_allocated) by (instance))' }) // result.data: [{ metric: { instance: '...' }, value: 42 }] // Prometheus range-vector query (time-series) const series = await cardApi.getRangeVector({ query: 'sum(hami_container_vcore_allocated) / sum(hami_core_size) * 100', range: { start: '2024-01-01T00:00:00Z', end: '2024-01-01T01:00:00Z', step: '60' } }) // series.data: [{ metric: {}, values: [[timestamp, value], ...] }] ``` -------------------------------- ### Vue Component for WebSocket Singleton - WS Source: https://context7.com/project-hami/hami-webui/llms.txt Provides a singleton Socket.IO client factory. Use `WS.getInstance(url)` to get a shared socket connection and interact with the server. ```javascript // packages/web/src/components/Socket/index.js import WS from '@/components/Socket' // Create or reuse a shared connection const ws = WS.getInstance('http://localhost:3000') const socket = ws.getSocket() socket.on('gpu-metrics', (payload) => { console.log('live GPU metrics:', payload) }) socket.emit('subscribe', { nodeId: 'gpu-node-01' }) ``` -------------------------------- ### Uninstall HAMi-WebUI Deployment Source: https://github.com/project-hami/hami-webui/blob/main/docs/installation/helm/index.md Removes the HAMi-WebUI deployment from the specified namespace. This command requires the release name and namespace name used during installation. ```bash helm uninstall my-hami-webui -n hami ``` -------------------------------- ### SPA Fallback Source: https://context7.com/project-hami/hami-webui/llms.txt Handles all GET requests that do not match specific API or health check routes by serving the Vue.js Single Page Application entry point. ```APIDOC ## GET * (Catch-All) ### Description Every GET request that does not match `/api/*` or `/health_check` is served `public/index.html` so Vue Router can handle client-side navigation. ### Method GET ### Endpoint * ### Response #### Success Response (200) - Serves the `public/index.html` file. ### Request Example ```bash curl http://localhost:3000/admin/vgpu/monitor/overview ``` ### Response Example (Content of `public/index.html`) ``` -------------------------------- ### Development Frontend Proxy Middleware Source: https://context7.com/project-hami/hami-webui/llms.txt When `NODE_ENV` is 'development', this middleware forwards non-API, non-BFF GET requests to the Vite dev server at port 8080. It excludes paths matching `/api`, `/health_check`, and `/bff/`. ```typescript // Target is resolved dynamically at first use: const localIP = address.ip() || '127.0.0.1' // Proxies to http://:8080 // Filter (does NOT proxy these paths to Vite): const filter = (pathname) => !/^/api|health_check|bff//.test(pathname) ``` -------------------------------- ### API Reverse Proxy Middleware Source: https://context7.com/project-hami/hami-webui/llms.txt Proxies requests starting with `/api/` to configured upstream targets based on the path segment after `/api/`. Handles proxy errors by returning a specific error object. ```typescript // Config (src/config/production/proxy.ts): export default { vgpu: { target: 'http://127.0.0.1:8000', secure: false, pathRewrite: { '^/api/vgpu': '' } // strips /api/vgpu prefix } } // A request to /api/vgpu/v1/nodes → proxied to http://127.0.0.1:8000/v1/nodes // Error example: // { "code": 599, "reason": "PROXY_ERROR", "message": "", "metadata": {} } ``` -------------------------------- ### Build for Production Source: https://github.com/project-hami/hami-webui/blob/main/packages/web/README.md Compiles and minifies the application for production deployment. ```bash pnpm run build ``` -------------------------------- ### Build HAMi-WebUI Frontend Docker Image Source: https://github.com/project-hami/hami-webui/blob/main/docs/contribute/developer-guide.md Build a Docker image for the HAMi-WebUI frontend. Specify the Docker image name and version. The resulting image will be tagged accordingly. ```bash make build-image DOCKER_IMAGE=projecthami/hami-webui-fe VERSION=dev ``` -------------------------------- ### Build HAMi-WebUI Backend Docker Image Source: https://github.com/project-hami/hami-webui/blob/main/docs/contribute/developer-guide.md Build a Docker image for the HAMi-WebUI backend. Specify the Docker image name and version. The resulting image will be tagged accordingly. ```bash make build-image DOCKER_IMAGE=projecthami/hami-webui-be VERSION=dev ``` -------------------------------- ### Accessing Hami WebUI via Ingress Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/templates/NOTES.txt If Ingress is enabled, this snippet shows how to construct the application URL based on configured hosts and paths. ```go-template {{- if .Values.ingress.enabled }} {{- range $host := .Values.ingress.hosts }} {{- range .paths }} http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} {{- end }} {{- end }} {{- end }} ``` -------------------------------- ### useFetchList Source: https://context7.com/project-hami/hami-webui/llms.txt Executes a request promise on component mount and populates a reactive list from a specified response path. ```APIDOC ## useFetchList ### Description A Vue hook that executes a pre-built request promise when a component mounts. It populates a reactive `ref<[]>` list with data extracted from a specified path within the response body. ### Parameters - `requestPromise` (Promise) - A promise that resolves to the API response. - `responsePath` (String) - The key in the response object where the list data can be found (defaults to 'list'). ### Usage Example ```javascript import useFetchList from '@/hooks/useFetchList' import nodeApi from '~/vgpu/api/node' // Fetches on mount, reads response.list const nodeList = useFetchList( nodeApi.getNodeListReq({ filters: {} }), 'list' // default; use 'items' for task responses ) // nodeList.value → [] initially, populated after mount ``` ``` -------------------------------- ### Add HAMi-WebUI Helm Repository Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/README.md Add the HAMi-WebUI Helm repository to your local Helm configuration. This command fetches the latest chart information. ```console helm repo add hami-webui https://project-hami.github.io/HAMi-WebUI helm repo update ``` -------------------------------- ### vGPU API Client: System Information Source: https://context7.com/project-hami/hami-webui/llms.txt Use `InfoApi` to retrieve system-level metadata for the cluster. This includes information such as the HAMi version and cluster name. ```javascript // packages/web/projects/vgpu/api/info.js import InfoApi from '~/vgpu/api/info' const sysInfo = await InfoApi.getSysInfo({}) // Returns system metadata: HAMi version, cluster name, etc. ``` -------------------------------- ### monitorApi.summary Source: https://context7.com/project-hami/hami-webui/llms.txt Retrieves a cluster-wide GPU resource summary, including node count, card count, and vGPU count. ```APIDOC ## monitorApi.summary ### Description Fetches top-level cluster-wide GPU resource totals. ### Method `summary` ### Parameters - `params` (object) - Optional - Parameters for the summary request. ### Request Example ```javascript const summary = await monitorApi.summary({}) ``` ### Response - Returns an object containing cluster-wide totals (e.g., node count, card count, vGPU count). ``` -------------------------------- ### Add HAMi-WebUI Helm Repository Source: https://github.com/project-hami/hami-webui/blob/main/docs/installation/helm/index.md Adds the HAMi-WebUI Helm repository to your local Helm configuration. This command fetches the correct Helm charts for HAMi-WebUI. ```bash helm repo add hami-webui https://project-hami.github.io/HAMi-WebUI ``` -------------------------------- ### vGPU API Client: Cluster Summary Source: https://context7.com/project-hami/hami-webui/llms.txt Use `monitorApi` for cluster-wide GPU utilization summaries. It provides methods to fetch overall resource totals and current utilization rates. ```javascript // packages/web/projects/vgpu/api/monitor.js import monitorApi from '~/vgpu/api/monitor' // Cluster GPU resource summary const summary = await monitorApi.summary({}) // Returns top-level totals (node count, card count, vGPU count, etc.) // Monitor usage summary const usage = await monitorApi.usage({}) // Returns current utilisation rates across the cluster ``` -------------------------------- ### InfoApi.getSysInfo Source: https://context7.com/project-hami/hami-webui/llms.txt Retrieves system metadata, including HAMi version and cluster name. ```APIDOC ## InfoApi.getSysInfo ### Description Fetches system metadata such as HAMi version and cluster name. ### Method `getSysInfo` ### Parameters - `params` (object) - Optional - Parameters for the system info request. ### Request Example ```javascript const sysInfo = await InfoApi.getSysInfo({}) ``` ### Response - Returns an object containing system metadata. ``` -------------------------------- ### Port-Forward HAMi-WebUI Service Source: https://github.com/project-hami/hami-webui/blob/main/docs/installation/helm/index.md Establishes a connection from your localhost to the HAMi-WebUI service running in the cluster. This allows access to the WebUI via your browser. ```bash kubectl port-forward service/my-hami-webui 3000:3000 --namespace=kube-system ``` -------------------------------- ### Accessing Hami WebUI via ClusterIP Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/templates/NOTES.txt When using ClusterIP, this snippet demonstrates how to forward a local port to the application's container port, allowing access via localhost. ```bash export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "hami-webui.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") echo "Visit http://127.0.0.1:3000 to use your application" kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 3000:$CONTAINER_PORT ``` -------------------------------- ### Vue Router Configuration for vGPU Module Source: https://context7.com/project-hami/hami-webui/llms.txt Defines the route structure for the vGPU project, which is injected under `/admin/vgpu/`. Includes routes for node and GPU card administration, monitoring, and task management. ```javascript // packages/web/projects/vgpu/router.js // Route tree: // /admin/vgpu/ → redirect → /admin/vgpu/node/admin // /admin/vgpu/monitor/overview → Dashboard overview (gauges, top-5, trends) // /admin/vgpu/node/admin → Node list (filterable by status, type, IP) // /admin/vgpu/node/admin/:uid → Node detail page // /admin/vgpu/card/admin → GPU card list (filterable by type, node, UUID) // /admin/vgpu/card/admin/:uuid → GPU card detail page // /admin/vgpu/task/admin → Workload/task list (filterable by node, status, card) // /admin/vgpu/task/admin/detail → Task detail page (?name=&podUid=) // Registration (in the host application's router setup): import vgpuRoutes from '~/vgpu/router' router.addRoute(vgpuRoutes(LayoutComponent)) ``` -------------------------------- ### Environment Configuration for ProxyService Source: https://context7.com/project-hami/hami-webui/llms.txt Configure upstream services for ApiProxyMiddleware and ProxyService by defining a 'proxy' map in your environment configuration. Profiles are switched using NODE_ENV. ```typescript // src/config/production/proxy.ts (also identical for development) export default { vgpu: { target: 'http://127.0.0.1:8000', // HAMi backend address secure: false, pathRewrite: { '^/api/vgpu': '' } } } // Add additional upstream services by adding keys: export default { vgpu: { target: 'http://hami-backend:8000', secure: false, pathRewrite: { '^/api/vgpu': '' } }, prometheus: { target: 'http://prometheus:9090', secure: false, pathRewrite: { '^/api/prometheus': '' } } } ``` -------------------------------- ### Accessing Hami WebUI via LoadBalancer Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/templates/NOTES.txt For LoadBalancer service types, this snippet shows how to retrieve the LoadBalancer IP and construct the application URL. Note that it may take time for the IP to become available. ```bash NOTE: It may take a few minutes for the LoadBalancer IP to be available. You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "hami-webui.fullname" . }}' export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "hami-webui.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}) echo http://$SERVICE_IP:{{ .Values.service.port }} ``` -------------------------------- ### Collect HAMi-WebUI Server Logs Source: https://github.com/project-hami/hami-webui/blob/main/docs/installation/helm/index.md Retrieves logs from the HAMi-WebUI frontend and backend pods, which is essential for troubleshooting deployment issues. ```bash kubectl logs --namespace=hami deploy/my-hami-webui -c hami-webui-fe-oss ``` ```bash kubectl logs --namespace=hami deploy/my-hami-webui -c hami-webui-be-oss ``` -------------------------------- ### API Proxy for vGPU Service Source: https://context7.com/project-hami/hami-webui/llms.txt The BFF acts as a reverse proxy for API requests targeting the vGPU service. Requests to `/api/vgpu/*` are forwarded to the configured upstream target. ```APIDOC ## POST /api/vgpu/* (and other methods) ### Description Routes every `/api//...` request to the configured upstream target. Path segments after `/api/` are mapped to entries in `config.proxy`. On proxy error, returns a specific error structure. ### Method Any HTTP method (GET, POST, PUT, DELETE, etc.) ### Endpoint /api/vgpu/* ### Parameters #### Path Parameters - **** (string) - Required - The type of service to proxy to (e.g., 'vgpu'). - **<...rest>** (string) - Required - The remaining path segments for the upstream service. ### Request Body (Depends on the upstream service's requirements) ### Response #### Success Response (200) (Depends on the upstream service's response) #### Error Response (599) - **code** (number) - 599 - **reason** (string) - "PROXY_ERROR" - **message** (string) - Details of the proxy error (e.g., from AxiosError). - **metadata** (object) - Additional metadata about the error. ### Response Example (Error) { "code": 599, "reason": "PROXY_ERROR", "message": "", "metadata": {} } ``` -------------------------------- ### useRequest Source: https://context7.com/project-hami/hami-webui/llms.txt Wraps an HTTP call with a loading indicator, providing imperative control over request execution. ```APIDOC ## useRequest ### Description A Vue hook that wraps an HTTP call, providing a `loading` state indicator and an imperative `run` function to trigger the request. It simplifies managing loading states for asynchronous operations. ### Parameters - `options` (Object) - Configuration for the HTTP request, including `url`, `method`, and `data`. - `url` (String) - The endpoint URL. - `method` (String) - The HTTP method (e.g., 'POST', 'GET'). - `data` (Object) - The request payload. ### Returns - `{ loading: Ref, run: Function }` - `loading`: A reactive boolean indicating if the request is in progress. - `run`: A function to manually trigger the request. It accepts optional overrides for request parameters. ### Usage Example ```javascript import useRequest from '@/hooks/useRequest' const { loading, run } = useRequest({ url: '/api/vgpu/v1/nodes', method: 'POST', data: { filters: {} } }) // Trigger manually, with optional overrides: const result = await run({ data: { filters: { isSchedulable: 'true' } } }) // loading.value is true while the request is in-flight ``` ``` -------------------------------- ### Configure External Prometheus in HAMi-WebUI Chart Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/README.md Enable and configure an external Prometheus instance by providing its address. Replace '' with the actual domain or internal Ingress address. ```yaml externalPrometheus: enabled: true address: "" ``` -------------------------------- ### Fetching GPU Node List and Details Source: https://context7.com/project-hami/hami-webui/llms.txt Utilize nodeApi for Kubernetes node operations. Supports listing nodes with filters, retrieving single node details, and direct reactive fetching for UI components. ```javascript // packages/web/projects/vgpu/api/node.js import nodeApi from '~/vgpu/api/node' import request from '@/utils/request' // List nodes with filters const { list } = await request(nodeApi.getNodeList({ filters: { isSchedulable: 'true', type: 'NVIDIA-A100', ip: '10.0.0' } })) // list: [{ uid, name, ip, type, cardCnt, isSchedulable, isExternal, // vgpuTotal, vgpuUsed, coreTotal, coreUsed, memoryTotal, memoryUsed }] // Get single node detail const node = await nodeApi.getNodeDetail({ uid: 'node-uid-xyz' }) // Direct reactive fetch (returns a ref<[]> populated on mount) const nodes = useFetchList(nodeApi.getNodeListReq({ filters: {} })) // nodes.value populated after component mounts ``` -------------------------------- ### Accessing Hami WebUI via NodePort Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/templates/NOTES.txt When the service type is NodePort, these commands retrieve the NodePort and Node IP to construct the application URL. ```bash export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "hami-webui.fullname" . }}) export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT ``` -------------------------------- ### Vue Component for Preview Bar - PreviewBar Source: https://context7.com/project-hami/hami-webui/llms.txt Aggregates GPU distribution and usage data into a preview bar with a pie chart and two ranked bar charts. Supports node-scoped or GPU-scoped queries. ```vue ``` -------------------------------- ### vGPU API Client — taskApi (Containerised Workloads) Source: https://context7.com/project-hami/hami-webui/llms.txt Client for managing GPU-consuming container/pod (task) operations. ```APIDOC ## taskApi.getTaskListReq(options) ### Description Lists tasks (containers/pods) with optional filters. ### Parameters - **options** (object) - Optional - An object containing filters. - **filters** (object) - Optional - Filters to apply to the list. - **nodeName** (string) - Optional - Filter by node name. - **status** (string) - Optional - Filter by task status ('success', 'closed', 'failed', 'unknown'). - **deviceId** (string) - Optional - Filter by device ID. - **name** (string) - Optional - Filter by task name. ### Returns An object containing `items` which is a list of tasks. ``` ```APIDOC ## taskApi.getTaskDetail(options) ### Description Gets the details of a single task. ### Parameters - **options** (object) - Required - An object containing task identifiers. - **name** (string) - Required - The name of the task. - **podUid** (string) - Required - The unique identifier of the pod. ### Returns An object representing the task details. ``` ```APIDOC ## taskApi.deleteTask(options) ### Description Deletes a task. ### Parameters - **options** (object) - Required - An object containing task identifiers. - **name** (string) - Required - The name of the task. - **podUid** (string) - Required - The unique identifier of the pod. ### Returns No content on successful deletion. ``` -------------------------------- ### Vue Hook: Fetch and Populate List Source: https://context7.com/project-hami/hami-webui/llms.txt The `useFetchList` hook fetches data from a specified API endpoint on component mount and populates a reactive list ref from a given response path. It's useful for populating tables or lists with data. ```javascript // packages/web/src/hooks/useFetchList.js import useFetchList from '@/hooks/useFetchList' import nodeApi from '~/vgpu/api/node' // Fetches on mount, reads response.list const nodeList = useFetchList( nodeApi.getNodeListReq({ filters: {} }), 'list' // default; use 'items' for task responses ) // nodeList.value → [] initially, populated after mount ``` -------------------------------- ### Managing GPU-Consuming Tasks (Workloads) Source: https://context7.com/project-hami/hami-webui/llms.txt The taskApi client allows for listing, retrieving details of, and deleting GPU-consuming containerized workloads (tasks). Supports filtering by node, status, and device. ```javascript // packages/web/projects/vgpu/api/task.js import taskApi from '~/vgpu/api/task' // List tasks with filters const { items } = await taskApi.getTaskListReq({ filters: { nodeName: 'gpu-node-01', status: 'success', // 'success' | 'closed' | 'failed' | 'unknown' deviceId: 'GPU-abc123', name: 'training-job' } }) // items: [{ podUid, name, appName, nodeName, status, deviceIds, // allocatedCores, allocatedMem, createTime }] // Get task detail const task = await taskApi.getTaskDetail({ name: 'my-pod', podUid: 'uid-123' }) // Delete a task await taskApi.deleteTask({ name: 'my-pod', podUid: 'uid-123' }) ``` -------------------------------- ### Vue Hook: Fetch Instant Prometheus Metrics Source: https://context7.com/project-hami/hami-webui/llms.txt The `useInstantVector` hook fetches current and historical Prometheus metric values for dashboard gauges. It automatically re-fetches when reactive dependencies change and supports time-range data fetching when a `times` ref is provided. ```javascript // packages/web/projects/vgpu/hooks/useInstantVector.js import useInstantVector from '~/vgpu/hooks/useInstantVector' import { ref } from 'vue' const times = ref([new Date(Date.now() - 3600_000), new Date()]) const gauges = useInstantVector( [ { title: 'vGPU Alloc Rate', percent: 0, used: 0, total: 0, query: 'avg(sum(hami_container_vgpu_allocated) by (instance))', totalQuery: 'avg(sum(hami_vgpu_count) by (instance))', percentQuery: 'avg(sum(hami_container_vgpu_allocated) by (instance)) / avg(sum(hami_vgpu_count) by (instance)) * 100', unit: 'count', }, { title: 'Memory Alloc Rate', percent: 0, used: 0, total: 0, query: 'avg(sum(hami_container_vmemory_allocated) by (instance)) / 1024', totalQuery: 'avg(sum(hami_memory_size) by (instance)) / 1024', percentQuery: '(avg(sum(hami_container_vmemory_allocated) by (instance)) / 1024) / (avg(sum(hami_memory_size) by (instance)) / 1024) * 100', unit: 'GiB', }, ], (query) => query, // optional query transformer times // optional reactive time-range ref ) // gauges.value[0] → { title, percent, used, total, unit, data: [[ts, val], ...] } ``` -------------------------------- ### Lint and Fix Files Source: https://github.com/project-hami/hami-webui/blob/main/packages/web/README.md Runs linting checks on the project files and attempts to fix any identified issues. ```bash pnpm run lint ``` -------------------------------- ### useLocalPagination Source: https://context7.com/project-hami/hami-webui/llms.txt Provides client-side pagination for a local dataset, managing pagination state and computed data slices. ```APIDOC ## useLocalPagination ### Description A Vue hook for implementing client-side pagination on an already-fetched `ref<[]>` dataset. It returns a reactive `pagination` object and a computed `pagedTableData` slice representing the current page's data. ### Parameters - `tableData` (Ref) - A reactive reference to the dataset to be paginated. - `options` (Object) - Optional configuration for pagination. - `pageSize` (Number) - The number of items per page (defaults to 20). ### Returns - `{ pagination: Object, pagedTableData: ComputedRef, syncTotalAndClamp: Function, resetToFirstPage: Function }` - `pagination`: An object containing pagination state (`current`, `pageSize`, `total`, `pageSizeOptions`, `showJumper`). - `pagedTableData`: A computed property that returns the data slice for the current page. - `syncTotalAndClamp`: A function to call after `tableData` changes to update the total item count and ensure the current page is valid. - `resetToFirstPage`: A function to reset the current page to 1, useful before applying new filters. ### Usage Example ```javascript import useLocalPagination from '~/vgpu/hooks/useLocalPagination' import { ref } from 'vue' const tableData = ref([/* ... fetched items ... */]) const { pagination, pagedTableData, syncTotalAndClamp, resetToFirstPage, } = useLocalPagination(tableData, { pageSize: 20 }) // In template: // // ``` ``` -------------------------------- ### vGPU API Client — cardApi (GPU Cards) Source: https://context7.com/project-hami/hami-webui/llms.txt Client for managing GPU card operations. All requests have a base prefix of `/api/vgpu`. ```APIDOC ## cardApi.getCardListReq(options) ### Description Lists all GPU cards with optional filters. ### Parameters - **options** (object) - Optional - An object containing filters. - **filters** (object) - Optional - Filters to apply to the list. - **nodeName** (string) - Optional - Filter by node name. - **type** (string) - Optional - Filter by GPU card type. ### Returns An object containing a `list` of GPU cards. ``` ```APIDOC ## cardApi.getCardType() ### Description Gets distinct GPU card types. ### Returns An object containing a list of available GPU card types. ``` ```APIDOC ## cardApi.getCardDetail(options) ### Description Gets the details of a single GPU card. ### Parameters - **options** (object) - Required - An object containing the card's UUID. - **uuid** (string) - Required - The unique identifier of the GPU card. ### Returns An object representing the GPU card details. ``` ```APIDOC ## cardApi.getInstantVector(options) ### Description Performs a Prometheus instant-vector query to get current metric values. ### Parameters - **options** (object) - Required - An object containing the query. - **query** (string) - Required - The Prometheus query string. ### Returns An object containing the query result data. ``` ```APIDOC ## cardApi.getRangeVector(options) ### Description Performs a Prometheus range-vector query to get time-series metric data. ### Parameters - **options** (object) - Required - An object containing the query and time range. - **query** (string) - Required - The Prometheus query string. - **range** (object) - Required - The time range for the query. - **start** (string) - Required - The start time of the range (ISO 8601 format). - **end** (string) - Required - The end time of the range (ISO 8601 format). - **step** (string) - Required - The step interval for the data points. ### Returns An object containing the time-series data. ``` -------------------------------- ### useInstantVector Source: https://context7.com/project-hami/hami-webui/llms.txt Fetches current and historical Prometheus metric values for dashboard gauges. Automatically re-fetches on dependency changes. ```APIDOC ## useInstantVector ### Description A Vue hook that fetches current (instant) and optional range Prometheus metric values for dashboard gauge configurations. It utilizes `watchEffect` for automatic re-fetching when reactive dependencies change. If a `times` ref is provided, it also fetches historical range data. ### Parameters - `gauges` (Array) - An array of gauge configurations, each with `title`, `query`, `totalQuery`, `percentQuery`, and `unit`. - `queryTransformer` (Function) - Optional - A function to transform the query before execution. - `times` (Ref>) - Optional - A reactive ref containing a time range for historical data fetching. ### Usage Example ```javascript import useInstantVector from '~/vgpu/hooks/useInstantVector' import { ref } from 'vue' const times = ref([new Date(Date.now() - 3600_000), new Date()]) const gauges = useInstantVector( [ { title: 'vGPU Alloc Rate', percent: 0, used: 0, total: 0, query: 'avg(sum(hami_container_vgpu_allocated) by (instance))', totalQuery: 'avg(sum(hami_vgpu_count) by (instance))', percentQuery: 'avg(sum(hami_container_vgpu_allocated) by (instance)) / avg(sum(hami_vgpu_count) by (instance)) * 100', unit: 'count', }, // ... other gauge configurations ], (query) => query, // optional query transformer times // optional reactive time-range ref ) // Accessing data: gauges.value[0] → { title, percent, used, total, unit, data: [[ts, val], ...] } ``` ``` -------------------------------- ### vGPU API Client — nodeApi (GPU Nodes) Source: https://context7.com/project-hami/hami-webui/llms.txt Client for managing Kubernetes node operations. ```APIDOC ## nodeApi.getNodeList(options) ### Description Lists nodes with optional filters. ### Parameters - **options** (object) - Optional - An object containing filters. - **filters** (object) - Optional - Filters to apply to the list. - **isSchedulable** (string) - Optional - Filter by schedulability (e.g., 'true'). - **type** (string) - Optional - Filter by node type. - **ip** (string) - Optional - Filter by node IP address. ### Returns An object containing a `list` of nodes. ``` ```APIDOC ## nodeApi.getNodeDetail(options) ### Description Gets the details of a single node. ### Parameters - **options** (object) - Required - An object containing the node's UID. - **uid** (string) - Required - The unique identifier of the node. ### Returns An object representing the node details. ``` ```APIDOC ## nodeApi.getNodeListReq(options) ### Description A reactive request function to fetch the node list, suitable for use with `useFetchList`. ### Parameters - **options** (object) - Optional - An object containing filters. - **filters** (object) - Optional - Filters to apply to the list. ### Returns An object containing a `list` of nodes, which will be populated reactively. ``` -------------------------------- ### monitorApi.usage Source: https://context7.com/project-hami/hami-webui/llms.txt Retrieves the current GPU utilization rates across the cluster. ```APIDOC ## monitorApi.usage ### Description Fetches current GPU utilization rates across the cluster. ### Method `usage` ### Parameters - `params` (object) - Optional - Parameters for the usage request. ### Request Example ```javascript const usage = await monitorApi.usage({}) ``` ### Response - Returns an object detailing current cluster-wide GPU utilization. ``` -------------------------------- ### Making Server-Side HTTP Calls with ProxyService Source: https://context7.com/project-hami/hami-webui/llms.txt Use ProxyService within NestJS controllers or services to aggregate BFF logic. Ensure the serverName matches a key in your proxy configuration. ```typescript // src/proxy/proxy.service.ts import { ProxyService } from './proxy/proxy.service' // Inside a NestJS controller or service: @Injectable() class ExampleService { constructor(private proxy: ProxyService) {} async getNodes() { // request(serverName, axiosConfig) // serverName must match a key in config.proxy (e.g. 'vgpu') return this.proxy.request('vgpu', { url: '/v1/nodes', method: 'POST', data: { filters: {} } }) // Returns the parsed response body directly } async requestApi() { // requestApi: URL prefix (before first '/') is the server name return this.proxy.requestApi({ url: 'vgpu/v1/gpus', // 'vgpu' → target, '/v1/gpus' → path method: 'POST', data: { filters: {} } }) } } ``` -------------------------------- ### Deploy Separate Prometheus Instance with Existing Operator Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/README.md Enable kube-prometheus-stack to deploy a new Prometheus instance while reusing an existing Prometheus Operator and CRDs. ```yaml kube-prometheus-stack: enabled: true ... ``` -------------------------------- ### Health Check Endpoint Source: https://context7.com/project-hami/hami-webui/llms.txt A simple liveness probe that returns 'OK' when the BFF process is healthy. The TransformInterceptor will wrap this response. ```bash curl http://localhost:3000/health_check # Response (after TransformInterceptor): # { "code": 0, "msg": "success", "data": "OK" } ``` -------------------------------- ### ProxyService - Programmatic BFF HTTP Client Source: https://context7.com/project-hami/hami-webui/llms.txt The ProxyService allows making server-side HTTP calls from within NestJS handlers, useful for BFF aggregation logic. It supports direct requests to configured backend services. ```APIDOC ## ProxyService.request(serverName, axiosConfig) ### Description Makes an HTTP request to a configured backend service. ### Parameters - **serverName** (string) - Required - The name of the server to which the request will be made. This name must match a key in the `config.proxy` map. - **axiosConfig** (object) - Required - The Axios request configuration object, including `url`, `method`, and `data`. ### Returns The parsed response body directly. ``` ```APIDOC ## ProxyService.requestApi(axiosConfig) ### Description Makes an HTTP request to a configured backend service where the server name is derived from the URL prefix. ### Parameters - **axiosConfig** (object) - Required - The Axios request configuration object. The `url` property should include the server name as a prefix (e.g., 'vgpu/v1/gpus'). ### Returns The parsed response body directly. ``` -------------------------------- ### Health Check Source: https://context7.com/project-hami/hami-webui/llms.txt Provides a liveness probe for the HAMi-WebUI BFF. Returns 'OK' when the process is healthy, wrapped in a standard response envelope. ```APIDOC ## GET /health_check ### Description Returns the plain string "OK" when the BFF process is healthy. The `TransformInterceptor` wraps it into the standard envelope. ### Method GET ### Endpoint /health_check ### Response #### Success Response (200) - **code** (number) - 0 for success - **msg** (string) - "success" - **data** (string) - "OK" ### Response Example { "code": 0, "msg": "success", "data": "OK" } ``` -------------------------------- ### Vue Hook: Client-Side Pagination Source: https://context7.com/project-hami/hami-webui/llms.txt The `useLocalPagination` hook enables client-side pagination for an existing dataset. It returns pagination controls and a computed slice of data for the current page, ideal for managing large tables. ```javascript // packages/web/projects/vgpu/hooks/useLocalPagination.js import useLocalPagination from '~/vgpu/hooks/useLocalPagination' import { ref } from 'vue' const tableData = ref([/* ... fetched items ... */]) const { pagination, pagedTableData, syncTotalAndClamp, resetToFirstPage, } = useLocalPagination(tableData, { pageSize: 20 }) // In template: // // ``` -------------------------------- ### Vue Component for Resource Gauge Display Source: https://context7.com/project-hami/hami-webui/llms.txt Displays a resource metric as a percentage, progress bar, and used/total details. Color transitions indicate status: green (< 50%), blue (< 80%), and red (>= 80%). ```vue ``` -------------------------------- ### Uninstall HAMi-WebUI Helm Chart Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/README.md Uninstall the HAMi-WebUI Helm release. This command removes all associated Kubernetes components. ```console helm delete my-hami-webui ``` -------------------------------- ### Delete HAMi-WebUI Namespace Source: https://github.com/project-hami/hami-webui/blob/main/docs/installation/helm/index.md Removes the entire namespace dedicated to HAMi-WebUI, including all its associated resources. ```bash kubectl delete namespace hami ``` -------------------------------- ### Update ServiceMonitor Labels for Existing Prometheus Integration Source: https://github.com/project-hami/hami-webui/blob/main/charts/hami-webui/README.md When integrating with an existing Prometheus, ensure that 'prometheusSpec.serviceMonitorSelector.matchLabels' and all corresponding 'ServiceMonitor.additionalLabels' are updated to match. ```yaml prometheus: prometheusSpec: serviceMonitorSelector: matchLabels: : ``` ```yaml ...ServiceMonitor: additionalLabels: : ``` -------------------------------- ### Vue Hook: Imperative HTTP Request Source: https://context7.com/project-hami/hami-webui/llms.txt The `useRequest` hook wraps HTTP calls, providing a `loading` state and an imperative `run` function to trigger the request. It's suitable for actions like form submissions or manual data refreshes. ```javascript // packages/web/src/hooks/useRequest.js import useRequest from '@/hooks/useRequest' const { loading, run } = useRequest({ url: '/api/vgpu/v1/nodes', method: 'POST', data: { filters: {} } }) // Trigger manually (e.g. on button click), with optional overrides: const result = await run({ data: { filters: { isSchedulable: 'true' } } }) // loading.value is true while the request is in-flight ``` -------------------------------- ### Vue Hook for Table Column Visibility - useTableColumnVisibility Source: https://context7.com/project-hami/hami-webui/llms.txt Manages per-column show/hide state for TDesign tables. Derives `columnOptions` for a checkbox toolbar and `visibleColumns` for filtered column definitions. ```javascript // packages/web/projects/vgpu/hooks/useTableColumnVisibility.js import useTableColumnVisibility from '~/vgpu/hooks/useTableColumnVisibility' import { computed } from 'vue' const baseColumns = computed(() => [ { title: 'Name', dataIndex: 'name', key: 'col-name' }, { title: 'Status', dataIndex: 'status', key: 'col-status' }, { title: 'IP', dataIndex: 'ip' }, ]) const { eyeColumnKeys, columnOptions, visibleColumns } = useTableColumnVisibility(baseColumns) // eyeColumnKeys → ref of currently visible column keys (all visible by default) // columnOptions → computed [{ label, value }] for a column-picker checkbox group // visibleColumns → computed TDesign column definitions (with null→'--' normalisation) // In template: // // ```