feat: Unattend.xml support for Windows (#954)

Documentation: https://kubevirt.io/user-guide/user_workloads/startup_scripts/#sysprep
Related to: https://github.com/harvester/harvester/issues/1836

Signed-off-by: Volker Theile <vtheile@suse.com>
This commit is contained in:
Volker Theile
2026-07-06 08:45:33 +02:00
committed by GitHub
parent 479c298f4a
commit 495e80267d
6 changed files with 493 additions and 3 deletions
@@ -29,6 +29,7 @@ import RestartVMDialog from '../../dialog/RestartVMDialog';
import PciDevices from './VirtualMachinePciDevices/index';
import AccessCredentials from './VirtualMachineAccessCredentials';
import CloudConfig from './VirtualMachineCloudConfig';
import WindowsSysprep from './VirtualMachineWindowsSysprep';
import CpuMemory from './VirtualMachineCpuMemory';
import CpuModel from './VirtualMachineCpuModel';
import Network from './VirtualMachineNetwork';
@@ -59,6 +60,7 @@ export default {
CpuMemory,
CpuModel,
CloudConfig,
WindowsSysprep,
NodeScheduling,
PodAffinity,
AccessCredentials,
@@ -324,6 +326,10 @@ export default {
try {
await this.saveSecret(res);
await this.saveAccessCredentials(res);
if (this.isWindows) {
await this.saveSysprepConfig(res);
}
} catch (e) {
this.errors.push(...exceptionToErrorsArray(e));
}
@@ -369,6 +375,7 @@ export default {
clear(this.errors);
this.validateCPUMemory();
this.validateWindowsSysprep();
// block create VM flow if has validation errors
if (this.errors.length) {
@@ -396,6 +403,24 @@ export default {
}
},
validateWindowsSysprep() {
if (!this.isWindows) {
return;
}
if (this.sysprep?.secretName?.trim?.() && !this.sysprep?.xmlContent?.trim?.()) {
this.errors.push(this.t('validation.required', { key: this.t('harvester.virtualMachine.sysprep.xmlContent') }, true));
return;
}
const sysprepValidationError = this.$refs.sysprepConfig?.xmlContentValidationError;
if (sysprepValidationError) {
this.errors.push(sysprepValidationError);
}
},
async saveSingle(buttonCb) {
this.parseVM();
this.value.spec.template.spec.hostname = this.hostname ? this.hostname : this.value.metadata.name;
@@ -546,6 +571,7 @@ export default {
onTabChanged({ tab }) {
if (tab.name === 'advanced') {
this.$refs.yamlEditor?.refresh();
this.$refs.sysprepConfig?.refresh();
}
},
@@ -1019,11 +1045,11 @@ export default {
</div>
<CloudConfig
v-if="!isWindows"
ref="yamlEditor"
:user-script="userScript"
:mode="mode"
:os-type="osType"
:view-code="isWindows"
:namespace="value.metadata.namespace"
:network-script="networkScript"
@updateUserData="updateUserData"
@@ -1031,6 +1057,14 @@ export default {
@updateDataTemplateId="updateDataTemplateId"
/>
<WindowsSysprep
v-if="isWindows"
ref="sysprepConfig"
v-model:value="sysprep"
:mode="mode"
:namespace="value.metadata.namespace"
/>
<Checkbox
v-if="value.cpuPinningFeatureEnabled"
v-model:value="cpuPinning"