feat: align the storage performance options with the Rancher machine pool form (#1212)

* feat: align the storage performance options with the Rancher machine pool form

Show the storage performance profile on every volume instead of behind a
collapsible toggle, and move the VM-wide options to a plain Storage
Performance section in the Advanced Options tab. Put the Native I/O tip in
a live region so screen readers announce the cache mode change, use an
integer input for the I/O thread count, and use the same copy as the
Rancher form.

Skip the view-only backup row in the image and container volumes when it
has nothing to show, so it no longer adds an empty gap above the profile.

Signed-off-by: Marcelo Fukumoto <marcelo.fukumoto@suse.com>

* fix: announce the storage performance warnings and name the virtio requirement

- Put the bus tip and the Filesystem warning in an always-rendered status
  region. They appear above the field being changed, so screen readers need
  them announced.
- Say in the bus tip that a dedicated I/O thread needs the virtio bus, because
  KubeVirt rejects it on any other bus.
- Mark I/O Thread Count as required while editing, like the Rancher form.

Signed-off-by: Marcelo Fukumoto <marcelo.fukumoto@suse.com>

* fix: state only the dedicated I/O thread requirement in the bus tip

Neither the Harvester docs nor KubeVirt tie cache mode or I/O mode to the bus,
so stop saying that those options work best on virtio.

Signed-off-by: Marcelo Fukumoto <marcelo.fukumoto@suse.com>

---------

Signed-off-by: Marcelo Fukumoto <marcelo.fukumoto@suse.com>
This commit is contained in:
marcelofukumoto
2026-11-05 18:51:46 +01:00
committed by GitHub
parent 840f9de73e
commit 12c28c08fa
14 changed files with 373 additions and 274 deletions
@@ -2,7 +2,6 @@
import LabeledSelect from '@shell/components/form/LabeledSelect';
import { Checkbox } from '@components/Form/Checkbox';
import { Banner } from '@components/Banner';
import { _VIEW } from '@shell/config/query-params';
import { DISK_CACHE_MODE, DISK_IO_MODE, DISK_PERFORMANCE_PROFILE } from '../../../config/harvester-map';
const { DEFAULT, HIGH, CUSTOM } = DISK_PERFORMANCE_PROFILE;
@@ -31,11 +30,8 @@ export default {
},
data() {
const hasPerf = !!(this.value.cache || this.value.io || this.value.dedicatedIOThread);
return {
DISK_PERFORMANCE_PROFILE,
expanded: hasPerf,
profile: this.detectProfile(),
// Bus the disk used before the "High Performance" preset switched it to
// virtio, so returning to "Default" can put it back.
@@ -46,10 +42,6 @@ export default {
},
computed: {
isView() {
return this.mode === _VIEW;
},
storagePerformanceEnabled() {
return this.$store.getters['harvester-common/getFeatureEnabled']('highPerformanceStorage');
},
@@ -206,51 +198,49 @@ export default {
v-if="!isCdRom && storagePerformanceEnabled"
class="disk-performance"
>
<button
v-if="!isView"
type="button"
class="btn btn-sm role-link expand-toggle"
:aria-expanded="expanded"
:aria-label="expanded ? t('harvester.virtualMachine.volume.performance.collapse') : t('harvester.virtualMachine.volume.performance.expand')"
@click.prevent="expanded = !expanded"
>
<i
class="icon"
:class="expanded ? 'icon-chevron-down' : 'icon-chevron-right'"
/>
{{ t('harvester.virtualMachine.volume.performance.title') }}
</button>
<div
v-if="expanded || isView"
class="perf-body mt-10"
>
<div class="row mb-20">
<div
class="col span-6"
data-testid="input-disk-perf-profile"
>
<LabeledSelect
:value="profile"
:label="t('harvester.virtualMachine.volume.performance.profile.label')"
:tooltip="t('harvester.virtualMachine.volume.performance.profile.tip')"
:options="profileOptions"
:mode="mode"
@update:value="onProfileChange"
/>
</div>
</div>
<Banner
v-if="profile === DISK_PERFORMANCE_PROFILE.HIGH"
color="info"
label-key="harvester.virtualMachine.volume.performance.highProfileTip"
/>
<div class="row mb-20">
<div
v-if="isCustom || isView"
class="row mb-20"
class="col span-6"
data-testid="input-disk-perf-profile"
>
<LabeledSelect
:value="profile"
:label="t('harvester.virtualMachine.volume.performance.profile.label')"
:tooltip="t('harvester.virtualMachine.volume.performance.profile.tip')"
:options="profileOptions"
:mode="mode"
@update:value="onProfileChange"
/>
</div>
</div>
<Banner
v-if="profile === DISK_PERFORMANCE_PROFILE.HIGH"
color="info"
label-key="harvester.virtualMachine.volume.performance.highProfileTip"
/>
<!-- Always rendered, so screen readers announce these warnings when changing the fields below makes them appear
above the focused field -->
<div
role="status"
data-testid="disk-perf-warning-status"
>
<Banner
v-if="showBusTip"
color="warning"
data-testid="disk-perf-bus-tip"
:label="t('harvester.virtualMachine.volume.performance.busTip', { bus: value.bus }, true)"
/>
<Banner
v-if="showFilesystemCacheWarning"
color="warning"
label-key="harvester.virtualMachine.volume.performance.cacheMode.filesystemWarning"
/>
</div>
<template v-if="isCustom">
<div class="row mb-20">
<div
class="col span-6"
data-testid="input-disk-cache"
@@ -279,10 +269,7 @@ export default {
</div>
</div>
<div
v-if="isCustom || isView"
class="row mb-10"
>
<div class="row mb-20">
<div
class="col span-12"
data-testid="input-disk-dedicated-iothread"
@@ -296,39 +283,19 @@ export default {
/>
</div>
</div>
</template>
<!-- Always rendered, also outside Custom, so screen readers announce the tip when picking Native I/O changes
the cache mode, even if the new values switch the profile to High Performance -->
<div
role="status"
data-testid="disk-perf-native-status"
>
<Banner
v-if="isNativeIo"
color="info"
label-key="harvester.virtualMachine.volume.performance.ioMode.nativeRequiresNoCacheTip"
/>
<Banner
v-if="showFilesystemCacheWarning"
color="warning"
label-key="harvester.virtualMachine.volume.performance.cacheMode.filesystemWarning"
/>
<Banner
v-if="showBusTip"
color="warning"
label-key="harvester.virtualMachine.volume.performance.busTip"
/>
</div>
</div>
</template>
<style lang="scss" scoped>
.disk-performance {
border-top: 1px solid var(--border);
margin-top: 10px;
padding-top: 10px;
.expand-toggle {
padding: 0;
font-weight: 600;
.icon {
margin-right: 4px;
}
}
}
</style>