#!/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. [ -n "${PHPCOMMONDEPLOYLIB_VERSION:-}" ] && return 0; PHPCOMMONDEPLOYLIB_VERSION="0.1"; inherit default exceptor; $PROGRAM 'grep'; $PROGRAM 'unzip'; $PROGRAM 'bzip2'; $PROGRAM 'gunzip'; $PROGRAM 'xz'; $PROGRAM 'uncompress'; VERBOSE=0; [[ -n "${WEBROOT}" ]] && [ ! -d "$WEBROOT" ] && mkdir -p ${WEBROOT}; [ -e "${MANAGE_CORE_PATH}/${COMPUTE_TYPE}"-deploy.lib ] && { include ${COMPUTE_TYPE}-deploy; } function unpack(){ APPWEBROOT=$1; getPackageName; shopt -s dotglob; set -f rm -Rf ${APPWEBROOT}/*; set +f shopt -u dotglob; ensureFileCanBeUncompressed "${package_path}/${package_name}"; [[ ! -d "$APPWEBROOT" ]] && { mkdir -p $APPWEBROOT;} unset TAR_UNPACK_OPTIONS; unset UNPACK_COMMAND; if [[ ${package_url} =~ .zip$ ]] || [[ ${package_name} =~ .zip$ ]] then $UNZIP -Z -1 "${package_path}/${package_name}" 2>>$ACTIONS_LOG | $GREP -qEw "^/$" && local skip_path="-x /"; $UNZIP -o "${package_path}/${package_name}" -d "$APPWEBROOT" $skip_path 2>>$ACTIONS_LOG 1>/dev/null; rcode=$?; [ "$rcode" -eq 1 ] && return 0 || return $rcode fi if [[ ${package_url} =~ .tar$ ]] || [[ ${package_name} =~ .tar$ ]] then TAR_UNPACK_OPTIONS="-xpf" elif [[ ${package_url} =~ (.tar.gz$|.tgz$) ]] || [[ ${package_name} =~ (.tar.gz$|.tgz$) ]] then TAR_UNPACK_OPTIONS="-xpzf" elif [[ ${package_url} =~ (.tar.bz2$|.tbz$) ]] || [[ ${package_name} =~ (.tar.bz2$|.tbz$) ]] then TAR_UNPACK_OPTIONS="-xpjf" elif [[ ${package_url} =~ (.tar.xz$|.txz$) ]] || [[ ${package_name} =~ (.tar.xz$|.txz$) ]] then TAR_UNPACK_OPTIONS="-xJf" elif [[ ${package_url} =~ (.tar.lzma$|.tlz$) ]] || [[ ${package_name} =~ (.tar.lzma$|.tlz$) ]] then TAR_UNPACK_OPTIONS="--xz -xf" elif [[ ${package_url} =~ (.tar.Z$|.taz$) ]] || [[ ${package_name} =~ (.tar.Z$|.taz$) ]] then TAR_UNPACK_OPTIONS="-xzf" elif [[ ${package_url} =~ .bz2$ ]] || [[ ${package_name} =~ .bz2$ ]] then UNPACK_COMMAND="$BZIP2 -d" elif [[ ${package_url} =~ .gz$ ]] || [[ ${package_name} =~ .gz$ ]] then UNPACK_COMMAND="$GUNZIP" elif [[ ${package_url} =~ (.xz$|.lzma$) ]] || [[ ${package_name} =~ (.xz$|.lzma$) ]] then UNPACK_COMMAND="$XZ -d" elif [[ ${package_url} =~ .Z$ ]] || [[ ${package_name} =~ .Z$ ]] then UNPACK_COMMAND="$UNCOMPRESS" else clearCache; deployLog "Archive format of ${package_name} is not supported"; writeJSONResponseErr "result=>4175" "message=>Archive format of ${package_name} is not supported"; die -q; fi if [ -n "${TAR_UNPACK_OPTIONS}" ] then $TAR --overwrite ${TAR_UNPACK_OPTIONS} "${package_path}/${package_name}" -C "$APPWEBROOT" >> $ACTIONS_LOG 2>&1; return $?; elif [ -n "${UNPACK_COMMAND}" ] then cp ${package_path}/${package_name} ${APPWEBROOT}/${package_name}; ${UNPACK_COMMAND} ${APPWEBROOT}/${package_name} >> $ACTIONS_LOG 2>&1; return $?; else return 1; fi } function deployLog(){ echo -en "$(date) "$@ '\n' >> "$DEPLOY_LOG"; if [ "$UID" == '0' ]; then [ -f "$DEPLOY_LOG" ] && chown -f "$DATA_OWNER" "$DEPLOY_LOG"; fi } function shiftContentFromSubdirectory(){ local appwebroot=$1; shopt -s dotglob; amount=$(ls $appwebroot | wc -l) ; if [ "$amount" -eq 1 ] then object=$(ls "$appwebroot"); if [ -d "${appwebroot}/${object}/${object}" ] then amount=$(ls "$appwebroot/$object" | wc -l); if [ "$amount" -gt 1 ] then # in $appwebroot/$object more then one file - exit shopt -u dotglob; return 0; fi if [ "$amount" -eq 1 ] then mv "${appwebroot}/${object}/${object}/"* "${appwebroot}/${object}/" 2>/dev/null; if [ "$?" -ne 0 ] then shopt -u dotglob; return 0; fi fi [ -d "${appwebroot}/${object}/${object}" ] && rm -rf "${appwebroot}/${object}/${object}" ; shopt -u dotglob; return 0; fi amount=$(ls "$appwebroot/$object" | wc -l) ; if [ "$amount" -gt 0 ] then mv "$appwebroot/$object/"* "$appwebroot/" 2>/dev/null ; [ -d "$appwebroot/$object" ] && rm -rf "$appwebroot/$object"; else rmdir "$appwebroot/$object" && [ "x$(basename $appwebroot)" != "xROOT" ] && { [ -d "$appwebroot" ] && { set -f; rm -rf "$appwebroot"; set +f; } } ; writeJSONResponseErr "result=>4072" "message=>Empty package!"; die -q; fi fi shopt -u dotglob; } function updateOwnership(){ shopt -s dotglob; APPWEBROOT=$1; chown -Rf "$DATA_OWNER" "$APPWEBROOT" 2>>"$JEM_CALLS_LOG" && deployLog "${APPWEBROOT} owner is set to ${DATA_OWNER}" || deployLog "${APPWEBROOT} ownership set failed"; chmod -Rf a+r "$APPWEBROOT" 2>>"$JEM_CALLS_LOG" && deployLog "Added read permissions for all to ${APPWEBROOT}" || deployLog "Setting read permissions for all to ${APPWEBROOT} failed"; chmod -Rf u+w "$APPWEBROOT" 2>>"$JEM_CALLS_LOG" && deployLog "Added write permissions for ${DATA_OWNER} to ${APPWEBROOT}" || deployLog "Adding write permissions to ${APPWEBROOT} failed"; shopt -u dotglob; } function prepareContext(){ local context=$1; APPWEBROOT=$WEBROOT/$context/; } function deploy(){ echo "Starting deploying application ..." >> $ACTIONS_LOG 2>&1; local package_url=$1; local context=$2; local ext=$3; clearCache; prepareContext ${context} ; # check exactly FILE - it should not exists, otherwise 'mkdir' returns error if [ "x$(basename ${APPWEBROOT})" == "xROOT" ] && [ "x${atomic_deploy}" == "xtrue" ] then local NEXT_DIR=ROOT_$(date +%Y.%m.%d-%H.%M.%S); [ -h ${WEBROOT}/ROOT ] && local CURRENT_DIR=$(readlink ${WEBROOT}/ROOT | $GREP -o "ROOT_[0-9.-]*"); if [ ! -d ${WEBROOT}/${CURRENT_DIR} ] ; then CURRENT_DIR=$(ls ${WEBROOT} | $GREP "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$" | tail -n1); [ -n "${CURRENT_DIR}" ] && { ln -sfT ${WEBROOT}/${CURRENT_DIR}/ ${WEBROOT}/ROOT && deployLog "Switching the ROOT context to ${CURRENT_DIR} directory";} || CURRENT_DIR=" "; fi local PREVIOUS_DIR=$(ls ${WEBROOT} | $GREP "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$" | $GREP -v "$CURRENT_DIR" | head -1); if [ -z "${PREVIOUS_DIR}" ] ;then local DIR_AMOUNT=$(ls "${WEBROOT}" | $GREP -c "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$"); [ ${DIR_AMOUNT} -gt 1 ] && PREVIOUS_DIR=$(ls "${WEBROOT}" | $GREP "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$" | tail -n2 | head -1); fi [ -n "${PREVIOUS_DIR}" ] && rm -rf ${WEBROOT}/${PREVIOUS_DIR} && deployLog "Removing old deprecated application directory ${PREVIOUS_DIR}"; [[ -d "${WEBROOT}/ROOT/" && ! -h ${WEBROOT}/ROOT ]] && rm -rf ${WEBROOT}/ROOT/ && deployLog "Removing existing ROOT directory"; unpack ${WEBROOT}/${NEXT_DIR}/ && deployLog "Unpacking application to new ROOT context directory ${NEXT_DIR}" || { rm -rf ${WEBROOT}/${NEXT_DIR}/ 1>/dev/null 2>&1; writeJSONResponseErr "result=>4071" "message=>Cannot unpack package" && deployLog "Not enough disk space. Cannot unpack application to new context directory"; die -q; }; shiftContentFromSubdirectory ${WEBROOT}/${NEXT_DIR}/; updateOwnership ${WEBROOT}/${NEXT_DIR}/; ln -sfT ${WEBROOT}/${NEXT_DIR}/ ${WEBROOT}/ROOT && deployLog "Switching the ROOT context to ${NEXT_DIR} directory"; APPWEBROOT=${WEBROOT}/ROOT; else undeploy ${context}; unpack $APPWEBROOT || { rm -rf $APPWEBROOT 1>/dev/null 2>&1; writeJSONResponseErr "result=>4071" "message=>Cannot unpack package"; die -q; } shiftContentFromSubdirectory $APPWEBROOT; setContext $context; echo "Application deployed successfully!" >> $ACTIONS_LOG 2>&1; deployLog "Application successfully deployed to $APPWEBROOT"; fi finishDeploy; } function finishDeploy(){ updateOwnership $APPWEBROOT; clearCache; } function undeploy(){ local context=$1; if [ "x$context" == "xROOT" ] then APPWEBROOT=${WEBROOT}/ROOT; [ -h $APPWEBROOT ] && { rm -f $APPWEBROOT; cd ${WEBROOT}; ROOT_DIRS=$(ls ${WEBROOT} | $GREP "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$"); rm -rf ${ROOT_DIRS} && deployLog "Removing ROOT context and all the related directories: ${ROOT_DIRS}"; } if [[ -d "$APPWEBROOT" ]] then rm -Rf $APPWEBROOT && deployLog "Content of $APPWEBROOT directory deleted"; else mkdir $APPWEBROOT; updateOwnership $APPWEBROOT; fi else APPWEBROOT=$WEBROOT/$context if [[ -d "$APPWEBROOT" ]] then rm -Rf $APPWEBROOT && deployLog "Directory $APPWEBROOT removed"; fi delContext $context; fi } function renameContext(){ local newContext=$1; local oldContext=$2; if [ ! -d "$WEBROOT/$newContext" ] then mkdir -p "$WEBROOT/$newContext"; else shopt -s dotglob set -f rm -Rf "$WEBROOT/$newContext/"* && deployLog "Content of $newContext directory removed"; set +f shopt -u dotglob fi if [ ! -h "${WEBROOT}/${oldContext}" ]; then if [ -d "${WEBROOT}/${oldContext}" ] then if [ "$UID" == '0' ]; then chown -R ${DATA_OWNER} "${WEBROOT}/${oldContext}"; fi shopt -s dotglob; mv "$WEBROOT/$oldContext/"* "$WEBROOT/$newContext/" 2>/dev/null && [ "$oldContext" != "ROOT" ] && rm -rf $WEBROOT/$oldContext; deployLog "Moving application data from $oldContext to $newContext"; shopt -u dotglob; else writeJSONResponseErr "result=>4052" "message=>Context does not exist"; die -q; fi fi if [ "x${newContext}" == "xROOT" ] then set -f rm -Rf $WEBROOT/$oldContext/ 2>/dev/null && deployLog "Directory $oldContext deleted"; set +f delContext $oldContext; return 0; else if [ "x${oldContext}" == "xROOT" ] then if [ -h ${WEBROOT}/ROOT ] then local CURRENT_DIR=$(readlink ${WEBROOT}/ROOT | $GREP -o "ROOT_[0-9.-]*"); [ ! -d ${WEBROOT}/${CURRENT_DIR} ] && CURRENT_DIR=$(ls ${WEBROOT} | $GREP "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$" | tail -n1); [ ! -n ${CURRENT_DIR} ] && { writeJSONResponseErr "result=>4052" "message=>Context does not exist"; die -q; } if [ -d ${WEBROOT}/${CURRENT_DIR} ] ;then if [ "$UID" == '0' ]; then chown -R ${DATA_OWNER} ${WEBROOT}/${CURRENT_DIR}; fi shopt -s dotglob; set +f mv ${WEBROOT}/${CURRENT_DIR}/* ${WEBROOT}/${newContext} 2>/dev/null && deployLog "Moving application data from ${CURRENT_DIR} to ${newContext}"; shopt -u dotglob; fi rm -rf ${WEBROOT}/ROOT; cd ${WEBROOT}; ROOT_DIRS=$(ls ${WEBROOT} | $GREP "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$"); rm -rf ${ROOT_DIRS} && deployLog "Removing ROOT context directories ${ROOT_DIRS}"; [ ! -d ${WEBROOT}/ROOT ] && mkdir ${WEBROOT}/ROOT; fi setContext $newContext; else rm -Rf $WEBROOT/${oldContext} 2>/dev/null && deployLog "Directory ${oldContext} deleted"; isFunction "rename" && rename $newContext $oldContext ; fi fi updateOwnership "$WEBROOT/$newContext" }