summaryrefslogblamecommitdiffstats
path: root/os-plugins/plugins/vmgrid/files/run-vmgrid.sh
blob: 626dfcca94d0a52bc1275a855e4fd1ec3dff21b4 (plain) (tree)

































































































































































































































































































































































































                                                                                
#!/bin/bash
# -----------------------------------------------------------------------------
# Copyright (c) 2007..2010 - RZ Uni FR
# Copyright (c) 2007..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
#[ -f ${PLUGINCONFVMGRID}/vmgrid.include ] && \
#  . ${PLUGINCONFVMGRID}/vmgrid.include
# 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
writelog () {
  # write to stdout
  echo -e "$1"
  # log into file
  echo -e "$1" >> ${OPENSLX_DEFAULT_LOGDIR}/run-vmgrid.${USER}.$$.log
  # log into share dir, so that log is available in vm as well
  echo -e "$1" >> ${vmgrid_rwmnt}/logs/run-vmgrid.${USER}.$$.log
}

################################################################################
### Get XML file and dir
################################################################################

# check if forcemem or graphical mode set
headless=1
while [ $# -gt 0 ]; do
  case "$1" in
    -h|--help)
      echo -e "Usage: run-vmgrid.sh [-g] [--forcemem <memorysize in MB>] \c"
      echo -e "[/path/]filename[.xml]"
      exit
    ;;
    -g)
      headless=0
    ;;
    --forcemem)
      forcemem=$2
      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})"

if ! grep '<?xml' "${xmlfile}" >/dev/null 2>&1; then
  writelog \
    "Submitted configuration file ${xmlfile} seems to have wrong XML format"
  exit 1
fi

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)
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 }')

# definition of the networking the client system is connected to
network_kind=$(grep -io 'network param=.*"' ${xmlfile} \
               | awk -F '"' '{ print $2 }')
network_card=$(grep -io 'netcard param=.*"' ${xmlfile} \
               | awk -F '"' '{ print $2 }')

writelog "\tVirtualization:\t\t$xmlvirt"
writelog "\tVM name:\t\t$vm_name"
writelog "\tVM short name:\t\t$vm_shortname"

###############################################################################
### Declaration of default variables
###############################################################################

# TODO: cpu cores
#vmgrid::maxvcpus
#vmgrid::minvcpus
#cpu_cores="${cpu_cores}"

# check for CPU virtualization flags
#vmgrid::hvm

# get total amount of memory installed in your machine
totalmem=$(expr $(grep -i "memtotal" /proc/meminfo | awk '{print $2}') / 1024)
permem=60
mem=$(expr ${totalmem} / 100 \* ${permem} / 4 \* 4)
#vmgrid::maxram
#vmgrid::minram

# 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=$($(which ifconfig) br0 | grep br0 | sed -e "s/ //g" \
              | 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"

# 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
# TODO: rename to run-vuirt.include
if [ -e ${PLUGINCONFROOT}/${vmgrid_virt}/run-virt.include ] ; then
  writelog "Strating ${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!"
    exit 1
  fi
  writelog "Starting ${vmgrid_virt} in graphical mode..."
  ${VIRTCMD} ${VIRTCMDOPTS} 2>/dev/null
# start headless
elif [ -n "${VIRTCMDHL}" ]; then
  writelog "Starting ${vmgrid_virt} in headless mode..."
  ${VIRTCMDHL} ${VIRTCMDOPTSHL} 2>/dev/null
else
  writelog "${vmgrid_virt}: No headless mode defined, exiting!"
  exit 1
fi

# remove config dirs when finished
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

echo -e "Bye."
exit 0