From 94fab6008b14c8b62e8b5a68b5e19cf9797b6499 Mon Sep 17 00:00:00 2001 From: Jonathan Bauer Date: Thu, 1 Feb 2018 18:01:22 +0100 Subject: [vbox-src] run-virt plugin functional (wip) --- .../vmchooser/plugins/virtualbox/empty-diff.vdi.gz | Bin 0 -> 285 bytes .../virtualbox/includes/create_vbox_config.inc | 45 ++++++++ .../includes/finalize_machine_config.inc | 58 ++++++++++ .../virtualbox/includes/guest_hardware_limits.inc | 118 +++++++++++++++++++++ .../plugins/virtualbox/includes/init_core.inc | 52 +++++++++ .../virtualbox/includes/log_config_summary.inc | 30 ++++++ .../virtualbox/includes/prepare_snapshot.inc | 36 +++++++ .../vmchooser/plugins/virtualbox/run-virt.include | 57 ++++++++++ .../vmchooser/plugins/virtualbox/rwimg.vdi.gz | Bin 0 -> 268 bytes 9 files changed, 396 insertions(+) create mode 100644 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/empty-diff.vdi.gz create mode 100755 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/create_vbox_config.inc create mode 100755 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/finalize_machine_config.inc create mode 100755 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/guest_hardware_limits.inc create mode 100755 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/init_core.inc create mode 100755 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/log_config_summary.inc create mode 100755 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/prepare_snapshot.inc create mode 100755 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/run-virt.include create mode 100644 core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/rwimg.vdi.gz (limited to 'core/modules/vbox-src/data/opt/openslx/vmchooser') diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/empty-diff.vdi.gz b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/empty-diff.vdi.gz new file mode 100644 index 00000000..c6abbd57 Binary files /dev/null and b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/empty-diff.vdi.gz differ diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/create_vbox_config.inc b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/create_vbox_config.inc new file mode 100755 index 00000000..2825da5d --- /dev/null +++ b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/create_vbox_config.inc @@ -0,0 +1,45 @@ +################################################################################ +# Include: create main vbox config file and add machine, hdd, ... entries # +################################################################################ +create_vbox_config() { + cat <<- EOF > "${VBOX_ROOT}/VirtualBox.xml" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EOF +} + +call_post_source create_vbox_config diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/finalize_machine_config.inc b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/finalize_machine_config.inc new file mode 100755 index 00000000..c5b062f9 --- /dev/null +++ b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/finalize_machine_config.inc @@ -0,0 +1,58 @@ +################################################################################ +# Include: write final machine configuration file # +################################################################################ +finalize_machine_config() { + # Expected path to the final vbox file + VBOX_MACHINE_CONFIG="${VBOX_MACHINES_DIR}/${VM_CLEANNAME}/${VM_CLEANNAME}.xml" + + # remove ':' from MAC addr for vbox and generate a VDE (virtual device ethernet) + # MAC addr from the first one (put in prefix 00DE) + VM_MAC_ADDR=$(echo ${VM_MAC_ADDR} | sed 's/://g') + VM_VDE_MAC_ADDR=$(echo ${VM_MAC_ADDR} | sed 's/^..../00DE/g') + + # 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 + + sed -i "s,%VM_DISK_REDOLOGDIR%,$VBOX_SNAPSHOT_DIR,g" $TMPCONFIG + sed -i "s,%VM_DISK_PATH%,${VBOX_HDD_LINK},g" $TMPCONFIG + sed -i "s/#OpenSLX_MUUID_place_holder/{${MACHINE_UUID}}/g" $TMPCONFIG + sed -i "0,/#OpenSLX_HDDUUID_0_placeholder/ s/#OpenSLX_HDDUUID_0_placeholder/{${HDD_UUID}}/" $TMPCONFIG + sed -i "0,/#OpenSLX_HDDUUID_0_placeholder/ s/#OpenSLX_HDDUUID_0_placeholder/{${SNAPSHOT_UUID}}/" $TMPCONFIG + sed -i 's,#OpenSLX_CPU_place_holder,'"${CPU_CORES}"',g' $TMPCONFIG + sed -i 's,#OpenSLX_MEMORY_place_holder,'"${VM_MEM}"',g' $TMPCONFIG + + # Add a HardDisk node + xmlstarlet ed -L -N x="http://www.virtualbox.org/" -s "//x:VirtualBox/x:Machine/x:MediaRegistry/x:HardDisks/x:HardDisk" -t elem -n HardDisk $TMPCONFIG + # Add attributes: + # 1) uuid attribute and point to the snapshotuuid from above + # 2) location pointing to the snapshot file + # 3) specify that format is VDI + # 4) hdd type is "normal" + xmlstarlet ed -L -N x="http://www.virtualbox.org/" \ + -i "//x:VirtualBox/x:Machine/x:MediaRegistry/x:HardDisks/x:HardDisk/x:HardDisk" -t attr -n uuid -v "{${SNAPSHOT_UUID}}" \ + -i "//x:VirtualBox/x:Machine/x:MediaRegistry/x:HardDisks/x:HardDisk/x:HardDisk" -t attr -n location -v "$VBOX_SNAPSHOT_DIR/{${SNAPSHOT_UUID}}.vdi" \ + -i "//x:VirtualBox/x:Machine/x:MediaRegistry/x:HardDisks/x:HardDisk/x:HardDisk" -t attr -n format -v "VDI" \ + -i "//x:VirtualBox/x:Machine/x:MediaRegistry/x:HardDisks/x:HardDisk/x:HardDisk" -t attr -n type -v "Normal" \ + $TMPCONFIG + # set the MAC address + xmlstarlet ed -L -N x="http://www.virtualbox.org/" -u "//x:VirtualBox/x:Machine/x:Hardware/x:Network/x:Adapter/@MACAddress" -v "$VM_VDE_MAC_ADDR" $TMPCONFIG + # delete USB controller - TODO fix + xmlstarlet ed -L -N x="http://www.virtualbox.org/" -d "//x:VirtualBox/x:Machine/x:Hardware/x:USB" $TMPCONFIG + + # TODO VT-x + + cp $TMPCONFIG /tmp/vbox-last-config + cp $TMPCONFIG $VBOX_MACHINE_CONFIG +} + +call_post_source finalize_machine_config diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/guest_hardware_limits.inc b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/guest_hardware_limits.inc new file mode 100755 index 00000000..224bccde --- /dev/null +++ b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/guest_hardware_limits.inc @@ -0,0 +1,118 @@ +################################################################################ +# Include: Set hardware limitations determined by the guest os type # +################################################################################ + +set_hardware_limits() { + #SHARED_FOLDERS="TRUE" + #enablevt="true" + #enable2d + #enable3d + + # set some base configuration depending on the guest operating system + # NOTE: list supported OS type with: VBoxManage list ostypes + case "${VM_OS_TYPE}" in + Windows31) + MAXCORES="1" + MAXMEM="32" + MAXVRAM="16" + SHARED_FOLDERS="FALSE" + ;; + WindowsNT*) + MAXCORES="4" + MAXMEM="1024" + MAXVRAM="32" + SHARED_FOLDERS="FALSE" + ;; + Windows95) + MAXCORES="1" + MAXMEM="128" + MAXVRAM="32" + SHARED_FOLDERS="FALSE" + ;; + Windows98) + MAXCORES="1" + MAXMEM="256" + MAXVRAM="64" + SHARED_FOLDERS="FALSE" + ;; + WindowsMe) + MAXCORES="1" + MAXMEM="384" + MAXVRAM="64" + SHARED_FOLDERS="FALSE" + ;; + Windows2000|Windows2003) + MAXCORES="4" + MAXMEM="4000" + MAXVRAM="128" + SHARED_FOLDERS="FALSE" + ;; + Windows2003_64|WindowsXP_64) + MAXCORES="4" + MAXMEM="8000" + MAXVRAM="128" + ;; + WindowsXP) + MAXCORES="4" + MAXMEM="4000" + MAXVRAM="128" + ;; + WindowsVista) + MAXCORES="4" + MAXMEM="4000" + MAXVRAM="128" + ;; + WindowsVista_64) + MAXCORES="4" + MAXMEM="16000" + MAXVRAM="128" + ;; + Windows7|Windows8|Windows81|Windows10) + MAXCORES="4" + MAXMEM="4000" + MAXVRAM="128" + ;; + Windows7_64|Windows8_64|Windows81_64|Windows10_64) + MAXCORES="4" + MAXMEM="32000" + MAXVRAM="128" + ;; + ArchLinux|Debian|OpenSUSE|Fedora|Gentoo|Mandriva|RedHat|Turbolinux|Ubuntu) + MAXCORES="4" + MAXMEM="4000" + MAXVRAM="128" + ;; + ArchLinux_64|Debian_64|OpenSUSE_64|Fedora_64|Gentoo_64|Mandriva_64|RedHat_64|Turbolinux_64|Ubuntu_64) + MAXCORES="8" + MAXMEM="32000" + MAXVRAM="128" + ;; + *Linux*) + MAXCORES="4" + MAXMEM="1024" + MAXVRAM="32" + ;; + *Linux*64) + MAXCORES="8" + MAXMEM="8000" + MAXVRAM="128" + ;; + OS2eCS) + MAXMEM="256" + MAXCORES=1 + ;; + *) + MAXMEM="512" + MAXCORES="1" + ;; + # TODO: FreeBSD, NetBSD, MacOS*, Solaris, Oracle, ... + esac + + [ "${CPU_CORES}" -gt "{MAXCORES}" ] && CPU_CORES="${MAXCORES}" + + [ "${VM_MEM}" -gt "${MAXMEM}" ] && VM_MEM="${MAXMEM}" + + return 0 +} + +call_post_source set_hardware_limits diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/init_core.inc b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/init_core.inc new file mode 100755 index 00000000..ad3cbe96 --- /dev/null +++ b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/init_core.inc @@ -0,0 +1,52 @@ +####################################################################### +# Include: Declaration of core variables and some sanity checks # +####################################################################### +init_core() { + # check for variables that should have been set by the generic run-virt + if ! isset VM_CLEANNAME IMG_BASENAME SRC_IMG_ABSOLUTE VM_OS_TYPE; then + local MSG="Incomplete A required variable was not set by generic run-virt." + slxlog "virt-vbox-init" "${MSG}" + writelog "${MSG}" + error_user "Wichtige variablen, die das VBox Plugin benötigt, wurden nicht + gesetzt. Kann die VM nicht starten." + cleanexit 1 + fi + + # Check for vbox binaries in VBOX_BASE_DIR + for BIN in VBoxManage VirtualBox VBoxHeadless; do + if ! [ -x "${VBOX_BASE_DIR}/${BIN}" ]; then + local MSG="${BIN} not found in ${VBOX_BASE_DIR}." + writelog "${MSG}" + slxlog "virt-vbox-bin" "${MSG}" + cleanexit 1 + fi + done + + # Define which features the VMware plugin supports + 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_CLEANNAME}/Snapshots" + if ! mkdir -p "${VBOX_SNAPSHOT_DIR}"; then + writelog "Failed to create '${VBOX_SNAPSHOT_DIR}'." + cleanexit 1 + fi + declare -rg VBOX_HDD_DIR="${VBOX_ROOT}/HardDisks" + if ! mkdir -p "${VBOX_HDD_DIR}"; then + writelog "Failed to create '${VBOX_HDD_DIR}'." + cleanexit 1 + fi + declare -rg VBOX_HDD_LINK="${VM_DISKFILE_RO}" + export VBOX_USER_HOME="${VBOX_ROOT}" # instead of $HOME/.VirtualBox + + # finally generate a random machine UUID, using some default if it fails. + declare -g MACHINE_UUID="$(cat /proc/sys/kernel/random/uuid)" + notempty MACHINE_UUID || MACHINE_UUID="00000000-0000-0000-0000-12345678" + readonly MACHINE_UUID + + writelog "Directories:" + writelog "\tConfig dir:\t\t$VBOX_ROOT" + writelog "\tMachines dir:\t\t$VBOX_MACHINES_DIR" + writelog "\tSnapshots dir:\t\t$VBOX_SNAPSHOT_DIR" +} + +call_post_source init_core diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/log_config_summary.inc b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/log_config_summary.inc new file mode 100755 index 00000000..a084ee1f --- /dev/null +++ b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/log_config_summary.inc @@ -0,0 +1,30 @@ +################################################################################ +# Include: log a summary of the configuration state for this machine # +################################################################################ +log_config_summary() { + writelog "\tSnapshots dir:\t\t$VBOX_SNAPSHOT_DIR" + writelog "Diskimage:" + writelog "\tDisk file:\t\t$VBOX_HDD_LINK" + writelog "\tDisk type:\t\tVDI" + writelog "\tGuest OS:\t\t$VM_OS_TYPE" + writelog "\tMachine UUID:\t\t$MACHINE_UUID" + writelog "\tDisk UUID:\t\t$VBOX_HDD_UUID" + writelog "Virtual Hardware:" + writelog "\tCPU cores:\t\t${CPU_CORES}\c" + writelog "" + [ "$HW_KVM" = "ENABLED" ] && writelog "\t(VT enabled CPU)" + writelog "\tGuest RAM:\t\t${VM_MEM} MB" + # echo nur wenn HOST_MEM_REMAINING gesetzt + [ -n "${HOST_MEM_REMAINING}" ] && writelog "\tHost RAM:\t\t${HOST_MEM_REMAINING} MB" + writelog "\tMAC address:\t\t$VM_MAC_ADDR" + 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 "\tFloppy_A:\t\t${floppy0}" + writelog "\tFloppy_B:\t\t${floppy1}" + writelog "\tShared Folders '${sharename}':\t${sharepath}" +} + +call_post_source log_config_summary diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/prepare_snapshot.inc b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/prepare_snapshot.inc new file mode 100755 index 00000000..296f55ae --- /dev/null +++ b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/includes/prepare_snapshot.inc @@ -0,0 +1,36 @@ +prepare_snapshot() { + SNAPSHOT_UUID="34f617be-192a-46b3-a8ae-bce1029e093f" # snapshot UUID is static + + # get UUID of VBox image + HDD_UUID=$(${VBOX_BASE_DIR}/VBoxManage -q showvdiinfo ${VBOX_HDD_LINK} \ + | grep UUID | grep -v "Parent UUID" | awk '{print $2}' \ + | grep -v use ) # nec. for VBox >= 4 + + # TODO support vmdk disks? + VBOX_HDD_FORMAT="VDI" + + if isset VM_DISKFILE_RO; then + # use temp disk as snapshot to get CoW + VBOX_HDD_TYPE="Immutable" # make disk immutable + VBOX_HDD_UUID=${SNAPSHOT_UUID} + < "${VBOX_PLUGIN_DIR}/empty-diff.vdi.gz" gunzip > "${VBOX_SNAPSHOT_DIR}/{${SNAPSHOT_UUID}}.vdi" + # patch the disk file uuid into the snapshot vdi file: + # We read from offset 424 in the source HDD and write the 16 bytes long UUID + # starting at offset 392 in the snapshot. + # 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}/{${SNAPSHOT_UUID}}.vdi" seek=424 \ + skip=392 bs=1 count=16 conv=notrunc || \ + writelog "Could not patch snapshot file" + elif isset VM_DISKFILE_RW; then + # Image is already RW - easy + VBOX_HDD_TYPE="Normal" + VBOX_HDD_UUID=${HDD_UUID} + else + writelog "Neither VM_DISKFILE_RO nor VM_DISKFILE_RW defined!" + cleanexit 1 + fi +} + +call_post_source prepare_snapshot diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/run-virt.include b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/run-virt.include new file mode 100755 index 00000000..6fedf15c --- /dev/null +++ b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/run-virt.include @@ -0,0 +1,57 @@ +# ----------------------------------------------------------------------------- +# Copyright (c) 2009..2018 - RZ Uni Freiburg +# Copyright (c) 2009..2018 - 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 +################################################################################ + +declare -rg VBOX_PLUGIN_DIR="$(dirname "${BASH_SOURCE[0]}")" +declare -rg VBOX_INCLUDE_DIR="${VBOX_PLUGIN_DIR}/includes" +declare -rg VBOX_BASE_DIR="/usr/lib/virtualbox" + +#declare -rg PLUGIN_FEATURES="slxfloppy firewall printer usb sound netshares" +declare -rg PLUGIN_FEATURES="slxfloppy" + +run_plugin() { + # declaration of default variables and some sanity checks + $(safesource --exit "${VBOX_INCLUDE_DIR}/init_core.inc") + + # determine hardware limits based on guest OD + $(safesource --exit "${VBOX_INCLUDE_DIR}/guest_hardware_limits.inc") + + # prepare volatile rw layer for the disk image using a snapshot + $(safesource --exit "${VBOX_INCLUDE_DIR}/prepare_snapshot.inc") + + # create main virtualbox configuration + $(safesource --exit "${VBOX_INCLUDE_DIR}/create_vbox_config.inc") + + # finalize machine configuration + $(safesource --exit "${VBOX_INCLUDE_DIR}/finalize_machine_config.inc") + + # log config summary + $(safesource --exit "${VBOX_INCLUDE_DIR}/log_config_summary.inc") + + # This is necessary for the VM to start (don't ask me why, yet!) + 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) + declare -rg VIRTCMD="${VBOX_BASE_DIR}/VirtualBox" + declare -rg VIRTCMDOPTS="--startvm ${MACHINE_UUID} --start-running --fullscreen" + + # set headless mode (-v off to disable vrdp) + declare -rg VIRTCMDHL="${VBOX_BASE_DIR}/VBoxHeadless" + declare -rg VIRTCMDOPTSHL="-s ${MACHINE_UUID}" +} diff --git a/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/rwimg.vdi.gz b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/rwimg.vdi.gz new file mode 100644 index 00000000..e2133d6d Binary files /dev/null and b/core/modules/vbox-src/data/opt/openslx/vmchooser/plugins/virtualbox/rwimg.vdi.gz differ -- cgit v1.2.3-55-g7522