summaryrefslogblamecommitdiffstats
path: root/src/os-plugins/plugins/vmgrid/files/run-vmgrid.sh
blob: 51cb5dbc62f04054e0216f24789c482bbe5e4d92 (plain) (tree)
1
2
3
4

                                                                               

                                   
























                                                                                


                                                                








                                                                                
                                                           



                   
                            



                                                                










                                                                



                                                                                
                                          
          
        


                      
                                                                        
                                                            




                
          
                                                   

















                                                                            













































                                                                                
                                














































                                                                                
                                    






































































                                                                                
                                                               










































                                                                            

                                                                            

                                                                
                                                         
                                                            
                                                         
                                                           
 
















                                                                              







                                                                               

                                  

                 
                                    
           
 
                                           
         
                                             
                                                   

               





                                                                       
                                                                       







                                                                      
              
             
                               




















                                                                                
                                                                  
                                                      










                                                            
               
    


                                                                                

                                


                                                                               

                                                               
             

  




                                                   
           
      
#!/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