# run-virt.include # ----------------------------------------------------------------------------- # Copyright (c) 2009..2010 - RZ Uni Freiburg # Copyright (c) 2009..2010 - 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 # - Include script for running the VirtualBox on an OpenSLX client via the # run-virt.sh or run-vmgrid.sh ################################################################################ ################################################################################ ### Include general configuration ################################################################################ if [ -f ${OPENSLX_DEFAULT_CONFDIR}/plugins/${self}/${self}.conf ]; then . ${OPENSLX_DEFAULT_CONFDIR}/plugins/${self}/${self}.conf else writelog "Problems reading config file of ${self} plugin" exit 1 fi ################################################################################ ### Declaration of default variables ################################################################################ PLUGINCONFVIRTUALBOX="${PLUGINCONFROOT}/${self}" PLUGINDIRVIRTUALBOX="${OPENSLX_DEFAULT_DIR}/plugin-repo/${self}" # create TMPDIR for all users TMPDIR=/tmp/${self} mkdir -m 1777 ${TMPDIR} 2>/dev/null # dir for configs confdir="/tmp/${self}/${USER}/${VM_ID}" # use alternate configuration directory instead of $HOME/.VirtualBox export VBOX_USER_HOME=${confdir} # define dirs and files which can be removed after exit, be carefull! RMDIRS="${snapshotdir} ${confdir} /tmp/.vbox-${USER}-ipc" rm -rf ${RMDIRS} 2>/dev/null machfolder="${confdir}/Machines" # use vm_shortname for VM name 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 # configure our own rwimg, empty image which we support if [ "${imgmode}" = "rwimg" ]; then # what is our rwimg called? imgname="${vm_shortname}.vdi" vmpath=${imgpath}/${imgname} if ! [ -e "${vmpath}" ]; then cat ${PLUGINDIRVIRTUALBOX}/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 -iE "vdi|vmdk|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|vmdk|vhd), exiting!" exit 1 fi # TODO: maybe rewrite, to reduce checks, merge it with network option, # so we can have a "compatibility to vmware config" section case "${vmostype}" in winxp*) vmostype="WindowsXP" ;; winvista*) vmostype="WindowsVista" ;; Windows7*) vmostype="Windows7" ;; linux*) vmostype="Linux26" ;; 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 macaddr=$(echo ${macaddr} | sed 's/://g') # machine UUID, MAC addr part of it machineuuid="00000000-0000-0000-0000-${macaddr}" # cosmetical, since UUID in lower case machineuuid=$(echo ${machineuuid} | tr [A-Z] [a-z]) # get UUID of VBox image, if not diskless [ ${diskless} -eq 0 ] && diskuuid=$(VBoxManage -q showvdiinfo ${diskfile} \ | grep UUID | awk '{print $2}') # make disk immutable imgtype="Immutable" # snapshot UUID is static snapshotuuid="88bc8b6d-f248-468a-95fe-318084904f8b" # imageuuid in machine.include, dafault snapshotuuid imageuuid=${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: ${vmpath}, exiting!" writelog "Remove lock if you are shure that this is not the case" exit 1 # image rw? elif ! [ -w ${vmpath} ]; then writelog "You defined mode rw, but image ${vmpath} is not rw! \c" writelog "Please correct, exiting!" exit 1 fi # add lock touch "${vmpath}.lock" # remove lock after VM stopped RMDIRS="${RMDIRS} ${vmpath}.lock" imgtype="Normal" # replace image uuid in machine config imageuuid=${diskuuid} elif [ ${diskless} -eq 0 ]; then # use temp disk as snapshot cat ${PLUGINDIRVIRTUALBOX}/empty-diff.vdi.gz \ | gunzip > "${snapshotdir}/{${snapshotuuid}}.vdi" fi # TODO: MEM muss noch angepasst werden. Maschine crasht wenn nehr 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 memhost=$(expr ${totalmem} - ${mem}) else memhost=$(expr ${totalmem} - ${mem} - ${mem}) fi #permem=40 #mem=$(expr ${totalmem} * ${permem}) if [ "${mem}" -lt "256" ] || [ "${memhost}" -lt "256" ]; then writelog "Memory out of range: ${mem} MB (guest) / ${memhost} MB (host)!" writelog "Min. 256 MB for host and guest!" exit 1 fi fi # translate network cards if [ "${network_card}" = "e1000" ]; then vb_network_card="82540EM" else network_card="pcnet" vb_network_card="Am79C973" fi # translate network kinds (nat, bridged, host-only) case "${network_kind}" in bridged) network_kind='BridgedInterface name="br0"' ;; hostonly|host-only) network_kind='HostOnlyInterface name="vboxnet0"' ;; *) network_kind="NAT" esac # external GUI vrdpport="590${VM_ID}" # TODO: nur bei vmchooser # TODO: most of the following does not make much sense yet ... # virtual fd/cd/dvd and drive devices, floppy b: for configuration # if $floppy_0 from run-virt.include set then fdtest="TRUE" fdtest= fdtest=${floppy_0:+"TRUE"} # if $fdtest not set floppy0="FALSE", else "TRUE" floppy0=${fdtest:-"FALSE"} floppy1="TRUE" floppy1name="/var/lib/virt/vmchooser/loopimg/fd.img" # if $cdrom_0 from run-virt.include set then cdtest="TRUE" cdtest= cdtest=${cdrom_0:+"TRUE"} # if $cdtest not set cdrom0="FALSE", else "TRUE" cdrom0=${cdtest:-"FALSE"} # if $cdrom_1 from run-virt.include set then cdtest="TRUE" cdtest= cdtest=${cdrom_1:+"TRUE"} # if $cdtest not set cdrom1="FALSE", else "TRUE" cdrom1=${cdtest:-"FALSE"} # ide is expected default, test for the virtual disk image type should # be done while creating the runscripts ... ide="TRUE" hddrv="ide" # translate boot, use if set else set to HardDisk if [ -n "${boot}" ]; then case ${boot} in n*) # usually support for a,c,d,n, stands for Floppy, HD, CD-ROM, Network boot="Network" if [ "${network_kind}" = "NAT" ] && [ -n "${virtualbox_tftpdir}" ]; then # remove spaces from VM name to avoid Problems /w TFTP in NAT vm_name=$(echo ${vm_name} | sed -e "s, ,-,g") # link TFTP dir for NAT TFTP boots mkdir -p ${confdir}/TFTP cp ${virtualbox_tftpdir}/pxelinux.0 ${confdir}/TFTP/${vm_name}.pxe 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 else boot="HardDisk" fi [ ${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 "\tGuest RAM:\t\t${mem} MB" # echo nur wenn memhost gesetzt [ -n "${memhost}" ] && writelog "\tHost RAM:\t\t${memhost} 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${cdrom0}" #writelog "\tCD-ROM2:\t${cdrom1}" #writelog "\tFloppy_A:\t${floppy0}" #writelog "\tFloppy_B:\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 . ${PLUGINCONFVIRTUALBOX}/virtualbox.include # 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"/> # create machine.xml . ${PLUGINCONFVIRTUALBOX}/machine.include # if diskless remove all disks if [ ${diskless} -eq 1 ]; then sed -i "//d" ${machconfig} fi # add ssh port if linux and NAT if [ "${vmostype}" = "Linux26" ] && [ "${network_kind}" = "NAT" ]; then vmsshport="220${VM_ID}" extradataitem='" extradataprotocol='Protocol" value="TCP"/>' sed -i "s,, ${extradataitem}${extradataguestport}\n\ ${extradataitem}${extradatahostport}\n\ ${extradataitem}${extradataprotocol}\n\ ," "${machconfig}" writelog "\tGuest SSH port:\t\t${vmsshport}" fi ################################################################################ ### finally set env for run-virt.sh ################################################################################ # 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" # set headless mode VIRTCMDHL=$(which VBoxHeadless 2>/dev/null) VIRTCMDOPTSHL="-s ${machineuuid}"