From 5bc04570f60ce8be5281ee445c690c9b847b7cb8 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 21 Mar 2018 10:30:08 +0100 Subject: [MountVmStore] Support passing custom mount options --- scripts/mount-store | 185 +++++++++++++-------- .../openslx/taskmanager/tasks/MountVmStore.java | 17 +- 2 files changed, 133 insertions(+), 69 deletions(-) diff --git a/scripts/mount-store b/scripts/mount-store index 81fe438..0faf236 100755 --- a/scripts/mount-store +++ b/scripts/mount-store @@ -3,10 +3,16 @@ if [ $# -lt 2 ]; then echo "Bad call to $0." >&2 echo "Expected: $0 images " >&2 - echo "USERNAME and PASSWORD are expected environment variables for CIFS" >&2 + echo "TM_USERNAME and TM_PASSWORD are expected environment variables for CIFS" >&2 + echo "TM_MOUNT_OPTIONS can be supplied in both cases to override automatic guessing" >&2 exit 1 fi +USERNAME="$TM_USERNAME" +PASSWORD="$TM_PASSWORD" +MOUNT_OPTIONS="$TM_MOUNT_OPTIONS" +unset TM_PASSWORD + declare -rg CIFS_OPTS="/opt/openslx/cifs.opts" declare -rg NFS_OPTS="/opt/openslx/nfs.opts" @@ -40,7 +46,7 @@ storage_test () { chgrp images "${DEST}" 2>/dev/null mkdir -p "${SUBDIR}" if [ ! -d "${SUBDIR}" ]; then - echo "Error: Could not create $(basename "$SUBDIR")! Storage not writable!" >&2 + echo "Error: Could not create directory $(basename "${SUBDIR}")! Storage not writable!" >&2 return 6 fi echo "Applying group..." @@ -68,25 +74,27 @@ TRIES=0 while awk '{print $2}' "/proc/mounts" | grep -Fxq "${DEST}"; do echo "Trying to unmount '$DEST'..." if [ "$TRIES" -gt 5 ]; then - echo "Error: Cannot unmount '$DEST', giving up." >&2 - exit "$RET" - elif [ "$TRIES" -gt 3 ]; then - umount -v -f "$DEST" - else - umount -v "$DEST" - fi - RET=$? - if [ "$RET" -ne "0" ]; then cat >&2 <<-HEREDOC Error: Cannot unmount '$DEST'! Storage might be in use (running VM upload etc.) Try stopping DMSD first If the problem persists, try rebooting the server. + + Possible troublemaker(s): HEREDOC - exit "$RET" + lsof -n | grep "$DEST" >&2 + exit 99 # marker that nothing changed + elif [ "$TRIES" -gt 3 ]; then + umount -v -f "$DEST" + RET=$? + else + umount -v "$DEST" + RET=$? fi - TRIES=$(( $TRIES + 1 )) + [ "$RET" = 0 ] && break + sleep 1 + TRIES=$(( TRIES + 1 )) done # Sanity checks: Destination exists? @@ -120,66 +128,109 @@ fi # Mount! -if grep -E -q '^[^/].+:.+' <<<$SOURCE; then - # seems to be NFS - for opt in vers=4 vers=3; do - echo " * Trying ${opt}..." - mount -v -t nfs -o rw,noatime,noexec,nodev,async,nolock,$opt,fg,ac,retry=0,timeo=200,sec=sys "$SOURCE" "$DEST" - RET=$? - [ "$RET" -ne "0" ] && continue - echo "Mount succeeded, checking write permissions...." - storage_test - RET=$? - [ "$RET" -eq "0" ] && break - umount -v "$DEST" || umount -v -f -l "$DEST" +# exec_mount +exec_mount () { + local fstype="$1" + local mntopts="$2" + local SOURCE="$3" + local DEST="$4" + echo " * Trying ${fstype} with ${mntopts}..." + mount -v -t "$fstype" -o "$mntopts" "$SOURCE" "$DEST" + RET=$? + [ "$RET" -ne "0" ] && return "$RET" + echo "Mount succeeded, checking write permissions...." + storage_test + RET=$? + [ "$RET" -eq "0" ] && return 0 + umount -v "$DEST" || umount -v -f -l "$DEST" + return "$RET" +} + +remove_option () { + local opt + while [ $# -gt 0 ]; do + opt=$1 + shift + [[ "$MOUNT_OPTIONS" =~ (^|,)$opt($|,|=) ]] || continue + MOUNT_OPTIONS=$( echo "$MOUNT_OPTIONS" | sed -r "s/(^|,)$opt(|=[^,]*)(,|$)/\\1/g;s/,$//" ) done -elif grep -E -q '^//' <<<$SOURCE; then - # seems to be SMB - export USER="$USERNAME" - export PASSWD="$PASSWORD" - RET=999 - OPTSTR= - if [ -f "$CIFS_OPTS" ]; then - OPTSTR=$(cat "$CIFS_OPTS") - fi - if [ -n "$OPTSTR" ]; then - echo " * Trying last successful mount options..." - if mount -v -t cifs -o "$OPTSTR" "$SOURCE" "$DEST"; then - echo "Mount succeeded, checking write permissions...." - storage_test +} + +main () { + local RET=999 + if grep -E -q '^[^/].+:.+' <<<$SOURCE; then + # seems to be NFS + if [ "$RET" != 0 ] && [ -n "$MOUNT_OPTIONS" ]; then + remove_option bg retry ro + MOUNT_OPTIONS="$MOUNT_OPTIONS,fg,retry=0,rw" + exec_mount "nfs" "$MOUNT_OPTIONS" "$SOURCE" "$DEST" + return $? + fi + OPTSTR= + if [ -f "$NFS_OPTS" ]; then + OPTSTR=$(cat "$NFS_OPTS") + fi + if [ "$RET" != 0 ] && [ -n "$OPTSTR" ]; then + echo " * Trying last successful mount options..." + exec_mount "nfs" "$OPTSTR" "$SOURCE" "$DEST" RET=$? - if [ "$RET" -ne "0" ]; then - umount -v "$DEST" || umount -v -f -l "$DEST" - fi fi - fi - if [ "$RET" -ne "0" ]; then - for vers in "" "3.0" "2.1" "1.0" "2.0"; do - [ -n "$vers" ] && vers=",vers=${vers}" - for sec in "" "ntlmssp" "ntlmv2" "ntlm"; do - [ -n "$sec" ] && sec=",sec=${sec}" - echo " * Trying ...${vers}${sec}..." - OPTSTR="rw,uid=0,gid=12345,forceuid,forcegid,nounix,file_mode=0664,dir_mode=0775$vers$sec" - mount -v -t cifs -o "$OPTSTR" "$SOURCE" "$DEST" - RET=$? - [ "$RET" -ne "0" ] && continue - echo "Mount succeeded, checking write permissions...." - storage_test + if [ "$RET" != 0 ]; then + for opt in "#" "vers=4" "vers=3"; do + mntopts="rw,noatime,noexec,nodev,async,nolock,fg,ac,retry=0,timeo=200,sec=sys" + [ "$opt" != "#" ] && mntopts="$mntopts,$opt" + exec_mount "nfs" "$mntopts" "$SOURCE" "$DEST" RET=$? - [ "$RET" -eq "0" ] && break - umount -v "$DEST" || umount -v -f -l "$DEST" + [ "$RET" = 0 ] && break + done + if [ "$RET" = 0 ] && [ -n "$mntopts" ]; then + echo "$OPTSTR" > "$NFS_OPTS" + fi + fi + elif grep -E -q '^//' <<<$SOURCE; then + # seems to be SMB + export USER="$USERNAME" + export PASSWD="$PASSWORD" + if [ "$RET" != 0 ] && [ -n "$MOUNT_OPTIONS" ]; then + remove_option uid gid file_mode dir_mode umask + MOUNT_OPTIONS="$MOUNT_OPTIONS,uid=0,gid=12345,forceuid,forcegid,file_mode=0664,dir_mode=0775" + exec_mount "cifs" "$MOUNT_OPTIONS" "$SOURCE" "$DEST" + return $? + fi + OPTSTR= + if [ -f "$CIFS_OPTS" ]; then + OPTSTR=$(cat "$CIFS_OPTS") + fi + if [ "$RET" != 0 ] && [ -n "$OPTSTR" ]; then + echo " * Trying last successful mount options..." + exec_mount "cifs" "$OPTSTR" "$SOURCE" "$DEST" + RET=$? + fi + if [ "$RET" != 0 ]; then + for vers in "" "3.0" "2.1" "2.0" "1.0"; do + [ -n "$vers" ] && vers=",vers=${vers}" + for sec in "" "ntlmssp" "ntlmv2" "ntlm"; do + [ -n "$sec" ] && sec=",sec=${sec}" + OPTSTR="rw,uid=0,gid=12345,forceuid,forcegid,nounix,file_mode=0664,dir_mode=0775$vers$sec" + exec_mount "cifs" "$OPTSTR" "$SOURCE" "$DEST" + RET=$? + [ "$RET" = 0 ] && break 2 + done done - [ "$RET" -eq "0" ] && break - done - if [ "$RET" -eq "0" ] && [ -n "$OPTSTR" ]; then - echo "$OPTSTR" > "$CIFS_OPTS" + if [ "$RET" = 0 ] && [ -n "$OPTSTR" ]; then + echo "$OPTSTR" > "$CIFS_OPTS" + fi fi + unset USER PASSWD + else + echo "Unknown mount type: $SOURCE" + RET=1 fi - unset USER PASSWD -else - echo "Unknown mount type: $SOURCE" - exit 1 -fi + return "$RET" +} + +main +RET=$? echo "" @@ -190,5 +241,5 @@ if [ "$RET" = "0" ]; then systemctl --no-block start dnbd3-server.service fi -exit $RET +exit "$RET" diff --git a/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java b/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java index 034dab5..11c15db 100644 --- a/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java +++ b/src/main/java/org/openslx/taskmanager/tasks/MountVmStore.java @@ -1,10 +1,13 @@ package org.openslx.taskmanager.tasks; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import org.openslx.satserver.util.Constants; +import org.openslx.satserver.util.Util; import org.openslx.taskmanager.api.SystemCommandTask; +import com.btr.proxy.util.Logger; import com.google.gson.annotations.Expose; public class MountVmStore extends SystemCommandTask @@ -14,6 +17,8 @@ public class MountVmStore extends SystemCommandTask @Expose private String type = null; @Expose + private String opts = null; + @Expose private String username = null; @Expose private String password = null; @@ -52,10 +57,18 @@ public class MountVmStore extends SystemCommandTask Constants.BASEDIR + "/scripts/mount-store", "images", this.address, - this.username, - this.password }; } + + @Override + protected void initEnvironment( Map environment ) + { + environment.put( "TM_USERNAME", this.username ); + environment.put( "TM_PASSWORD", this.password ); + if ( !Util.isEmpty( this.opts ) ) { + environment.put( "TM_MOUNT_OPTIONS", this.opts ); + } + } @Override protected boolean processEnded( int exitCode ) -- cgit v1.2.3-55-g7522