diff --git a/packages/apps/virtual-machine/README.md b/packages/apps/virtual-machine/README.md index 305ec727..14593edc 100644 --- a/packages/apps/virtual-machine/README.md +++ b/packages/apps/virtual-machine/README.md @@ -53,6 +53,7 @@ virtctl ssh @ | `sshKeys` | List of SSH public keys for authentication. Can be a single key or a list of keys. | `[]` | | `cloudInit` | cloud-init user data config. See cloud-init documentation for more details. | `#cloud-config ` | +| `cloudInitSeed` | A seed string to generate an SMBIOS UUID for the VM. | `""` | ## U Series diff --git a/packages/apps/virtual-machine/templates/_helpers.tpl b/packages/apps/virtual-machine/templates/_helpers.tpl index 671b8934..f3ade695 100644 --- a/packages/apps/virtual-machine/templates/_helpers.tpl +++ b/packages/apps/virtual-machine/templates/_helpers.tpl @@ -49,3 +49,23 @@ Selector labels app.kubernetes.io/name: {{ include "virtual-machine.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} + +{{/* +Generate a stable UUID for cloud-init re-initialization upon upgrade. +*/}} +{{- define "virtual-machine.stableUuid" -}} +{{- $source := printf "%s-%s-%s" .Release.Namespace (include "virtual-machine.fullname" .) .Values.cloudInitSeed }} +{{- $hash := sha256sum $source }} +{{- $uuid := printf "%s-%s-4%s-9%s-%s" (substr 0 8 $hash) (substr 8 12 $hash) (substr 13 16 $hash) (substr 17 20 $hash) (substr 20 32 $hash) }} +{{- if eq .Values.cloudInitSeed "" }} + {{- /* Try to save previous uuid to not trigger full cloud-init again if user decided to remove the seed. */}} + {{- $vmResource := lookup "kubevirt.io/v1" "VirtualMachine" .Release.Namespace (include "virtual-machine.fullname" .) -}} + {{- if $vmResource }} + {{- $existingUuid := $vmResource | dig "spec" "template" "spec" "domain" "firmware" "uuid" "" }} + {{- if $existingUuid }} + {{- $uuid = $existingUuid }} + {{- end }} + {{- end }} +{{- end }} +{{- $uuid }} +{{- end }} diff --git a/packages/apps/virtual-machine/templates/vm.yaml b/packages/apps/virtual-machine/templates/vm.yaml index 6cb0aa8b..3681abd8 100644 --- a/packages/apps/virtual-machine/templates/vm.yaml +++ b/packages/apps/virtual-machine/templates/vm.yaml @@ -68,6 +68,8 @@ spec: requests: memory: {{ .Values.resources.memory | quote }} {{- end }} + firmware: + uuid: {{ include "virtual-machine.stableUuid" . }} devices: {{- if .Values.gpus }} gpus: diff --git a/packages/apps/virtual-machine/values.schema.json b/packages/apps/virtual-machine/values.schema.json index ed81bc0a..b94e5f6a 100644 --- a/packages/apps/virtual-machine/values.schema.json +++ b/packages/apps/virtual-machine/values.schema.json @@ -199,6 +199,11 @@ "type": "string", "description": "cloud-init user data config. See cloud-init documentation for more details.", "default": "#cloud-config\n" + }, + "cloudInitSeed": { + "type": "string", + "description": "A seed string to generate an SMBIOS UUID for the VM.", + "default": "" } } } diff --git a/packages/apps/virtual-machine/values.yaml b/packages/apps/virtual-machine/values.yaml index fb7eef3e..78b845db 100644 --- a/packages/apps/virtual-machine/values.yaml +++ b/packages/apps/virtual-machine/values.yaml @@ -57,3 +57,12 @@ sshKeys: [] ## cloudInit: | #cloud-config + +## @param cloudInitSeed A seed string to generate an SMBIOS UUID for the VM. +cloudInitSeed: "" +## Change it to any new value to force a full cloud-init reconfiguration. Change it when you want to apply +## to an existing VM settings that are usually written only once, like new SSH keys or new network configuration. +## An empty value does nothing (and the existing UUID is not reverted). Please note that changing this value +## does not trigger a VM restart. You must perform the restart separately. +## Example: +## cloudInitSeed: "upd1" diff --git a/packages/apps/vm-instance/README.md b/packages/apps/vm-instance/README.md index 42ecec5f..031bec7c 100644 --- a/packages/apps/vm-instance/README.md +++ b/packages/apps/vm-instance/README.md @@ -51,6 +51,7 @@ virtctl ssh @ | `sshKeys` | List of SSH public keys for authentication. Can be a single key or a list of keys. | `[]` | | `cloudInit` | cloud-init user data config. See cloud-init documentation for more details. | `#cloud-config ` | +| `cloudInitSeed` | A seed string to generate an SMBIOS UUID for the VM. | `""` | ## U Series diff --git a/packages/apps/vm-instance/templates/_helpers.tpl b/packages/apps/vm-instance/templates/_helpers.tpl index 671b8934..f3ade695 100644 --- a/packages/apps/vm-instance/templates/_helpers.tpl +++ b/packages/apps/vm-instance/templates/_helpers.tpl @@ -49,3 +49,23 @@ Selector labels app.kubernetes.io/name: {{ include "virtual-machine.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} + +{{/* +Generate a stable UUID for cloud-init re-initialization upon upgrade. +*/}} +{{- define "virtual-machine.stableUuid" -}} +{{- $source := printf "%s-%s-%s" .Release.Namespace (include "virtual-machine.fullname" .) .Values.cloudInitSeed }} +{{- $hash := sha256sum $source }} +{{- $uuid := printf "%s-%s-4%s-9%s-%s" (substr 0 8 $hash) (substr 8 12 $hash) (substr 13 16 $hash) (substr 17 20 $hash) (substr 20 32 $hash) }} +{{- if eq .Values.cloudInitSeed "" }} + {{- /* Try to save previous uuid to not trigger full cloud-init again if user decided to remove the seed. */}} + {{- $vmResource := lookup "kubevirt.io/v1" "VirtualMachine" .Release.Namespace (include "virtual-machine.fullname" .) -}} + {{- if $vmResource }} + {{- $existingUuid := $vmResource | dig "spec" "template" "spec" "domain" "firmware" "uuid" "" }} + {{- if $existingUuid }} + {{- $uuid = $existingUuid }} + {{- end }} + {{- end }} +{{- end }} +{{- $uuid }} +{{- end }} diff --git a/packages/apps/vm-instance/templates/vm.yaml b/packages/apps/vm-instance/templates/vm.yaml index bd73807a..30e8cd18 100644 --- a/packages/apps/vm-instance/templates/vm.yaml +++ b/packages/apps/vm-instance/templates/vm.yaml @@ -40,6 +40,8 @@ spec: requests: memory: {{ .Values.resources.memory | quote }} {{- end }} + firmware: + uuid: {{ include "virtual-machine.stableUuid" . }} devices: {{- if .Values.gpus }} gpus: diff --git a/packages/apps/vm-instance/values.schema.json b/packages/apps/vm-instance/values.schema.json index d289ef76..1edfaa66 100644 --- a/packages/apps/vm-instance/values.schema.json +++ b/packages/apps/vm-instance/values.schema.json @@ -180,6 +180,11 @@ "type": "string", "description": "cloud-init user data config. See cloud-init documentation for more details.", "default": "#cloud-config\n" + }, + "cloudInitSeed": { + "type": "string", + "description": "A seed string to generate an SMBIOS UUID for the VM.", + "default": "" } } } diff --git a/packages/apps/vm-instance/values.yaml b/packages/apps/vm-instance/values.yaml index 245558c9..26edf59c 100644 --- a/packages/apps/vm-instance/values.yaml +++ b/packages/apps/vm-instance/values.yaml @@ -55,3 +55,12 @@ sshKeys: [] ## cloudInit: | #cloud-config + +## @param cloudInitSeed A seed string to generate an SMBIOS UUID for the VM. +cloudInitSeed: "" +## Change it to any new value to force a full cloud-init reconfiguration. Change it when you want to apply +## to an existing VM settings that are usually written only once, like new SSH keys or new network configuration. +## An empty value does nothing (and the existing UUID is not reverted). Please note that changing this value +## does not trigger a VM restart. You must perform the restart separately. +## Example: +## cloudInitSeed: "upd1"