#!/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 net; include log virtuozzo vzexec; DESCRIPTION="Manipulate NFS authentication inside container"; VERSION="1" DEFAULT_ACTION="Usage"; declare -l ATYPE; declare DESTINATION; declare -a IPLIST; declare -i CTID; declare FALSE=1 declare TRUE=0 declare _BACKUP_COUNT=5 VERBOSE=1 EXPORTS_PATH="/etc/exports" EXPORTS_EXT="" CONTAINER_EXPORTS_FILE="${EXPORTS_PATH}${EXPORTS_EXT}" NFS_CONFIG_DIR="/etc" DEFAULTEXPORTOPT="async,rw,no_subtree_check,no_root_squash" NFS_BACKEND="Native" STORAGE_BACKEND="nfs" # nfs | gluster _NFS_VERSION=3 MOUNTPROG="/sbin/unfsd" MOUNTPACKAGE="/var/lib/jelastic/packages/jelastic-nfs-server.tar.gz" METAINFOFILE="/etc/jelastic/metainf.conf" CLIENTSPATH="/etc/jelastic/clients" CLIENTS="" $PROGRAM "tar" VZ_TYPE=0 function doUsage() { showUsageMessage } function onModLoadCallback() { log "Preload callback"; ## TODO: remove "params" garbarge option local temp=`getopt -o t:,l:,p:,c:,r: -l list:,clients:,type:,path:,ctid:,uuid:,vtype:,readonly:,version: -- params "$@" 2>/dev/null` oldifs; [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while true ; do case "$1" in -t | --type) shift ATYPE=${1,,} shift ;; -l | --list ) shift oldifs=$IFS IFS=';' IPLIST=(${1}) IFS=${oldifs} shift ;; -p | --path ) shift DESTINATION=${1} shift ;; -c | --ctid ) shift CTID=$1 vzexecSetCTID $CTID shift ;; --uuid) shift; _UUID=$1 UUID=$1 shift; ;; --vtype) shift; VTYPE=$1 shift; ;; --clients ) shift CLIENTS="$1" shift ;; --version ) shift case ${1^^} in NFS | NFS3 ) _NFS_VERSION=3 ;; NFS4 ) _NFS_VERSION=4 ;; GLUSTER ) STORAGE_BACKEND="gluster" ;; esac shift ;; --) shift break ;; esac; done; [[ ! -z "${CTID}" ]] && { populateVEVarsVZ $CTID res=$? if [[ "$res" -eq 3 ]] ; then writeJSONResponseErr "result=>4003" "message=>ctid $CTID not found" die -q; fi VZ_CTID_ROOT=$VZ_VEID_ROOT NFS_CONFIG_DIR="$(vzctPath $VZ_VEID_ROOT /etc)" NFS_CONFIG_FILE="$(vzctPath $VZ_VEID_ROOT /etc/exports)" EXPORTS_FILE="$(vzctPath $VZ_VEID_ROOT $CONTAINER_EXPORTS_FILE)" if vzexecRun "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 vzexecRun "sed -rne '/VAP_FIREWALL_BACKEND=/{s/VAP_FIREWALL_BACKEND=(nftables|iptables)/\1/g;p}' /etc/jelastic/metainf.conf" ; then res=$(vzexecGetLastStdOut) [ -n "$res" ] && VAP_FIREWALL_BACKEND=$res echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - Firewall backend from metainf is $VAP_FIREWALL_BACKEND" >> $JEM_CALLS_LOG fi vzexecRun "[ ! -d $CLIENTSPATH ] && mkdir -p $CLIENTSPATH" VZ_TYPE=$(set +f; cat /etc/*release /etc/issue | grep -i "virtuozzo\|parallels" | awk '{ for (i=1; i/dev/null); VAP_FIREWALL_BACKEND=$( detectFirewallBackend "$issue_string" ) fi } function dosetupUtils() { if [[ "x$CTID" == "x" ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install packages: CTID is required" return 1 fi if isContainerRunning $CTID ; then if [ -z "$_metainf" ] ; then _metainf="$(vzctPath $VZ_CTID_ROOT $METAINFOFILE)" fi echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - Looking COMPUTE_TYPE in $_metainf" >> $JEM_CALLS_LOG local computetype="$( [ -e "$_metainf" ] && $SED -nre '/COMPUTE_TYPE=/{s/COMPUTE_TYPE=(\S+)/\1/g;p}' "$_metainf")" if [[ "xstorage" == "x$computetype" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - The node is a shared storage. Enabling nfs server" >> $JEM_CALLS_LOG vzexecRun "systemctl enable nfs-server" return 0 fi fi if [[ ! -e "$MOUNTPACKAGE" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - error installing unfsd. $MOUNTPACKAGE not found" >> $JEM_CALLS_LOG return 1 fi local proxy_env="export http_proxy=\"$(printenv http_proxy)\"; export https_proxy=\"$(printenv https_proxy)\"; export ftp_proxy=\"$(printenv ftp_proxy)\"; export no_proxy=\"$(printenv no_proxy)\""; local addPackages="" #install nfs-utils case $VZ_VEID_OS in almalinux|centos|fedora|vzlinux ) if [ "x$VZ_VEID_OS" == "xcentos" -a "$VZ_VEID_OS_VER" -eq 5 ] ; then writeJSONResponseErr "result=>4112" "message=>NFS: CentOS 5 is not supported" return 1 fi if [ "x$VZ_VEID_OS" == "xcentos" -a "$VZ_VEID_OS_VER" -eq 6 ] ; then writeJSONResponseErr "result=>4112" "message=>NFS: CentOS 6 is not supported" return 1 fi addPackages="libtirpc" if [ "$VZ_VEID_OS_VER" -eq 7 -o "x$VZ_VEID_OS" == "xvzlinux" ]; then addPackages="$addPackages nfs-utils" fi #perform repos update local repo="updates,base" [[ "${VZ_VEID_OS_VER/.*}" == "9" ]] && repo="appstream" vzexecRun "$proxy_env; yum update -y ca-certificates --disablerepo=* --enablerepo=$repo" ;; debian|ubuntu ) if [ "x$VZ_VEID_OS" == "xdebian" -a "$VZ_VEID_OS_VER" -eq 6 ] ; then writeJSONResponseErr "result=>4112" "message=>NFS: Debian 6 is not supported" return 1 fi addPackages="libtirpc1 nfs-common" case $VZ_VEID_OS_VER in 10|11|12|20|22) addPackages="libtirpc-common nfs-common" ;; esac waitCounter=90 echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - waiting until dpkg lock is released" >> $JEM_CALLS_LOG; for apt_lock_file in "/var/lib/dpkg/lock" "/var/lib/dpkg/lock-frontend"; do if [ -f "$(vzctPath $VZ_VEID_ROOT $apt_lock_file)" ]; then while [ -n "$(vzexecRun "pgrep 'apt|dpkg' | tr '[:cntrl:]' ' '"; vzexecGetLastStdOut;)" ]; do waitCounter=$((waitCounter-1)); [[ $waitCounter -eq 0 ]] && break sleep 3; done rm -f "$(vzctPath $VZ_VEID_ROOT $apt_lock_file)" fi done case $VZ_VEID_OS_VER in 10|11) ric="--allow-releaseinfo-change" ;; *) ric="" ;; esac #perform repos update vzexecRun "$proxy_env; apt-get $ric update -y" ;; alpine) writeJSONResponseErr "result=>4112" "message=>NFS: Alpine Linux is not supported" return 1 ;; esac echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - installing rpcbind $addPackages" >> $JEM_CALLS_LOG installCmd=$(installPackageCmd $VZ_VEID_OS install rpcbind $addPackages) checkCmd=$(checkPackageCmd $VZ_VEID_OS rpcbind ) #the installFromTAR indicates whether unfsd will be unpacked from TAR or we use package installFromTAR=1 case $VZ_VEID_OS in ubuntu) if [ $VZ_VEID_OS_VER -ge 22 ] ; then installFromTAR=0 dc=3 de=0 packageName="unfsd_0.9.23.deb" while [[ $dc -gt 0 ]] ; do VEDownloadFileWMD5 "http://repository.jelastic.com/pub/unfsd/deb/22.04/$packageName" de=$? dc=$((dc-1)) done if [[ $de -ne 0 ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $packageName. Downloading error!" fi fi ;; debian) if [ $VZ_VEID_OS_VER -ge 12 ] ; then installFromTAR=0 dc=3 de=0 packageName="unfsd_0.9.23.deb" while [[ $dc -gt 0 ]] ; do VEDownloadFileWMD5 "http://repository.jelastic.com/pub/unfsd/deb/22.04/$packageName" de=$? dc=$((dc-1)) done if [[ $de -ne 0 ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $packageName. Downloading error!" fi fi ;; almalinux) if [ $VZ_VEID_OS_VER -ge 9 ] ; then installFromTAR=0 dc=3 de=0 packageName="unfsd-0.9.23-1.el9.x86_64.rpm" while [[ $dc -gt 0 ]] ; do VEDownloadFileWMD5 "http://repository.jelastic.com/pub/unfsd/rpm/$packageName" de=$? dc=$((dc-1)) done if [[ $de -ne 0 ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $packageName. Downloading error!" fi fi ;; esac if [[ $installFromTAR -eq 1 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - unpacking $MOUNTPACKAGE" >> $JEM_CALLS_LOG $TAR hzxf "$MOUNTPACKAGE" -C "$VZ_VEID_ROOT/" fi # install systemD unit [[ -d "$(vzctPath $VZ_VEID_ROOT /lib/systemd/system)" ]] && echo "$SystemDUnit" > "$(vzctPath $VZ_VEID_ROOT /lib/systemd/system/unfsd.service)" isContainerRunning $CTID && { vzexecRun "$installCmd" #log output from package manager echo "CTID:$CTID Detected OS: $VZ_VEID_OS package manager response: $(vzexecGetLastStdOut) $(vzexecGetLastStdErr)" >> $ACTIONS_LOG # if not installed from TAR-package use the package manager if [[ $installFromTAR -eq 0 ]] ; then PMInstallCmd="" case $VZ_VEID_OS in debian|ubuntu) PMInstallCmd="dpkg --install ./unfsd_0.9.23.deb && rm ./unfsd_0.9.23.deb" ;; almalinux) PMInstallCmd="rpm -i ./unfsd-0.9.23-1.el9.x86_64.rpm && rm ./unfsd-0.9.23-1.el9.x86_64.rpm" ;; esac if ! VEExecRun "$PMInstallCmd" ; then stdout=$(vzexecGetLastStdOut) writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $stdout" return 1 fi fi vzexecRun "eval $checkCmd" stdout=$(vzexecGetLastStdOut) if [[ -n "$stdout" ]] ; then writeJSONResponseErr "result=>4140" "message=>Failed to install following packages: $stdout" return 1 fi if [ "x$VZ_VEID_OS" == "xubuntu" -o "x$VZ_VEID_OS" == "xdebian" -o "x$VZ_VEID_OS" == "xsuse" ] ; then vzexecRun '[ -d /etc/conf.d1 ] && ln -s "/etc/rc.d/init.d/unfsd.jelastic" "/etc/init.d/unfsd.jelastic"' fi if [ "x$VZ_VEID_OS" == "xubuntu" -o "x$VZ_VEID_OS" == "xdebian" ] ; then vzexecRun 'update-rc.d unfsd.jelastic defaults' if [ "x$VZ_VEID_OS" == "xdebian" ] ; then if [ "$VZ_VEID_OS_VER" -ge "8" ] ; then vzexecRun "systemctl enable unfsd" else vzexecRun 'sed -i -r "/^#/!s/exit\s+0/service rpcbind start;\n\/etc\/init.d\/unfsd.jelastic start;\nexit 0/g" /etc/rc.local' fi fi fi if ! vzexecRun "$_INSTALLUNFSDCMD" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - error installing unfsd." >> $JEM_CALLS_LOG return 1 fi } return 0 } function gatherCTInfo() { isContainerRunning $CTID || { echo "Container $CTID is not running" } _ctExportsFile="$(vzexecRun "[[ -e $CONTAINER_EXPORTS_FILE ]] && cat $CONTAINER_EXPORTS_FILE || echo \"$CONTAINER_EXPORTS_FILE not found\""; vzexecGetLastStdOut)" if [ "x$VAP_FIREWALL_BACKEND" == "xiptables" ] ; then _ctFirewallRules="$(vzexecRun "iptables -S"; vzexecGetLastStdOut)" else _ctFirewallRules="$(vzexecRun "nft list ruleset"; vzexecGetLastStdOut)" fi _ctIpInfo="$(vzexecRun "ip a l; ip r l" ; vzexecGetLastStdOut)" echo -e "\n`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID \n=====\nContainer $CTID Info:\nexports:\n$_ctExportsFile\nip info:\n$_ctIpInfo\niptables:\n$_ctFirewallRules\n=====\n" } function _adjustFirewall() { if isFunction "_adjust${STORAGE_BACKEND^^}Firewall" ; then "_adjust${STORAGE_BACKEND^^}Firewall" "$@" fi } function _adjustNFSFirewall() { echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID _adjustNFSFirewall started" >> $JEM_CALLS_LOG isContainerRunning ${CTID} || return $FALSE; vzexecRun "jem firewall isEnabled" fwstatus=$(vzexecGetLastErrCode) if [[ "$fwstatus" -gt 0 ]] ; then #firewall is not running in container (or old jem inside) set -f [ -e "$(vzctPath $VZ_CTID_ROOT /etc/exports)" ] && NFSIPS=($($SED -re 's/.+(\s|\t)+((\*)|([0-9]+\.){3}[0-9]+(\/[0-9]{0,2})?).*/\2/g' -e '/#/d' "$(vzctPath $VZ_CTID_ROOT /etc/exports)" | sort | uniq | $SED -e '/^$/d' -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g')) if [ "x$VAP_FIREWALL_BACKEND" == "xiptables" ] ; then local __allnetwork=0 IPT="iptables" if [[ "${#NFSIPS[@]}" -gt 0 ]] ; then for nfsip in ${NFSIPS[@]} ; do if [ "$nfsip" == "*" ] ; then # whole network requested vzexecRun "$IPT -D INPUT -p tcp -m multiport --dports 111,2049 -j ACCEPT; $IPT -D INPUT -p udp -m multiport --dports 111,2049 -j ACCEPT; $IPT -I INPUT -p tcp -m multiport --dports 111,2049 -j ACCEPT; $IPT -I INPUT -p udp -m multiport --dports 111,2049 -j ACCEPT" #all network exported __allnetwork=1 break else #remove rule if already exists vzexecRun "$IPT -D INPUT -p tcp -m multiport --dports 111,2049 -s $nfsip -j ACCEPT; $IPT -D INPUT -p udp -m multiport --dports 111,2049 -s $nfsip -j ACCEPT" #add new rule for selected IP vzexecRun "$IPT -I INPUT -p tcp -m multiport --dports 111,2049 -s $nfsip -j ACCEPT; $IPT -I INPUT -p udp -m multiport --dports 111,2049 -s $nfsip -j ACCEPT" fi done fi vzexecRun "$IPT -D INPUT -i lo -j ACCEPT; $IPT -I INPUT -i lo -j ACCEPT" if [[ "$__allnetwork" -eq 0 ]] ; then #DROP ALL OTHER SOURCES vzexecRun "$IPT -D INPUT -p udp -m multiport --dports 111,2049 -j DROP; $IPT -D INPUT -p tcp -m multiport --dports 111,2049 -j DROP" vzexecRun "$IPT -A INPUT -p udp -m multiport --dports 111,2049 -j DROP; $IPT -A INPUT -p tcp -m multiport --dports 111,2049 -j DROP" fi vzexecRun "service iptables save" #JE-26417 vzexecRun "[ -x /etc/init.d/iptables-persistent ] && /etc/init.d/iptables-persistent save ; [ -x /etc/init.d/netfilter-persistent ] && /etc/init.d/netfilter-persistent save" else inherit nftables local __allnetwork=0 for nfsip in ${NFSIPS[@]} ; do if [[ "${#NFSPort}" -gt 0 ]] ; then if [ "$nfsip" == "*" ] ; then vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip daddr $ip tcp dport { $NFSPort} counter accept" 2>>$JEM_CALLS_LOG vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip daddr $ip udp dport { $NFSPort} counter accept" 2>>$JEM_CALLS_LOG __allnetwork=1 else if [[ "$__allnetwork" -eq 0 ]] ; then vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip saddr $nfsip ip daddr $ip tcp dport { $NFSPort} counter accept" 2>>$JEM_CALLS_LOG vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip saddr $nfsip ip daddr $ip udp dport { $NFSPort} counter accept" 2>>$JEM_CALLS_LOG fi fi fi if [[ "${#RPCPort}" -gt 0 ]] ; then if [ "$nfsip" == "*" ] ; then vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip daddr $ip tcp dport { $RPCPort} counter accept" 2>>$JEM_CALLS_LOG vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip daddr $ip udp dport { $RPCPort} counter accept" 2>>$JEM_CALLS_LOG __allnetwork=1 else if [[ "$__allnetwork" -eq 0 ]] ; then vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol tcp ip saddr $nfsip ip daddr $ip tcp dport { $RPCPort} counter accept" 2>>$JEM_CALLS_LOG vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol udp ip saddr $nfsip ip daddr $ip udp dport { $RPCPort} counter accept" 2>>$JEM_CALLS_LOG fi fi fi done vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_TABLE_NAME $FW_FILTER_INPUT_CHAIN iifname \"lo\" accept" if [[ "$__allnetwork" -eq 0 ]] ; then #DROP ALL OTHER SOURCES #UDP vzexecRun "nft -a list ruleset | sed -rne '/udp.+111,\s*2049.*drop.*/{s/.*handle\s([0-9]+)$/\1/g;p}'" h="$(vzexecGetLastStdOut)" if [ -n $h ] ; then vzexecRun "nft delete rule ip filter INPUT handle $h" fi #TCP vzexecRun "nft -a list ruleset | sed -rne '/tcp.+111,\s*2049.*drop.*/{s/.*handle\s([0-9]+)$/\1/g;p}'" h="$(vzexecGetLastStdOut)" if [ -n $h ] ; then vzexecRun "nft delete rule ip filter INPUT handle $h" fi vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol ip udp dport { 111,2049} counter accept" vzexecRun "nft add rule $FW_DEFAULT_TABLE_TYPE $FW_FILTER_TABLE_NAME $FW_FILTER_INPUT_CHAIN ip protocol ip tcp dport { 111,2049} counter accept" fi vzexecRun "nft -s list ruleset >> \"$FW_RULESET_FILE\" 2>> $JEM_CALLS_LOG" fi set +f else #firewall is enabled, so call reconfiguration method vzexecRun "jem firewall FWReconfigure" fi } function validateExports() { : ${1:?"Missing param: file to check"}; OIFS=$IFS;IFS=$'\n' dd=($(getExportedDirList $1)); #IFS=$OIFS if [[ $? -eq 0 ]] ; then for (( i = 0; i < ${#dd[@]}; i++)) ; do isValidShare ${dd[$i]} $1 "$VZ_CTID_ROOT" || invalidExports=("${invalidExports[@]}" "${dd[$i]}") done local backup="$1.backup-$(date +%d-%m-%Y.%H:%M:%S.%N)" cp -f "$1" "$backup" > /dev/null 2>&1 keeplist=$(mktemp) fulllist=$(mktemp) find $NFS_CONFIG_DIR -name exports.backup-??-??-????.??:??:??.* -printf '%T@ %p\n' 2>/dev/null | sort -k 1nr | sed 's/^[^ ]* //' | head -n $_BACKUP_COUNT > $keeplist 2>/dev/null find $NFS_CONFIG_DIR -name exports.backup-??-??-????.??:??:??.* -printf '%T@ %p\n' 2>/dev/null | sort -k 1nr | sed 's/^[^ ]* //' > $fulllist 2>/dev/null comm -13 --nocheck-order $keeplist $fulllist 2>/dev/null | while read f ; do echo "removing backup file $f " >> $ACTIONS_LOG rm $f 2>/dev/null done /bin/rm -f $keeplist 2>/dev/null /bin/rm -f $fulllist 2>/dev/null for (( i = 0; i < ${#invalidExports[@]}; i++)) ; do lineToComment="/$(sed -re 's/\//\\\//g' <<< $(sed -re 's/\^/\\^/g' -e 's/\$/\\$/g' -e 's/(\+\{|\}|\[|\]|\(|\))/\\\1/g' -e 's/\s/(\\\\040|\\s)/g' <<< "${invalidExports[$i]}"))/ s/^#*/#/" sed -i -re "$lineToComment" "$1" done else IFS=$OIFS return 1 fi IFS=$OIFS local tmpfile=$( mktemp -p /tmp ) $AWK '!seen[$0]++' "$1" > "$tmpfile" 2>/dev/null && sed -i -re '/^".*"\s*$/d' -e '/^[^\s]+\s?$/d' $tmpfile && mv -f "$tmpfile" "$1" >/dev/null 2>&1 chmod 666 "$1" return 0 } function _checkConfigs() { local UNFSDBIN='/sbin/unfsd' local _metainf="$(vzctPath $VZ_CTID_ROOT $METAINFOFILE)" vzexecRun "[[ ! -e '/etc/exports' ]]" && return 1 validateExports "$(vzctPath $VZ_CTID_ROOT /etc/exports)" || return 1 isContainerRunning $CTID && { local computetype="$( [ -e "$_metainf" ] && $SED -nre '/COMPUTE_TYPE=/{s/COMPUTE_TYPE=(\S+)/\1/g;p}' "$_metainf")" if [[ "xstorage" == "x$computetype" ]] ; then vzexecRun "[[ ! -e $MOUNTPROG ]]" && return 0 fi vzexecRun "$UNFSDBIN -T" errCode=$(vzexecGetLastErrCode) [[ "$errCode" -ne 0 ]] && return 1 } return 0 } function _nfsReexport() { local _metainf="$(vzctPath $VZ_CTID_ROOT $METAINFOFILE)" log "ReExporting shares" _checkConfigs || { echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID _nfsReexport: Cannot add client configuration. $(gatherCTInfo)" >> ${JEM_CALLS_LOG} return 1 } _adjustFirewall >> ${JEM_CALLS_LOG} isContainerRunning ${CTID} && { local computetype="$( [ -e "$_metainf" ] && $SED -nre '/COMPUTE_TYPE=/{s/COMPUTE_TYPE=(\S+)/\1/g;p}' "$_metainf")" if [[ "xstorage" == "x$computetype" ]] ; then if vzexecRun "[[ ! -e $MOUNTPROG ]]" ; then vzexecRun "exportfs -ra" local err=$(vzexecGetLastStdErr) [[ -z "${err// }" ]] && return $TRUE echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID _nfsReexport: Cannot add client configuration. exports:$(gatherCTInfo) | $err " >> ${JEM_CALLS_LOG} return 1 fi fi } PID=$(vzctl exec ${CTID} pgrep unfsd) if [[ ! -z "${PID}" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - Reloading unfsd with PID: $PID" >> ${JEM_CALLS_LOG} vzctl exec ${CTID} kill -HUP $PID > /dev/null 2>&1; res=$? echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - Reloading done, exit result is $res" >> ${JEM_CALLS_LOG} fi return 0 } function doRestart() { if [[ "x$STORAGE_BACKEND" == "xnfs" ]] ; then if ! _nfsReexport ; then writeJSONResponseErr "result=>4113" "message=>NFS: Cannot verify client configuration" return 1 fi fi writeJSONResponseOut "result=>0" "message=>Success" return 0 } function _addNativeip() { if [[ -z "${IPLIST[*]}" ]] ; then log "ADD: Empty ip list. Nothing to do. Exiting"; return; fi eval "$($SED -re "/^r[ow]:.*/{s/^((ro|rw):)?(\/?.*)/accessMode='\2'\ndestinationPath='\3'/g;ta};s/^(\/.*)/destinationPath='\1'/g;ta;s/(.*)/errValue='\1'/;q1;:a;q0;" <<< "$DESTINATION" | $SED -re "s/='(.*?)'.*/=\1/g" | $SED -re "s/('|\"|\`)/\\\\\1/g" | $SED -re 's/(.*)=(.*)/\1="\2"/g')" [[ -z "$destinationPath" ]] && { writeJSONResponseErr "result=>4066" "message=>Wrong param. DESTINATION required" ; return 1; } if [[ "x$STORAGE_BACKEND" == "xgluster" ]] ; then _addGlusterShare || return 1 return 0 fi local aCurrentIPs=() local running local _createPath=1 local _isFUSE=0 local _done=0 local _version=$_NFS_VERSION local _metainf="$(vzctPath $VZ_CTID_ROOT $METAINFOFILE)" isContainerRunning ${CTID} ; running=$? if [[ $running -ne 0 ]] ; then $VZCTL mount $CTID > /dev/null 2>&1 EXPORTS_FILE="$(vzctPath $VZ_CTID_ROOT $CONTAINER_EXPORTS_FILE)" else if ! vzexecRun "which rpcbind showmount" ; then dosetupUtils $CTID || return 1 fi if [[ ! -e "${VZ_CTID_ROOT}${MOUNTPROG}" ]] ; then dosetupUtils $CTID || return 1 fi fi local computetype="$( [ -e "$_metainf" ] && $SED -nre '/COMPUTE_TYPE=/{s/COMPUTE_TYPE=(\S+)/\1/g;p}' "$_metainf")" if [[ "xstorage" == "x$computetype" ]] ; then _version=4 if isContainerRunning ${CTID} ; then if vzexecRun "grep -q \" $destinationPath fuse\" /proc/mounts" ; then _createPath=0 _isFUSE=1 elif vzexecRun "fuse_avail=\$(grep \"fuse\" /proc/mounts | awk '{print \$2}'); [ -n \"\$fuse_avail\" ] && grep -q \$fuse_avail <<< \"$destinationPath\"" ; then vzexecRun "[ ! -e \"${destinationPath}\" ]" && _createPath=1 || _createPath=0 _isFUSE=1 fi else _createPath=0 fi fi [ "$VZ_TYPE" -eq 6 ] && _version=3 if [ -e "${EXPORTS_FILE}" ] ; then dPath="\\\"?$($SED -re 's/(\[|\]|\*|\(|\)|\$|\?|\|)/\\\1/g' <<< $destinationPath)\\\"?\s+" if [[ $running -eq 0 ]] ; then if vzexecRun "grep -E \"$dPath\" \"$CONTAINER_EXPORTS_FILE\"" ; then aCurrentIPs=($(vzexecGetLastStdOut | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\/[0-9]{2})?')) fi else aCurrentIPs=($(grep -E "$dPath" "$EXPORTS_FILE" | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\/[0-9]{2})?')) fi fi log "Adding IPs to exports file (${EXPORTS_FILE})" for i in "${IPLIST[@]}" ; do isValidIP $i || continue if [[ $running -ne 0 ]] ; then # container is mounted, but not running. Try to perform operations directly on mounted fs # --------------------------------------------------------------------------------------- echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - container is not running." >> ${JEM_CALLS_LOG} if [[ -f "$(vzctPath $VZ_CTID_ROOT ${destinationPath})" ]] ; then writeJSONResponseOut "result=>4150" "message=>Exporting regular files via NFS is not supported. Please export directory" ; return $FALSE fi [[ ! -d "$(vzctPath $VZ_CTID_ROOT ${destinationPath})" ]] && [ ! -L "${VZ_CTID_ROOT}${destinationPath}" ] && { if [[ $_createPath -eq 1 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - creating directory ${VZ_CTID_ROOT}${destinationPath} " >> ${JEM_CALLS_LOG} mkdir -p "${VZ_CTID_ROOT}${destinationPath}" chmod 0777 "${VZ_CTID_ROOT}${destinationPath}" fi } else # container is running. use vzctl # --------------------------------------------------------------------------------------- echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - container is running. Performing all operations via vzctl" >> ${JEM_CALLS_LOG} if vzexecRun "[[ -f \"$destinationPath\" ]]" ; then writeJSONResponseOut "result=>4150" "message=>Exporting regular files via NFS is not supported. Please export directory" ; return $FALSE fi if vzexecRun "[[ ! -d \"$destinationPath\" ]] && [ ! -L \"$destinationPath\" ]" ; then if [[ $_createPath -eq 1 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - creating directory $destinationPath" >> ${JEM_CALLS_LOG} if ! vzexecRun "mkdir -p \"$destinationPath\" && chmod 0777 \"$destinationPath\"" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - Error creating directory: $(vzexecGetLastStdErr; vzexecGetLastStdOut)" >> ${JEM_CALLS_LOG} fi fi fi fi if [[ -z $(indexOf "${aCurrentIPs[*]}" "$i") ]] ; then log "${DESTINATION}\t${i}${DEFAULTEXPORTOPT}" [[ "x${accessMode}" == "xro" ]] && DEFAULTEXPORTOPT=$($SED -re 's/,rw,/,ro,/g' <<< $DEFAULTEXPORTOPT) _opts="$DEFAULTEXPORTOPT" if [[ $_version -eq 4 ]] ; then if [ -z "$_UUID" ] ; then local pathID=$(md5sum <<< "$i:$destinationPath" | cut -d' ' -f1 ) # md5sum of : _UUID="${pathID::8}-${pathID:8:4}-${pathID:12:4}-${pathID:16:4}-${pathID:20:12}" fi _opts="$DEFAULTEXPORTOPT,fsid=$_UUID" fi if [[ $running -ne 0 ]] ; then echo -e "\"${destinationPath}\"\t$i($_opts)" >> "${EXPORTS_FILE}" else if ! vzexecRun "echo -e \"\\\"${destinationPath}\\\"\t$i($_opts)\">> $CONTAINER_EXPORTS_FILE" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - error adding entry. Error: $(vzexecGetLastStdErr; vzexecGetLastStdOut). $(gatherCTInfo)" >> ${JEM_CALLS_LOG} fi fi _done=1 else echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - entry for $i already exists" >> ${JEM_CALLS_LOG} _done=1 fi done if [[ $running -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - umounting container" >> ${JEM_CALLS_LOG} $VZCTL umount $CTID > /dev/null 2>&1 else if [[ $_done -eq 1 ]] ; then if ! _nfsReexport ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - ReExporting data fail. $(gatherCTInfo)" >> ${JEM_CALLS_LOG} _removeNativeip writeJSONResponseErr "result=>4113" "message=>NFS: Cannot add client configuration" return 1 fi if [ -z "$JELASTIC_CHECK_MOUNT" ]; then if ! vzexecRun "rpcinfo -p $1 | grep -q mountd" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - mountd procedures not found on RPC server. Checking remote share will be disabled" >> ${JEM_CALLS_LOG} JELASTIC_CHECK_MOUNT=0 fi JELASTIC_CHECK_MOUNT=1 fi case "$JELASTIC_CHECK_MOUNT" in false|0) echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - remote server checking disabled" >> ${JEM_CALLS_LOG} return 0 ;; true|1) echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - remote server checking enabled" >> ${JEM_CALLS_LOG} ;; esac retries=5 vzexecRun "showmount -e 127.0.0.1 | grep -qP \"$IPLIST\"" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID - showmount $(vzexecGetLastStdErr; vzexecGetLastStdOut)" >> ${JEM_CALLS_LOG} echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID: checking exports" >> ${JEM_CALLS_LOG}; while [[ $retries -gt 0 ]] ; do if [[ "$(vzexecGetLastErrCode)" -gt 0 ]]; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID: $(vzexecGetLastStdOut)" >> ${JEM_CALLS_LOG}; sleep 4 vzexecRun "showmount -e 127.0.0.1 | grep -qP \"$IPLIST\"" retries=$((retries-1)) else [[ $_isFUSE -eq 1 ]] && _isFUSE="true" || _isFUSE="false" writeJSONResponseOut "result=>0" "message=>Client configuration has been changed" "version=>NFS$_version" "fuse=>$_isFUSE" "UUID=>$_UUID" return $(vzexecGetLastErrCode) fi done echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID: timeout has elapsed" >> ${JEM_CALLS_LOG}; lasterr=$(vzexecGetLastErrCode) if [[ "$lasterr" -ne 0 ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID showmount fails. $(gatherCTInfo) | $err " >> ${JEM_CALLS_LOG} writeJSONResponseErr "result=>4113" "message=>NFS: Cannot add client configuration" fi return $lasterr else echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID Error adding export entry. $(gatherCTInfo) | $err " >> ${JEM_CALLS_LOG} writeJSONResponseErr "result=>4113" "message=>NFS: Cannot add client configuration" fi fi return $? } function _addGlusterShare() { if ! isContainerRunning $CTID ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID Container is not running. Skipping with OK " >> ${JEM_CALLS_LOG} writeJSONResponseOut "result=>0" "message=>Operation was skipped due container is stopped" "version=>GLUSTER" return 0 fi if ! vzexecRun "command -v gluster &>/dev/null" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID gluster command not found " >> ${JEM_CALLS_LOG} writeJSONResponseErr "result=>4208" "message=>GlusterFS cluster is not available" return 1 fi local volumeName=$(sed 's/\///g' <<< $destinationPath) if ! vzexecRun "gluster volume list | grep $volumeName" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID gluster volume $volumeName not found " >> ${JEM_CALLS_LOG} writeJSONResponseErr "result=>4209" "message=>Volume $volumeName is not found" return 1 fi vzexecRun "gluster volume get $volumeName auth.allow 2>/dev/null | tail -n 1 | tr -s ' ' | cut -d ' ' -f2 | tr ',' ' '" local aCurrentIPs=($(vzexecGetLastStdOut)) #explicit remove '*' from a list of allowed IPs aCurrentIPs=(${aCurrentIPs[*]/'*'}) local aNewIPs=("${aCurrentIPs[*]}") local setNewList=0 for i in "${IPLIST[@]}" ; do isValidIP $i || continue if [[ -z "$(indexOf "${aCurrentIPs[*]}" "$i")" ]] ; then aNewIPs=("${aNewIPs[@]}" "$i") setNewList=1 fi done #explicit add localhost if not presnt if [[ -z "$(indexOf "${aCurrentIPs[*]}" "127.0.0.1")" ]] ; then aNewIPs=("${aNewIPs[@]}" "127.0.0.1") setNewList=1 fi if [[ $setNewList -eq 1 ]] ; then _ipstr="${aNewIPs[@]}" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID setting $volumeName auth.allow to ${_ipstr// /,}" >> ${JEM_CALLS_LOG} vzexecRun "gluster volume set $volumeName auth.allow ${_ipstr// /,}" || return 1 vzexecRun "[[ -d $CLIENTSPATH ]] && echo \"$_ipstr\" | sed -r -e 's/ / /g' -e 's/^ //g' -e 's/ $//g' -e 's/\*//g' > $CLIENTSPATH/$volumeName" else #JE-59318 _ipstr="${aCurrentIPs[@]}" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID saving client list for $volumeName: ${_ipstr// /,}" >> ${JEM_CALLS_LOG} vzexecRun "[[ -d $CLIENTSPATH ]] && echo \"$_ipstr\" | sed -r -e 's/ / /g' -e 's/^ //g' -e 's/ $//g' -e 's/\*//g' > $CLIENTSPATH/$volumeName" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID auth.allow not changed" >> ${JEM_CALLS_LOG} fi writeJSONResponseOut "result=>0" "message=>Client configuration has been changed" "version=>GLUSTER" return 0 } function _removeNativeip() { if [[ -z "${IPLIST[*]}" ]] ; then log "REMOVE: Empty ip list. Nothing to do. Exiting"; return; fi [[ "${DESTINATION:0:1}" != '/' ]] && STORAGE_BACKEND="gluster" if [[ "x$STORAGE_BACKEND" == "xgluster" ]] ; then _removeGlusterShare || return 1 return 0 fi isContainerRunning ${CTID} ; running=$? if [[ $running -ne 0 ]] ; then $VZCTL mount $CTID > /dev/null 2>&1 EXPORTS_FILE="$(vzctPath $VZ_CTID_ROOT $CONTAINER_EXPORTS_FILE)" fi _checkConfigs || { echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID _checkConfigs failed. $(gatherCTInfo) | $err " >> ${JEM_CALLS_LOG} writeJSONResponseErr "result=>4113" "message=>NFS: Cannot add client configuration" return $FALSE } DESTINATION=${DESTINATION//\//\\/} DESTINATION=${DESTINATION//\+/\\+} if [[ $running -eq 0 ]] ; then if [ "x$VAP_FIREWALL_BACKEND" == "xiptables" ] ; then for i in "${IPLIST[@]}" ; do isValidIP $i || continue echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID removing $i | $err " >> ${JEM_CALLS_LOG} if ! vzexecRun "sed -i -re \"/\\\"?$DESTINATION\\\"?\s+${i//./\\.}/{/${i//./\\.}[\(| ]/{s/(${i//./\\.}(\([^\)]*\))?)\s?.*//g}}\" $CONTAINER_EXPORTS_FILE" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID error removing $i " >> ${JEM_CALLS_LOG} fi vzexecRun "$IPT -D INPUT -p udp -m multiport --dports 111,2049 -s $i -j ACCEPT; $IPT -D INPUT -p tcp -m multiport --dports 111,2049 -s $i -j ACCEPT" done else for i in "${IPLIST[@]}" ; do isValidIP $i || continue echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID removing $i | $err " >> ${JEM_CALLS_LOG} if ! vzexecRun "sed -i -re \"/\\\"?$DESTINATION\\\"?\s+${i//./\\.}/{/${i//./\\.}[\(| ]/{s/(${i//./\\.}(\([^\)]*\))?)\s?.*//g}}\" $CONTAINER_EXPORTS_FILE" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID error removing $i " >> ${JEM_CALLS_LOG} fi vzexecRun "nft -a list ruleset | sed -rne '/8\.8\.8\.8.*udp dport \{ 111, 2049 \}/{s/.*handle\s([0-9]+)$/\1/g;p}'" h="$(vzexecGetLastStdOut)" if [ -n $h ] ; then vzexecRun "nft delete rule ip filter INPUT handle $h" fi #TCP vzexecRun "nft -a list ruleset | sed -rne '/8\.8\.8\.8.*tcp dport \{ 111, 2049 \}/{s/.*handle\s([0-9]+)$/\1/g;p}'" h="$(vzexecGetLastStdOut)" if [ -n $h ] ; then vzexecRun "nft delete rule ip filter INPUT handle $h" fi done fi #JE-26420 vzexecRun "jem firewall isEnabled" fwstatus=$(vzexecGetLastErrCode) if [[ "$fwstatus" -gt 1 ]] ; then vzexecRun "jem firewall FWReconfigure" fi else for i in "${IPLIST[@]}" ; do isValidIP $i || continue echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID removing $i | $err " >> ${JEM_CALLS_LOG} $SED -i -re "/\"?$DESTINATION\"?\s+/{/${i//./\\.}[\(| ]/{s/(${i//./\\.}(\([^\)]*\))?)\s?.*//g}}" "${EXPORTS_FILE}" done fi # clean up the exports file $SED -i -re '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/!d' "${EXPORTS_FILE}" if [[ $running -ne 0 ]] ; then $VZCTL umount $CTID > /dev/null 2>&1 else _nfsReexport fi return $? } function _removeGlusterShare() { if ! isContainerRunning $CTID ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID Container is not running. Skipping with OK " >> ${JEM_CALLS_LOG} writeJSONResponseOut "result=>0" "message=>Operation was skipped due container is stopped" "version=>GLUSTER" return 0 fi if ! vzexecRun "command -v gluster &>/dev/null" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID gluster command not found " >> $JEM_CALLS_LOG writeJSONResponseErr "result=>4208" "message=>GlusterFS cluster is not available" return 1 fi local volumeName=$(sed 's/\///g' <<< $DESTINATION) if ! vzexecRun "gluster volume list | grep $volumeName" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID gluster volume $volumeName not found " >> $JEM_CALLS_LOG writeJSONResponseErr "result=>4209" "message=>Volume $volumeName is not found" return 1 fi vzexecRun "gluster volume get $volumeName auth.allow 2>/dev/null | tail -n 1 | tr -s ' ' | cut -d ' ' -f2 | tr ',' ' '" local aCurrentIPs=($(vzexecGetLastStdOut)) #explicit remove '*' from a list of allowed IPs aCurrentIPs=(${aCurrentIPs[*]/'*'}) local aNewIPs=("${aCurrentIPs[*]}") for i in "${IPLIST[@]}" ; do isValidIP $i || continue if [[ ! -z "$(indexOf "${aCurrentIPs[*]}" "$i")" ]] ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID removing $i from auth.allow " >> $JEM_CALLS_LOG aNewIPs=("${aNewIPs[@]/$i}") vzexecRun "[ -e $CLIENTSPATH/$volumeName ] && sed -i -re 's/$i//g' -e 's/ / /g' -e 's/^ //g' -e 's/ $//g' -e 's/\*//g' $CLIENTSPATH/$volumeName" setNewList=1 fi done if [[ $setNewList -eq 1 ]] ; then _ipstr=${aNewIPs[@]} #do not remove localhost [[ -z "$_ipstr" ]] && _ipstr="127.0.0.1" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID setting $volumeName auth.allow to ${_ipstr// /,}" >> $JEM_CALLS_LOG vzexecRun "gluster volume set $volumeName auth.allow ${_ipstr// /,}" || return 1 else #JE-59318 _ipstr="${aCurrentIPs[@]}" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID saving client list for $volumeName: ${_ipstr// /,}" >> ${JEM_CALLS_LOG} vzexecRun "[[ -d $CLIENTSPATH ]] && echo \"$_ipstr\" | sed -r -e 's/ / /g' -e 's/^ //g' -e 's/ $//g' -e 's/\*//g' > $CLIENTSPATH/$volumeName" echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID auth.allow not changed" >> $JEM_CALLS_LOG fi writeJSONResponseOut "result=>0" "message=>Client configuration has been changed" "version=>GLUSTER" return 0 } function _cleanNativeip() { if [[ -z "${IPLIST[*]}" ]] ; then log "ADD: Empty ip list. Cleaning all"; if [[ "x$STORAGE_BACKEND" == "xgluster" ]] ; then _cleanGlusterAuth || return 1 return 0 fi isContainerRunning ${CTID} ; running=$? if [[ $running -ne 0 ]] ; then $VZCTL mount $CTID > /dev/null 2>&1 fi echo "" > "${EXPORTS_FILE}" if [[ $running -ne 0 ]] ; then $VZCTL umount $CTID > /dev/null 2>&1 else _nfsReexport fi return; fi return 0 } function _cleanGlusterAuth() { if ! vzexecRun "command -v gluster &>/dev/null" ; then echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID gluster command not found " >> ${JEM_CALLS_LOG} return 1 fi vzexecRun "gluster volume set data auth.allow 127.0.0.1" vzexecRun "gluster volume reset data auth.reject" } function _cleanip() { return 0 } function doAdjustFirewall() { if ! _adjustFirewall ; then PUBLISH_ERROR=1 writeJSONResponseErr "result=>4068" "message=>Firewall reconfiguration error" return 1 else writeJSONResponseOut "result=>0" "message=>Firewall reconfigured successfully" return 0 fi } function doAdd() { local requiredParqams=("CTID" "DESTINATION" "IPLIST" "TYPE") local msg=$(checkParams ${requiredParqams[@]}) [[ ! -z "${msg}" ]] && { writeJSONResponseErr "result=>4099" "message=>Missing param $msg" ; return 99; } _add${NFS_BACKEND}${ATYPE}; } function doRemove() { local requiredParqams=("CTID" "DESTINATION" "IPLIST" "TYPE") local msg=$(checkParams ${requiredParqams[@]}) [[ ! -z "${msg}" ]] && { writeJSONResponseErr "result=>4099" "message=>Missing param $msg" ; return 99; } _remove${NFS_BACKEND}${ATYPE}; return $? } function doList() { local _first=0 if [ ! -e "${EXPORTS_FILE}" ] ; then echo '{"result":"4099", "message":"'${EXPORTS_FILE}' not found!"}' return 1 fi echo '{"result":"0", "shares":[' while read l ; do [[ $_first -eq 0 ]] && _first=1 || echo "," echo -n "{" sed -re 's/^"(.*)"\s+.*fsid=([^,\)]+).*/"name":"\1","fsid":"\2"/' <<< $l | \ sed -re'/root"$/{s/.*"root"/\0,"fuse":"false"/;q}' -e 's/.*/\0,"fuse":"true"/' echo -n "}" done < "${EXPORTS_FILE}" echo "]}" } function doClean() { _clean${NFS_BACKEND}${ATYPE}; return $? } function doSet() { OIFS=$IFS;IFS=";" clist=($CLIENTS);IFS=$OIFS volumes=() re='(.*):(.*):(.*)' for e in ${clist[@]}; do if [[ $e =~ $re ]] ; then volName=${BASH_REMATCH[3]} ipa=${BASH_REMATCH[1]} if [[ ! " ${volumes[@]} " =~ " clp$volName " ]]; then volumes+=("clp$volName") eval "clp${volName}=()" fi eval "clp${volName}+=($ipa)" fi done if ! vzexecRun "gluster volume list" ; then writeJSONResponseErr "result=>4208" "message=>GlusterFS cluster is not available" return 1 fi cVols=($(vzexecGetLastStdOut)) for v in ${cVols[@]} ; do if ! vzexecRun "gluster volume get $v auth.allow 2>/dev/null | tail -n 1 | tr -s ' ' | cut -d ' ' -f2 | tr ',' ' '" ; then writeJSONResponseErr "result=>4210" "message=>Cannot get volume auth list for $v" return 1 fi eval "clc$v=($(vzexecGetLastStdOut))" vzexecRun "[ -e $CLIENTSPATH/$v ] && cat $CLIENTSPATH/$v" eval "clf$v=($(vzexecGetLastStdOut))" aList=clc$v[@] bList=clf$v[@] pList=clp$v[@] rList=() FVol=" ${!bList} " for i in "${!aList}" ; do [[ $FVol =~ " $i " ]] || rList+=($i) done rList+=(${!pList}) #explicit add localhost if not presnt if [[ -z "$(indexOf "${rList[*]}" "127.0.0.1")" ]] ; then rList=("${rList[@]}" "127.0.0.1") fi rList=$(tr ' ' '\n' <<< "${rList[@]}" | sort -u | tr '\n' ' ') if ! vzexecRun "gluster volume set $v auth.allow ${rList// /,}" ; then writeJSONResponseErr "result=>4210" "message=>Cannot set volume auth list for $v" return 1 fi echo "`date +%D.%k:%M:%S.%N`: $action:$subaction CTID:$CTID saving client list for $v: ${rList// /,}" >> ${JEM_CALLS_LOG} vzexecRun "[[ -d $CLIENTSPATH ]] && echo \"$rList\" | sed -r -e 's/ / /g' -e 's/^ //g' -e 's/ $//g' -e 's/\*//g' > $CLIENTSPATH/$v" done writeJSONResponseOut "result=>0" "message=>Clients set successfully" return 0 } defineBigInline SystemDUnit << 'EOF' [Unit] Description=Jelastic UNFSD Requires=rpcbind.target rpcbind.service [Service] Type=forking ExecStart=/sbin/unfsd -i /var/run/unfsd.pid ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure [Install] WantedBy=multi-user.target Alias=unfsd.service EOF defineBigInline _INSTALLUNFSDCMD <<'EOF' if [ -d /run/systemd/system ] ; then systemctl restart rpcbind systemctl restart rpcbind.socket systemctl enable unfsd systemctl start unfsd else [ -f /etc/init.d/rpcbind ] && /etc/init.d/rpcbind restart sed -i "s/\/usr\/sbin\/unfsd/\/sbin\/unfsd/g" /etc/init.d/unfsd.jelastic sed -i "s/\/usr\/sbin\/unfsd/\/sbin\/unfsd/g" /etc/rc.d/init.d/unfsd.jelastic chkconfig --level 345 rpcbind on chkconfig --level 345 unfsd.jelastic on /etc/init.d/unfsd.jelastic start fi EOF