diff options
Diffstat (limited to 'core/modules/run-virt-docker/data/opt/openslx/vmchooser/plugins/docker/includes')
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 |