#!/bin/bash # Copyright: 2023 Virtuozzo International GmbH # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. inherit os output tests; include log virtuozzo vzexec; DESCRIPTION="Manipulate storage mounts inside specified container"; VERSION="1" DEFAULT_ACTION="Usage"; $PROGRAM "vzctl" $PROGRAM "prlctl" $PROGRAM "vzlist" $PROGRAM "awk" $PROGRAM "ifconfig" $PROGRAM "rsync" $PROGRAM "grep" $PROGRAM "tar" declare -i _CTID="" declare -i CTID="" declare VEID="" declare -i _MOVEDATA=0 declare CLUSTER="false" declare _SOURCE="" declare _DESTINATION="" declare _DEFAULT_NFS_MOUNT_OPTS="-fstype=nfs,nfsvers=3,nolock,udp,soft,timeo=120,retrans=20,_netdev" declare _DEFAULT_GLUSTER_MOUNT_OPTS="-fstype=glusterfs" declare CONTAINER_MOUNTS_STORAGE="/etc/autofs.jelastic" declare _IPLIST declare -a UNKNOWN_ARG declare SAVE_CONFIG="true" declare TRUE=0 declare FALSE=1 FORCE_UMOUNT=$TRUE FORCE_MOUNT=$FALSE STORAGE_BACKEND="nfs" # nfs | gluster MOUNTPROG="/usr/sbin/automount" MOUNTPROG_APK="/sbin/mount.nfs" MOUNTPACKAGE="/var/lib/jelastic/packages/jelastic-nfs-utils.tar.gz" _UI_RESULT=0 USERID=0 GROUPID=0 VERBOSE=1 DEFAULT_AUTOFS_TIMEOUT=300 JELASTIC_AUTOFS_TIMEOUT=3 NOLOCK=0 EXEC="/bin/bash -c " SED_COPY_OPTION='--copy' function doUsage() { showUsageMessage } function onModLoadCallback() { log "Preload callback"; ## TODO: remove "params" garbarge option local temp=`getopt -o c:,s:,d:,u:,g:,l:,m: -l ctid:,source:,destination:,ip:,uid:,gid:,movedata:,saveconfig:,force:,cluster:,uuid:,vtype:,backend:,nolock: -- "$@" 2>/dev/null`; [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while true ; do case "$1" in --force) shift; FORCE_UMOUNT=$TRUE FORCE_MOUNT=$TRUE shift; ;; --saveconfig) shift; SAVE_CONFIG=${1,,} shift; ;; -c | --ctid) shift; _CTID=$1 CTID=$1 shift; ;; --uuid) shift; _UUID=$1 UUID=$1 shift; ;; --vtype) shift; VTYPE=$1 shift; ;; --cluster) shift; CLUSTER=$1 if [ "x$CLUSTER" != "xtrue" ]; then JELASTIC_AUTOFS_TIMEOUT="300" fi shift; ;; -s | --source) shift; _SOURCE=$1 shift; ;; -d | --destination) shift; _DESTINATION=$1 shift; ;; -l | --ip ) shift; _IPLIST=$1; shift; ;; -m | --movedata) shift; _MOVEDATA=$1; shift; ;; -u | --uid) shift; USERID=$1; shift; ;; -g | --gid) shift; GROUPID=$1; shift; ;; --backend) shift; STORAGE_BACKEND=${1,,}; shift; if [ "x$STORAGE_BACKEND" != "xgluster" -a "x$STORAGE_BACKEND" != "xnfs" ] ; then STORAGE_BACKEND="nfs" fi ;; --nolock) shift; if [ "x$NOLOCK" != "xtrue" ]; then NOLOCK=1 else NOLOCK=0 fi shift; ;; --) shift; break; ;; esac; done; if [[ "$VTYPE" == VM ]]; then EXEC="$PRLCTL exec ${UUID}" vzexecSetENVID ${UUID} VEID=${UUID} isVMexist $UUID || { writeJSONResponseErr "result=>4003" "message=>uuid $UUID not found"; die -q; }; else EXEC="$VZCTL exec2 ${CTID}" vzexecSetCTID ${CTID} VEID=${CTID} vzIsContainerExists $CTID || { writeJSONResponseErr "result=>4003" "message=>ctid $CTID not found"; die -q; }; fi if [ -n "$VEID" ] ; then populateVEVarsVZ $VEID res=$? if [[ "$res" -eq 3 ]] ; then writeJSONResponseErr "result=>4003" "message=>ctid $CTID not found" die -q; fi if VEExecRun "sed -rne '/JELASTIC_CHECK_MOUNT=/{s/JELASTIC_CHECK_MOUNT=([0-9])/\1/g;p}' /.jelenv" ; then res=$(vzexecGetLastStdOut) [ -n "$res" ] && JELASTIC_CHECK_MOUNT=$res fi if [ "x$VZ_VEID_OS" == "xubuntu" -o "x$VZ_VEID_OS" == "xdebian" ] ; then SED_COPY_OPTION='' fi else SED_COPY_OPTION='' fi if [[ -n "$UUID" && "$VTYPE" == VM ]] ; then VE_ROOT="/vz/tmp/${UUID}" else #fallback to old var VE_ROOT=$VZ_VEID_ROOT fi for arg do UNKNOWN_ARG+=("$arg") ; done [[ ! -z "${VEID}" ]] && { MOUNTS_STORAGE="${VE_ROOT}${CONTAINER_MOUNTS_STORAGE}" } log "${UNKNOWN_ARG[*]}" return 0 } function _hasActiveMounts() { #-hosts is /net/host #dir:path -> /path/* _cmd='[ -f /etc/auto.master ] && sed -re "/^#/d" -e "s/dir:(.*)/+ \1\/*/g" -e "/\s/!d" -e "s/-hosts/\/net\/host/g" /etc/auto.master | awk "{print $2}"' VEExecRun "$_cmd" autoFSMaps=($(VEexecGetLastStdOut)) if [ -n "$autoFSMaps" ] ; then for f in ${autoFSMaps[*]} ; do #skipping also cdrom. it is not available in jelastic vzcontainers VEExecRun "[ -f \"$f\" ] && sed -re '/^#/d' -e '/^$/d' -e '/\/dev\/cdrom/d' $f" [ -n "$(VEexecGetLastStdOut)" ] && return 0 done fi return 1 } function _reloadAutoFS() { local _cmd="systemctl reload autofs || service autofs reload" VEExecRun "$_cmd" && return 0 _cmd="pgrep automount >/dev/null && kill -s SIGHUP $(pidof -s automount)" VEExecRun "$_cmd" return $? } function _restartAutoFS() { local _cmd="systemctl restart autofs || service autofs restart" VEExecRun "$_cmd" return $? } function getTargetIPs() { isUUID $VEID && { VEExecRunInteractive "ip -o addr" | awk '!/^[0-9]*: ?lo|link\/ether/ {split($4,a,"/"); print a[1]}' } || { $AWK '/[ \t]*'${VEID}'/{$1=$2=$3="";gsub(/^[ \t]+/,"",$0);print $0}' /proc/vz/veinfo } } function preparePath() { local tpath=${1:?"Path required"} local hn=${2} isVERunning $VEID; _running=$? if [[ ! -z "$hn" ]] ; then [[ $_running -eq 0 ]] || tpath="$VZ_VEID_ROOT$tpath" tpath=$($SED -re 's/\$/\\$/g' -e 's/(`)/\\\1/g' <<< "${tpath}") fi local cmd="[[ -d '$($SED -re "s/'/\\\'\'/g" <<< "${tpath}")' ]] || { mkdir -p \"$($SED -re 's/"/\\\"/g' <<< "${tpath}")\" 2>/dev/null && chmod 0777 \"$($SED -re 's/"/\\\"/g' <<< "${tpath}")\";}"; if [[ $_running -eq 0 ]] ; then VEExecRun "$cmd" return $(VEexecGetLastErrCode) fi /bin/bash -c "$cmd" return $? } function remountPath() { local share=$1 local remountCmd="umount -l \"$share\" ; mount \"$share\"" out=$(VEExecRunInteractive "$remountCmd" 2>&1) if [[ -z "${out}" ]] ; then log "$out" fi return $? } function checkMount() { #skip check if VEID is empty [[ -z "${VEID}" ]] && return 0 if [ -z "$JELASTIC_CHECK_MOUNT" ]; then if ! VEExecRun "rpcinfo -p $1 | grep -q mountd" ; then log "mountd procedures not found on RPC server. Checking remote share will be disabled" JELASTIC_CHECK_MOUNT=0 fi JELASTIC_CHECK_MOUNT=1 fi case "$JELASTIC_CHECK_MOUNT" in false|0) log "remote server checking disabled for VEID $VEID" return 0 ;; true|1) log "remote server checking enabled for VEID $VEID" ;; esac retries=5 cmdShowmount='showmount -e '$1' | grep -P "^'$2'\s"' localCIPs=($(getTargetIPs)) while [[ $retries -gt 0 ]] ; do #get IPs from remote storage VEExecRun $cmdShowmount ipsWODir="$(VEexecGetLastStdOut)" sharedIPs=($(awk '{split($1,a,",") ; if (a[1] != $0) { for (k in a) { if (a[k] != "") { print a[k] } } } else {print $2}}' <<< "${ipsWODir//$2/}")) #is local IP in remote network range for lIP in ${localCIPs[@]} ; do for sIP in ${sharedIPs[@]} ; do [[ "x$sIP" == "x*" || "x$sIP" == "x(everyone)" ]] && return 0 (( $(inSubnet $sIP $lIP) )) && return 0 done done sleep 4 retries=$((retries-1)) done if [[ "$(VEexecGetLastErrCode)" -gt 0 ]]; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID: StdErr: $(VEexecGetLastStdErr) StdOut": $(VEexecGetLastStdOut) >> ${JEM_CALLS_LOG}; fi echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID: timeout has elapsed" >> ${JEM_CALLS_LOG}; return 1 } function detectNFSVersions() { cmd='rpcinfo $1 | sed -rne "/nfs/{s/\s+[0-9]+([0-9])\s+.*/\1/g;p}" | sort -ur' if VEExecRun $cmd ; then echo "$(VEexecGetLastStdOut)" else echo "0" fi } function processnfs4() { _DEFAULT_NFS_MOUNT_OPTS="-fstype=nfs,soft,timeo=30,retrans=2,_netdev" [[ $NOLOCK -eq 1 ]] && _DEFAULT_NFS_MOUNT_OPTS="$_DEFAULT_NFS_MOUNT_OPTS,nolock" processnfs "$@" } function processnfs3() { sourceIP=$1 nfsVers=("3") #fallback in case of disabled mount check lproto="udp" case "$JELASTIC_CHECK_MOUNT" in true|1) if [ ! -z $sourceIP ] ; then nfsVers=($(detectNFSVersions $sourceIP)) fi ;; false|0) nfsVers=("3") ;; esac if [[ "x${nfsVers[0]}" == "x3" ]] ; then lproto="tcp" fi _DEFAULT_NFS_MOUNT_OPTS="-fstype=nfs,nfsvers=3,nolock,$lproto,soft,timeo=120,retrans=20,_netdev" processnfs "$@" } function processnfs() { local sourceIP=${1:?"Source address required"} local sourceMount=${2:?"Source share name required"} local sourceMountUnEsc=$($SED -re 's/\\(\/|\(|\)|\]|\[|\\)/\1/g' <<< "$sourceMount") local destinationEsc=$($SED -re 's/\s/\\\\040/g' <<< "${_DESTINATION}" ) local running isVERunning ${VEID} ; running=$? if [[ $running -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - VE is not running." >> ${JEM_CALLS_LOG} if ! mountVE ${VEID} $VE_ROOT > /dev/null 2>&1 ; then writeJSONResponseErr "result=>4195" "message=>Cannot mount VE:$VEID" log "Cannot mount VE:$VEID" return 1 fi fi OS=$VZ_VEID_OS OS_ver=$VZ_VEID_OS_VER if [[ "x$VZ_VEID_OS" == "xalpine" ]] ; then echo "echo `date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : Alpine Linux detected. " >> ${JEM_CALLS_LOG} if VEExecRun "[[ ! -e \"$MOUNTPROG_APK\" ]]" ; then if ! dosetupUtils ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : Error installing utils $(gatherCTInfo) " >> ${JEM_CALLS_LOG} return 2 fi fi [[ ! -z "${CTID}" ]] && { MOUNTS_STORAGE="$(vzctPath $VE_ROOT /etc/fstab)" } _DEFAULT_NFS_MOUNT_OPTS="$($SED -re 's/-fstype=nfs,//g' <<< $_DEFAULT_NFS_MOUNT_OPTS)" mntEntry="${sourceIP}:$($SED -re 's/\\\$/$/g' <<< "${sourceMountUnEsc}")\t${destinationEsc}\tnfs\t${_DEFAULT_NFS_MOUNT_OPTS}\t0\t0" #cmdRegisterMount="echo -e \"$mntEntry\" >> ${MOUNTS_STORAGE};" else echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : looking for $CONTAINER_MOUNTS_STORAGE " >> ${JEM_CALLS_LOG} isConfigDefined=1 if [ $running -eq 0 -a "x$VTYPE" == "xVM" ] ; then grep -q "$CONTAINER_MOUNTS_STORAGE" <<< "$(VEExecRunInteractive cat /etc/auto.master 2>/dev/null)" 2>&1 isConfigDefined=$? else grep -q "$CONTAINER_MOUNTS_STORAGE" "$(vzctPath $VZ_VEID_ROOT /etc/auto.master)" 2>&1 isConfigDefined=$? fi if [[ $isConfigDefined -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : installing storage utils " >> ${JEM_CALLS_LOG} dosetupUtils || return 2 fi autofsdest="$($SED -e 's/\s/\\ /g' <<< $_DESTINATION)" mntEntry="$autofsdest ${_DEFAULT_NFS_MOUNT_OPTS},uid=${USERID},gid=${GROUPID} ${sourceIP}:$($SED -re 's/\\\$/$/g' <<< "${sourceMountUnEsc}")" #cmdRegisterMount="echo -e \"$mntEntry\" >> ${MOUNTS_STORAGE}" fi if [[ $running -eq 0 ]] ; then if ! checkMount $sourceIP "$sourceMountUnEsc" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : Destination NFS server is not reachable. $(gatherCTInfo)" >> ${JEM_CALLS_LOG} echo "Destination NFS server is not reachable. Server IP: $(VEExecRunInteractive host ${sourceIP} 2>/dev/null), Client IP: $($AWK '/[ \t]*'${VEID}'/{$1=$2=$3="";gsub(/^[ \t]+/,"",$0);print $0}' /proc/vz/veinfo )" return 1 fi fi if ! preparePath "${_DESTINATION}" "${VEID}" ; then echo "Cannot create path ${_DESTINATION}" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : Cannot create path ${_DESTINATION}. $(gatherCTInfo)" >> ${JEM_CALLS_LOG} return 1 fi if [[ "x$SAVE_CONFIG" == "xtrue" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : registering ${sourceIP}:${sourceMount} in ${VEID}" >> ${JEM_CALLS_LOG} if ! [[ $running == 0 && "$VTYPE" == VM ]]; then out=$(echo -e $mntEntry >> ${MOUNTS_STORAGE}) else VEExecRun "echo -e $mntEntry >> ${MOUNTS_STORAGE##"$VZ_VEID_ROOT"}" out=$(vzexecGetLastStdOut) fi if [[ ! -z "${out}" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : $out" >> ${JEM_CALLS_LOG} fi fi msg="" res=0 if [[ "x$VZ_VEID_OS" == "xalpine" ]] ; then if [[ $running -eq 0 ]] ; then mntcmd="mount \"$($SED -re 's/("\*|\$|\?|\|\^|`|'\'')/\\\1/g' <<< "${_DESTINATION}")\"" VEExecRun "${mntcmd}" res="$(VEexecGetLastErrCode)" msg="$(VEexecGetLastStdErr)" if [[ $res -gt "0" ]] && [[ $FORCE_MOUNT -eq $FALSE ]] ; then local mntEntryCheck="${sourceIP}:$($SED -re 's/(\$|\[|\]|\*|\(|\)|\?|\||\^)/\\\1/g' -e 's/\\\\\$/$/g' <<< ${sourceMount})/? on $($SED -re 's/(\[|\]|\*|\(|\)|\$|\?|\||\^|`)/\\\1/g' <<< ${destinationEsc})" VEExecRun "mount | $GREP -P \"$mntEntryCheck\"" res=$(VEexecGetLastErrCode) if [[ $res -ne $TRUE ]] ; then #remove the /etc/fstab entry cmdUnregisterMount="/$(echo -e $mntEntry | $SED -r -e 's/\t/\\\s+/g;' -e 's/\//\\\//g' -e 's/\./\\./g' -e 's/(\[|\]|\*|\(|\)|\$|\?|\||\^)/\\\1/g')/d" if [[ "x$SAVE_CONFIG" == "xtrue" ]] ; then out=$($SED -i -re "$cmdUnregisterMount" ${MOUNTS_STORAGE} 2>&1) fi log $out msg="${msg}. Server IP is: $(host ${sourceIP}), RPC connection: $(timeout 1 bash -c "cat < /dev/null > /dev/tcp/${sourceIP}/111" 2>/dev/null; echo $?)" echo "echo `date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : Error mounting share. $(gatherCTInfo)" >> ${JEM_CALLS_LOG} res=4111 else res=0 fi fi fi [[ -z "$msg" ]] && echo "successfuly mounted" || echo $msg [[ "$res" -gt 0 ]] && return 1; fi if [[ $running -eq 0 ]] ; then if _hasActiveMounts ; then VEExecRun "$_ENABLEAUTOFSCMD" if [[ "x$SAVE_CONFIG" == "xfalse" ]] ; then _restartAutoFS else _reloadAutoFS fi else VEExecRun "$_DISABLEAUTOFSCMD" fi else log "unmounting" umountVE ${VEID} "$VE_ROOT" >> ${JEM_CALLS_LOG} 2>&1 fi [[ -z "$msg" ]] && echo "successfuly mounted" || echo $msg [[ "$res" -gt 0 ]] && return 1; return 0 } function checkUtils() { if isUUID $VEID; then #check only on running VM [ -z "$VZ_VEID_ROOT" ] && return 1 isVERunning $VEID || return 1 #check for jelastic's autofs config VEExecRun "[ -e $VZ_VEID_ROOT/etc/autofs.gluster ]" [[ "$(VEexecGetLastErrCode)" != "0" ]] && return 1 #check for gluster helper VEExecRun "[ ! -x $VZ_VEID_ROOT/usr/sbin/mount.glusterfs -a ! -x $VZ_VEID_ROOT/sbin/mount.glusterfs ]" [[ "$(VEexecGetLastErrCode)" == "0" ]] && return 1 else #check only on mounted or running container [ -z "$VZ_VEID_ROOT" ] && return 1 isContainerMounted $CTID || return 1 #check for jelastic's autofs config if [ ! -e "$VZ_VEID_ROOT/etc/autofs.gluster" ] ; then return 1 fi #check for gluster helper if [ ! -x "$VZ_VEID_ROOT/usr/sbin/mount.glusterfs" -a ! -x "$VZ_VEID_ROOT/sbin/mount.glusterfs" ] ; then return 1 fi fi return 0 } function processgluster() { CONTAINER_MOUNTS_STORAGE='/etc/autofs.gluster' STORAGE_BACKEND="gluster" #check if client available if isVERunning $VEID ; then if ! VEExecRun "command -v mount.glusterfs &>/dev/null" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID glusterfs helper not found. Installing..." >> $JEM_CALLS_LOG dosetupUtils || return 2 fi else if ! checkUtils $CTID ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - container is not running. Missing utilities" >> $JEM_CALLS_LOG writeJSONResponseErr "result=>4207" "message=>Cannot setup gluster native client. Container is stopped" return 2 fi fi local sourceMountUnEsc=$(sed -re 's/\\(\/|\(|\)|\]|\[|\\)/\1/g' <<< "$sourceMount") local destinationEsc=$(sed -re 's/\s/\\\\040/g' <<< "$_DESTINATION" ) [[ ! -z "$VEID" ]] && { MOUNTS_STORAGE="${VE_ROOT}${CONTAINER_MOUNTS_STORAGE}" } if [[ $running -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - container is not running." >> $JEM_CALLS_LOG $VZCTL mount $CTID > /dev/null 2>&1 fi if [[ "x$VZ_VEID_OS" == "xalpine" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : Alpine Linux detected. Glusterfs is not supported for it" >> $JEM_CALLS_LOG writeJSONResponseErr "result=>4207" "message=>Cannot setup gluster native client" return 2 fi if ! VEExecRun "command -v mount.glusterfs &>/dev/null" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID glusterfs helper not found. Installing..." >> ${JEM_CALLS_LOG} dosetupUtils || return 1 fi autofsdest="$(sed -e 's/\s/\\ /g' <<< $_DESTINATION)" mntEntry="$autofsdest $_DEFAULT_GLUSTER_MOUNT_OPTS $sourceIP:/$(sed -re 's/\\\$/$/g' <<< "$sourceMountUnEsc")" #cmdRegisterMount="echo -e \"$mntEntry\" >> $MOUNTS_STORAGE" if ! preparePath "$_DESTINATION" "$VEID" ; then echo "Cannot create path $_DESTINATION" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : Cannot create path $_DESTINATION. $(gatherCTInfo)" >> $JEM_CALLS_LOG return 1 fi if [[ "x$SAVE_CONFIG" == "xtrue" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : registering $sourceIP:$sourceMount in $VEID" >> $JEM_CALLS_LOG if ! [[ $running == 0 && "$VTYPE" == VM ]]; then out=$(echo -e $mntEntry >> $MOUNTS_STORAGE) else VEExecRun "echo -e $mntEntry >> ${MOUNTS_STORAGE##"$VE_ROOT"}" out="$(VEexecGetLastStdOut)"; fi if [[ ! -z "$out" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : $out" >> $JEM_CALLS_LOG fi fi if [[ $running -eq 0 ]] ; then if _hasActiveMounts ; then VEExecRun "$_ENABLEAUTOFSCMD" if [[ "x$SAVE_CONFIG" == "xfalse" ]] ; then _restartAutoFS else _reloadAutoFS fi else VEExecRun "$_DISABLEAUTOFSCMD" fi else log "unmounting" umountVE ${VEID} "$VE_ROOT" >> ${JEM_CALLS_LOG} 2>&1 fi echo "successfuly mounted" return 0 } function processlocal() { CONTAINER_MOUNTS_STORAGE="/etc/fstab" log "source: $sourceMount destination: ${_DESTINATION} veid: ${VEID}" local mntEntry="${sourceMount}\t${_DESTINATION}\tnone\trw,bind\t0\t0" if [ -z "$VEID" ] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : there is no VEID. Local mounts available only via hardnode call $(gatherCTInfo)" >> ${JEM_CALLS_LOG} echo "VEID required" return 1; fi isVERunning ${VEID} ; running=$? if [[ $running -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - VE is not running." >> ${JEM_CALLS_LOG} if ! mountVE ${VEID} $VE_ROOT > /dev/null 2>&1 ; then writeJSONResponseErr "result=>4195" "message=>Cannot mount VE:$VEID" log "Cannot mount VE:$VEID" return 1 fi fi OIFS=${IFS};IFS=$'\n' if [[ $running == 0 && "$VTYPE" == VM ]]; then local aCurrentMounts=($($SED -nre "/none/{/bind/{s/\s*(\S+).*/\1/;p}}" <<<"$(VEExecRunInteractive cat $CONTAINER_MOUNTS_STORAGE)")) else local aCurrentMounts=($($SED -nre "/none/{/bind/{s/\s*(\S+).*/\1/;p}}" "$(vzctPath $VE_ROOT $CONTAINER_MOUNTS_STORAGE)")) fi IFS=${OIFS} log "${aCurrentMounts[@]}" if [[ ${#aCurrentMounts[@]} -gt 0 ]] ; then if indexOf "${aCurrentMounts[*]}" "${sourceMount}" >/dev/null; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : ${sourceMount} already mounted" >> ${JEM_CALLS_LOG} echo "already mounted" if [[ $running -ne 0 ]] ; then log "unmounting" umountVE ${VEID} "$VE_ROOT" >> ${JEM_CALLS_LOG} 2>&1 fi return 0; fi else echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : cannot get fstab entries" >> ${JEM_CALLS_LOG} fi if ! preparePath "${_DESTINATION}" 1 ; then echo "Cannot create path ${_DESTINATION}" return 1 fi if ! preparePath "${sourceMount}" 1 ; then echo "Cannot create path ${sourceMount}" return 1 fi hnSrcPath=${sourceMount} hnDstPath=${_DESTINATION} if [[ "$_MOVEDATA" -gt 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : moving data from $hnDstPath to $hnSrcPath" >> ${JEM_CALLS_LOG} if ! [[ $running == 0 && "$VTYPE" == VM ]]; then if [[ "$VEID" != 0 ]] ; then hnDstPath="${VE_ROOT}${hnDstPath}" hnSrcPath="${VE_ROOT}${hnSrcPath}" fi $RSYNC -aP --force "${hnDstPath}/" "${hnSrcPath}/" >> $ACTIONS_LOG 2>&1 rm -fr "${hnDstPath}/*" >> $ACTIONS_LOG 2>&1 else VEExecRun "rsync -aP --force \"${hnDstPath}/\" \"${hnSrcPath}/\" 2>&1" VEexecGetLastStdOut >> $ACTIONS_LOG VEExecRun "rm -fr \"${hnDstPath}/*\" 2>&1" VEexecGetLastStdOut >> $ACTIONS_LOG fi fi if ! [[ $running == 0 && "$VTYPE" == VM ]]; then echo -e $mntEntry >> "${VE_ROOT}${CONTAINER_MOUNTS_STORAGE}" else VEExecRun "echo -e $mntEntry >> \"${CONTAINER_MOUNTS_STORAGE}\"" fi echo $mntEntry if [[ $running -eq 0 ]] ; then VEExecRun "mount \"$($SED -re 's/("\*|\$|\?|\|\^|`|'\'')/\\\1/g' <<< "${_DESTINATION}")\"" else umountVE ${VEID} "$VE_ROOT" >> ${JEM_CALLS_LOG} 2>&1 fi res=$? if [[ $res -gt 0 ]]; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : error mounting share $(gatherCTInfo)" >> ${JEM_CALLS_LOG} return 1; fi if [[ $running -ne 0 ]] ; then log "unmounting" umountVE ${VEID} "$VE_ROOT" >> ${JEM_CALLS_LOG} 2>&1 fi return 0; } function doRemount() { if [[ "x$VZ_VEID_OS" == "xalpine" ]] ; then log "OS is ALPINE" local shares=(${_DESTINATION}) [[ -z ${_DESTINATION} ]] && { [[ ! -z "${VEID}" ]] && MOUNTS_STORAGE="$(vzctPath $VZ_VEID_ROOT /etc/fstab)" shares=($($SED -nre "/\snfs(3|4)?\s/{s/\s*(\S+)\s*(\S+).*/\2/;p}" "$MOUNTS_STORAGE" )) } for share in ${shares[*]} ; do remountPath "$share" done return 0 fi isVERunning ${VEID} ; running=$? if [[ $running -eq 0 ]] ; then if _hasActiveMounts ; then VEExecRun "$_ENABLEAUTOFSCMD" _reloadAutoFS else VEExecRun "$_DISABLEAUTOFSCMD" fi fi return 0; } function dosetupUtils() { if [[ "x$VEID" == "x" ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install packages: CTID is required" return 1 fi if ! isVERunning $VEID ; then writeJSONResponseErr "result=>4110" "message=>Cannot execute command. Container is not running" return 1 fi OS=$VZ_VEID_OS OS_ver=$VZ_VEID_OS_VER #JE-25896 if [[ "x$OS" == "xalpine" ]] ; then if [[ "$STORAGE_BACKEND" == "gluster" ]] ; then writeJSONResponseErr "result=>4112" "message=>NFS: Alpine Linux is not supported" return 1 fi installCmd=$(installPackageCmd $OS install nfs-utils) VEExecRun "$installCmd" checkCmd=$(checkPackageCmd $OS nfs-utils) VEExecRun "eval $checkCmd" stdout=$(VEexecGetLastStdOut) if [[ -n "$stdout" ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $stdout" return 1 fi VEExecRun "rc-update add netmount default" return 0 fi [[ "$STORAGE_BACKEND" == "nfs" ]] && _packages="autofs nfs-utils" [[ "$STORAGE_BACKEND" == "gluster" ]] && _packages="autofs glusterfs-fuse" if [ "x$OS" == "xubuntu" -o "x$OS" == "xdebian" ] ; then VEExecRun "apt update" dc=3 de=0 packageName="autofs_5.1.6-1j_amd64.deb" while [[ $dc -gt 0 ]] ; do VEDownloadFileWMD5 "http://repository.jelastic.com/pub/$packageName" de=$? dc=$((dc-1)) done if [[ $de -ne 0 ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $packageName. Downloading error!" fi if [ "x$OS" == "xdebian" -a "$OS_ver" -eq "8" ]; then VEExecRun "$(installPackageCmd $OS install autofs)" VEExecRun "DEBIAN_FRONTEND=noninteractive dpkg -i ./$packageName" else VEExecRun "$(installPackageCmd $OS install ./$packageName)" fi VEExecRun "rm -f $packageName" if [[ "$STORAGE_BACKEND" == "gluster" ]] ; then if [ "x$OS" == "xubuntu" ] ; then #Ubuntu VEExecRun "add-apt-repository ppa:gluster/glusterfs-7 -y" else #Debian if [ "$OS_ver" -eq "8" ] ; then writeJSONResponseErr "result=>4112" "message=>Gluster: Debian 8 GNU/Linux is not supported" return 1 fi local _code_name="bullseye" # Debian 11 [ "$OS_ver" -eq "9" ] && _code_name="stretch" [ "$OS_ver" -eq "10" ] && _code_name="buster" VEExecRun "wget -O - https://download.gluster.org/pub/gluster/glusterfs/7/rsa.pub | apt-key add -" VEExecRun "[ ! -d /etc/apt/sources.list.d ] && mkdir -p /etc/apt/sources.list.d" VEExecRun "echo deb [arch=amd64] https://download.gluster.org/pub/gluster/glusterfs/7/LATEST/Debian/$_code_name/amd64/apt $_code_name main > /etc/apt/sources.list.d/gluster.list" VEExecRun "apt install apt-transport-https -y" fi VEExecRun "apt-get update -y" installCmd="$(installPackageCmd $OS install glusterfs-client)" checkCmd=$(checkPackageCmd $OS autofs glusterfs-client) else installCmd="$(installPackageCmd $OS install nfs-common)" checkCmd=$(checkPackageCmd $OS autofs nfs-common) fi elif [[ "$OS" == "centos" || "$OS" == "almalinux" ]] ; then _isCertified=0 if [ "$OS_ver" -eq "8" ]; then _autofspkg="http://repository.jelastic.com/pub/autofs-5.1.6-1j.el8.x86_64.rpm" elif [ "$OS_ver" -eq "9" ]; then _autofspkg="http://repository.jelastic.com/pub/autofs-5.1.8-1j.el9.x86_64.rpm" if vzexecRun "sed -rne '/CERTIFIED_VERSION=/{s/CERTIFIED_VERSION=([0-9]{1,})/\1/g;p}' /etc/jelastic/metainf.conf" ; then res=$(vzexecGetLastStdOut) CERTIFIED_VERSION=$res _isCertified="$CERTIFIED_VERSION" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - certified template version $_isCertified" >> ${JEM_CALLS_LOG}; [[ _isCertified -ge 3 ]] && { vzexecRun "rpm -ivh $_autofspkg"; _autofspkg=""; } fi fi if [ "$OS_ver" -eq "7" ]; then _autofspkg="http://repository.jelastic.com/pub/autofs-5.1.6-1j.el7.x86_64.rpm" fi if [[ "$STORAGE_BACKEND" == "gluster" ]] ; then installCmd=$(installPackageCmd $OS install $_isCertified $_autofspkg glusterfs-fuse) else installCmd=$(installPackageCmd $OS install $_isCertified $_autofspkg nfs-utils) fi checkCmd=$(checkPackageCmd $OS $_packages) else installCmd=$(installPackageCmd $OS install $_packages) checkCmd=$(checkPackageCmd $OS $_packages) fi VEExecRun "$installCmd" echo "$(VEexecGetLastStdOut)" >> ${ACTIONS_LOG} VEExecRun "eval $checkCmd" stdout=$(VEexecGetLastStdOut) if [[ -n "$stdout" ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $stdout" return 1 fi VEExecRun '[ -e /etc/rc.d/init.d/autofs ]' if [[ "$(VEexecGetLastErrCode)" == 0 ]]; then VEExecRunInteractive "grep killproc -A2 /etc/rc.d/init.d/autofs" | $GREP -q 'sleep 1' || \ VEExecRunInteractive "sed -i '/killproc/{N;s/$/\n\t\tsleep 1;/}' /etc/rc.d/init.d/autofs" fi VEExecRun '[ -e /etc/autofs.conf ]' if [[ "$(VEexecGetLastErrCode)" == 0 ]]; then VEExecRunInteractive "sed -i $SED_COPY_OPTION -e \"s/^timeout = .*/timeout = ${JELASTIC_AUTOFS_TIMEOUT}/g\" /etc/autofs.conf" fi if [ "x$OS" == "xdebian" -a "$OS_ver" -eq "7" ] ; then VEExecRun '[ -e /etc/init.d/autofs) ]' if [[ "$(VEexecGetLastErrCode)" == 0 ]]; then VEExecRunInteractive "sed -i -re 's/PROG=automount/PROG=automount\n_SYSTEMCTL_SKIP_REDIRECT=\"true\"/' /etc/init.d/autofs" fi fi if [ "x$OS" == "xcentos" -a "$OS_ver" -eq "7" ] ; then VEExecRun "sed -i -re '/automount/d' /etc/nsswitch.conf" VEExecRun 'echo -e "\nautomount: files" >> /etc/nsswitch.conf' fi if [[ "$STORAGE_BACKEND" == "gluster" ]] ; then VEExecRun "echo '/- /etc/autofs.gluster --timeout=3600' >> /etc/auto.master" else VEExecRun "echo '/- /etc/autofs.jelastic' >> /etc/auto.master" fi VEExecRun "$_DISABLEAUTOFSCMD" return 0 } function gatherCTInfo() { isVERunning $VEID || { echo "VE $VEID is not running" } local _autoFSCfg [[ -n "$CONTAINER_MOUNTS_STORAGE" ]] && _autoFSCfg=$CONTAINER_MOUNTS_STORAGE || _autoFSCfg=${MOUNTS_STORAGE##"$VE_ROOT"} _ctAutoFSFile="$(VEExecRun " [ -e \"$_autoFSCfg\" ] && cat \"$_autoFSCfg\" || echo \"$_autoFSCfg not found\""; VEexecGetLastStdOut)" _ctFstab="$(VEExecRun " [ -e \"/etc/fstab\" ] && cat /etc/fstab || echo \"/etc/fstab not found\""; VEexecGetLastStdOut)" _ctIptablesRules="$(VEExecRun "iptables -S"; VEexecGetLastStdOut)" _ctIpInfo="$(VEExecRun "ip a l; ip r l; [ -e /etc/resolv.conf ] && cat /etc/resolv.conf || echo /etc/resolv.conf" ; VEexecGetLastStdOut)" _ctnftablesrules="$(VEExecRun "[ -x /usr/sbin/nft ] && nft -s list ruleset")" echo -e "\n`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID \n=====\nContainer $VEID Info:\nautofs:\n$_ctAutoFSFile\nfstab:\n$_ctFstab\nip info:\n$_ctIpInfo\niptables:\n$_ctIptablesRules\n=====\nnft:\n$_ctnftablesrules\n======" } function doMount() { [[ -z ${_SOURCE} && -z ${_DESTINATION} ]] && { out=$($EXEC "mount -a" 2>&1) if [[ ! -z "${out}" ]] ; then log "$out" fi return 0; } [[ -z ${_SOURCE} ]] && { writeJSONResponseErr "result=>4065" "message=>SOURCE required" ; return 1; } [[ -z ${_DESTINATION} ]] && { writeJSONResponseErr "result=>4066" "message=>DESTINATION required" ; return 1; } local mtype sourceIP sourceMount isVERunning ${VEID} ; running=$? if [[ $running -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - VE is not running." >> $JEM_CALLS_LOG if ! mountVE ${VEID} $VE_ROOT > /dev/null 2>&1 ; then writeJSONResponseErr "result=>4195" "message=>Cannot mount VE:$VEID" return 1 fi [ -e "$(vzctPath $VZ_VEID_ROOT /etc/autofs.conf)" ] && $SED -i -e "s/^timeout = ${DEFAULT_AUTOFS_TIMEOUT}/timeout = ${JELASTIC_AUTOFS_TIMEOUT}/g" "$(vzctPath $VZ_VEID_ROOT /etc/autofs.conf)" else VEExecRun " [ -e \"/etc/autofs.conf\" ] && sed -i $SED_COPY_OPTION -e \"s/^timeout = ${DEFAULT_AUTOFS_TIMEOUT}/timeout = ${JELASTIC_AUTOFS_TIMEOUT}/g\" \"/etc/autofs.conf\"" fi # parse connection string _SOURCE="$($SED -re 's/(\[|\]|\*|\(|\)|\$|\?|\|)/\\\1/g' <<< "$_SOURCE")" availProtos="[Ll][Oo][Cc][Aa][Ll]|[Nn][Ff][Ss]3?4?|[Ww][Ee][Bb][Dd][Aa][Vv]|[Gg][Ll][Uu][Ss][Tt][Ee][Rr]" availModes="[Rr][Oo]|[Rr][Ww]" eval "$(echo "${_SOURCE}" | \ $SED -rne "s/(($availModes):?($availProtos):?(\/){0,2})?([^:]+):?(.*)/atype=\2\nmtype='\3'\nsourceIP='\5'\nsourceMount='\6';/g;p" | \ $SED -re "s/='(.*?)'.*/=\1/g" | \ $SED -re "s/('|\"|\`)/\\\\\1/g" | \ $SED -re 's/(.*)=(.*)/\1="\2"/g')" mtype=${mtype,,} atype=${atype,,} atype=$($SED -re 's/;//g' <<< $atype) echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - protocol=${mtype} source=${sourceIP} sourceMount=${sourceMount}" >> ${JEM_CALLS_LOG} [[ -z "${mtype}" ]] && mtype="nfs" # for local mounts (bind) if [ "${mtype}" == "local" -a "x${sourceMount}" == "x" ] ; then sourceMount="/${sourceIP}" fi [[ -z "${sourceMount}" ]] && mountpoint="/volumes" [[ -z "${sourceIP}" ]] && { writeJSONResponseErr "result=>4067" "message=>invalid source string format." ; return 1; } _DEFAULT_NFS_MOUNT_OPTS="${_DEFAULT_NFS_MOUNT_OPTS},${atype}" msg=$(process${mtype} "${sourceIP}" "${sourceMount}"); res=$? result="$res" if [[ $running -ne 0 ]] ; then umountVE ${VEID} "$VE_ROOT" >> ${JEM_CALLS_LOG} 2>&1 fi [[ "$res" -gt 0 ]] && result="4111"; [[ "$res" -eq 2 ]] && return 1 writeJSONResponseOut "result=>$result" "message=>${msg}" ; return 0 } function doUmount() { [[ -z ${_DESTINATION} && -z ${UNKNOWN_ARG} ]] && { writeJSONResponseErr "result=>4066" "message=>DESTINATION required" ; return 1; } local rescode retfunc msg="successfully unmounted"; local running local -a shares isVERunning ${VEID}; running=$? if [[ $running -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - VE is not running." >> $JEM_CALLS_LOG if ! mountVE ${VEID} $VE_ROOT > /dev/null 2>&1 ; then writeJSONResponseErr "result=>4195" "message=>Cannot mount VE:$VEID" return 1 fi fi for i in $(seq 0 $((${#UNKNOWN_ARG[@]}-1))); do if [ ! -z "${UNKNOWN_ARG[$i]}" ] ; then [ ${#shares[*]} -gt 0 ] && shares=("${shares[@]}" "${UNKNOWN_ARG[$i]}") || shares=("${UNKNOWN_ARG[$i]}") fi done if [[ ! -z ${_DESTINATION} ]] ; then shares+=("${_DESTINATION}") fi if [[ "x$VZ_VEID_OS" == "xalpine" ]] ; then [[ ! -z "${CTID}" ]] && MOUNTS_STORAGE="$(vzctPath $VZ_VEID_ROOT /etc/fstab)" fi OIFS=$IFS; IFS=$'\n' for i in $(seq 0 $((${#shares[*]}-1)) ) ; do IFS=$OIFS if [[ $running -eq 0 ]] ; then if ! VEExecRun "umount '${shares[$i]}';" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID - Performing lazy umount of ${shares[$i]}" >> $JEM_CALLS_LOG if ! VEExecRun "umount -l '${shares[$i]}';" ; then msg="$(VEexecGetLastStdErr)"; else msg="$(VEexecGetLastStdOut)"; fi fi rescode=$(VEexecGetLastErrCode) else #Already mounted #mountVE ${VEID} $VE_ROOT > /dev/null 2>&1 || { writeJSONResponseOut "result=>4195" "message=>Cannot mount VE:$VEID" ; # log "Cannot mount VE:$VEID"; # return 99; } rescode=0 fi if [[ $FORCE_UMOUNT -eq 0 ]] ; then rescode=0 fi if [[ "x$SAVE_CONFIG" == "xtrue" ]] ; then if [ $rescode -eq 0 ] ; then if [[ "x$VZ_VEID_OS" == "xalpine" ]] ; then local dpath="\s+$($SED -re 's/\//\\\//g' <<< $($SED -re 's/\^/\\^/g' -e 's/\$/\\$/g' -e 's/(\+\{|\}|\[|\]|\(|\))/\\\1/g' -e 's/\s/\\\\040/g' <<< "${shares[$i]}"))\s+(nfs|none)\s+"; else local dpath="^$($SED -re 's/\//\\\//g' <<< $($SED -re 's/\^/\\^/g' -e 's/\$/\\$/g' -e 's/(\+\{|\}|\[|\]|\(|\))/\\\1/g' -e 's/\s/\\\\ /g' <<< "${shares[$i]}"))\s+-fstype=(nfs|glusterfs).*"; fi if ! [[ $running == 0 && "$VTYPE" == VM ]]; then out=$( [[ -e "$MOUNTS_STORAGE" ]] && $SED -i -re /"${dpath}"/d "$MOUNTS_STORAGE" 2>&1 ) out=$( [[ -e "${VE_ROOT}/etc/autofs.gluster" ]] && $SED -i -re /"${dpath}"/d "${VE_ROOT}/etc/autofs.gluster" 2>&1 ) else VEExecRun "[[ -e \"$CONTAINER_MOUNTS_STORAGE\" ]] && sed -i -re /\"${dpath}\"/d \"$CONTAINER_MOUNTS_STORAGE\" 2>&1" out="$(VEexecGetLastStdOut)"; VEExecRun "[[ -e \"/etc/autofs.gluster\" ]] && sed -i -re /\"${dpath}\"/d \"/etc/autofs.gluster\" 2>&1" out="$out $(VEexecGetLastStdOut)"; fi [[ ! -z "${out}" ]] && log "${out}"; retfunc="writeJSONResponseOut result=>0" else echo "`date +%D.%k:%M:%S.%N`: $action:$subaction VEID:$VEID : error umounting share $(gatherCTInfo)" >> ${JEM_CALLS_LOG} retfunc="writeJSONResponseErr result=>99" fi else retfunc="writeJSONResponseOut result=>$rescode" fi done if [[ $running -ne 0 ]] ; then umountVE ${VEID} "$VE_ROOT" >> ${JEM_CALLS_LOG} 2>&1 else if _hasActiveMounts ; then VEExecRun "$_ENABLEAUTOFSCMD" _reloadAutoFS else VEExecRun "$_DISABLEAUTOFSCMD" fi fi $retfunc "message=>$msg"; return 0; } function doList() { msg=$($EXEC "mount | $SED -nre '/nfs(3|4)?/{s/(.*)\s+type.*/\1/g;p}';") writeJSONResponseOut "result=>0" "message=>$msg" return 0 } function doExport() { [[ -z ${_SOURCE} ]] && { writeJSONResponseErr "result=>4065" "message=>SOURCE required" ; return 1; } if ! VEExecRun "jem auth add -t ip -l ${_IPLIST};" ; then writeJSONResponseErr "result=>4030" "message=>$(VEexecGetLastStdErr)"; return $(VEexecGetLastErrCode); fi if ! VEExecRun "mkdir -p '${_SOURCE}'; chmod 0777 '${_SOURCE}';" ; then writeJSONResponseErr "result=>4030" "message=>$(VEexecGetLastStdErr)"; return $(VEexecGetLastErrCode); fi if ! VEExecRun "exportfs -ra;" ; then writeJSONResponseErr "result=>4030" "message=>$(VEexecGetLastStdErr)"; return $(VEexecGetLastErrCode); fi writeJSONResponseOut "result=>0" "message=>success"; return 0; } function describeExport() { echo "Export"; } function describeExportParameters() { echo "-o|--ctid -s|--source "; } function describeExportOptions() { echo "-s|--source: source path"; echo "-o|--ctid: container ID"; } function describeList() { echo "List mount points"; } function describeListParameters() { echo "-o|--ctid "; } function describeListOptions() { echo "-o|--ctid: container ID"; } function describeMount() { echo "Mount source to destination"; } function describeMountParameters() { echo "-o|--ctid --uuid --vtype -s||--source -d|--destination "; } function describeMountOptions() { echo "-o|--ctid: container ID"; echo "--uuid: VM uuid"; echo "--vtype: VE type: VM or CT"; echo "-s|--source: source path"; echo "-d|--destination: destination path"; } function describeUmount() { echo "Umount destination"; } function describeUmountParameters() { echo "-o|--ctid --uuid --vtype -d|--destination "; } function describeUmountOptions() { echo "-o|--ctid: container ID "; echo "--uuid: VM uuid"; echo "--vtype: VE type: VM or CT"; echo "-d|--destination: destination path"; } defineBigInline _DISABLEAUTOFSCMD <<'EOF' if pgrep automount >/dev/null ; then if [ -d /run/systemd/system ] ; then systemctl disable autofs; systemctl stop autofs; elif command -V initctl >/dev/null 2>&1 ; then if command -V update-rc.d >/dev/null 2>&1 ; then update-rc.d autofs disable ; else chkconfig autofs off; service autofs stop ; fi; fi; else if [ -d /run/systemd/system ] ; then systemctl disable autofs; elif command -V initctl >/dev/null 2>&1 ; then update-rc.d autofs disable ; else chkconfig autofs off; fi fi EOF defineBigInline _ENABLEAUTOFSCMD <<'EOF' if [ -d /run/systemd/system ] ; then systemctl enable autofs; if ! pgrep automount >/dev/null ; then systemctl start autofs; fi elif command -V initctl >/dev/null 2>&1 ; then if command -V update-rc.d >/dev/null 2>&1 ; then update-rc.d autofs enable ; else chkconfig autofs on; fi if ! pgrep automount >/dev/null ; then service autofs start ; fi else chkconfig autofs on; if ! pgrep automount >/dev/null ; then service autofs start ; fi fi; EOF