[vm] allow switching between instancetype and custom resources (#2008)

Implemented by upgrade hook atomically patching VM resource

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does

Allow switching between `instancetype` and custom resources for VM

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[vm] allow switching between instancetype and custom resources
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Improved virtual machine resource configuration with more flexible CPU
and memory management
* Added support for transitioning between instancetype and custom
resource configurations
* Enhanced VM update process to automatically detect and handle
resource-related changes, including removal of outdated configurations

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Andrei Kvapil authored and GitHub committed 2026-02-10 12:20:38 +01:00
commit ec86a03d40
3 files changed
+55 -11

No files matched your search

@@ -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
*/}}
@@ -14,14 +14,21 @@
{{- $needUpdateProfile := false -}}
{{- $needResizePVC := false -}}
{{- $needRecreateService := false -}}
{{- $needRemoveInstanceType := false -}}
{{- $needRemoveCustomResources := false -}}
{{- if and $existingVM $instanceType -}}
{{- $existingHasInstanceType := and $existingVM $existingVM.spec.instancetype -}}
{{- 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 +52,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 +97,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 }} \
@@ -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
@@ -71,15 +74,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" . }}