summaryrefslogtreecommitdiffstats
path: root/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes
diff options
context:
space:
mode:
Diffstat (limited to 'core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes')
-rwxr-xr-xcore/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_allow_root_fix.inc12
-rwxr-xr-xcore/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_mount_netshare.inc173
-rwxr-xr-xcore/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_bind_mount.inc57
-rw-r--r--core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_user_context.inc92
4 files changed, 334 insertions, 0 deletions
diff --git a/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_allow_root_fix.inc b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_allow_root_fix.inc
new file mode 100755
index 00000000..9ef14d81
--- /dev/null
+++ b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_allow_root_fix.inc
@@ -0,0 +1,12 @@
+#!/bin/bash
+writelog "+ apply 'allow_root' Option for gvfsd-fuse"
+
+# exec dummy call to start gvfsd and gvfsd-fuse
+gio mount
+
+# create gvfs user dir mybe it does not exist at this point
+mkdir -p "/run/user/$(id -u)/gvfs"
+
+fusermount -zu "/run/user/$(id -u)/gvfs"
+killall gvfsd-fuse
+/usr/lib/gvfs/gvfsd-fuse -o allow_root "/run/user/$(id -u)/gvfs"
diff --git a/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_mount_netshare.inc b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_mount_netshare.inc
new file mode 100755
index 00000000..50e28fc0
--- /dev/null
+++ b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/gio_mount_netshare.inc
@@ -0,0 +1,173 @@
+#!/bin/bash
+
+# This script will be exectutet in docker lectures
+# and provide the functonallity to mount netshares in the bwlp maxilinux system for the logged in user.
+#
+
+# VARS
+#
+NETSHAREFILE="$CONFDIR/netshares"
+CONFIGFILE="$TMPDIR/configfile"
+
+MOUNTS=()
+DIRECTORY_LINKS=()
+
+GVFS_MOUNTDIR="/run/user/$( id -u "$USER" )/gvfs"
+
+declare -a ROHSHARES
+
+function cleanup_gio_mount()
+{
+ for i in "${MOUNTS[@]}"; do
+ gio mount -u "$i"
+ done
+
+ for i in "${DIRECTORY_LINKS[@]}"; do
+ unlink "$i"
+ done
+}
+
+function do_mount()
+{
+gio mount "$MOUNT_PREFIX$SHAREPATH" <<HEREDOC
+$MOUNT_USER
+
+$MOUNT_PASS
+HEREDOC
+ DO_MOUNT_RETVAL=$?
+}
+
+
+function provide_directory_links()
+{
+ # split sharepath into server address and share
+ # expected: //server.name.de/share
+ IFS='/' read -ra SHAREINFO <<< "$SHAREPATH" # str is read into an array as tokens separated by IFS
+
+ # index 0 and 1 are zero 2 is SHARESERVER 3 is SHARENAME
+ if [[ -z "${SHAREINFO[2]}" && -z "${SHAREINFO[3]}" ]]; then
+ writelog "+ shareinfo not as expected, can not create dir links"
+ return 1
+ fi
+
+ local SHARESERVER="${SHAREINFO[2]}"
+ local SHARE="${SHAREINFO[3]}"
+
+ local SHARE_MOUNT_POINT="$GVFS_MOUNTDIR/smb-share:server=${SHARESERVER},share=${SHARE}"
+
+ if [[ ! -e "$SHARE_MOUNT_POINT" ]]; then
+ writelog "+ mount directory for $SHAREPATH not found, can not create links!"
+ return 1
+ fi
+
+ NETSHARE_DIR["$SHARELETTER"]="$SHARE_MOUNT_POINT"
+
+ # create link do desktop and user home
+ ln -sf "${SHARE_MOUNT_POINT}" "${HOME}/${SHARENAME}"
+ mkdir -p "${HOME}/Desktop"
+ ln -sf "${SHARE_MOUNT_POINT}" "${HOME}/Desktop/${SHARENAME}"
+
+ # register cleanup function
+ DIRECTORY_LINKS+=("${HOME}/${SHARENAME}")
+ DIRECTORY_LINKS+=("${HOME}/Desktop/${SHARENAME}")
+}
+
+
+function mount_shares()
+{
+ for (( CONFIGROW = 1; CONFIGROW < ${#ROHSHARES[@]}; CONFIGROW++ )); do
+ SHAREPATH=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 1 -d$'\t' | \
+ sed 's:\\:/:g')
+ SHARELETTER=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 2 -d$'\t' | \
+ sed 's/://g') # Laufwerksbuchstabe ohne :
+ SHARENAME=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 3 -d$'\t' | sed 's/ /_/g') # Leerzeichen raus.
+ SHAREUSER=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 4 -d$'\t') # Username, bei Userhome nicht vorhanden
+ SHAREPASS=$(echo "${ROHSHARES[CONFIGROW]}" | cut -f 5 -d$'\t') # User-PW, bei Userhome nicht vorhanden
+
+
+ MOUNT_PREFIX="smb:"
+
+ if [[ -z "$SHAREUSER" || -z "$SHAREPASS" ]]; then
+ MOUNT_USER="$USER"
+ MOUNT_PASS="$PW"
+ else
+ MOUNT_USER="$SHAREUSER"
+ MOUNT_PASS="$SHAREPASS"
+ fi
+
+ writelog "+ mount netshare $MOUNT_PREFIX$SHAREPATH"
+ do_mount > /dev/null
+
+ if [[ "$DO_MOUNT_RETVAL" -eq 0 ]]; then
+ writelog "+ ... mount was successfull"
+ sleep 1
+ provide_directory_links
+ MOUNTS+=("$MOUNT_PREFIX$SHAREPATH")
+ else
+ writelog "+ ... mount faild"
+ fi
+ done
+
+ unset MOUNT_USER MOUNT_PASS
+}
+
+
+function gio_mount()
+{
+ # CLEANUP
+ rm -f -- "$CONFIGFILE"
+ touch "$CONFIGFILE"
+ # TODO existing gio mounts shouldn´t exist at this points
+ # remove them anyway
+ for location in "$GVFS_MOUNTDIR"/*; do
+ [ -d "$location" ] && gio mount -u "$location"
+ done
+ sleep 1
+
+ # Fill CONFIGFILE with pwdaemon info, how it is done in /opt/openslx/vmchooser/run-virt.d/setup_virtual_floppy.inc
+ # TODO some checks if everthing run fine.
+ pwdaemon --query "$HOME/.pwsocket" > "$CONFIGFILE"
+ sed -i 's/^/192.168.101.1\t/' "$CONFIGFILE"
+
+ # Attach netshares to CONFIGFILE
+ cat "$NETSHAREFILE" >> "$CONFIGFILE"
+
+ # With this preparetion of CONFIGFILE functions from /opt/openslx/vmchooser/data/linux/includes/
+ # can be uesed. NATADDR, PORT, KEYTEMP, RAWKEYTEMP and BYTES required in get_creds
+ NATADDR=$( head -n 1 "$CONFIGFILE" | cut -f 1 -d$'\t' )
+ PORT=$( head -n 1 "$CONFIGFILE" | cut -f 2 -d$'\t' )
+ KEYTEMP="$( mktemp -t XXXXXXXXXX.dat )"
+ RAWKEYTEMP="$( mktemp -t XXXXXXXXXX.dat )"
+ BYTES=256
+
+ source /opt/openslx/vmchooser/data/linux/includes/10_functions.inc
+ source /opt/openslx/vmchooser/data/linux/includes/20_get_creds.inc
+ source /opt/openslx/vmchooser/data/linux/includes/30_get_shares.inc
+
+ # getting user credentials
+ get_creds
+
+ # load shares from CONFIGFILE (../metadata/netshares) into ROHSHARES variable
+ get_shares
+
+ # check if required VARS for mounting are non zero
+ if [[ -n "$ROHSHARES" && -n "$PW" && -n "$USER" ]]; then
+ # mount each mountpoint
+ writelog "+ initialize complete ... mount shares"
+ mount_shares
+ else
+ writelog "+ initialize failed"
+ fi
+}
+
+# check if size of NETSHAREFILE > 0
+if [[ -s "$NETSHAREFILE" ]]; then
+ writelog "+ NETSHAREFILE: ${NETSHAREFILE} contains informations for network drives... initialize gio mount"
+ gio_mount
+ add_cleanup cleanup_gio_mount
+else
+ writelog "+ NETSHAREFILE: ${NETSHAREFILE} empty ... nothing to mount"
+fi
+
+unset PW
+rm -f -- "$KEYTEMP" "$RAWKEYTEMP" "$CONFIGFILE"
diff --git a/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_bind_mount.inc b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_bind_mount.inc
new file mode 100755
index 00000000..ad82ef51
--- /dev/null
+++ b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_bind_mount.inc
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+## required vars
+# TMPDIR=/tmp/virt/<CURRENT_USER>/<PID>/
+# USER_CONTAINER_CONFIG
+# NETSHARE_DIR
+
+# vars
+BIND_MOUNT_FILE="$CONFDIR/container_meta.json"
+# TODO: Maybe make this an array to support spaces
+BIND_MOUNT_STRING=""
+
+
+BIND_MOUNT_COUNT="$( cat "$BIND_MOUNT_FILE" | jq '.bind_mount_config | length' )"
+
+for (( index=0; index < "$BIND_MOUNT_COUNT"; index++ )); do
+
+ BIND_MOUNT_INFO="$( jq .bind_mount_config["$index"] "$BIND_MOUNT_FILE" )"
+
+ # expecting source to be a MOUNT_LETTER, wich must replaced with the directory
+ BIND_MOUNT_SOURCE="$( jq -r .source <<< "$BIND_MOUNT_INFO" )"
+ BIND_MOUNT_TARGET="$( jq -r .target <<< "$BIND_MOUNT_INFO" )"
+ BIND_MOUNT_OPTION="$( jq -r .option <<< "$BIND_MOUNT_INFO" )"
+
+ if [[ -z "$BIND_MOUNT_SOURCE" || -z "$BIND_MOUNT_TARGET" ]]; then
+ writelog "+ no proper bind mount option provided!"
+ continue
+ fi
+
+ # USER_HOME is selected
+ if [[ "$BIND_MOUNT_SOURCE" == "USER_HOME" ]]; then
+ if [[ -d "$HOME/PERSISTENT" ]]; then
+ BIND_MOUNT_STRING+=" --mount type=bind,source=$HOME/PERSISTENT,target=$BIND_MOUNT_TARGET"
+ else
+ # user has no PERSISTENT, maybe this is a demo user just mount $HOME
+ BIND_MOUNT_STRING+=" --mount type=bind,source=$HOME,target=$BIND_MOUNT_TARGET"
+ fi
+
+ # If USER_TMP is used, create a locaten for client user and bind mount into container
+ elif [[ "$BIND_MOUNT_SOURCE" == "USER_TMP" ]]; then
+ # DOCKER_TMP created and cleand in opt/openslx/pam/hooks/auth-final-exec.d/30-add-to-docker.sh
+ DOCKER_TMP="/tmp/docker"
+ DOCKER_USER_TMP="$DOCKER_TMP/$(id -u)"
+ [ ! -e $DOCKER_USER_TMP ] && mkdir -p $DOCKER_USER_TMP && chmod 0700 $DOCKER_USER_TMP
+ BIND_MOUNT_STRING+=" --mount type=bind,source=$DOCKER_USER_TMP,target=$BIND_MOUNT_TARGET"
+
+ elif [[ -z "${NETSHARE_DIR[$BIND_MOUNT_SOURCE]}" ]]; then
+ writelog "+ no bind mount mapping for letter $BIND_MOUNT_SOURCE found!"
+ continue
+ else
+ BIND_MOUNT_STRING+=" --mount type=bind,\\\"source=${NETSHARE_DIR[$BIND_MOUNT_SOURCE]}\\\",target=$BIND_MOUNT_TARGET"
+ fi
+
+done
+
+writelog "+ write final CONTAINER_BIND_MOUNT_STRING $BIND_MOUNT_STRING in config $USER_CONTAINER_CONFIG"
+echo "CONTAINER_BIND_MOUNT_STRING=\"${BIND_MOUNT_STRING}\"" >> ${USER_CONTAINER_CONFIG}
diff --git a/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_user_context.inc b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_user_context.inc
new file mode 100644
index 00000000..99ba4580
--- /dev/null
+++ b/core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes/init_user_context.inc
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+
+function process_container_meta()
+{
+ writelog "+ process container_meta.json"
+ # Try to make a valid CONTAINER_IMAGE_NAME
+ export CONTAINER_IMAGE_NAME=$( jq -r '.image_name' "$CONFDIR/container_meta.json" | \
+ tr '[:upper:]' '[:lower:]' | sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*$//g' | sed -e 's/[[:space:]]/_/g')
+ export CONTAINER_RUN_OPTIONS=$( jq -r '.run_options' "$CONFDIR/container_meta.json" )
+
+
+ # set build context
+ build_context_method=$( jq -r '.build_context_method' "$CONFDIR/container_meta.json" )
+ if [[ "$build_context_method" == "0" ]]; then
+ writelog "+ container_build_context: dockerfile"
+ export CONTAINER_BUILD_CONTEXT="$CONFDIR/"
+ elif [[ "$build_context_method" == "1" ]]; then
+ writelog "+ container_build_context: git url"
+ export CONTAINER_BUILD_CONTEXT=$( jq -r '.build_context_url' "$CONFDIR/container_meta.json" )
+ else
+ writelog "+ no proper build_context_method!"
+ cleanexit 1
+ fi
+}
+
+
+function setup_user_container_context()
+{
+ mkdir -p "$USER_CONTAINER_CONTEXT"
+ # init user directory with scripts
+ cp "$DOCKER_PLUGIN_DIR/docker-init" "$USER_CONTAINER_CONTEXT/"
+ cp "$DOCKER_PLUGIN_DIR/remount" "$USER_CONTAINER_CONTEXT/"
+ cp "$DOCKER_PLUGIN_DIR/.bwlp-user-conf" "$USER_CONTAINER_CONFIG"
+ chmod u+x "$USER_CONTAINER_CONTEXT/docker-init"
+ chmod u+x "$USER_CONTAINER_CONTEXT/remount"
+}
+
+
+function setup_user_container_autostart()
+{
+ # TODO: maybe there is a better way to load and start the container which is used in the current lecture
+ mkdir -p "$HOME/.config/autostart/"
+ cp -f "$DOCKER_PLUGIN_DIR/docker-init.desktop" "$HOME/.config/autostart/"
+ sed -i "s:Exec=:Exec=$USER_CONTAINER_CONTEXT/docker-init:" "$HOME/.config/autostart/docker-init.desktop"
+}
+
+
+function init_user_container_config()
+{
+ if [[ ! -f "$USER_CONTAINER_CONFIG" ]]; then
+ writelog "+ USER_CONTAINER_CONFIG: $USER_CONTAINER_CONFIG does not exist!"
+ cleanexit 1
+ fi
+
+ process_container_meta
+
+ writelog "+ init USER_CONTAINER_CONFIG: $USER_CONTAINER_CONFIG"
+ sed -i "s#export DOCKER_PLUGIN_DIR=".*"#export DOCKER_PLUGIN_DIR=\"$DOCKER_PLUGIN_DIR\"#" "$USER_CONTAINER_CONFIG"
+ sed -i "s#export DOCKER_INCLUDE_DIR=".*"#export DOCKER_INCLUDE_DIR=\"$DOCKER_INCLUDE_DIR\"#" "$USER_CONTAINER_CONFIG"
+ sed -i "s#export TMPDIR=".*"#export TMPDIR=\"$TMPDIR\"#" "$USER_CONTAINER_CONFIG"
+
+ sed -i "s#export VM_DISKFILE_RO=".*"#export VM_DISKFILE_RO=\"$VM_DISKFILE_RO\"#" "$USER_CONTAINER_CONFIG"
+
+ sed -i "s#export CONTAINER_BUILD_CONTEXT=".*"#export CONTAINER_BUILD_CONTEXT=\"$CONTAINER_BUILD_CONTEXT\"#" "$USER_CONTAINER_CONFIG"
+ sed -i "s#export CONTAINER_IMAGE_NAME=".*"#export CONTAINER_IMAGE_NAME=\"$CONTAINER_IMAGE_NAME\"#" "$USER_CONTAINER_CONFIG"
+ sed -i "s#export CONTAINER_RUN_OPTIONS=".*"#export CONTAINER_RUN_OPTIONS=\"$CONTAINER_RUN_OPTIONS\"#" "$USER_CONTAINER_CONFIG"
+
+ local RUNSCRIPT="$CONFDIR/runscript"
+ # check if runscript file contains more than default line "ext=;visibility=1;soundMuted=-1"
+ if [[ "$( < "$RUNSCRIPT" wc -l )" -gt "1" ]]; then
+ sed -i "s#export RUNSCRIPT=".*"#export RUNSCRIPT=\"$RUNSCRIPT\"#" "$USER_CONTAINER_CONFIG"
+ fi
+
+ sed -i "s#USER_CONTAINER_CONFIG=".*"#USER_CONTAINER_CONFIG=\"$USER_CONTAINER_CONFIG\"#" "$USER_CONTAINER_CONTEXT/docker-init"
+}
+
+
+function cleanup_user_container_context()
+{
+ [ -d "$USER_CONTAINER_CONTEXT" ] && rm -rf -- "$USER_CONTAINER_CONTEXT"
+ [ -f "$HOME/.config/autostart/docker-init.desktop" ] && rm "$HOME/.config/autostart/docker-init.desktop"
+
+ # force remove all containers
+ [ -n "$(docker ps -aq)" ] && docker rm -f $(docker ps -aq) > /dev/null
+}
+
+
+setup_user_container_context
+setup_user_container_autostart
+init_user_container_config
+add_cleanup cleanup_user_container_context