|
|
# -----------------------------------------------------------------------------
# Copyright (c) 2009..2011 - RZ Uni Freiburg
# Copyright (c) 2009..2013 - 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
# - component for virtualbox of the vmchooser plugin vmchooser-run_virt
################################################################################
[ -r /run/hwinfo ] && source /run/hwinfo
################################################################################
### declaration of default variables
################################################################################
if ! isset VM_NAME_CLEAN IMG_BASENAME SRC_IMG_ABSOLUTE VM_OS_TYPE; then
env=$(mktemp)
env > "$env"
slxlog -d "virt-vbox-init" "A required variable is not set." "$env"
writelog "Incomplete variable set passed from main run-virt"
error_user "Wichtige variablen, die das VBox Plugin benötigt, wurden nicht
gesetzt. Kann die VM nicht starten."
cleanexit 1
fi
declare -rg VMCHOOSERVBOX="/opt/openslx/vmchooser/${self}"
declare -rg VBOX_ROOT="${TMPDIR}/vbox" # dir for configs
declare -rg VBOX_MACHINES_DIR="${VBOX_ROOT}/Machines"
declare -rg VBOX_SNAPSHOT_DIR="${VBOX_MACHINES_DIR}/${VM_NAME_CLEAN}/Snapshots"
declare -rg VBOX_HDD_DIR="${VBOX_ROOT}/HardDisks"
declare -rg VBOX_HDD_LINK="${VBOX_HDD_DIR}/${IMG_BASENAME}"
export VBOX_USER_HOME="${VBOX_ROOT}" # instead of $HOME/.VirtualBox
# use VM_NAME_CLEAN for dir and config names since VM_DISPLAYNAME can be very long
VBOX_MACHINE_CONFIG="${VBOX_MACHINES_DIR}/${VM_NAME_CLEAN}/${VM_NAME_CLEAN}.xml"
mkdir -p "${VBOX_HDD_DIR}" "${VBOX_SNAPSHOT_DIR}" 2>/dev/null
enable2d="true" # default setting for accelerated 2D grapics (OS dependent)
vram="128" # set default graphics ram
snapshotuuid="34f617be-192a-46b3-a8ae-bce1029e093f" # snapshot UUID is static
# link to image, determine extension (type)
imgfmt=$(echo ${SRC_IMG_ABSOLUTE##*.} | tr '[a-z]' '[A-Z]')
if [ -n "$VM_DISKFILE_RW" ]; then
ln -sf "${VM_DISKFILE_RW}" "${VBOX_HDD_LINK}"
else
ln -sf "${VM_DISKFILE_RO}" "${VBOX_HDD_LINK}"
# image is RO, we only support VDI?
if [ "$imgfmt" != "VDI" ]; then
writelog "Image is not VDI, cannot create snapshot.."
error_log "Die gewählte VM nutzt VBox, hat aber kein VDI image (sondern '$imgfmt'), kann VM nicht starten."
cleanexit 1
fi
fi
# Setting some default variables
shfolders="TRUE"
enablevt="true"
# set some base configuration depending on the guest operating system
case "${VM_OS_TYPE}" in
Windows31)
mem="32"
vram="16"
cpu_cores=1
enablevt="false"
shfolders="FALSE"
;;
WindowsNT)
mem="4096"
vram="16"
cpu_cores=4
enablevt="false"
shfolders="FALSE"
;;
Windows95)
mem="128"
vram="32"
cpu_cores=1
enablevt="false"
shfolders="FALSE"
;;
Windows98)
mem="256"
vram="64"
cpu_cores=1
shfolders="FALSE"
;;
WindowsMe)
mem="256"
vram="64"
cpu_cores=1
shfolders="FALSE"
;;
WindowsXP)
;;
WindowsVista)
;;
Windows7)
;;
Windows8)
;;
OS2eCS)
mem="256"
cpu_cores=1
enable2d="false"
;;
MacOS)
enable2d="false"
;;
Linux*)
;;
*)
VM_OS_TYPE="Other"
enable2d="false"
;;
esac
if [ "$HW_KVM" != "ENABLED" ]; then
enablevt="false"
cpu_cores=1 # check for VT, if not available only 1 cpu supported
fi
writelog "Directories:"
writelog "\tConfig dir:\t\t$VBOX_ROOT"
writelog "\tMachines dir:\t\t$VBOX_MACHINES_DIR"
writelog "\tMachine config:\t\t$VBOX_MACHINE_CONFIG"
################################################################################
### Hardware checks
################################################################################
# remove ':' from MAC addr for vbox and generate a VDE (virtual device ethernet)
# MAC addr from the first one (put in prefix 00DE)
macaddr=$(echo ${macaddr} | sed 's/://g')
vdemacaddr=$(echo ${macaddr} | sed 's/^..../00DE/g')
machineuuid="00000000-0000-0000-0000-${macaddr}" # machine UUID, MAC addr part of it
machineuuid=$(echo ${machineuuid} | tr "[A-Z]" "[a-z]") # cosmetical, since UUID in lower case
# get UUID of VBox image
diskuuid=$(VBoxManage -q showvdiinfo ${VBOX_HDD_LINK} \
| grep UUID | grep -v "Parent UUID" | awk '{print $2}' \
| grep -v use ) # nec. for VBox >= 4
if [ -n "$VM_DISKFILE_RW" ]; then
# Image is already RW - easy
imgtype="Normal"
imageuuid=${diskuuid}
else
# use temp disk as snapshot to get CoW
imgtype="Immutable" # make disk immutable
imageuuid=${snapshotuuid}
< "${VMCHOOSERVBOX}/empty-diff.vdi.gz" gunzip > "${VBOX_SNAPSHOT_DIR}/{${snapshotuuid}}.vdi"
# patch the disk file uuid into the snapshot vdi file:
# We read from offset 424 in the source HDD and write to offset 392 in out prepared
# CoW container. 16 bytes will be copied, which is the binary UUID
# TODO: This requires the image to be a vdi/vdh; Afaik, vbox supports vmdk,
# so this code would break in that case. Can we use the diskuuid we got via
# VBoxManage, convert to binary, and patch it
dd if=${VBOX_HDD_LINK} of="${VBOX_SNAPSHOT_DIR}/{${snapshotuuid}}.vdi" seek=424 \
skip=392 bs=16 count=1 conv=notrunc
fi
# translate network kinds (nat, bridged, host-only)
# TODO: Server should prepare this in returned xml
case "${network_kind}" in
bridge*)
network_kind='HostOnlyInterface name="vboxnet0"'
;;
host*)
network_kind='HostOnlyInterface name="vboxnet2"'
;;
*)
network_kind='HostOnlyInterface name="vboxnet1"'
esac
boot="HardDisk"
writelog "\tSnapshots dir:\t\t$VBOX_SNAPSHOT_DIR"
writelog "Diskimage:"
writelog "\tDisk file:\t\t$VBOX_HDD_LINK"
writelog "\tDisk type:\t\t$imgtype"
writelog "\tVMostype:\t\t$VM_OS_TYPE"
writelog "\tMachine UUID:\t\t$machineuuid"
writelog "\tDisk UUID:\t\t$diskuuid"
writelog "Virtual Hardware:"
writelog "\tCPU cores:\t\t${cpu_cores}\c"
writelog ""
[ "$HW_KVM" = "ENABLED" ] && writelog " (VT enabled CPU)"
writelog "\tGuest RAM:\t\t${mem} MB"
# echo nur wenn hostmem gesetzt
[ -n "${hostmem}" ] && writelog "\tHost RAM:\t\t${hostmem} 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"
writelog ""
writelog "\tCD-ROM1:\t\t${cdrom0}"
#writelog "\tCD-ROM2:\t\t${cdrom1}"
writelog "\tFloppy_A:\t\t${floppy0}"
writelog "\tFloppy_B:\t\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
# Shares given?
if [ "x$shfolders" != "xFALSE" ]; then
sharelist="<SharedFolders>
<SharedFolder name=\"${homesharename}\" hostPath=\"${homesharepath}\" writable=\"true\"/>
<SharedFolder name=\"${commonsharename}\" hostPath=\"${commonsharepath}\" writable=\"true\"/>
</SharedFolders>"
else
sharelist=''
fi
source "${VMCHOOSERVBOX}/virtualbox.include" # create Virtualbox.xml
# remove snapshot disk when using rw images
if [ "${imgtype}" != "Immutable" ]; then
sed -i "/${snapshotuuid}/d" "${VBOX_ROOT}/VirtualBox.xml"
fi
# TODO: add rawdisk if requested
#"raw.vmdk" format="VMDK" type="Writethrough"/>
source "${VMCHOOSERVBOX}/machine.include" # create machine.xml
# remove CD-ROM if not available
if [ "${cdrom0}" != "TRUE" ]; then
sed -i "/HostDrive/d" "${VBOX_MACHINE_CONFIG}"
sed -i '/AttachedDevice.*type="DVD"/d' "${VBOX_MACHINE_CONFIG}"
sed -i "/<!-- PLEASE DO NOT REMOVE THIS COMMENT (CD)!!! -->/d" "${VBOX_MACHINE_CONFIG}"
fi
################################################################################
### Set env for vmchooser-run_virt
################################################################################
# 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 --fullscreen"
# set headless mode (-v off to disable vrdp)
VIRTCMDHL=$(which VBoxHeadless 2>/dev/null)
VIRTCMDOPTSHL="-s ${machineuuid}"
|