# -----------------------------------------------------------------------------
# Copyright (c) 2009..2011 - RZ Uni Freiburg
# Copyright (c) 2009..2013 - OpenSLX GmbH
#
# This program/file is free software distributed under the GPL version 2.
# See http://openslx.org/COPYING
#
# If you have any feedback please consult http://openslx.org/feedback and
# send your feedback to feedback@openslx.org
#
# General information about OpenSLX can be found at http://openslx.org
# -----------------------------------------------------------------------------
# run-virt.include
# - component for virtualbox of the vmchooser plugin vmchooser-run_virt
################################################################################
################################################################################
### declaration of default variables
################################################################################
VMCHOOSERVBOX="/opt/openslx/vmchooser/${self}"
confdir="${TMPDIR}/vbox" # dir for configs
export VBOX_USER_HOME=${confdir} # instead of $HOME/.VirtualBox
# define dirs and files which can be removed after exit, be carefull!
# TODO: Machanism not in use anymore. A better approach would be anyways to
# Define a fixed directory which can be deleted recursively on exit. $TMPDIR
# would be a start.
#RMDIRS="${snapshotdir} ${confdir} /tmp/virt/.vbox-${USER}-ipc"
# rm -rf ${RMDIRS} 2>/dev/null
machfolder="${confdir}/Machines"
# use vm_shortname for dir and config names since vm_name can be very long
machconfig="${machfolder}/${vm_shortname}/${vm_shortname}.xml"
diskfolder="${confdir}/HardDisks"
snapshotdir=${machfolder}/${vm_shortname}/Snapshots
mkdir -p ${diskfolder} ${snapshotdir} 2>/dev/null
[ -z "${diskless}" ] && diskless=0 # check if diskless var empty?
guestaudio="HDA" # default guest audio controller (SB16, AC97, HDA)
vb_network_card="82540EM" # default guest network adaptor (Am79C970A, Am79C973, 82540EM)
enable2d="true" # default setting for accelerated 2D grapics (OS dependent)
vram="128" # set default graphics ram
# configure our own rwimg, empty image which we provide
if [ "${imgmode}" = "rwimg" ]; then
imgname="${vm_shortname}.vdi" # what is our rwimg called?
vmpath=${imgpath}/${imgname}
if ! [ -e "${vmpath}" ]; then
cat /opt/openslx/vmchooser/virtualbox/rwimg.vdi.gz | gunzip > "${vmpath}"
fi
fi
# link to image
diskfile="${diskfolder}/${imgname}"
[ ${diskless} -eq 0 ] && ln -sf ${vmpath} ${diskfile}
# check the file type
if echo ${imgname} | grep -qiE "vdi|vhd" && [ ${diskless} -eq 0 ]; then
imgfmt=$(echo ${imgname##*.} | tr "[a-z]" "[A-Z]")
elif [ ${diskless} -eq 0 ]; then
writelog "${imgname} is not a valid image format (vdi|vhd), exiting!"
cleanexit 1
fi
npaging="false" # nested paging: Default: not enabled
enablevt="false" # VT: Default: not enabled
[ ${vtflag} -eq 0 ] && cpu_cores=1 # check for VT, if not available only 1 cpu supported
[ ${vtflag} -eq 1 ] && enablevt="true"
# Setting some default variables
shfolders="TRUE"
# set some base configuration depending on the guest operating system
case "${vmostype}" in
win31*)
guestaudio="SB16"
vb_network_card="Am79C973"
vmostype="Windows31"
mem="32"
vram="16"
cpu_cores=1
enablevt="false"
shfolders="FALSE"
;;
winnt*)
guestaudio="SB16"
vb_network_card="Am79C973"
vmostype="Windows31"
mem="32"
vram="16"
cpu_cores=1
enablevt="false"
shfolders="FALSE"
;;
win95*)
vmostype="Windows95"
guestaudio="SB16"
vb_network_card="Am79C973"
mem="92"
vram="32"
cpu_cores=1
enablevt="false"
shfolders="FALSE"
;;
win98*)
vmostype="Windows98"
guestaudio="SB16"
vb_network_card="Am79C973"
mem="256"
vram="64"
cpu_cores=1
shfolders="FALSE"
;;
winme*)
vmostype="WindowsMe"
guestaudio="AC97"
vb_network_card="Am79C973"
mem="256"
vram="64"
cpu_cores=1
shfolders="FALSE"
;;
winxp*|windowsxp*)
vmostype="WindowsXP"
guestaudio="AC97"
;;
winvista*|windowsvista*)
vmostype="WindowsVista"
;;
windows7*)
vmostype="Windows7"
;;
windows8*)
vmostype="Windows8"
;;
linux*|*ubuntu*|*suse*|debian*|*sci*)
if echo "${vmostype}" | grep -q "64"; then
vmostype="Linux26_64"
# check for vtflag
if [ ${vtflag} -ne 1 ]; then
writelog "You are trying to boot a 64 bit OS without a VT enabled CPU"
writelog "This is not supported, exiting!"
cleanexit 1
fi
# check if host is only 32 bit, then use only 1 cpu (only 1 supported)
if echo "${host_arch}" | grep -qE "i.86"; then
cpu_cores=1
fi
else
vmostype="Linux26"
fi
;;
os2*)
mem="256"
vmostype="OS2eCS"
cpu_cores=1
enable2d="false"
;;
macos*|MacOS*)
vmostype="MacOS"
enable2d="false"
;;
*)
vmostype="Other"
enable2d="false"
;;
esac
writelog "Directories:"
writelog "\tConfig dir:\t\t$confdir"
writelog "\tMachines dir:\t\t$machfolder"
writelog "\tMachine config:\t\t$machconfig"
[ ${diskless} -eq 0 ] && writelog "\tHardDisks dir:\t\t$diskfolder"
################################################################################
### Hardware checks
################################################################################
# remove ':' from MAC addr for vbox and generate a VDE (virtual device ethernet)
# MAC addr from the first one (put in prefix 0DE)
macaddr=$(echo ${macaddr} | sed 's/://g')
vdemacaddr=$(echo ${macaddr} | sed 's/^..../00DE/g')
machineuuid="00000000-0000-0000-0000-${macaddr}" # machine UUID, MAC addr part of it
machineuuid=$(echo ${machineuuid} | tr "[A-Z]" "[a-z]") # cosmetical, since UUID in lower case
# get UUID of VBox image, if not diskless
[ ${diskless} -eq 0 ] && diskuuid=$(VBoxManage -q showvdiinfo ${diskfile} \
| grep UUID | grep -v "Parent UUID" | awk '{print $2}' \
| grep -v use ) # nec. for VBox >= 4
imgtype="Immutable" # make disk immutable
snapshotuuid="34f617be-192a-46b3-a8ae-bce1029e093f" # snapshot UUID is static
imageuuid=${snapshotuuid} # imageuuid in machine.include, default snapshotuuid
# check if rw image
# remove disk and add rwimg if set
if echo "${imgmode}" | grep -q rw; then
# lock existing?
if [ -e "${vmpath}.lock" ]; then
writelog "This rw image is already in use."
writelog "Found lock: ${vmpath}.lock, exiting!"
writelog "Remove lock if you are sure that this is not the case"
cleanexit 1
# image rw?
elif ! [ -w ${vmpath} ]; then
writelog "You defined mode rw, but image ${vmpath} is not rw! \c"
writelog "Please correct, exiting!"
cleanexit 1
fi
touch "${vmpath}.lock" # add lock
#RMDIRS="${RMDIRS} ${vmpath}.lock" # remove lock after VM stopped TODO See note at the top
imgtype="Normal"
imageuuid=${diskuuid} # replace image uuid in machine config
elif [ ${diskless} -eq 0 ]; then
# use temp disk as snapshot
cat ${VMCHOOSERVBOX}/empty-diff.vdi.gz \
| gunzip > "${snapshotdir}/{${snapshotuuid}}.vdi"
# patch the disk file uuid into the snapshot vdi file
dd if=${diskfile} of="${snapshotdir}/{${snapshotuuid}}.vdi" seek=424 \
skip=392 bs=1 count=16 conv=notrunc
fi
# TODO: MEM muss noch angepasst werden. Maschine crasht wenn mehr als 50% MEM
# memory part equal to vmware plugin
# percentage of memory to use for virtualbox in standard case
#if [ -n "${forcemem}" ]; then
# mem="${forcemem}"
#else
# permem=30
# if [ "${totalmem}" -ge "1600" ]; then
# permem=40
# fi
# # check if /tmp is on harddisk
# if grep -qe "/dev/.* /tmp " /proc/mounts ; then
# permem=60
# id44="1"
# # Hack, if more than 2,5G RAM use 40% of Ram and write vmem into Ram as well
# # (40% vmware | 40% confdir(vmem...) | 20% host
# # VMplayer 2+ issue
# # TODO: makes this sense for vbox?
# #if [ "${totalmem}" -ge "2500" ]; then
# #permem=40
# #rmdir ${snapshotdir}
# #snapshotdirold=${snapshotdir}
# #snapshotdir=/dev/shm/${self}/${USER}/${VM_ID}
# #mkdir -p ${snapshotdir}
# #ln -sf ${snapshotdir} ${snapshotdirold}
# #fi
# fi
# mem=$(expr ${totalmem} / 100 \* ${permem})
# if [ "${id44}" = "1" ]; then
# hostmem=$(expr ${totalmem} - ${mem})
# else
# hostmem=$(expr ${totalmem} - ${mem} - ${mem})
# fi
# #permem=40
# #mem=$(expr ${totalmem} * ${permem})
#fi
# translate network cards
case "${network_card}" in
e1000)
vb_network_card="82540EM"
;;
virtio)
vb_network_card="virtio"
;;
*)
network_card="pcnet"
vb_network_card="Am79C973"
esac
# translate network kinds (nat, bridged, host-only)
case "${network_kind}" in
bridge*)
network_kind='HostOnlyInterface name="vboxnet0"'
;;
host*)
network_kind='HostOnlyInterface name="vboxnet2"'
;;
*)
network_kind='HostOnlyInterface name="vboxnet1"'
esac
# configure 3d settings
case "${enable3d}" in
*true*|*yes*)
enable3d="true"
;;
*)
enable3d="false"
;;
esac
# translate boot, use if set else set to HardDisk
# usually support for a,c,d,n, stands for Floppy, HD, CD-ROM, Network
# support nfs and tftp as well
case ${boot} in
n*|tftp)
boot="Network"
if [ "${network_kind}" = "NAT" ] && [ -n "${virtualbox_tftpdir}" ]; then
vm_name=${vm_shortname} # use vm_shortname to avoid Problems /w TFTP in NAT
mkdir -p ${confdir}/TFTP # link TFTP dir for NAT TFTP boots
if [ -e ${virtualbox_tftpdir}/pxelinux.0 ]; then
cp ${virtualbox_tftpdir}/pxelinux.0 ${confdir}/TFTP/${vm_name}.pxe
else
writelog "${virtualbox_tftpdir}/pxelinux.0 not found!"
writelog "Network boot won't work, exiting!"
cleanexit 1
fi
for i in $(ls ${virtualbox_tftpdir}); do
ln -sf ${virtualbox_tftpdir}/${i} ${confdir}/TFTP/${i}
done
fi
;;
# later maybe c|disk|hd*|sd*) for HD and d|cd*) for CD-ROM
*)
boot="HardDisk"
;;
esac
vrdpport=${remotedesktopport} # external GUI
[ ${diskless} -eq 0 ] && writelog "\tSnapshots dir:\t\t$snapshotdir"
writelog "Diskimage:"
[ ${diskless} -eq 0 ] && writelog "\tDisk file:\t\t$diskfile"
[ ${diskless} -eq 0 ] && writelog "\tDisk format:\t\t$imgfmt"
[ ${diskless} -eq 0 ] && writelog "\tDisk type:\t\t$imgtype"
writelog "\tVMostype:\t\t$vmostype"
writelog "\tMachine UUID:\t\t$machineuuid"
[ ${diskless} -eq 0 ] && writelog "\tDisk UUID:\t\t$diskuuid"
writelog "Virtual Hardware:"
writelog "\tCPU cores:\t\t${cpu_cores}\c"
[ ${vtflag} -eq 0 ] && writelog ""
[ ${vtflag} -eq 1 ] && writelog " (VT enabled CPU)"
writelog "\tGuest RAM:\t\t${mem} MB"
# echo nur wenn hostmem gesetzt
[ -n "${hostmem}" ] && writelog "\tHost RAM:\t\t${hostmem} MB"
writelog "\tMAC address:\t\t$macaddr"
writelog "\tNetwork card:\t\t${vb_network_card}"
writelog "\tNetwork kind:\t\t${network_kind}"
writelog "\tBooting from:\t\t${boot}\c"
[ ${diskless} -eq 0 ] && writelog ""
[ ${diskless} -eq 1 ] && writelog " 'diskless'"
# TODO: server start activate via xml, etc...
#writelog "\tGuest VRDP port:\t${vrdpport}"
writelog "\tCD-ROM1:\t\t${cdrom0}"
#writelog "\tCD-ROM2:\t\t${cdrom1}"
writelog "\tFloppy_A:\t\t${floppy0}"
writelog "\tFloppy_B:\t\t${floppy1}"
# defined in run-virt.sh and run-vmgrid.sh
writelog "\tShared Folders '${sharename}':\t${sharepath}"
################################################################################
### Pepare and configure virtual machine and disk image
################################################################################
# create Virtualbox.xml
# Shares given?
if [ "x$shfolders" != "xFALSE" ]; then
sharelist="
"
else
sharelist=''
fi
source ${VMCHOOSERVBOX}/virtualbox.include # create Virtualbox.xml
# remove snapshot disk when using rw images
if [ "${imgtype}" != "Immutable" ]; then
sed -i "/${snapshotuuid}/d" "${confdir}/VirtualBox.xml"
fi
# TODO: add rawdisk if requested
#"raw.vmdk" format="VMDK" type="Writethrough"/>
source ${VMCHOOSERVBOX}/machine.include # create machine.xml
# remove CD-ROM if not available
if [ "${cdrom0}" != "TRUE" ]; then
sed -i "/HostDrive/d" ${machconfig}
sed -i '/AttachedDevice.*type="DVD"/d' ${machconfig}
sed -i "//d" ${machconfig}
fi
# if diskless remove all disks
if [ ${diskless} -eq 1 ]; then
sed -i "//d" ${machconfig}
fi
# define redirects
if [ ${redirects} -ge 1 ]; then
(( i=1 ))
writelog "\tGuest redirects:\t\c"
while [ ${i} -le ${redirects} ]; do
extradataitem='"
extradatahostport="HostPort\" value=\"${redirect_hport[$i]}\"/>"
extradataguestport="GuestPort\" value=\"${redirect_gport[$i]}\"/>"
sed -i "s,, ${extradataitem}${extradataguestport}\n\
${extradataitem}${extradatahostport}\n\
${extradataitem}${extradataprotocol}\n\
," "${machconfig}"
writelog "${tabspace}${redirect_name[$i]} port: ${redirect_hport[$i]}"
tabspace='\t\t\t\t'
(( i=$i+1 ))
done
fi
################################################################################
### Set env for vmchooser-run_virt
################################################################################
# wait for a certain command to settle
# get the PID of the right process
# kill PID, seems to work
VBMANPID=$(pstree -p | grep VBoxXPCOMIPCD | grep -ivE "VirtualBox|VBoxHeadless"\
| sed -e "s/.*VBoxXPCOMIPCD(\(.*\)).*/\1/")
for i in $(echo ${VBMANPID}); do
kill -9 ${VBMANPID} >/dev/null 2>&1
done
# set the variables appropriately (several interfaces with different names)
VIRTCMD=$(which VirtualBox 2>/dev/null)
VIRTCMDOPTS="--startvm ${machineuuid} --start-running --fullscreen"
# set headless mode (-v off to disable vrdp)
VIRTCMDHL=$(which VBoxHeadless 2>/dev/null)
VIRTCMDOPTSHL="-s ${machineuuid}"