# ----------------------------------------------------------------------------- # 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=" " 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 "//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}"