diff options
author | Simon Rettberg | 2019-05-17 12:30:24 +0200 |
---|---|---|
committer | Simon Rettberg | 2019-05-17 12:30:24 +0200 |
commit | e384d068e1f101087b85e97c35ef1d434cc7790a (patch) | |
tree | bc8130eed93bc8eee730fa3431f7fc8e70ddea25 | |
parent | [screen-standby] Remove forgotten interfering module (diff) | |
download | mltk-e384d068e1f101087b85e97c35ef1d434cc7790a.tar.gz mltk-e384d068e1f101087b85e97c35ef1d434cc7790a.tar.xz mltk-e384d068e1f101087b85e97c35ef1d434cc7790a.zip |
[run-virt] Add hook system, remove legacy code
6 files changed, 164 insertions, 132 deletions
diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/download_vm_metadata.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/download_vm_metadata.inc index 17b679ea..dd3f63e3 100644 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/download_vm_metadata.inc +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/download_vm_metadata.inc @@ -6,16 +6,32 @@ # Legacy mode: As runvirt has been before. # New mode: uuid in xml _and_ vmx given via http. download_metadata() { - local TRIES EXTRA_ERROR WLOG TMPFILE RET ERRCODE CMDLINE + local EXTRA_ERROR= + declare -rg TMPCONFIG="$CONFDIR/vmx" + + # Run hooks + if ! run_hooks "download" "$CONFDIR"; then + # No hooks found + download_metadata_default + fi + [ -s "$TMPCONFIG" ] && return 0 + # Seems we are in legacy mode, which is no longer supported. Warn user and exit + EXIT_TYPE="user" EXIT_REASON="msg.vm.no-metadata +Die Metadaten der Lehrumgebung konnten nicht vom bwLehrpool-Satelliten +heruntergeladen werden. Bitte versuchen Sie es in wenigen Minuten erneut +und wenden Sie sich an den Support, wenn das Problem bestehen bleibt. +$EXTRA_ERROR +" cleanexit 1 +} + +download_metadata_default() { + local TRIES WLOG TMPFILE RET ERRCODE CMDLINE # Sanity checks - if ! check_dep wget; then + if ! check_dep curl; then writelog "Could not find 'wget' in PATH: $PATH" EXIT_TYPE="internal" EXIT_REASON="Fehlendes Dienstprogramm 'wget'!" cleanexit 1 fi - writelog "Detecting current/legacy mode..." - declare -rg TMPCONFIG="$CONFDIR/vmx" - # Try new unified .tar.gz way TMPFILE="$TMPDIR/metadata.tgz" WLOG="$TMPDIR/wget-metadata.log" @@ -26,51 +42,14 @@ download_metadata() { RET=$? if [ "$RET" = 0 ] && [ -n "$ERRCODE" ] && [ "$ERRCODE" -ge 200 ] && [ "$ERRCODE" -lt 300 ]; then # Success, see if data is usable - if tar -C "$CONFDIR" -x -f "$TMPFILE" && [ -s "$CONFDIR/vmx" ]; then + if tar -C "$CONFDIR" -x -f "$TMPFILE" && [ -s "$TMPCONFIG" ]; then return 0 fi rm -rf -- "$TMPFILE" - writelog "Extracting metadata.tgz failed. Trying legacy mode." + writelog "Extracting metadata.tgz failed. Cannot start VM." else - writelog "Downloading metadata.tgz failed (HTTP $ERRCODE). Trying legacy mode." - #slxlog --delete "run-virt-wget" "Downloading MetaData failed" "$WLOG" + writelog "Downloading metadata.tgz failed (HTTP $ERRCODE). Cannot start VM." "$WLOG" fi - - TRIES=0 - while [ "$TRIES" -lt 3 ]; do - TRIES=$(( TRIES + 1 )) - writelog "wget try $TRIES" - WLOG="$TMPDIR/wget-${TRIES}.log" - if wget -T 6 -O "$TMPCONFIG" "${url_lecture_config}" &>"$WLOG"; then - rm -f -- "$WLOG" - writelog "Downloaded VM description from '${url_lecture_config}' successfully." - if [ -s "$TMPCONFIG" ]; then - # Downloaded a non-zero VM description file, all good - return 0 - else - writelog "Server sent zero byte virtual machine description file." - EXTRA_ERROR="(Der Server hat eine leere Antwort gesendet)" - fi - else - ERRCODE=$(grep -m1 -o -E '\b[0-9]{3}\b' "$WLOG") - if [ -n "$ERRCODE" ]; then - EXTRA_ERROR="(HTTP Error Code $ERRCODE)" - else - EXTRA_ERROR="(Der Server ist nicht erreichbar)" - fi - writelog "wget failed." - fi - done - - slxlog --delete "run-virt-wget" "Downloading VMX/Metadata failed" "$WLOG" - - # Seems we are in legacy mode, which is no longer supported. Warn user and exit - EXIT_TYPE="user" EXIT_REASON="msg.vm.no-metadata -Die Metadaten der Lehrumgebung konnten nicht vom bwLehrpool-Satelliten -heruntergeladen werden. Bitte versuchen Sie es in wenigen Minuten erneut -und wenden Sie sich an den Support, wenn das Problem bestehen bleibt. -$EXTRA_ERROR -" cleanexit 1 } ## Main ## diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/load_configs.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/load_configs.inc index 0f1fab39..7a132fcc 100644 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/load_configs.inc +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/load_configs.inc @@ -17,9 +17,6 @@ load_configs() { # Load general virtualization information $(safesource --exit "$VMCHOOSER_CONF_DIR/virtualization.conf") - - # Load general openslx config - $(safesource --exit "/opt/openslx/config") # Load config for resource URLs $(safesource "$VMCHOOSER_CONF_DIR/resource_urls.conf") diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_image_access.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_image_access.inc index ea8afc7e..cc921228 100644 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_image_access.inc +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/setup_image_access.inc @@ -85,29 +85,25 @@ setup_fallback() { readonly VM_DISKFILE_RO } -setup_jambo() { - declare -r CMDLOG="$TMPDIR/sshfs.jambo" - declare -rg CLIENTPARTITION_ADMIN="/var/lib/vmware_admin" - #declare -r UPLOAD_KEYFILE="/var/lib/uploaduser" - #sudo -n sshfs "uploaduser@$JAMBOSERVER:/vms/bwlehrpool_store" "$CLIENTPARTITION_ADMIN" -o allow_other -o PreferredAuthentications=publickey -o IdentityFile="$UPLOAD_KEYFILE" -o IdentitiesOnly=yes &> "$CMDLOG" - sudo -n sshfs "uploaduser@$JAMBOSERVER:/vms/bwlehrpool_store" "$CLIENTPARTITION_ADMIN" -o allow_other -o PreferredAuthentications=publickey &> "$CMDLOG" - RET=$? - if [ "$RET" != "0" ]; then - writelog "SSHFS Failed - $(cat "$CMDLOG")" - EXIT_TYPE="user" EXIT_REASON="Schreibbarer VM-Speicher konnte nicht eingebunden werden. Adminmodus fehlgeschlagen." cleanexit 1 - fi - declare -rg VM_DISKFILE_RW="$CLIENTPARTITION_ADMIN/$SRC_IMG_RELATIVE" -} - - ## MAIN PART / Sanity checks ## setup_image_access() { writelog "Setting up virtual hard disk access for virtualizer/emulator ..." + unset VM_DISKFILE_RO VM_DISKFILE_RW + declare -g VM_DISKFILE_RO VM_DISKFILE_RW + + run_hooks "image-access" - if [ "$VMCHOOSER_ADMIN_MODE" = "TRUE" ] && [ -n "$SLX_JAMBOSERVER" ]; then - setup_jambo - writelog "\tVM disk file RW:\t\t$VM_DISKFILE_RW" + if [ -n "$VM_DISKFILE_RW" ]; then + writelog "A hook in setup_image_access supplied a writable diskfile. Not running default setup." + elif [ -n "$VM_DISKFILE_RO" ]; then + writelog "A hook in setup_image_access supplied a read-only diskfile. Not running default setup." + else + setup_image_access_default + fi + readonly VM_DISKFILE_RO VM_DISKFILE_RW + + if [ -n "$VM_DISKFILE_RW" ]; then + writelog "\tVM disk file (RW):\t\t$VM_DISKFILE_RW" if ! [ -s "$VM_DISKFILE_RW" ]; then writelog ".... not found!" EXIT_TYPE="user" EXIT_REASON="Schreibbare VM nicht gefunden. Adminmodus fehlgeschlagen." cleanexit 1 @@ -116,12 +112,22 @@ setup_image_access() { writelog ".... not writable!" EXIT_TYPE="user" EXIT_REASON="VM-Image auf schreibbarem VM-Speicher nicht schreibbar. Adminmodus fehlgeschlagen." cleanexit 1 fi - return 0 + elif [ -n "$VM_DISKFILE_RO" ]; then + writelog "\tVM disk file (RO):\t\t$VM_DISKFILE_RO" + if ! [ -s "$VM_DISKFILE_RO" ]; then + writelog ".... not found!" + EXIT_TYPE="user" EXIT_REASON="VM-Image nicht gefunden." cleanexit 1 + fi + if ! [ -r "$VM_DISKFILE_RO" ]; then + writelog ".... not readable!" + EXIT_TYPE="user" EXIT_REASON="VM-Image nicht lesbar." cleanexit 1 + fi + else + EXIT_TYPE="user" EXIT_REASON="Kein VM-Image Dateiname angegeben/gefunden." cleanexit 1 fi - - unset VM_DISKFILE_RO - declare -g VM_DISKFILE_RO - +} + +setup_image_access_default() { # See if we should setup dnbd3 image access at all if ! check_dep dnbd3-fuse fusermount; then writelog "\tCan't use dnbd3 as dnbd3-fuse/fusermount binaries are not in PATH" @@ -141,14 +147,6 @@ setup_image_access() { writelog "Trying fallback image access via NFS/CIFS..." setup_fallback fi - - # Check if we finally found a valid, readable container - if isempty VM_DISKFILE_RO || [ ! -r "${VM_DISKFILE_RO}" ]; then - writelog "Virtual machine image ${VM_DISKFILE_RO} not found!" - EXIT_TYPE="user" EXIT_REASON="Konnte virtuelle Festplatte der gewählten VM nicht finden!" cleanexit 1 - fi - - writelog "\tVM disk file:\t\t${VM_DISKFILE_RO}" } call_post_source setup_image_access diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/vmchooser_runvirt_functions.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/vmchooser_runvirt_functions.inc index 932c4aad..7b4554ea 100644 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/vmchooser_runvirt_functions.inc +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt-includes/vmchooser_runvirt_functions.inc @@ -220,6 +220,34 @@ translate() { fi } +## +# run_hooks type args... +# eg run_hooks "download" "$CONFDIR" +# returns 100 if no hooks exist +run_hooks() { + local dir file retval r + declare -a files + dir="$BASEDIR/hooks/${1}.d" + [ -d "$dir" ] || return 100 + shift + files=( "${dir}"/* ) + retval=100 + for file in "${files[@]}"; do + [ -e "${file}" ] || continue + r=100 + if [ "${file##*.}" = "sh" ] && [ -x "$file" ]; then + export TMPDIR IMGUUID USER + "$file" "$@" + r="$?" + elif [ "${file##.*}" = "inc" ]; then + . "$file" + r="$?" + fi + [ "$r" -lt "$retval" ] && retval="$r" + done + return "$retval" +} + ################# SOURCING FUNCTIONS ################# # Wrapped 'source' that first checks for existence and # syntax before actually sourcing the given file. diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt.d/setup_virtual_floppy.inc b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt.d/setup_virtual_floppy.inc index e302bdd7..c077bb42 100644 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt.d/setup_virtual_floppy.inc +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/run-virt.d/setup_virtual_floppy.inc @@ -4,7 +4,7 @@ ## Functions ## setup_virtual_floppy() { declare -rg SLX_FLOPPY_IMG="${TMPDIR}/floppy.img" - declare -rg TMPHOME="${HOME}" + declare -r TMPHOME="${HOME}" # create floppy disk file + filesystem dd "if=/dev/zero" "of=${SLX_FLOPPY_IMG}" count=1440 bs=1024 @@ -13,10 +13,15 @@ setup_virtual_floppy() { if [ -s "${TMPHOME}/.openslx/shares" ]; then $(safesource "${TMPHOME}/.openslx/shares") - else + elif [ -s "/opt/openslx/inc/shares" ]; then $(safesource "/opt/openslx/inc/shares") fi + # Directory for files that go into the virtual floppy + declare -r FLOPPYDIR="$TMPDIR/floppy" + mkdir -p "$FLOPPYDIR" + chmod 0700 "$FLOPPYDIR" + if notempty SHARE_REMAP_MODE; then local SHARE_REMAP_MODE_INI="$SHARE_REMAP_MODE" else @@ -25,24 +30,16 @@ setup_virtual_floppy() { fi notempty SHARE_CREATE_MISSING_REMAP || local SHARE_CREATE_MISSING_REMAP="1" - # Legacy: openslx.exe expects HOSTRES.TXT - local RESOLUTION=$(xrandr | grep -o -E 'connected\s*(primary)?\s*[0-9]+x[0-9]+\+0\+0' \ - | grep -o -E -m1 '[0-9]+x[0-9]+') - # TODO fallback if this fails? this is currently never checked... - cat > "${TMPDIR}/HOSTRES.TXT" <<-EOF - ${RESOLUTION} - EOF - # Create file for network shares to mount - declare -g SHARES="${TMPDIR}/shares.dat" + declare -g SHARES="${FLOPPYDIR}/shares.dat" touch "${SHARES}" chmod 0600 "${SHARES}" if ! pwdaemon --query "${TMPHOME}/.pwsocket" > "${SHARES}"; then - slxlog "virt-pwdaemon" "Could not start pwdaemon" + slxlog "run-virt-pwdaemon" "Could not query pwdaemon" echo -e '-\t-\t-\t-\t-' > "${SHARES}" else sed -i 's/^/192.168.101.1\t/' "${SHARES}" # TODO: Depending on nettype (in case we have != nat some day) - if [ "${SHARE_REMAP_MODE}" = 1 -o "${SHARE_REMAP_MODE}" = 2 ] && [ -e "${TMPHOME}/.openslx/home" ]; then + if [ "${SHARE_REMAP_MODE}" = 1 -o "${SHARE_REMAP_MODE}" = 2 ] && [ -s "${TMPHOME}/.openslx/home" ]; then NETHOME=$(cat "${TMPHOME}/.openslx/home") notempty SHARE_HOME_DRIVE || local SHARE_HOME_DRIVE="H:" # Tab between items, so spaces can be used! @@ -53,25 +50,22 @@ setup_virtual_floppy() { done fi - local NETSHARES="$CONFDIR/netshares" - local RUNSCRIPT="$CONFDIR/runscript" - + declare -r NETSHARES="$CONFDIR/netshares" + declare -r RUNSCRIPT="$CONFDIR/runscript" ## Network shares # openslx.exe expects network shares line in the following format: # <path> <letter> <shortcut> <username> <password> # which is coincidentally the one we received from dmsd :) - if [ -f "$NETSHARES" ] || download_file "$url_lecture_netshares" "$NETSHARES"; then - if [ -s "${NETSHARES}" ]; then - # try to detect if we are running windows and replace '/' with '\' - # in an attempt to fix an improperly given samba path - cmd=(cat) - if [[ "$( tr '[A-Z]' '[a-z]' <<< ${VM_OS_TYPE})" = *windows* ]]; then - cmd=(tr / '\\') - fi - # replace the tag for the username, if present; the variable expansion escapes all ':' in $USER - sed -i "s:%loginuser%:${USER//:/\\:}:g" "${NETSHARES}" - < "${NETSHARES}" "${cmd[@]}" >> "${SHARES}" + if [ -f "$NETSHARES" ] && [ -s "${NETSHARES}" ]; then + # try to detect if we are running windows and replace '/' with '\' + # in an attempt to fix an improperly given samba path + cmd=(cat) + if [[ "$( tr 'A-Z' 'a-z' <<< ${VM_OS_TYPE})" = *windows* ]]; then + cmd=(tr / '\\') fi + # replace the tag for the username, if present; the variable expansion escapes all ':' in $USER + sed -i "s:%loginuser%:${USER//:/\\:}:g" "${NETSHARES}" + < "${NETSHARES}" "${cmd[@]}" >> "${SHARES}" fi ## Runscript @@ -79,17 +73,15 @@ setup_virtual_floppy() { # Check downloaded runscript and handle options like # extension, visibility flag, ... # options are 'key=value' pairs separated with ';' - if [ -f "$RUNSCRIPT" ] || download_file "$url_lecture_runscript" "$RUNSCRIPT"; then - if [ -s "$RUNSCRIPT" ]; then - IFS=$'\n' - for OPT in $(head -n 1 "$RUNSCRIPT" | tr ";" "\n"); do - KEY=$(cut -s -d '=' -f 1 <<< "${OPT^^}") - [ -n "$KEY" ] && OPTIONS["$KEY"]=$(cut -s -d '=' -f 2- <<< "$OPT") - done - unset IFS + if [ -f "$RUNSCRIPT" ] && [ -s "$RUNSCRIPT" ]; then + IFS=$'\n' + for OPT in $( head -n 1 "$RUNSCRIPT" | tr ";" "\n" ); do + KEY=$( cut -s -d '=' -f 1 <<< "${OPT^^}" ) + [ -n "$KEY" ] && OPTIONS["$KEY"]="$( cut -s -d '=' -f 2- <<< "$OPT" )" + done + unset IFS - [ ${OPTIONS[EXT]} ] && [ "x${OPTIONS[EXT]:0:1}" != "x." ] && OPTIONS[EXT]=".${OPTIONS[EXT]}" - fi + [ -n "${OPTIONS[EXT]}" ] && [ "x${OPTIONS[EXT]:0:1}" != "x." ] && OPTIONS[EXT]=".${OPTIONS[EXT]}" fi # Default to muted @@ -113,7 +105,14 @@ setup_virtual_floppy() { SHARE_NO_HOME_WARN=0 fi - cat > "${TMPDIR}/openslx.ini" <<-EOF + # Legacy: openslx.exe expects HOSTRES.TXT + local RESOLUTION=$(xrandr | grep -o -E 'connected\s*(primary)?\s*[0-9]+x[0-9]+\+0\+0' \ + | grep -o -E -m1 '[0-9]+x[0-9]+') + cat > "${FLOPPYDIR}/HOSTRES.TXT" <<-EOF + ${RESOLUTION} + EOF + + cat > "${FLOPPYDIR}/openslx.ini" <<-EOF [openslx] username=${UNAME} resolution=${RESOLUTION} @@ -135,35 +134,43 @@ setup_virtual_floppy() { other=${SHARE_OTHER} EOF - # Copy all them there filez into floppy image - mcopy -i "${SLX_FLOPPY_IMG}" "${TMPDIR}/openslx.ini" "${TMPDIR}/HOSTRES.TXT" "${SHARES}" "${VMCHOOSER_DIR}/data/openslx.exe" "::/" + ln -n -s "${VMCHOOSER_DIR}/data/openslx.exe" "${FLOPPYDIR}/openslx.exe" # If we have a kerberos ticket, copy that one too (TODO: Copy keytab too?) if [ -n "$KRB5CCNAME" ]; then kf=${KRB5CCNAME#FILE:} kf=${kf#file:} if [ -n "$kf" ] && [ -f "$kf" ]; then - mcopy -i "${SLX_FLOPPY_IMG}" "$kf" "::/krb5user.key" + ln -n -s "$kf" "${FLOPPYDIR}/krb5user.key" fi fi - # Copy guest configuration (with added information) config.xml to be accessed - # via virtual floppy - mcopy -i "${SLX_FLOPPY_IMG}" "$XML_FILE" "::/config.xml" - # Copying linux directory: - mcopy -s -i "${SLX_FLOPPY_IMG}" "$VMCHOOSER_DIR/data/linux" "::/" + # Linux directory + ln -n -s "$VMCHOOSER_DIR/data/linux" "${FLOPPYDIR}/linux" # User supplied runscript if [ -n "${OPTIONS[EXT]}" ]; then sed -i '1d' "${RUNSCRIPT}" - mcopy -i "${SLX_FLOPPY_IMG}" "${RUNSCRIPT}" "::/runscript${OPTIONS[EXT]}" + ln -n -s "${RUNSCRIPT}" "${FLOPPYDIR}/runscript${OPTIONS[EXT]}" fi # Admin supplied runscript(s) if [ -d "${CONFDIR}/adminrun" ]; then - mcopy -s -i "${SLX_FLOPPY_IMG}" "${CONFDIR}/adminrun" "::/" + ln -n -s "${CONFDIR}/adminrun" "${FLOPPYDIR}/adminrun" + fi + + # Hook + run_hooks "floppy" "$FLOPPYDIR" + + local size="$( du -s -l -L "${FLOPPYDIR}" | awk '{print $1}' )" + if [ -n "$size" ] && [ "$size" -ge 1400 ]; then + writelog "WARNING: Floppydir contains $size kb of data, will most likely not fit..." fi - rm -f -- "${SHARES}" "${TMPDIR}/openslx.ini" "${TMPDIR}/HOSTRES.TXT" + if ! mcopy -s -i "${SLX_FLOPPY_IMG}" "${FLOPPYDIR}"/* "::/"; then + writelog "Error creating floppy image from ${FLOPPYDIR}" + elif ! $DEBUG; then + rm -rf -- "${FLOPPYDIR}" + fi } ## MAIN ## diff --git a/core/modules/run-virt/data/opt/openslx/vmchooser/vmchooser-run_virt b/core/modules/run-virt/data/opt/openslx/vmchooser/vmchooser-run_virt index d8f7d6ba..4a4b8f16 100755 --- a/core/modules/run-virt/data/opt/openslx/vmchooser/vmchooser-run_virt +++ b/core/modules/run-virt/data/opt/openslx/vmchooser/vmchooser-run_virt @@ -19,16 +19,39 @@ # tools and then include the specific plugin which configures the speci- # fied virtualization tool. ################################################################################ -SELF=$(readlink -f "$0") +SELF="$( readlink -f "${BASH_SOURCE[0]}" )" +if [ -z "$SELF" ] || ! [ -f "$SELF" ]; then + SELF="$( readlink -f "$0" )" +fi +if [ -z "$SELF" ] || ! [ -f "$SELF" ]; then + slxlog "run-virt" "Cannot find SELF" + exit 1 +fi +readonly SELF + +# Useless without this +. /opt/openslx/config + +# Debug mode? +if [ "x$1" = "x--debug" ]; then + shift + DEBUG=true +elif [ "$SLX_DEBUG_MODE" = "ON" ] || grep -qE '\bdebug\b' "/proc/cmdline"; then + DEBUG=true +else + DEBUG=false +fi # This script expects the path to the xml file describing the VM to be started declare -rg XML_FILE="$1" -# A path to the logfile can be given as second argument +# A path to the logfile can be given as second argument (will be set later if empty) declare -g LOGFILE="$2" # Functions needed by vmchooser-run_virt (writelog(), cleanexit(), safesource()) -declare -rg RUN_VIRT_INCLUDE_DIR="$(dirname $SELF)/run-virt-includes" +BASEDIR="$( dirname "${SELF}" )" +RUN_VIRT_INCLUDE_DIR="${BASEDIR}/run-virt-includes" +readonly BASEDIR RUN_VIRT_INCLUDE_DIR if ! source "${RUN_VIRT_INCLUDE_DIR}/vmchooser_runvirt_functions.inc"; then slxlog "run-virt" "Could not source ${RUN_VIRT_INCLUDE_DIR}/vmchooser_runvirt_functions.inc" exit 1 |