diff options
Diffstat (limited to 'src/os-plugins/plugins/vmgrid/files/run-vmgrid.sh')
-rw-r--r-- | src/os-plugins/plugins/vmgrid/files/run-vmgrid.sh | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/src/os-plugins/plugins/vmgrid/files/run-vmgrid.sh b/src/os-plugins/plugins/vmgrid/files/run-vmgrid.sh new file mode 100644 index 00000000..51cb5dbc --- /dev/null +++ b/src/os-plugins/plugins/vmgrid/files/run-vmgrid.sh @@ -0,0 +1,430 @@ +#!/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 <memory size in MB>] \c" + echo -e "[--nice <nice level>] [/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 '<?xml' "${xmlfile}" >/dev/null 2>&1; then + writelog \ + "Submitted configuration file ${xmlfile} seems to have wrong XML format" + exit 1 +fi + +################################################################################ +### Logo for console +################################################################################ + +cat <<EOL + __ __ + .----.--.--.-----.___.--.--.--------.-----.----.|__|.--| | + | _| | | |___| | | | _ | _|| || _ | + |__| |_____|__|__| \___/|__|__|__|___ |__| |__||_____| + |_____| + OpenSLX virtual machine environment preparation script ... + +EOL + +################################################################################ +### Read needed variables from XML file +################################################################################ + +writelog "Starting configuration..." +writelog "\tVM-ID:\t\t\t${VM_ID}" +writelog "\tLogfile:\t\t${OPENSLX_DEFAULT_LOGDIR}/run-vmgrid.${USER}.$$.log" +writelog "\t/tmp info:\t\t$(df -h | grep " /tmp$" | awk '{print $2}') \c" +writelog "$(grep "/tmp " /proc/mounts | awk '{print $1" "$2" "$3" "$4}')" +writelog "\tVM XML dir:\t\t$(dirname ${xmlfile})" +writelog "\tXML file:\t\t${xmlfile}" +writelog "VM config:" + +# name of the virt image or dir +imgname=$(grep -io '<image_name param=.*"' ${xmlfile} \ + | sed -e "s/&.*;/; /g" | awk -F '"' '{ print $2 }') + +# image mode +imgmode=$(grep -io '<image_mode param=.*"' ${xmlfile} \ + | sed -e "s/&.*;/; /g" | awk -F '"' '{ print $2 }') + +# get boot attr +boot=$(grep -io 'boot param=.*"' ${xmlfile} | awk -F '"' '{ print $2 }') +diskless=0 + +# special rw image +if [ "${imgmode}" = "rwimg" ]; then + # maybe you want to use an empty rw imgae? + # define only for writelog, will be set in the plugin include again! + vmpath="{special rw image}" + # add new path for rwimg + imgpath=${vmgrid_rwmnt}/specialrwimages + unset $imgname + mkdir -m 1777 -p ${imgpath} +# diskless boot +elif [ "${boot}" = "n" ] && [ -z "${imgname}" ]; then + diskless=1 + vmpath="{diskless boot}" +# imagename /w full path +elif echo ${imgname} 2>/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 '<os param=.*"' ${xmlfile} | awk -F '"' '{ print $2 }' \ + | tr [A-Z] [a-z]) + +# definition of the networking the client system is connected to +network_kind=$(grep -io '<network param=.*"' ${xmlfile} \ + | awk -F '"' '{ print $2 }' | tr [A-Z] [a-z]) +network_card=$(grep -io '<netcard param=.*"' ${xmlfile} \ + | awk -F '"' '{ print $2 }'| tr [A-Z] [a-z]) + +# define redirects +redirects=$(grep -ic '<redirect name=.*"' ${xmlfile}) +[ -z "${redirects}" ] && redirects=0 +(( i=1 )) +while [ ${i} -le ${redirects} ]; do + # get only the $i-th line + redirect_name[$i]=$(grep -m ${i} -io '<redirect.*' ${xmlfile} | tail -n 1 \ + | grep -o "name=\".*" | awk -F '"' '{ print $2 }') + redirect_proto[$i]=$(grep -m ${i} -io '<redirect.*' ${xmlfile} | tail -n 1 \ + | grep -o "proto=\".*" | awk -F '"' '{ print $2 }') + redirect_hport[$i]=$(grep -m ${i} -io '<redirect.*' ${xmlfile} | tail -n 1 \ + | grep -o "hostport=\".*" | awk -F '"' '{ print $2 }') + redirect_gport[$i]=$(grep -m ${i} -io '<redirect.*' ${xmlfile} | tail -n 1 \ + | grep -o "guestport=\".*" | awk -F '"' '{ print $2 }') + (( i=$i+1 )) +done + +writelog "\tVirtualization:\t\t$xmlvirt" +writelog "\tVM name:\t\t$vm_name" +writelog "\tVM short name:\t\t$vm_shortname" + +############################################################################### +### Declaration of default variables +############################################################################### + +# make sure cpu_cores is not empty +cpu_cores=${cpu_cores:-"1"} +#vmgrid::maxvcpus +#vmgrid::minvcpus +# check for CPU virtualization flags +#vmgrid::vt + +# total amount of memory defined in stage 3 +permem=60 +# get a result which can be divided through 4 +mem=$(expr ${totalmem} / 100 \* ${permem} / 4 \* 4) +#vmgrid::maxmem +#vmgrid::minmem + +# configuring ethernet mac address: first 3 bytes are fixed (00:50:56) +# 4th byte is the VM-ID +# last two bytes are taken from the bridge of the host +# define one MAC per guest +macguestpart="00:50:56:${VM_ID}" +machostpart=$(echo ${hostmacaddr} | awk -F ":" '{print $(NF-1)":"$NF}') +macaddr=$(echo "${macguestpart}:${machostpart}" | tr [a-z] [A-Z]) + +# ide is expected default, test for the virtual disk image type should +# be done while creating the runscripts ... +# TODO: cdrom / floppy? +ide="TRUE" +scsi="FALSE" +hddrv="ide" +cdrom0="FALSE" +audio="false" +remotedesktopport="590${VM_ID}" + +# add rw share +sharepath="${vmgrid_rwmnt}/folders/${vm_shortname}" +mkdir -p ${sharepath} +chmod -f 1777 "${vmgrid_rwmnt}/folders" +sharename="share" + +# set hostname: using original hostname and adding string +hostname="vmgrid${VM_ID}-$(hostname)" + +writelog "\tVM Hostname:\t\t$hostname" + +################################################################################ +### Setup the rest of the environment and run the configured vm +################################################################################ + +# Copy guest configuration (with added information) config.xml to be accessed +# via virtual floppy +# TODO: virt-floppy needed? + +# Get all virtual machine specific stuff from the respective include file +if [ -e ${PLUGINCONFROOT}/${vmgrid_virt}/run-virt.include ] ; then + writelog "Starting ${vmgrid_virt} specific part ..." + self=${vmgrid_virt} + . ${PLUGINCONFROOT}/${vmgrid_virt}/run-virt.include +else + writelog "Failed because of missing ${vmgrid_virt} plugin" + exit 1 +fi + +# start graphical mode +if [ ${headless} -eq 0 ]; then + if [ -z "${VIRTCMD}" ]; then + writelog "Grapical mode not available, exiting!" + cleanexit 1 + fi + writelog "Starting ${vmgrid_virt} in graphical mode /w nice level ${unice}..." + # start /w low nice level + nice -n ${unice} ${VIRTCMD} ${VIRTCMDOPTS} 2>/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 |