From 18b2cb8ccf140d51ac0d20b253704746b7b1fd47 Mon Sep 17 00:00:00 2001
From: Raphael Dannecker <raphael.dannecker@steinbeisschule-reutlingen.de>
Date: Thu, 27 Feb 2025 19:21:49 +0100
Subject: [PATCH] Add TPM support for win11 VMs

---
 roles/lmn_vm/files/vm-run    | 27 ++++++++++++++++++++++++---
 roles/lmn_vm/files/vm-upload |  8 ++++++++
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/roles/lmn_vm/files/vm-run b/roles/lmn_vm/files/vm-run
index 1e29ab6..c5c0ec9 100755
--- a/roles/lmn_vm/files/vm-run
+++ b/roles/lmn_vm/files/vm-run
@@ -34,8 +34,8 @@ exit_script() {
 }
 
 check_images() {
-   # sync vm-torrents and machine definition file
-   sudo -u lmnsynci /usr/local/bin/vm-sync get_file "${VM_NAME}.qcow2.torrent"
+   # sync vm-torrent and TPM data
+   sudo -u lmnsynci /usr/local/bin/vm-sync get_file "${VM_NAME}.qcow2.torrent" "${VM_NAME}.permall"
    [[ -f "${VM_SYSDIR}/${VM_NAME}.qcow2" ]] && sudo -u lmnsynci /usr/local/bin/vm-sync delete_outdated_image "${VM_NAME}.qcow2"
 
    BACKINGARRAY=()
@@ -106,6 +106,17 @@ create_clone() {
     cd "${VM_DIR}"
     qemu-img create -f qcow2 -F qcow2 -b "${VM_NAME}.qcow2" "${VM_NAME}-clone.qcow2"
 
+    if [[ -f "${VM_SYSDIR}/${VM_NAME}.permall" ]]; then
+      # Copy tpm file
+      if [[ ! -f "${VM_NAME}.permall" ]]; then
+        echo "copy tpm-file"
+        cp "${VM_SYSDIR}/${VM_NAME}.permall" .
+      fi
+      # create tpm-clone file
+      echo "create tpm-clone-file"
+      cp "${VM_NAME}.permall" "${VM_NAME}-clone.permall"
+    fi
+
 }
 
 create_printerlist() {
@@ -307,7 +318,7 @@ if  ! virsh --connect="${QEMU}" list | grep "${VM_NAME}-clone"; then
         create_clone "${VM_NAME}"
     fi
     # delete the old vm
-    virsh --connect=qemu:///session undefine "${VM_NAME}-clone" || echo "${VM_NAME}-clone did not exist"
+    virsh --connect=qemu:///session undefine --nvram "${VM_NAME}-clone" || echo "${VM_NAME}-clone did not exist"
     #trap exit_script SIGHUP SIGINT SIGTERM
 
     create_printerlist
@@ -316,9 +327,19 @@ if  ! virsh --connect="${QEMU}" list | grep "${VM_NAME}-clone"; then
     # start virtiofsd-service
     [[ "${QEMU}" = 'qemu:///session' ]] && start_virtiofsd
 
+    uuid=$(openssl rand -hex 16)
+    uuid="${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}"
+
+    if [[ -f "${VM_DIR}/${VM_NAME}-clone.permall" ]]; then
+      mkdir -p "/var/tmp/vm/${UID}/.config/libvirt/qemu/swtpm/${uuid}/tpm2/"
+      ln "${VM_DIR}/${VM_NAME}-clone.permall" "/var/tmp/vm/${UID}/.config/libvirt/qemu/swtpm/${uuid}/tpm2/tpm2-00.permall"
+      LIBVIRTOPTS="${LIBVIRTOPTS} --tpm backend.type=emulator,backend.version=2.0,model=tpm-crb "
+    fi
+
     # finally, create the new vm
 
     virt-install \
+	     --uuid="${uuid}" \
              --osinfo "${LIBVIRTOSINFO}" \
 	     --name "${VM_NAME}-clone" \
 	     --import \
diff --git a/roles/lmn_vm/files/vm-upload b/roles/lmn_vm/files/vm-upload
index 1fbdda3..32900d9 100755
--- a/roles/lmn_vm/files/vm-upload
+++ b/roles/lmn_vm/files/vm-upload
@@ -24,6 +24,10 @@ upload_image() {
       echo "copy private VM-Diskimage to system-dir"
       chown lmnsynci:lmnsynci "${VM_DIR}/${VM_NAME}.qcow2"
       ln -f "${VM_DIR}/${VM_NAME}.qcow2" "${VM_SYSDIR}/${VM_NAME}.qcow2"
+      if [[ -f "${VM_DIR}/${VM_NAME}.permall" ]]; then
+        cp "${VM_DIR}/${VM_NAME}.permall" "${VM_SYSDIR}/${VM_NAME}.permall"
+        chown lmnsynci:lmnsynci "${VM_SYSDIR}/${VM_NAME}.permall"
+      fi
     fi
     cd "${VM_SYSDIR}"
     if [[ -f "/tmp/${VM_NAME}.qcow2.torrent" ]]; then
@@ -31,6 +35,10 @@ upload_image() {
     fi
     uploadseed --server "${SEEDBOX_HOST}:${SEEDBOX_RPC_PORT}" --dht-port "${SEEDBOX_PORT}" \
 	       --pwdfile "${SEEDBOX_PWFILE}" --no-cert "${VM_NAME}.qcow2"
+    if [[ -f "${VM_SYSDIR}/${VM_NAME}.permall" ]]; then
+      uploadseed --server "${SEEDBOX_HOST}:${SEEDBOX_RPC_PORT}" --dht-port "${SEEDBOX_PORT}" \
+	       --pwdfile "${SEEDBOX_PWFILE}" --no-cert "${VM_NAME}.permall"
+    fi
 }
 
 source /etc/lmn/vm.conf