From 23344e0c0759e970bbdc88bc463774053448e0a1 Mon Sep 17 00:00:00 2001 From: Andy Lee Date: Wed, 11 Mar 2026 15:29:14 +0800 Subject: [PATCH] feat: add vGPU filter button and hide the enable/disable passthrough in PCIDevice page (#729) * feat: add another filter button Signed-off-by: Andy Lee * feat: add feature falg to hide vGPU enable/disable actions in PCIDevices page Signed-off-by: Andy Lee * refactor: update with conditionally rendering Signed-off-by: Andy Lee --------- Signed-off-by: Andy Lee --- pkg/harvester/config/feature-flags.js | 3 +- .../VirtualMachinePciDevices/DeviceList.vue | 37 +++++++++++++++---- .../VirtualMachinePciDevices/index.vue | 18 ++++++++- .../edit/kubevirt.io.virtualmachine/index.vue | 6 ++- pkg/harvester/l10n/en-us.yaml | 8 +++- .../devices.harvesterhci.io.pcidevice.js | 17 ++++++++- 6 files changed, 74 insertions(+), 15 deletions(-) diff --git a/pkg/harvester/config/feature-flags.js b/pkg/harvester/config/feature-flags.js index f57d4558..ed56b5f0 100644 --- a/pkg/harvester/config/feature-flags.js +++ b/pkg/harvester/config/feature-flags.js @@ -61,7 +61,8 @@ const FEATURE_FLAGS = { 'v1.8.0': [ 'hotplugCdRom', 'supportBundleFileNameSetting', - 'clusterRegistrationTLSVerify' + 'clusterRegistrationTLSVerify', + 'vGPUAsPCIDevice', ], }; diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/DeviceList.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/DeviceList.vue index 84f5b203..9ae59260 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/DeviceList.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/DeviceList.vue @@ -31,6 +31,7 @@ export default { const _hash = { pciclaims: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.PCI_CLAIM }), sriovs: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.SR_IOV }), + srigpuovs: this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.SR_IOVGPU_DEVICE }), }; await allHash(_hash); @@ -106,19 +107,32 @@ export default { }, computed: { - parentSriovOptions() { + allSriovs() { const inStore = this.$store.getters['currentProduct'].inStore; - const allSriovs = this.$store.getters[`${ inStore }/all`](HCI.SR_IOV) || []; - return allSriovs.map((sriov) => { - return sriov.id; - }); + return this.$store.getters[`${ inStore }/all`](HCI.SR_IOV) || []; + }, + allSriovGPUs() { + const inStore = this.$store.getters['currentProduct'].inStore; + + return this.$store.getters[`${ inStore }/all`](HCI.SR_IOVGPU_DEVICE) || []; + }, + parentSriovOptions() { + return this.allSriovs.map((sriov) => sriov.id); + }, + parentSriovGPUOptions() { + return this.allSriovGPUs.map((sriovgpu) => sriovgpu.id); }, parentSriovLabel() { return HCI_ANNOTATIONS.PARENT_SRIOV; - } + }, + parentSriovGPULabel() { + return HCI_ANNOTATIONS.PARENT_SRIOV_GPU; + }, + vGPUAsPCIDeviceEnabled() { + return this.$store.getters['harvester-common/getFeatureEnabled']('vGPUAsPCIDevice'); + }, }, - methods: { enableGroup(rows = []) { const row = rows[0]; @@ -206,6 +220,15 @@ export default { :rows="rows" @change-rows="changeRows" /> + diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue index e3534f89..254643fb 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue @@ -8,6 +8,7 @@ import { set } from '@shell/utils/object'; import { HCI } from '../../../types'; import DeviceList from './DeviceList'; import CompatibilityMatrix from '../CompatibilityMatrix'; +import MessageLink from '@shell/components/MessageLink'; export default { name: 'VirtualMachinePCIDevices', @@ -15,7 +16,8 @@ export default { LabeledSelect, DeviceList, CompatibilityMatrix, - Banner + Banner, + MessageLink }, props: { mode: { @@ -138,6 +140,13 @@ export default { return inUse; }, + toVGpuDevicesPage() { + return { + name: 'harvester-c-cluster-resource', + params: { cluster: this.$store.getters['clusterId'], resource: HCI.VGPU_DEVICE }, + }; + }, + devicesByNode() { return this.enabledDevices?.reduce((acc, device) => { const nodeName = device.status?.nodeName; @@ -232,7 +241,12 @@ export default {
- + For vGPU devices, please enable them on the' + middle: vGPU Devices + suffix: page first. deviceInTheSameHost: 'You can only select devices on the same host.' oldFormatDevices: help: |- @@ -1832,7 +1835,8 @@ harvester: numVFs: Number Of Virtual Functions vfAddresses: Virtual Functions Addresses showMore: Show More - parentSriov: Filter By Parent SR-IOV + parentSriov: Filter By Parent SR-IOV Netork Device + parentSriovGPU: Filter By Parent SR-IOV GPU Device sriovgpu: label: SR-IOV GPU Devices diff --git a/pkg/harvester/models/devices.harvesterhci.io.pcidevice.js b/pkg/harvester/models/devices.harvesterhci.io.pcidevice.js index 6b83ca19..453e0055 100644 --- a/pkg/harvester/models/devices.harvesterhci.io.pcidevice.js +++ b/pkg/harvester/models/devices.harvesterhci.io.pcidevice.js @@ -1,6 +1,7 @@ import SteveModel from '@shell/plugins/steve/steve-class'; import { escapeHtml } from '@shell/utils/string'; import { HCI } from '../types'; +import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations'; const STATUS_DISPLAY = { enabled: { @@ -32,7 +33,7 @@ export default class PCIDevice extends SteveModel { out.push( { action: 'enablePassthroughBulk', - enabled: !this.isEnabling, + enabled: !this.isEnabling && !this.isvGPUDevice, icon: 'icon icon-fw icon-dot', label: 'Enable Passthrough', bulkable: true, @@ -41,7 +42,7 @@ export default class PCIDevice extends SteveModel { }, { action: 'disablePassthrough', - enabled: this.isEnabling && this.claimedByMe, + enabled: this.isEnabling && this.claimedByMe && !this.isvGPUDevice, icon: 'icon icon-fw icon-dot-open', label: 'Disable Passthrough', bulkable: true, @@ -52,6 +53,14 @@ export default class PCIDevice extends SteveModel { return out; } + get isvGPUDevice() { + if (!this.vGPUAsPCIDeviceFeatureEnabled) { + return false; + } + + return !!this.metadata?.labels?.[HCI_ANNOTATIONS.PARENT_SRIOV_GPU] || this.status?.resourceName.includes('nvidia.com'); + } + get canYaml() { return false; } @@ -176,6 +185,10 @@ export default class PCIDevice extends SteveModel { return this.status?.description; } + get vGPUAsPCIDeviceFeatureEnabled() { + return this.$rootGetters['harvester-common/getFeatureEnabled']('vGPUAsPCIDevice'); + } + showDetachWarning() { this.$dispatch('growl/warning', { title: this.$rootGetters['i18n/t']('harvester.pci.detachWarning.title'),