feat: support network boot (PXE) for VM interfaces (#1176)

Add an "Enable network boot (PXE)" option to bridge network interfaces and
a VM-level choice to place network boot devices before or after volumes.
The form now owns interface boot order: enabled NICs get sequential boot
orders ahead of or behind the volumes, and a stale bootOrder is no longer
inherited from the old spec.

This also fixes editing a VM whose interface bootOrder was set in YAML
(the documented workaround): the form used to renumber disks from 1 while
keeping the NIC's bootOrder, producing a duplicate that KubeVirt rejects.

The boot order shown on the VM, snapshot and backup detail pages now
includes network interfaces.

Related: harvester/harvester#3325

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-07 11:21:27 +08:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 528255dea4
commit 5af181f5b6
11 changed files with 141 additions and 51 deletions
@@ -2,6 +2,7 @@
import InputOrDisplay from '@shell/components/InputOrDisplay';
import { LabeledInput } from '@components/Form/LabeledInput';
import LabeledSelect from '@shell/components/form/LabeledSelect';
import { Checkbox } from '@components/Form/Checkbox';
import { clone } from '@shell/utils/object';
import { _CREATE, _VIEW } from '@shell/config/query-params';
@@ -33,7 +34,7 @@ export default {
emits: ['update'],
components: {
LabeledInput, LabeledSelect, InputOrDisplay
LabeledInput, LabeledSelect, InputOrDisplay, Checkbox
},
props: {
@@ -169,6 +170,7 @@ export default {
this.value.isPod = true;
this.value.macAddress = '';
this.value.staticIp = '';
this.value.networkBoot = false;
} else {
this.value.isPod = false;
}
@@ -285,6 +287,22 @@ export default {
</div>
</div>
<div
v-if="!isMasquerade"
data-testid="input-hen-networkBoot"
class="row mb-20"
>
<div class="col span-12">
<Checkbox
v-model:value="value.networkBoot"
:label="t('harvester.virtualMachine.network.networkBoot.label')"
:tooltip="t('harvester.virtualMachine.network.networkBoot.tip')"
:mode="mode"
@update:value="update"
/>
</div>
</div>
<div v-if="!isMasquerade && isSingle">
<div class="row mb-20">
<a