feat: add feature falg to hide vGPU enable/disable actions in PCIDevices page

Signed-off-by: Andy Lee <andy.lee@suse.com>
This commit is contained in:
Andy Lee 2026-03-10 13:16:54 +08:00
parent 465488b52d
commit 2b669ba4d5
No known key found for this signature in database
GPG Key ID: 39DC4436AE3564D5
7 changed files with 44 additions and 9 deletions

View File

@ -29,8 +29,6 @@ export default {
required: true, required: true,
}, },
}, },
data() { data() {

View File

@ -61,7 +61,8 @@ const FEATURE_FLAGS = {
'v1.8.0': [ 'v1.8.0': [
'hotplugCdRom', 'hotplugCdRom',
'supportBundleFileNameSetting', 'supportBundleFileNameSetting',
'clusterRegistrationTLSVerify' 'clusterRegistrationTLSVerify',
'vGPUAsPCIDevice',
], ],
}; };

View File

@ -109,10 +109,12 @@ export default {
computed: { computed: {
allSriovs() { allSriovs() {
const inStore = this.$store.getters['currentProduct'].inStore; const inStore = this.$store.getters['currentProduct'].inStore;
return this.$store.getters[`${ inStore }/all`](HCI.SR_IOV) || []; return this.$store.getters[`${ inStore }/all`](HCI.SR_IOV) || [];
}, },
allSriovGPUs() { allSriovGPUs() {
const inStore = this.$store.getters['currentProduct'].inStore; const inStore = this.$store.getters['currentProduct'].inStore;
return this.$store.getters[`${ inStore }/all`](HCI.SR_IOVGPU_DEVICE) || []; return this.$store.getters[`${ inStore }/all`](HCI.SR_IOVGPU_DEVICE) || [];
}, },
parentSriovOptions() { parentSriovOptions() {

View File

@ -8,6 +8,7 @@ import { set } from '@shell/utils/object';
import { HCI } from '../../../types'; import { HCI } from '../../../types';
import DeviceList from './DeviceList'; import DeviceList from './DeviceList';
import CompatibilityMatrix from '../CompatibilityMatrix'; import CompatibilityMatrix from '../CompatibilityMatrix';
import MessageLink from '@shell/components/MessageLink';
export default { export default {
name: 'VirtualMachinePCIDevices', name: 'VirtualMachinePCIDevices',
@ -15,7 +16,8 @@ export default {
LabeledSelect, LabeledSelect,
DeviceList, DeviceList,
CompatibilityMatrix, CompatibilityMatrix,
Banner Banner,
MessageLink
}, },
props: { props: {
mode: { mode: {
@ -138,6 +140,13 @@ export default {
return inUse; return inUse;
}, },
toVGpuDevicesPage() {
return {
name: 'harvester-c-cluster-resource',
params: { cluster: this.$store.getters['clusterId'], resource: HCI.VGPU_DEVICE },
};
},
devicesByNode() { devicesByNode() {
return this.enabledDevices?.reduce((acc, device) => { return this.enabledDevices?.reduce((acc, device) => {
const nodeName = device.status?.nodeName; const nodeName = device.status?.nodeName;
@ -232,7 +241,12 @@ export default {
<div class="row"> <div class="row">
<div class="col span-12"> <div class="col span-12">
<Banner color="info"> <Banner color="info">
<t k="harvester.pci.howToUseDevice" /> <MessageLink
:to="toVGpuDevicesPage"
prefix-label="harvester.pci.howToUseDevice.prefix"
middle-label="harvester.pci.howToUseDevice.middle"
suffix-label="harvester.pci.howToUseDevice.suffix"
/>
</Banner> </Banner>
<Banner <Banner
v-if="selectedDevices.length > 0" v-if="selectedDevices.length > 0"

View File

@ -211,6 +211,10 @@ export default {
return false; return false;
}, },
vGPUAsPCIDeviceEnabled() {
return this.$store.getters['harvester-common/getFeatureEnabled']('vGPUAsPCIDevice');
},
usbPassthroughEnabled() { usbPassthroughEnabled() {
return this.$store.getters['harvester-common/getFeatureEnabled']('usbPassthrough'); return this.$store.getters['harvester-common/getFeatureEnabled']('usbPassthrough');
}, },
@ -740,7 +744,7 @@ export default {
</Tab> </Tab>
<Tab <Tab
v-if="enabledSriovgpu" v-if="enabledSriovgpu && !vGPUAsPCIDeviceEnabled"
:label="t('harvester.tab.vGpuDevices')" :label="t('harvester.tab.vGpuDevices')"
name="vGpuDevices" name="vGpuDevices"
:weight="-6" :weight="-6"

View File

@ -355,7 +355,10 @@ harvester:
available: Available Devices available: Available Devices
compatibleNodes: Compatible Nodes compatibleNodes: Compatible Nodes
impossibleSelection: 'There are no hosts with all of the selected devices.' impossibleSelection: 'There are no hosts with all of the selected devices.'
howToUseDevice: 'Use the table below to enable PCI passthrough on each device you want to use in this virtual machine.' howToUseDevice:
prefix: 'Use the table below to enable PCI passthrough on each device you want to use in this virtual machine.<br>For vGPU devices, please enable them on the'
middle: vGPU Devices
suffix: page first.
deviceInTheSameHost: 'You can only select devices on the same host.' deviceInTheSameHost: 'You can only select devices on the same host.'
oldFormatDevices: oldFormatDevices:
help: |- help: |-

View File

@ -1,6 +1,7 @@
import SteveModel from '@shell/plugins/steve/steve-class'; import SteveModel from '@shell/plugins/steve/steve-class';
import { escapeHtml } from '@shell/utils/string'; import { escapeHtml } from '@shell/utils/string';
import { HCI } from '../types'; import { HCI } from '../types';
import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
const STATUS_DISPLAY = { const STATUS_DISPLAY = {
enabled: { enabled: {
@ -32,7 +33,7 @@ export default class PCIDevice extends SteveModel {
out.push( out.push(
{ {
action: 'enablePassthroughBulk', action: 'enablePassthroughBulk',
enabled: !this.isEnabling, enabled: !this.isEnabling && !this.isvGPUDevice,
icon: 'icon icon-fw icon-dot', icon: 'icon icon-fw icon-dot',
label: 'Enable Passthrough', label: 'Enable Passthrough',
bulkable: true, bulkable: true,
@ -41,7 +42,7 @@ export default class PCIDevice extends SteveModel {
}, },
{ {
action: 'disablePassthrough', action: 'disablePassthrough',
enabled: this.isEnabling && this.claimedByMe, enabled: this.isEnabling && this.claimedByMe && !this.isvGPUDevice,
icon: 'icon icon-fw icon-dot-open', icon: 'icon icon-fw icon-dot-open',
label: 'Disable Passthrough', label: 'Disable Passthrough',
bulkable: true, bulkable: true,
@ -52,6 +53,14 @@ export default class PCIDevice extends SteveModel {
return out; 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() { get canYaml() {
return false; return false;
} }
@ -176,6 +185,10 @@ export default class PCIDevice extends SteveModel {
return this.status?.description; return this.status?.description;
} }
get vGPUAsPCIDeviceFeatureEnabled() {
return this.$rootGetters['harvester-common/getFeatureEnabled']('vGPUAsPCIDevice');
}
showDetachWarning() { showDetachWarning() {
this.$dispatch('growl/warning', { this.$dispatch('growl/warning', {
title: this.$rootGetters['i18n/t']('harvester.pci.detachWarning.title'), title: this.$rootGetters['i18n/t']('harvester.pci.detachWarning.title'),