fix: retry VM start without TPM when swtpm fails

VM creation would fail entirely if swtpm_setup failed at VM start time,
even though TPM is only needed for Secure Boot enforcement and disk
encryption during installation - not for live ISO boot testing.

Now vm_create() retries without TPM if the initial start fails with TPM
enabled. The VM is undefined, redefined with an empty TPM section, and
started again. This makes boot testing resilient to swtpm breakage in
environments where swtpm_setup can't initialize (permission issues,
missing deps, nested VMs).

💘 Generated with Crush

Assisted-by: GLM-4.7 via Crush <crush@charm.land>
This commit is contained in:
2026-07-30 13:12:58 -05:00
parent 82ad3a1b6d
commit 7ac52a09dc
+36 -18
View File
@@ -201,10 +201,10 @@ vm_create() {
# Detect KVM acceleration; fall back to QEMU software emulation # Detect KVM acceleration; fall back to QEMU software emulation
local domain_type="qemu" local domain_type="qemu"
local cpu_mode="qemu64" local cpu_element="<cpu mode='custom' match='exact' check='none'><model>qemu64</model></cpu>"
if [[ -e /dev/kvm ]]; then if [[ -e /dev/kvm ]]; then
domain_type="kvm" domain_type="kvm"
cpu_mode="host-passthrough" cpu_element="<cpu mode='host-passthrough' check='none'/>"
log_info "KVM acceleration enabled" log_info "KVM acceleration enabled"
else else
log_warn "KVM not available (/dev/kvm missing) - using QEMU software emulation" log_warn "KVM not available (/dev/kvm missing) - using QEMU software emulation"
@@ -218,7 +218,7 @@ vm_create() {
-e "s|@VM_RAM@|${VM_RAM}|g" \ -e "s|@VM_RAM@|${VM_RAM}|g" \
-e "s|@VM_CPUS@|${VM_CPUS}|g" \ -e "s|@VM_CPUS@|${VM_CPUS}|g" \
-e "s|@DOMAIN_TYPE@|${domain_type}|g" \ -e "s|@DOMAIN_TYPE@|${domain_type}|g" \
-e "s|@CPU_MODE@|${cpu_mode}|g" \ -e "s|@CPU_ELEMENT@|${cpu_element}|g" \
-e "s|@SECURE_BOOT@|${secure_boot}|g" \ -e "s|@SECURE_BOOT@|${secure_boot}|g" \
-e "s|@UEFI_CODE@|${uefi_code}|g" \ -e "s|@UEFI_CODE@|${uefi_code}|g" \
-e "s|@UEFI_VARS_TEMPLATE@|${uefi_vars}|g" \ -e "s|@UEFI_VARS_TEMPLATE@|${uefi_vars}|g" \
@@ -239,23 +239,41 @@ vm_create() {
# Start the VM # Start the VM
log_info "Starting VM..." log_info "Starting VM..."
if ! virsh -c "$LIBVIRT_URI" start "$VM_NAME"; then if ! virsh -c "$LIBVIRT_URI" start "$VM_NAME"; then
# Check if failure was due to swtpm permissions # If TPM was enabled, retry without it (swtpm may be broken)
if [[ -n "$tpm_section" && "$LIBVIRT_URI" == *"system"* ]]; then if [[ -n "$tpm_section" ]]; then
local vm_uuid log_warn "VM start failed with TPM - retrying without TPM..."
vm_uuid=$(virsh -c "$LIBVIRT_URI" dominfo "$VM_NAME" 2>/dev/null | grep "UUID:" | awk '{print $2}') log_warn "Live ISO boot testing does not require TPM."
local swtpm_vm_dir="/var/lib/libvirt/swtpm/${vm_uuid}" virsh -c "$LIBVIRT_URI" undefine "$VM_NAME" --nvram 2>/dev/null || true
if [[ -d "$swtpm_vm_dir" ]]; then
log_error "TPM initialization failed - swtpm permission issue" # Regenerate XML without TPM section
log_error "Libvirt creates per-VM swtpm state dirs as root:root." sed -e "s|@VM_NAME@|${VM_NAME}|g" \
log_error "Permanent fix (run once with sudo):" -e "s|@VM_UUID@|${vm_uuid}|g" \
log_error " sudo bash ${SCRIPT_DIR}/scripts/fix-swtpm-permissions.sh" -e "s|@VM_RAM@|${VM_RAM}|g" \
log_error "Then retry: ./run.sh test:iso destroy && ./run.sh test:iso create" -e "s|@VM_CPUS@|${VM_CPUS}|g" \
# Undefine so user can retry after fixing -e "s|@DOMAIN_TYPE@|${domain_type}|g" \
virsh -c "$LIBVIRT_URI" undefine "$VM_NAME" --nvram 2>/dev/null || true -e "s|@CPU_ELEMENT@|${cpu_element}|g" \
-e "s|@SECURE_BOOT@|${secure_boot}|g" \
-e "s|@UEFI_CODE@|${uefi_code}|g" \
-e "s|@UEFI_VARS_TEMPLATE@|${uefi_vars}|g" \
-e "s|@VM_DISK@|${vm_disk_path}|g" \
-e "s|@ISO_PATH@|${vm_iso_path}|g" \
-e "s|@TPM_SECTION@||g" \
"$template" > "$vm_xml"
if ! virsh -c "$LIBVIRT_URI" define "$vm_xml"; then
log_error "Failed to redefine VM without TPM"
cat "$vm_xml"
return 1
fi fi
if ! virsh -c "$LIBVIRT_URI" start "$VM_NAME"; then
log_error "Failed to start VM (with and without TPM)"
return 1
fi
else
log_error "Failed to start VM"
return 1
fi fi
log_error "Failed to start VM"
return 1
fi fi
# Verify VM is running # Verify VM is running