From 7c04b1417a380267f1e027d8a61cc47f9c00ecdc Mon Sep 17 00:00:00 2001 From: Francesco Torchia Date: Sun, 8 Sep 2024 18:08:03 +0200 Subject: [PATCH] Update USB devices - Add columns and filters - Filter other vm devices in pci and usb devices pages when selecting devices Signed-off-by: Francesco Torchia --- pkg/harvester/config/harvester-cluster.js | 8 +++ .../VirtualMachinePciDevices/index.vue | 18 +++++- .../VirtualMachineUSBDevices/DeviceList.vue | 61 +++++++++++++++++++ .../VirtualMachineUSBDevices/index.vue | 44 +++++++++++-- pkg/harvester/l10n/en-us.yaml | 4 +- .../devices.harvesterhci.io.usbdevice.vue | 12 ++-- .../devices.harvesterhci.io.usbdevice.js | 31 +++++----- 7 files changed, 149 insertions(+), 29 deletions(-) diff --git a/pkg/harvester/config/harvester-cluster.js b/pkg/harvester/config/harvester-cluster.js index 4051f90f..d3ede505 100644 --- a/pkg/harvester/config/harvester-cluster.js +++ b/pkg/harvester/config/harvester-cluster.js @@ -771,6 +771,14 @@ export function init($plugin, store) { hiddenNamespaceGroupButton: true, listGroups: [ { + icon: 'icon-list-grouped', + value: 'description', + field: 'groupByDevice', + hideColumn: 'description', + tooltipKey: 'resourceTable.groupBy.device' + }, + { + icon: 'icon-cluster', value: 'node', field: 'groupByNode', hideColumn: 'node', diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue index d7f74e2e..c8106178 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachinePciDevices/index.vue @@ -55,10 +55,13 @@ export default { const selectedDevices = []; const oldFormatDevices = []; - (this.value?.domain?.devices?.hostDevices || []).forEach(({ name, deviceName }) => { + const vmDevices = this.value?.domain?.devices?.hostDevices || []; + const otherDevices = this.otherDevices(vmDevices).map(({name}) => name); + + vmDevices.forEach(({ name, deviceName }) => { const checkName = (deviceName || '').split('/')?.[1]; - if (checkName && name.includes(checkName)) { + if (checkName && name.includes(checkName) && !otherDevices.includes(name)) { oldFormatDevices.push(name); } else if (this.enabledDevices.find(device => device?.metadata?.name === name)) { selectedDevices.push(name); @@ -96,7 +99,12 @@ export default { }; }); - set(this.value.domain.devices, 'hostDevices', formatted); + const devices = [ + ...this.otherDevices(this.value.domain.devices.hostDevices), + ...formatted, + ]; + + set(this.value.domain.devices, 'hostDevices', devices); } }, @@ -187,6 +195,10 @@ export default { }, methods: { + otherDevices(vmDevices) { + return vmDevices.filter((device) => !this.pciDevices.find((pci) => device.name === pci.name)); + }, + nodeNameFromUid(uid) { for (const deviceUid in this.uniqueDevices) { const nodes = this.uniqueDevices[deviceUid].nodes; diff --git a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineUSBDevices/DeviceList.vue b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineUSBDevices/DeviceList.vue index 921116da..01df9f3e 100644 --- a/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineUSBDevices/DeviceList.vue +++ b/pkg/harvester/edit/kubevirt.io.virtualmachine/VirtualMachineUSBDevices/DeviceList.vue @@ -34,6 +34,36 @@ export default { const headers = [ { ...STATE }, SIMPLE_NAME, + { + name: 'description', + labelKey: 'tableHeaders.description', + value: 'status.description', + sort: ['status.description'] + }, + { + name: 'node', + labelKey: 'tableHeaders.node', + value: 'status.nodeName', + sort: ['status.nodeName'] + }, + { + name: 'pciAddress', + label: 'Address', + value: 'status.pciAddress', + sort: ['status.pciAddress'] + }, + { + name: 'vendorID', + label: 'Vendor ID', + value: 'status.vendorID', + sort: ['status.vendorID', 'status.productID'] + }, + { + name: 'productID', + label: 'Product ID', + value: 'status.productID', + sort: ['status.productID', 'status.vendorID'] + }, ]; if (!isSingleProduct) { @@ -58,12 +88,32 @@ export default { handler(v) { this.rows = v; this.filterRows = this.rows; + + console.log(this.filterRows) }, immediate: true, }, }, methods: { + enableGroup(rows = []) { + const row = rows[0]; + + if (row) { + row.enablePassthroughBulk(rows); + } + }, + disableGroup(rows = []) { + rows.forEach((row) => { + if (row.passthroughClaim) { + row.disablePassthrough(); + } + }); + }, + groupIsAllEnabled(rows = []) { + return !rows.find(device => !device.passthroughClaim); + }, + changeRows(filterRows) { this.$set(this, 'filterRows', filterRows); }, @@ -94,6 +144,17 @@ export default { :sort-generation-fn="sortGenerationFn" :rows-per-page="10" > + diff --git a/pkg/harvester/models/devices.harvesterhci.io.usbdevice.js b/pkg/harvester/models/devices.harvesterhci.io.usbdevice.js index 88b7c054..9424ebfc 100644 --- a/pkg/harvester/models/devices.harvesterhci.io.usbdevice.js +++ b/pkg/harvester/models/devices.harvesterhci.io.usbdevice.js @@ -32,7 +32,7 @@ export default class USBDevice extends SteveModel { out.push( { action: 'enablePassthroughBulk', - enabled: !this.isEnabling, + enabled: !this.passthroughClaim && !this.status.enabled, icon: 'icon icon-fw icon-dot', label: 'Enable Passthrough', bulkable: true, @@ -40,7 +40,7 @@ export default class USBDevice extends SteveModel { }, { action: 'disablePassthrough', - enabled: this.isEnabling && this.claimedByMe, + enabled: this.status.enabled, icon: 'icon icon-fw icon-dot-open', label: 'Disable Passthrough', bulkable: true @@ -69,7 +69,7 @@ export default class USBDevice extends SteveModel { get passthroughClaim() { const passthroughClaims = this.$getters['all'](HCI.USB_CLAIM) || []; - return !!this.status && passthroughClaims.find(req => req?.spec?.nodeName === this.status?.nodeName && req?.spec?.address === this.status?.address); + return !!this.status && passthroughClaims.find(req => req?.status?.nodeName === this.status?.nodeName && req?.status?.pciAddress === this.status?.pciAddress); } // this is an id for each 'type' of device - there may be multiple instances of device CRs @@ -98,23 +98,12 @@ export default class USBDevice extends SteveModel { return this.claimedBy === userName; } - // isEnabled controls visibility in vm create page & ability to delete claim - // isEnabling controls ability to add claim - // there will be a brief period where isEnabling === true && isEnabled === false - get isEnabled() { - return !!this.passthroughClaim?.status?.passthroughEnabled; - } - - get isEnabling() { - return !!this.passthroughClaim; - } - // map status.passthroughEnabled to disabled/enabled & overwrite default dash colors get claimStatusDisplay() { if (!this.passthroughClaim) { return STATUS_DISPLAY.disabled; } - if (this.isEnabled) { + if (this.status.enabled) { return STATUS_DISPLAY.enabled; } @@ -155,4 +144,16 @@ export default class USBDevice extends SteveModel { }, { root: true }); } } + + // group device list by node + get groupByNode() { + const name = this.status?.nodeName || this.$rootGetters['i18n/t']('generic.none'); + + return this.$rootGetters['i18n/t']('resourceTable.groupLabel.node', { name: escapeHtml(name) }); + } + + // group device list by unique device (same vendorid and deviceid) + get groupByDevice() { + return this.status?.description; + } }