#!/bin/bash # devices VM_HW_HDD=${VM_HW_HDD:-ide} VM_HW_HDD_FORMAT=${VM_HW_HDD_FORMAT:-raw} VM_DISK_1_FORMAT=${VM_HW_HDD_FORMAT} VM_HW_NET=${VM_HW_NET:-rtl8139} if [ -n "$( cat /etc/redhat-release | grep Fedora )" ]; then QEMU_BINARY="/usr/bin/qemu-kvm" else QEMU_BINARY="/usr/libexec/qemu-kvm" if grep -q -i "release 5" /etc/redhat-release; then export SL5=1 export PATH="$PATH:/sbin:/usr/sbin" fi fi gen_general_options () { local name=$1 local cpus=$2 local memory=$3 if [ -n "$SL5" ]; then echo "--name $name -cpu qemu64 -smp $cpus -m $memory -vnc none -vga cirrus " else echo "--name $name -cpu qemu64 -enable-kvm -nodefconfig -nodefaults -smp $cpus -m $memory -rtc base=localtime -vnc none -vga cirrus " fi } qemu_add_disk () { local imgpath=$1 local imgformat=$2 echo "-drive file=$imgpath,if=${VM_HW_HDD},format=${imgformat:-raw} " } qemu_add_vvfat () { local dirpath=$1 echo "-drive file=fat:rw:$dirpath " } qemu_add_iso () { local isopath=$1 echo "-drive file=$isopath,media=cdrom,if=ide " } qemu_add_mactap () { local macaddr=$1 local tapcdev=$2 echo "-net nic,model=$VM_HW_NET,macaddr=${macaddr} -net tap,fd=100 100<>${tapcdev} " } qemu_add_bridgednet () { local macaddr=$1 local tapdev=$2 if [ -n "$SL5" ]; then echo "-net nic,model=$VM_HW_NET,vlan=0,macaddr=${macaddr} -net tap,vlan=0,ifname=${tapdev},script=no,downscript=no " else echo "-device $VM_HW_NET,netdev=net0,mac=${macaddr} -netdev tap,id=net0,ifname=${tapdev},script=no,downscript=no " fi } check_vvfat_support () { local dirpath=$( mktemp -d ) $QEMU_BINARY -nodefconfig -nodefaults -vnc none -drive file=fat:rw:$dirpath >/dev/null 2>&1 & local qemu_pid=$! sleep 1 ps -p $qemu_pid >/dev/null 2>&1 local exit_code=$? [ $exit_code -eq 0 ] && kill $qemu_pid return $exit_code } check_vm_running () { ps -p $VM_QEMU_PID >/dev/null 2>&1 return $? } destroy_vm () { kill $VM_QEMU_PID sleep 10 kill -9 $VM_QEMU_PID } # general VM settings qemu_opts=$( gen_general_options "$VM_NAME" "${VM_CPUS:-1}" "$VM_MEMORY_SIZE" ) # disk images diskidx=1 diskvar="VM_DISK_$diskidx" while [ -n "${!diskvar}" ]; do diskformat="${diskvar}_FORMAT" qemu_opts="$qemu_opts $( qemu_add_disk \"${!diskvar}\" ${!diskformat} ) " diskidx=$(( diskidx + 1 )) diskvar="VM_DISK_$diskidx" done # vvfat disk mappings check_vvfat_support && vvfat_supported=1 diskidx=1 diskvar="VM_VVFAT_DISK_$diskidx" while [ -n "${!diskvar}" ]; do if [ -n "$vvfat_supported" ]; then qemu_opts="$qemu_opts $( qemu_add_vvfat \"${!diskvar}\" ) " else # no VVFAT support in QEMU echo "WARNING: There is no VVFAT support on WN hypervisor. Falling back to general VFAT image method." datadir=${!diskvar} sudo diskimg-manage -c -d "$datadir" -i "${datadir%/}.img" -u "$(whoami)" 1>&2 echo "sudo diskimg-manage -e -d \"$datadir\" -i \"${datadir%/}.img\"" | add2_cleanup_script qemu_opts="$qemu_opts $( qemu_add_disk \"${datadir%/}.img\" ) " fi diskidx=$(( diskidx + 1 )) diskvar="VM_VVFAT_DISK_$diskidx" done # ISO images diskidx=1 diskvar="VM_CD_DISK_$diskidx" while [ -n "${!diskvar}" ]; do qemu_opts="$qemu_opts $( qemu_add_iso ${!diskvar} ) " diskidx=$(( diskidx + 1 )) diskvar="VM_CD_DISK_$diskidx" done # networking if [ "$VM_NET_TYPE" = "direct" ]; then # add tap device and obtain character device file r_debug "DEBUG: Creating network interface: sudo macvtap-manage -m $VM_NET_MAC -i $VM_NET_INT -u $(whoami)" tapcdev=$( sudo macvtap-manage -m "$VM_NET_MAC" -i "$VM_NET_INT" -u "$(whoami)" 2>/dev/null ) || return 2 echo "sudo macvtap-manage -m \"$VM_NET_MAC\" -d" | add2_cleanup_script qemu_opts="$qemu_opts $( qemu_add_mactap "$VM_NET_MAC" "${tapcdev}" )" elif [ "$VM_NET_TYPE" = "bridge" ]; then r_debug "DEBUG: Creating network interface: sudo brtap-manage -a -b $VM_NET_INT -u $(whoami)" tapdev=$( sudo brtap-manage -a -b "$VM_NET_INT" -u "$(whoami)" 2>/dev/null ) || return 2 echo "sudo brtap-manage -b \"$VM_NET_INT\" -t \"$tapdev\" -d" | add2_cleanup_script qemu_opts="$qemu_opts $( qemu_add_bridgednet "$VM_NET_MAC" "${tapdev}" )" fi # run QEMU r_debug "DEBUG: Running qemu with the following options: $qemu_opts" eval "$QEMU_BINARY $qemu_opts" & if [ $? -eq 0 ]; then export VM_QEMU_PID=$! sleep 1 check_vm_running else false fi