From cf2c6bc15f138f9621b2135054a7136f84564d9e Mon Sep 17 00:00:00 2001 From: Kirill Ilin Date: Tue, 10 Feb 2026 13:00:33 +0500 Subject: [PATCH 1/2] [vm] allow switching between instancetype and custom resources Implemented by upgrade hook atomically patching VM resource Signed-off-by: Kirill Ilin --- .../virtual-machine/templates/_helpers.tpl | 23 ++++++++++++++ .../templates/vm-update-hook.yaml | 31 +++++++++++++++++-- .../apps/virtual-machine/templates/vm.yaml | 13 +++----- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/packages/apps/virtual-machine/templates/_helpers.tpl b/packages/apps/virtual-machine/templates/_helpers.tpl index e65cad9db..ddea90feb 100644 --- a/packages/apps/virtual-machine/templates/_helpers.tpl +++ b/packages/apps/virtual-machine/templates/_helpers.tpl @@ -70,6 +70,29 @@ Generate a stable UUID for cloud-init re-initialization upon upgrade. {{- $uuid }} {{- end }} +{{/* +Domain resources (cpu, memory) as a JSON object. +Used in vm.yaml for rendering and in the update hook for merge patches. +*/}} +{{- define "virtual-machine.domainResources" -}} +{{- $result := dict -}} +{{- if or .Values.cpuModel (and .Values.resources .Values.resources.cpu .Values.resources.sockets) -}} + {{- $cpu := dict -}} + {{- if and .Values.resources .Values.resources.cpu .Values.resources.sockets -}} + {{- $_ := set $cpu "cores" (.Values.resources.cpu | int64) -}} + {{- $_ := set $cpu "sockets" (.Values.resources.sockets | int64) -}} + {{- end -}} + {{- if .Values.cpuModel -}} + {{- $_ := set $cpu "model" .Values.cpuModel -}} + {{- end -}} + {{- $_ := set $result "cpu" $cpu -}} +{{- end -}} +{{- if and .Values.resources .Values.resources.memory -}} + {{- $_ := set $result "resources" (dict "requests" (dict "memory" .Values.resources.memory)) -}} +{{- end -}} +{{- $result | toJson -}} +{{- end -}} + {{/* Node Affinity for Windows VMs */}} diff --git a/packages/apps/virtual-machine/templates/vm-update-hook.yaml b/packages/apps/virtual-machine/templates/vm-update-hook.yaml index 3c7d7d341..b12231509 100644 --- a/packages/apps/virtual-machine/templates/vm-update-hook.yaml +++ b/packages/apps/virtual-machine/templates/vm-update-hook.yaml @@ -14,14 +14,25 @@ {{- $needUpdateProfile := false -}} {{- $needResizePVC := false -}} {{- $needRecreateService := false -}} +{{- $needRemoveInstanceType := false -}} +{{- $needRemoveCustomResources := false -}} -{{- if and $existingVM $instanceType -}} +{{- $existingHasInstanceType := false -}} +{{- if and $existingVM $existingVM.spec.instancetype -}} + {{- $existingHasInstanceType = true -}} +{{- end -}} + +{{- if and $existingHasInstanceType (not $instanceType) -}} + {{- $needRemoveInstanceType = true -}} +{{- else if and $existingHasInstanceType $instanceType -}} {{- if not (eq $existingVM.spec.instancetype.name $instanceType) -}} {{- $needUpdateType = true -}} {{- end -}} +{{- else if and $existingVM (not $existingHasInstanceType) $instanceType -}} + {{- $needRemoveCustomResources = true -}} {{- end -}} -{{- if and $existingVM $instanceProfile -}} +{{- if and $existingVM $existingVM.spec.preference $instanceProfile -}} {{- if not (eq $existingVM.spec.preference.name $instanceProfile) -}} {{- $needUpdateProfile = true -}} {{- end -}} @@ -45,7 +56,7 @@ {{- end -}} {{- end -}} -{{- if or $needUpdateType $needUpdateProfile $needResizePVC $needRecreateService }} +{{- if or $needUpdateType $needUpdateProfile $needResizePVC $needRecreateService $needRemoveInstanceType $needRemoveCustomResources }} apiVersion: batch/v1 kind: Job metadata: @@ -90,6 +101,20 @@ spec: -p '{"spec":{"preference":{"name": "{{ $instanceProfile }}", "revisionName": null}}}' {{- end }} + {{- if $needRemoveInstanceType }} + echo "Removing instancetype from VM (switching to custom resources)..." + kubectl patch virtualmachines.kubevirt.io {{ $vmName }} -n {{ $namespace }} \ + --type merge \ + -p '{"spec":{"instancetype":null{{- if not $instanceProfile }},"preference":null{{- end }},"template":{"spec":{"domain":{{ include "virtual-machine.domainResources" . }}}}}}' + {{- end }} + + {{- if $needRemoveCustomResources }} + echo "Removing custom CPU/memory from domain (switching to instancetype)..." + kubectl patch virtualmachines.kubevirt.io {{ $vmName }} -n {{ $namespace }} \ + --type merge \ + -p '{"spec":{"instancetype":{"name":"{{ $instanceType }}","revisionName":null},"template":{"spec":{"domain":{"cpu":null,"resources":null}}}}}' + {{- end }} + {{- if $needResizePVC }} echo "Patching PVC for storage resize..." kubectl patch pvc {{ $vmName }} -n {{ $namespace }} \ diff --git a/packages/apps/virtual-machine/templates/vm.yaml b/packages/apps/virtual-machine/templates/vm.yaml index 1a2e7a30c..35f0dae92 100644 --- a/packages/apps/virtual-machine/templates/vm.yaml +++ b/packages/apps/virtual-machine/templates/vm.yaml @@ -71,15 +71,12 @@ spec: {{- include "virtual-machine.labels" . | nindent 8 }} spec: domain: - {{- if and .Values.resources .Values.resources.cpu .Values.resources.sockets }} - cpu: - cores: {{ .Values.resources.cpu }} - sockets: {{ .Values.resources.sockets }} + {{- $domainRes := include "virtual-machine.domainResources" . | fromJson -}} + {{- with $domainRes.cpu }} + cpu: {{- . | toYaml | nindent 10 }} {{- end }} - {{- if and .Values.resources .Values.resources.memory }} - resources: - requests: - memory: {{ .Values.resources.memory | quote }} + {{- with $domainRes.resources }} + resources: {{- . | toYaml | nindent 10 }} {{- end }} firmware: uuid: {{ include "virtual-machine.stableUuid" . }} From 13d848efc3530407cf9c66c1247223e85b9b7d16 Mon Sep 17 00:00:00 2001 From: Kirill Ilin Date: Tue, 10 Feb 2026 13:36:49 +0500 Subject: [PATCH 2/2] [vm] add validation for resources Signed-off-by: Kirill Ilin --- packages/apps/virtual-machine/templates/vm-update-hook.yaml | 6 +----- packages/apps/virtual-machine/templates/vm.yaml | 3 +++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/apps/virtual-machine/templates/vm-update-hook.yaml b/packages/apps/virtual-machine/templates/vm-update-hook.yaml index b12231509..65ee02f01 100644 --- a/packages/apps/virtual-machine/templates/vm-update-hook.yaml +++ b/packages/apps/virtual-machine/templates/vm-update-hook.yaml @@ -17,11 +17,7 @@ {{- $needRemoveInstanceType := false -}} {{- $needRemoveCustomResources := false -}} -{{- $existingHasInstanceType := false -}} -{{- if and $existingVM $existingVM.spec.instancetype -}} - {{- $existingHasInstanceType = true -}} -{{- end -}} - +{{- $existingHasInstanceType := and $existingVM $existingVM.spec.instancetype -}} {{- if and $existingHasInstanceType (not $instanceType) -}} {{- $needRemoveInstanceType = true -}} {{- else if and $existingHasInstanceType $instanceType -}} diff --git a/packages/apps/virtual-machine/templates/vm.yaml b/packages/apps/virtual-machine/templates/vm.yaml index 35f0dae92..c1b673440 100644 --- a/packages/apps/virtual-machine/templates/vm.yaml +++ b/packages/apps/virtual-machine/templates/vm.yaml @@ -4,6 +4,9 @@ {{- if and .Values.instanceProfile (not (lookup "instancetype.kubevirt.io/v1beta1" "VirtualMachineClusterPreference" "" .Values.instanceProfile)) }} {{- fail (printf "Specified profile not exists in cluster: %s" .Values.instanceProfile) }} {{- end }} +{{- if and (not .Values.instanceType) (not (and .Values.resources .Values.resources.cpu .Values.resources.sockets .Values.resources.memory)) }} +{{- fail "Either instanceType or resources (cpu, sockets, memory) must be specified" }} +{{- end }} apiVersion: kubevirt.io/v1 kind: VirtualMachine