fix: use libvirt session URI consistently, remove QEMU fallback
- All virsh commands now use qemu:///session explicitly - Removed direct QEMU fallback (libvirt only) - Added VM XML template in vm/template.xml with variable substitution - Template generates UUID and MAC address dynamically - VM is now properly defined AND started in libvirt - Fixed vm_destroy, vm_console, vm_status, vm_is_running, vm_capture_screen - Added UUID fallback using /proc/sys/kernel/random/uuid Fixes issue where VMs were created but not visible/running in virt-manager. 💘 Generated with Crush Assisted-by: GLM-5 via Crush <crush@charm.land>
This commit is contained in:
160
run.sh
160
run.sh
@@ -86,19 +86,22 @@ vm_create_disk() {
|
||||
|
||||
# Create and start VM
|
||||
vm_create() {
|
||||
log_info "Creating VM: $VM_NAME"
|
||||
|
||||
# Destroy existing VM if present
|
||||
virsh destroy "$VM_NAME" 2>/dev/null || true
|
||||
virsh undefine "$VM_NAME" 2>/dev/null || true
|
||||
|
||||
# Define libvirt session URI (use session for user-mode, avoids sudo)
|
||||
local LIBVIRT_URI="qemu:///session"
|
||||
|
||||
log_info "Creating VM: $VM_NAME (libvirt: $LIBVIRT_URI)"
|
||||
|
||||
# Destroy existing VM if present (in session libvirt)
|
||||
virsh -c "$LIBVIRT_URI" destroy "$VM_NAME" 2>/dev/null || true
|
||||
virsh -c "$LIBVIRT_URI" undefine "$VM_NAME" --nvram 2>/dev/null || true
|
||||
|
||||
# Create disk
|
||||
vm_create_disk
|
||||
|
||||
|
||||
# Find UEFI firmware with Secure Boot support (REQUIRED)
|
||||
local uefi_code=""
|
||||
local uefi_vars=""
|
||||
|
||||
|
||||
# Prefer Secure Boot enabled firmware
|
||||
for fw_dir in /usr/share/OVMF /usr/share/qemu; do
|
||||
if [[ -f "$fw_dir/OVMF_CODE_4M.secboot.fd" ]]; then
|
||||
@@ -115,116 +118,129 @@ vm_create() {
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
if [[ -z "$uefi_code" || ! -f "$uefi_code" ]]; then
|
||||
log_error "UEFI firmware with Secure Boot (OVMF) not found"
|
||||
log_error "Install required: sudo apt install ovmf"
|
||||
log_error "UEFI with Secure Boot is REQUIRED for KNEL-Football testing"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Create copy of OVMF_VARS for this VM (Secure Boot state stored here)
|
||||
local vm_vars="/tmp/${VM_NAME}_OVMF_VARS.fd"
|
||||
local vm_vars="/tmp/${VM_NAME}_VARS.fd"
|
||||
cp "$uefi_vars" "$vm_vars"
|
||||
|
||||
|
||||
if [[ "$uefi_code" == *".secboot.fd" ]]; then
|
||||
log_info "Using UEFI firmware with Secure Boot: $uefi_code"
|
||||
else
|
||||
log_warn "Using UEFI firmware WITHOUT Secure Boot: $uefi_code"
|
||||
log_warn "For full Secure Boot testing, install: sudo apt install ovmf"
|
||||
fi
|
||||
|
||||
# Try virt-install first, fall back to direct QEMU
|
||||
if virt-install \
|
||||
--connect qemu:///session \
|
||||
--name "$VM_NAME" \
|
||||
--ram "$VM_RAM" \
|
||||
--vcpus "$VM_CPUS" \
|
||||
--disk path="$VM_DISK_PATH",format=qcow2 \
|
||||
--cdrom "$ISO_PATH" \
|
||||
--os-variant debian12 \
|
||||
--network user \
|
||||
--graphics vnc,listen=0.0.0.0 \
|
||||
--boot uefi \
|
||||
--noautoconsole \
|
||||
--virt-type kvm 2>&1; then
|
||||
log_info "VM created via virt-install (UEFI mode)"
|
||||
else
|
||||
log_warn "virt-install failed, using direct QEMU with UEFI..."
|
||||
|
||||
# Use QEMU directly with UEFI firmware
|
||||
qemu-system-x86_64 \
|
||||
-name "$VM_NAME" \
|
||||
-m "$VM_RAM" \
|
||||
-smp "$VM_CPUS" \
|
||||
-drive file="$VM_DISK_PATH",format=qcow2,if=virtio \
|
||||
-cdrom "$ISO_PATH" \
|
||||
-netdev user,id=net0 \
|
||||
-device virtio-net-pci,netdev=net0 \
|
||||
-vnc :0 \
|
||||
-drive if=pflash,format=raw,readonly=on,file="$uefi_code" \
|
||||
-drive if=pflash,format=raw,file="$vm_vars" \
|
||||
-enable-kvm \
|
||||
-daemonize \
|
||||
-pidfile "/tmp/${VM_NAME}.pid"
|
||||
log_info "VM started via QEMU with UEFI (PID: $(cat /tmp/${VM_NAME}.pid 2>/dev/null || echo 'unknown'))"
|
||||
|
||||
# Determine secure boot setting
|
||||
local secure_boot="no"
|
||||
if [[ "$uefi_code" == *".secboot.fd" ]]; then
|
||||
secure_boot="yes"
|
||||
fi
|
||||
|
||||
# Use persisted XML template
|
||||
local template="${SCRIPT_DIR}/vm/template.xml"
|
||||
if [[ ! -f "$template" ]]; then
|
||||
log_error "VM template not found: $template"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Generate dynamic values
|
||||
local vm_uuid
|
||||
if command -v uuidgen &> /dev/null; then
|
||||
vm_uuid=$(uuidgen)
|
||||
else
|
||||
vm_uuid=$(cat /proc/sys/kernel/random/uuid)
|
||||
fi
|
||||
local mac_address="52:54:00:$(od -An -N3 -tx1 /dev/urandom | tr ' ' ':' | cut -c2-13)"
|
||||
|
||||
# Create VM XML from template
|
||||
local vm_xml="/tmp/${VM_NAME}.xml"
|
||||
sed -e "s|@VM_NAME@|${VM_NAME}|g" \
|
||||
-e "s|@VM_UUID@|${vm_uuid}|g" \
|
||||
-e "s|@VM_RAM@|${VM_RAM}|g" \
|
||||
-e "s|@VM_CPUS@|${VM_CPUS}|g" \
|
||||
-e "s|@SECURE_BOOT@|${secure_boot}|g" \
|
||||
-e "s|@UEFI_CODE@|${uefi_code}|g" \
|
||||
-e "s|@UEFI_VARS@|${vm_vars}|g" \
|
||||
-e "s|@VM_DISK@|${VM_DISK_PATH}|g" \
|
||||
-e "s|@ISO_PATH@|${ISO_PATH}|g" \
|
||||
-e "s|@MAC_ADDRESS@|${mac_address}|g" \
|
||||
"$template" > "$vm_xml"
|
||||
|
||||
# Define and START the VM
|
||||
if ! virsh -c "$LIBVIRT_URI" define "$vm_xml"; then
|
||||
log_error "Failed to define VM from XML"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! virsh -c "$LIBVIRT_URI" start "$VM_NAME"; then
|
||||
log_error "Failed to start VM"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get VNC display info
|
||||
local vnc_display
|
||||
vnc_display=$(virsh -c "$LIBVIRT_URI" vncdisplay "$VM_NAME" 2>/dev/null)
|
||||
|
||||
log_info "VM created and STARTED successfully"
|
||||
log_info "VNC display: $vnc_display"
|
||||
log_info ""
|
||||
log_info "To connect in virt-manager:"
|
||||
log_info " 1. Open virt-manager"
|
||||
log_info " 2. File → Add Connection"
|
||||
log_info " 3. Enter URI: qemu:///session"
|
||||
log_info " 4. Connect and double-click '$VM_NAME'"
|
||||
}
|
||||
|
||||
# Connect to VM console
|
||||
vm_console() {
|
||||
local LIBVIRT_URI="qemu:///session"
|
||||
log_info "Connecting to VM console..."
|
||||
virsh console "$VM_NAME"
|
||||
virsh -c "$LIBVIRT_URI" console "$VM_NAME"
|
||||
}
|
||||
|
||||
# Get VM status
|
||||
vm_status() {
|
||||
local LIBVIRT_URI="qemu:///session"
|
||||
log_info "VM Status for: $VM_NAME"
|
||||
virsh dominfo "$VM_NAME" 2>/dev/null || log_error "VM not running"
|
||||
virsh -c "$LIBVIRT_URI" dominfo "$VM_NAME" 2>/dev/null || log_error "VM not running"
|
||||
}
|
||||
|
||||
# Check if VM is running
|
||||
vm_is_running() {
|
||||
# Check virsh first
|
||||
if virsh domstate "$VM_NAME" 2>/dev/null | grep -q "running"; then
|
||||
local LIBVIRT_URI="qemu:///session"
|
||||
# Check virsh session
|
||||
if virsh -c "$LIBVIRT_URI" domstate "$VM_NAME" 2>/dev/null | grep -q "running"; then
|
||||
return 0
|
||||
fi
|
||||
# Check QEMU pidfile
|
||||
if [[ -f "/tmp/${VM_NAME}.pid" ]]; then
|
||||
local pid
|
||||
pid=$(cat "/tmp/${VM_NAME}.pid")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Capture boot screenshot
|
||||
vm_capture_screen() {
|
||||
local LIBVIRT_URI="qemu:///session"
|
||||
local output_dir="${SCRIPT_DIR}/tmp/vm-screenshots"
|
||||
mkdir -p "$output_dir"
|
||||
|
||||
|
||||
log_info "Capturing boot screen..."
|
||||
virsh screenshot "$VM_NAME" "${output_dir}/boot-screen.ppm" 2>/dev/null || {
|
||||
virsh -c "$LIBVIRT_URI" screenshot "$VM_NAME" "${output_dir}/boot-screen.ppm" 2>/dev/null || {
|
||||
log_warn "Could not capture screenshot"
|
||||
}
|
||||
}
|
||||
|
||||
# Destroy VM and cleanup
|
||||
vm_destroy() {
|
||||
local LIBVIRT_URI="qemu:///session"
|
||||
log_info "Destroying VM: $VM_NAME"
|
||||
# Try virsh first
|
||||
virsh destroy "$VM_NAME" 2>/dev/null || true
|
||||
virsh undefine "$VM_NAME" 2>/dev/null || true
|
||||
# Kill QEMU process if running
|
||||
if [[ -f "/tmp/${VM_NAME}.pid" ]]; then
|
||||
local pid
|
||||
pid=$(cat "/tmp/${VM_NAME}.pid")
|
||||
kill "$pid" 2>/dev/null || true
|
||||
rm -f "/tmp/${VM_NAME}.pid"
|
||||
fi
|
||||
rm -f "$VM_DISK_PATH"
|
||||
virsh -c "$LIBVIRT_URI" destroy "$VM_NAME" 2>/dev/null || true
|
||||
virsh -c "$LIBVIRT_URI" undefine "$VM_NAME" --nvram 2>/dev/null || true
|
||||
rm -f "$VM_DISK_PATH" "/tmp/${VM_NAME}_VARS.fd" "/tmp/${VM_NAME}.xml"
|
||||
log_info "Cleanup complete"
|
||||
}
|
||||
|
||||
|
||||
55
vm/template.xml
Normal file
55
vm/template.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<domain type='kvm'>
|
||||
<name>@VM_NAME@</name>
|
||||
<uuid>@VM_UUID@</uuid>
|
||||
<memory unit='MiB'>@VM_RAM@</memory>
|
||||
<currentMemory unit='MiB'>@VM_RAM@</currentMemory>
|
||||
<vcpu placement='static'>@VM_CPUS@</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='q35'>hvm</type>
|
||||
<loader readonly='yes' secure='@SECURE_BOOT@' type='pflash'>@UEFI_CODE@</loader>
|
||||
<nvram>@UEFI_VARS@</nvram>
|
||||
<boot dev='cdrom'/>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<smm state='on'/>
|
||||
</features>
|
||||
<cpu mode='host-passthrough' check='none'/>
|
||||
<clock offset='utc'>
|
||||
<timer name='rtc' tickpolicy='catchup'/>
|
||||
<timer name='pit' tickpolicy='delay'/>
|
||||
<timer name='hpet' present='no'/>
|
||||
</clock>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
||||
<disk type='file' device='disk'>
|
||||
<driver name='qemu' type='qcow2'/>
|
||||
<source file='@VM_DISK@'/>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='@ISO_PATH@'/>
|
||||
<target dev='sda' bus='sata'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<interface type='user'>
|
||||
<mac address='@MAC_ADDRESS@'/>
|
||||
<model type='virtio'/>
|
||||
</interface>
|
||||
<graphics type='vnc' port='-1' autoport='yes'>
|
||||
<listen type='address' address='127.0.0.1'/>
|
||||
</graphics>
|
||||
<video>
|
||||
<model type='virtio' heads='1' primary='yes'/>
|
||||
</video>
|
||||
<console type='pty'>
|
||||
<target type='serial' port='0'/>
|
||||
</console>
|
||||
</devices>
|
||||
</domain>
|
||||
Reference in New Issue
Block a user