feat: move OS type, CPU model and system options to the VM Basics tab (#1179)

* feat: move OS type, CPU model and system options to the VM Basics tab

OS Type, CPU Model and the CPU/system checkboxes (CPU pinning, USB
tablet, TPM, EFI, Secure Boot and their persistent-state options) are
core machine settings, but they were buried at the bottom of Advanced
Options. Show them on the Basics tab, next to CPU and memory.

Install Guest Agent stays in Advanced Options because it changes the
cloud config. It now sits right below the User Data editor (the data it
modifies) through a new optional slot in the Cloud Config component.

Only the placement changes; behaviour and validation are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Alejandro Bonilla <abonilla@suse.com>

* feat: follow the review on the VM Basics layout

- Basics now reads OS Type and CPU Model, then CPU and memory, then the
  system checkboxes, the CPU Manager banner and the SSH key, in the order
  proposed in review. The checkboxes sit in one wrapper; USB Tablet drops
  its extra mt-20 and uses the plain `check` class like the others.
- Advanced Options puts Maintenance Strategy on the same row as Run
  Strategy; Reserved Memory moves to its own row.
- The moved labels leave harvester.virtualMachine.advancedOptions: TPM,
  EFI, Secure Boot and the persistent-state labels are now under
  harvester.virtualMachine.systemOptions (also used by the template
  version editor), and the CPU Manager banner text is under
  harvester.virtualMachine.cpuPinning.cpuManager.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Alejandro Bonilla <abonilla@suse.com>

* feat: match the VM template form and address review on the VM Basics layout

The VM template form still had OS Type, CPU Model and the CPU/system
checkboxes under Advanced Options, so creating a VM and creating a
template put them in different places. Use the same layout as the VM
form:

- Basics: OS Type and CPU Model, then CPU and memory, then the CPU
  Pinning, USB Tablet, TPM, EFI and Secure Boot checkboxes (plus the
  persistent-state options when they apply), then the SSH key.
- Advanced Options: Run Strategy and Maintenance Strategy on one row,
  Reserved Memory on its own row, then Show more and Cloud Config.
  Install Guest Agent sits right below the User Data editor through the
  after-user-data slot.

Review follow-ups on both forms:

- OS Type shows an info icon in create mode warning that selecting an
  image with an OS label on the Volumes tab may change the OS Type
  selection, now that OS Type comes before the volumes.
- The CPU Manager banner under CPU Pinning is info in create mode, where
  it only explains why the checkbox is disabled, and stays a warning in
  edit mode, where it is about the restart.

Only placement and presentation change; behaviour and validation are
untouched.

Signed-off-by: Alejandro Bonilla <abonilla@suse.com>

---------

Signed-off-by: Alejandro Bonilla <abonilla@suse.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alejandro Bonilla
2026-10-22 22:38:16 +08:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 2f72f25b6e
commit 39ed41e527
4 changed files with 220 additions and 209 deletions
@@ -278,6 +278,25 @@ export default {
name="Basics"
:label="t('harvester.vmTemplate.tabs.basics')"
>
<div class="row mb-20">
<div class="col span-6">
<LabeledSelect
v-model:value="osType"
label-key="harvester.virtualMachine.osType"
:mode="mode"
:options="OS"
:tooltip="isCreate ? t('harvester.virtualMachine.osTypeTooltip') : null"
/>
</div>
<div class="col span-6">
<CpuModel
:value="spec.template.spec.domain.cpu?.model || ''"
:mode="mode"
@update:value="updateCpuModel"
/>
</div>
</div>
<CpuMemory
class="mb-20"
:cpu="cpu"
@@ -289,6 +308,69 @@ export default {
@updateCpuMemory="updateCpuMemory"
/>
<div class="mb-20">
<Checkbox
v-if="value.cpuPinningFeatureEnabled"
v-model:value="cpuPinning"
class="check"
type="checkbox"
tooltip-key="harvester.virtualMachine.cpuPinning.tooltip"
label-key="harvester.virtualMachine.cpuPinning.label"
:mode="mode"
/>
<Checkbox
v-model:value="installUSBTablet"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.enableUsb')"
:mode="mode"
/>
<Checkbox
v-model:value="tpmEnabled"
class="check"
type="checkbox"
label-key="harvester.virtualMachine.systemOptions.tpm"
:mode="mode"
/>
<Checkbox
v-if="value.tpmPersistentStateFeatureEnabled && tpmEnabled"
v-model:value="tpmPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.tpmPersistentState')"
:mode="mode"
/>
<Checkbox
v-model:value="efiEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.efiEnabled')"
:mode="mode"
/>
<Checkbox
v-if="value.efiPersistentStateFeatureEnabled && efiEnabled"
v-model:value="efiPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.efiPersistentState')"
:mode="mode"
/>
<Checkbox
v-if="efiEnabled"
v-model:value="secureBoot"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.secureBoot')"
:mode="mode"
/>
</div>
<div class="mb-20">
<SSHKey
v-model:value="sshKey"
@@ -446,18 +528,6 @@ export default {
:mode="mode"
/>
</div>
<div class="col span-6">
<LabeledSelect
v-model:value="osType"
label-key="harvester.virtualMachine.osType"
:mode="mode"
:options="OS"
/>
</div>
</div>
<div class="row mb-20">
<div class="col span-6">
<LabeledSelect
v-model:value="maintenanceStrategy"
@@ -467,6 +537,9 @@ export default {
:mode="mode"
/>
</div>
</div>
<div class="row mb-20">
<div class="col span-6">
<Reserved
:reserved-memory="reservedMemory"
@@ -476,16 +549,6 @@ export default {
</div>
</div>
<div class="row mb-20">
<div class="col span-6">
<CpuModel
:value="spec.template.spec.domain.cpu?.model || ''"
:mode="mode"
@update:value="updateCpuModel"
/>
</div>
</div>
<div class="row mb-20">
<a
v-if="showAdvanced"
@@ -523,76 +586,17 @@ export default {
:network-script="networkScript"
@updateUserData="updateUserData"
@updateNetworkData="updateNetworkData"
/>
<div class="spacer"></div>
<Checkbox
v-if="value.cpuPinningFeatureEnabled"
v-model:value="cpuPinning"
class="check"
type="checkbox"
tooltip-key="harvester.virtualMachine.cpuPinning.tooltip"
label-key="harvester.virtualMachine.cpuPinning.label"
:mode="mode"
/>
<Checkbox
v-model:value="installUSBTablet"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.enableUsb')"
:mode="mode"
/>
<Checkbox
v-model:value="installAgent"
class="check"
type="checkbox"
label-key="harvester.virtualMachine.installAgent"
:mode="mode"
/>
<Checkbox
v-model:value="tpmEnabled"
class="check"
type="checkbox"
label-key="harvester.virtualMachine.advancedOptions.tpm"
:mode="mode"
/>
<Checkbox
v-if="value.tpmPersistentStateFeatureEnabled && tpmEnabled"
v-model:value="tpmPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.tpmPersistentState')"
:mode="mode"
/>
<Checkbox
v-model:value="efiEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.efiEnabled')"
:mode="mode"
/>
<Checkbox
v-if="value.efiPersistentStateFeatureEnabled && efiEnabled"
v-model:value="efiPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.efiPersistentState')"
:mode="mode"
/>
<Checkbox
v-if="efiEnabled"
v-model:value="secureBoot"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.secureBoot')"
:mode="mode"
/>
>
<template #after-user-data>
<Checkbox
v-model:value="installAgent"
class="check mb-20"
type="checkbox"
label-key="harvester.virtualMachine.installAgent"
:mode="mode"
/>
</template>
</CloudConfig>
</Tab>
</Tabbed>
</CruResource>
@@ -219,6 +219,8 @@ export default {
/>
</div>
<slot name="after-user-data" />
<div class="mb-20">
<DataTemplate
ref="networkTemplate"
@@ -742,6 +742,25 @@ export default {
name="basics"
:label="t('harvester.virtualMachine.detail.tabs.basics')"
>
<div class="row mb-20">
<div class="col span-6">
<LabeledSelect
v-model:value="osType"
label-key="harvester.virtualMachine.osType"
:options="OS"
:disabled="!isCreate"
:tooltip="isCreate ? t('harvester.virtualMachine.osTypeTooltip') : null"
/>
</div>
<div class="col span-6">
<CpuModel
v-model:value="cpuModel"
:mode="mode"
@update:value="updateCpuModel"
/>
</div>
</div>
<CpuMemory
class="mb-20"
:cpu="cpu"
@@ -753,6 +772,87 @@ export default {
@updateCpuMemory="updateCpuMemory"
/>
<div class="mb-20">
<Checkbox
v-if="value.cpuPinningFeatureEnabled"
v-model:value="cpuPinning"
:disabled="!enableCpuPinningCheckbox"
class="check"
type="checkbox"
tooltip-key="harvester.virtualMachine.cpuPinning.tooltip"
label-key="harvester.virtualMachine.cpuPinning.label"
:mode="mode"
/>
<Checkbox
v-model:value="installUSBTablet"
class="check"
type="checkbox"
tooltip-key="harvester.virtualMachine.usbTip"
label-key="harvester.virtualMachine.enableUsb"
:mode="mode"
/>
<Checkbox
v-model:value="tpmEnabled"
class="check"
type="checkbox"
label-key="harvester.virtualMachine.systemOptions.tpm"
:mode="mode"
/>
<Checkbox
v-if="value.tpmPersistentStateFeatureEnabled && tpmEnabled"
v-model:value="tpmPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.tpmPersistentState')"
:mode="mode"
/>
<Checkbox
v-model:value="efiEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.efiEnabled')"
:mode="mode"
/>
<Checkbox
v-if="value.efiPersistentStateFeatureEnabled && efiEnabled"
v-model:value="efiPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.efiPersistentState')"
:mode="mode"
/>
<Checkbox
v-if="efiEnabled"
v-model:value="secureBoot"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.systemOptions.secureBoot')"
:mode="mode"
/>
</div>
<Banner
v-if="showCpuPinningBanner"
:color="mode === 'create' ? 'info' : 'warning'"
>
<MessageLink
v-if="mode === 'create'"
:to="to"
prefix-label="harvester.virtualMachine.cpuPinning.cpuManager.prefix"
middle-label="harvester.virtualMachine.cpuPinning.cpuManager.middle"
suffix-label="harvester.virtualMachine.cpuPinning.cpuManager.suffix"
/>
<span v-if="mode==='edit'">
{{ t('harvester.virtualMachine.cpuPinning.restartVMMessage') }}
</span>
</Banner>
<SSHKey
v-model:value="sshKey"
class="mb-20"
@@ -969,18 +1069,6 @@ export default {
:mode="mode"
/>
</div>
<div class="col span-6">
<LabeledSelect
v-model:value="osType"
label-key="harvester.virtualMachine.osType"
:options="OS"
:disabled="!isCreate"
/>
</div>
</div>
<div class="row mb-20">
<div class="col span-6">
<LabeledSelect
v-model:value="maintenanceStrategy"
@@ -990,6 +1078,9 @@ export default {
:mode="mode"
/>
</div>
</div>
<div class="row mb-20">
<div class="col span-6">
<Reserved
:reserved-memory="reservedMemory"
@@ -999,16 +1090,6 @@ export default {
</div>
</div>
<div class="row mb-20">
<div class="col span-6">
<CpuModel
v-model:value="cpuModel"
:mode="mode"
@update:value="updateCpuModel"
/>
</div>
</div>
<div class="row mb-20">
<a
v-if="showAdvanced"
@@ -1075,7 +1156,19 @@ export default {
@updateUserData="updateUserData"
@updateNetworkData="updateNetworkData"
@updateDataTemplateId="updateDataTemplateId"
/>
>
<template #after-user-data>
<Checkbox
v-model:value="installAgent"
class="check mb-20"
type="checkbox"
:disabled="isWindows"
label-key="harvester.virtualMachine.installAgent"
:mode="mode"
@update:value="updateAgent"
/>
</template>
</CloudConfig>
<WindowsSysprep
v-if="isWindows"
@@ -1084,95 +1177,6 @@ export default {
:mode="mode"
:namespace="value.metadata.namespace"
/>
<Checkbox
v-if="value.cpuPinningFeatureEnabled"
v-model:value="cpuPinning"
:disabled="!enableCpuPinningCheckbox"
class="check"
type="checkbox"
tooltip-key="harvester.virtualMachine.cpuPinning.tooltip"
label-key="harvester.virtualMachine.cpuPinning.label"
:mode="mode"
/>
<Checkbox
v-model:value="installUSBTablet"
class="check mt-20"
type="checkbox"
tooltip-key="harvester.virtualMachine.usbTip"
label-key="harvester.virtualMachine.enableUsb"
:mode="mode"
/>
<Checkbox
v-model:value="installAgent"
class="check"
type="checkbox"
:disabled="isWindows"
label-key="harvester.virtualMachine.installAgent"
:mode="mode"
@update:value="updateAgent"
/>
<Checkbox
v-model:value="tpmEnabled"
class="check"
type="checkbox"
label-key="harvester.virtualMachine.advancedOptions.tpm"
:mode="mode"
/>
<Checkbox
v-if="value.tpmPersistentStateFeatureEnabled && tpmEnabled"
v-model:value="tpmPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.tpmPersistentState')"
:mode="mode"
/>
<Checkbox
v-model:value="efiEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.efiEnabled')"
:mode="mode"
/>
<Checkbox
v-if="value.efiPersistentStateFeatureEnabled && efiEnabled"
v-model:value="efiPersistentStateEnabled"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.efiPersistentState')"
:mode="mode"
/>
<Checkbox
v-if="efiEnabled"
v-model:value="secureBoot"
class="check"
type="checkbox"
:label="t('harvester.virtualMachine.advancedOptions.secureBoot')"
:mode="mode"
/>
<Banner
v-if="showCpuPinningBanner"
color="warning"
>
<MessageLink
v-if="mode === 'create'"
:to="to"
prefix-label="harvester.virtualMachine.advancedOptions.cpuManager.prefix"
middle-label="harvester.virtualMachine.advancedOptions.cpuManager.middle"
suffix-label="harvester.virtualMachine.advancedOptions.cpuManager.suffix"
/>
<span v-if="mode==='edit'">
{{ t('harvester.virtualMachine.cpuPinning.restartVMMessage') }}
</span>
</Banner>
</Tab>
</Tabbed>
+6 -5
View File
@@ -687,6 +687,7 @@ harvester:
virtualMachine:
label: Virtual Machines
osType: OS Type
osTypeTooltip: Selecting an image with an OS label on the Volumes tab may change the OS Type selection.
cpuModel:
label: CPU Model
fetchError: 'Failed to load CPU model configuration: {error}'
@@ -758,6 +759,10 @@ harvester:
tooltip: Enable CPU Pinning brings better performance and reduce latency for the virtual machine
restartVMMessage: Changing the CPU Pinning setting requires a virtual machine reboot for the change to take effect
migrationMessage: This virtual machine can only be migrated to a target node that has CPU Manager enabled, as CPU Pinning is configured.
cpuManager:
prefix: You must enable CPU Manager for at least one node in
middle: 'host page'
suffix: to enable CPU Pinning for VM
restartNow: |-
{restart, select,
true {Restart}
@@ -767,13 +772,9 @@ harvester:
genericLoginError: Authentication failed. Please re-log in and try again.
installAgent: Install guest agent
enableUsb: Enable USB Tablet
advancedOptions:
systemOptions:
tpm: Enable TPM
tpmPersistentState: TPM Persistent State
cpuManager:
prefix: You must enable CPU Manager for at least one node in
middle: 'host page'
suffix: to enable CPU Pinning for VM
efiEnabled: Booting in EFI mode
efiPersistentState: EFI Persistent State
secureBoot: Secure Boot