#!/bin/bash # ----------------------------------------------------------------------------- # Copyright (c) 2010 - RZ Uni FR # Copyright (c) 2010 - OpenSLX GmbH # # This program 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 suggestions, praise, or complaints to feedback@openslx.org # # General information about OpenSLX can be found at http://openslx.org/ # ----------------------------------------------------------------------------- # vmgrid # - This is the generic wrapper for the several virtualization solutions... ################################################################################ . /etc/opt/openslx/openslx.conf ################################################################################ ### Define default dirs / get configs ################################################################################ PLUGINCONFROOT=${OPENSLX_DEFAULT_CONFDIR}/plugins PLUGINCONFVMGRID=${PLUGINCONFROOT}/vmgrid RWSHARE=/var/opt/openslx/plugins/vmgrid/share # include general configuration from vmgrid [ -f ${PLUGINCONFVMGRID}/vmgrid.conf ] && \ . ${PLUGINCONFVMGRID}/vmgrid.conf # load general virtualization information [ -f ${PLUGINCONFROOT}/virtualization/virtualization.conf ] && \ . ${PLUGINCONFROOT}/virtualization/virtualization.conf # get the vmchooser_active var [ -f ${PLUGINCONFROOT}/vmchooser/vmchooser.conf ] && \ . ${PLUGINCONFROOT}/vmchooser/vmchooser.conf ################################################################################ ### Functions used throughout the script ################################################################################ # function to write to stdout and logfile LOGFILE=${OPENSLX_DEFAULT_LOGDIR}/run-vmgrid.${USER}.$$.log writelog () { # write to stdout echo -e "$1" # log into file echo -e "$1" >> ${LOGFILE} # log into share dir, so that log is available in vm as well echo -e "$1" >> ${vmgrid_rwmnt}/logs/run-vmgrid.${USER}.$$.log } # remove config dirs when exit cleanexit () { if echo "${RMDIRS}" 2>/dev/null | grep -q ${vmgrid_virt}; then writelog "${vmgrid_virt} exited. Cleanning up... \c" rm -rf ${RMDIRS} >/dev/null 2>&1 writelog "done" fi exit "$1" } ################################################################################ ### Get XML file and dir ################################################################################ # check if mem, nice or graphical mode set headless=1 unice=19 while [ $# -gt 0 ]; do case "$1" in -h|--help) echo -e "Usage: run-vmgrid.sh [-g] [--mem ] \c" echo -e "[--nice ] [/path/]filename[.xml]" exit ;; -g) headless=0 ;; --mem) # get a result which can be divided through 4 if echo $2 | grep -qE \ '^[2-9][0-9][0-9]$|^[1-9][0-9][0-9][0-9]$|^1[0-9][0-9][0-9][0-9]$'; then forcemem=$(expr $2 / 4 \* 4) else echo "memory $2 not supported (200-19999)!" exit 1 fi shift ;; --nice) # set nice level if echo $2 | grep -qE '^-[1-9]$|-1[0-9]$|^-20$|^[0-9]$|^1[0-9]$'; then unice=$2 else echo "nice level $2 does not exist!" exit 1 fi shift ;; *) xmlfile=$@ break ;; esac shift done # absolute or relative path? if ls ${xmlfile} 2>/dev/null | grep '/' >/dev/null 2>&1; then xmlpath=$(dirname ${xmlfile}) xmlfile=$(basename ${xmlfile}) else xmlpath=${vmgrid_xmlpath} fi # full path xmlfile="${xmlpath}/${xmlfile%.xml}.xml" ################################################################################ ### Sanity checks ################################################################################ # test if the xml file is valid if ! [ -r "${xmlfile}" ]; then writelog "${xmlfile} not a readable XML file!" run-vmgrid.sh -h & exit 1 fi # start to log, create shrare log dir mkdir -m 1777 -p ${vmgrid_rwmnt}/logs echo "Starting to log at $(date)" \ >${vmgrid_rwmnt}/logs/run-vmgrid.${USER}.$$.log # test how many instances running runningvms=$(ps aux | grep "run-vmgrid.sh " | grep -v grep | wc -l) # 2 steps, /w only one is seems not to work runningvms=$(expr ${runningvms} - 1) # if Xen use different method if [ "${vmgrid_virt}" = "xen" ]; then runningvms=$(xm list 2>/dev/null | grep -vE "Domain-0|Name.*ID" | wc -l) runningvms=$(expr ${runningvms} + 1) fi # check value if [ ${runningvms} -le 0 ]; then writelog "Error in value: Running VMs: ${runningvms}. Exit!" exit 1 fi # check if vmchooser plugin installed if [ -n "${vmchooser_active}" ] && [ ${runningvms} -gt 1 ]; then # only allow one instance of vmgrid writelog "Already 1 VMs running and vmchooser plugin is active." writelog "Can't start ${xmlfile}, exiting!" exit 1 # else allow max. 4 instances elif [ ${runningvms} -gt 4 ]; then writelog "Already 4 VMs running, exiting!" exit 1 fi VM_ID="0${runningvms}" # test if XML file if ! grep '/dev/null 2>&1; then writelog \ "Submitted configuration file ${xmlfile} seems to have wrong XML format" exit 1 fi ################################################################################ ### Logo for console ################################################################################ cat </dev/null | grep -q '^/' >/dev/null 2>&1; then imgpath=$(dirname ${imgname}) imgname=$(basename ${imgname}) vmpath=${imgpath}/${imgname} # get path from var else imgpath=${vmgrid_imgpath} vmpath=${imgpath}/${imgname} fi # check if virtual machine container file exists, only if not rwimg if ! [ -e "${vmpath}" ] && [ "${imgmode}" != "rwimg" ] && [ ${diskless} -eq 0 ]; then writelog "Virtual machine image or directory ${vmpath} not found!" exit 1 fi # name of the virt machine, sed because of Windows formatting vm_name=$(grep -o 'short_description param=.*"' ${xmlfile} \ | sed -e "s/&.*;/; /g" | awk -F '"' '{print $2}') # if ${vm_name} not defined use ${xmlfile} vm_name=${vm_name:-${xmlfile%.xml}} # define vm_shortname since vm_name can be very long vm_shortname=$(basename ${xmlfile%.xml} | sed -e "s, ,-,g") # vm_name = displayname, define for old scripts displayname=${vm_name} [ "${imgmode}" != "rwimg" ] && [ ${diskless} -eq 0 ] \ && writelog "\tVM Image dir:\t\t${imgpath}" writelog "\tVM file/dir:\t\t$vmpath" # is there an additional configuration provided? additional_config=$(grep -o 'additional_config param=.*"' ${xmlfile} \ | sed -e "s/&.*;/; /g" | awk -F '"' '{print $2}') # image is for the following virtual machine xmlvirt=$(grep -o 'virtualmachine param=.*"' ${xmlfile} \ | sed -e "s/&.*;/; /g" | awk -F '"' '{print $2}') # make a guess from the filename extension if ${xmlvirt} is empty # (not set within the XML file) # TODO: implement possibility to submit own configuration files if [ -z "${xmlvirt}" ] && [ -n "${additional_config}" ]; then writelog "No virtual machine parameter defined in ${xmlfile}" writelog "Trying to guess VM...\c" case "$(cat ${additional_config} | tr [A-Z] [a-z])" in *config.version*|*virtualhw.version*|*independent-nonpersistent*|*vmdk*) xmlvirt="vmware" ;; *innotek*|*virtualbox*) xmlvirt="virtualbox" ;; *qemu*|*kvm*) xmlvirt="qemukvm" ;; *) xmlvirt="none" ;; esac elif [ -z "${xmlvirt}" ]; then case "$(echo ${imgname##*.} | tr [A-Z] [a-z])" in vmdk) xmlvirt="vmware" ;; vbox) xmlvirt="virtualbox" ;; img|qcow*) xmlvirt="qemukvm" ;; *) xmlvirt="none" ;; esac writelog "result:\t${xmlvirt}" fi # check for virt if [ "${vmgrid_virt}" != "${xmlvirt}" ]; then writelog "The virtual machine specified in ${xmlfile}" writelog "does not match the virtualization used here (${vmgrid_virt})" exit 1 fi # definition of the client system vmostype=$(grep -io '/dev/null # start headless elif [ -n "${VIRTCMDHL}" ]; then writelog "Starting ${vmgrid_virt} in headless mode /w nice level ${unice}..." # start /w low nice level nice -n ${unice} ${VIRTCMDHL} ${VIRTCMDOPTSHL} 2>/dev/null else writelog "${vmgrid_virt}: No headless mode defined, exiting!" cleanexit 1 fi # postrun for scripts after virtualization finishes if [ -n "${POSTRUN}" ]; then eval ${POSTRUN} >/dev/null 2>&1 fi cleanexit 0 exit 0