#!/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 default os envinfo output exceptor hooks; VERSION="1"; DEFAULT_ACTION="Usage"; DESCRIPTION="Compute node operations"; inherit_check "$deploy_module_inherit" || { writeJSONResponseErr "result=>4060" "message=>Invalid deploy module"; kill ${MANAGE_KILL_TARGET} 2>/dev/null; exit 255; } include "$replication_module_inherit"; include cartridge-common decrypt-passwd; DOWNLOADS='/var/cache/downloads'; TMPCONF="/tmp/tmp.conf.$$"; $PROGRAM 'wget'; $PROGRAM 'unzip'; $PROGRAM 'tar'; [ "x${COMPUTE_TYPE}" == "xcartridge" ] && restoreEnvironmentVariables && { [ -f "${CARTRIDGE_HOME}/jelastic/scripts/deploy.sh" ] && source "${CARTRIDGE_HOME}/jelastic/scripts/deploy.sh"; WEBROOT="${Webroot_Path}"; } [[ -n "${WEBROOT}" ]] && [ ! -d "$WEBROOT" ] && mkdir -p "$WEBROOT"; function doUsage() { showUsageMessage; } function preDeployCallback(){ ensureDiskSpaceIsOK; local temp=$(getopt -o u:,c:,e:,a: -- $@); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while [ $# -gt 0 ] do case "$1" in -u) package_url=$2; shift; ;; -c) context=$2; [ "x$context" == "xroot" ] && context='ROOT'; [ "x$context" == "x/" ] && context='ROOT'; shift; ;; -a) atomic_deploy=$2; shift; ;; --) shift; break; ;; esac; shift; done; if [[ -z "$package_url" ]] then writeJSONResponseErr "result=>4058" "message=>Wrong arguments for deploy" ; exit 1 fi if [[ -z "$context" ]] then writeJSONResponseErr "result=>4058" "message=>Wrong arguments for deploy" ; exit 1 fi local result=0 isFunction "postPreDeploy" && { postPreDeploy; result=$?; } return $result; } function doDeploy(){ # Contexts validation [ -n "$Context_Regex" ] && context_regex="/${Context_Regex}/p"; case ${COMPUTE_TYPE} in tomcat) case "${COMPUTE_TYPE_VERSION}" in 7|8|9|10|11) context_regex='/^((([a-zA-Z0-9])+((-|_|\.|#{1})?([a-zA-Z0-9])+)+(#{2}[0-9]+)?)|([a-zA-Z0-9]+))$/p;' ;; *) context_regex='/^((([a-zA-Z0-9])+((-|_|\.|#{1})([a-zA-Z0-9])+)+)|([a-zA-Z0-9]+))$/p;' ;; esac ;; jetty) context_regex='/^((([a-zA-Z0-9])+((-|_{1})([a-zA-Z0-9])+)+)|([a-zA-Z0-9]+))$/p;'; ;; glassfish|payara|wildfly) context_regex='/^((([a-zA-Z0-9])+((-|_|\.{1})([a-zA-Z0-9])+)+)|([a-zA-Z0-9]+))$/p;'; ;; apache-ruby|nginx-ruby) context_regex='/^(production|development|test)$/p;'; ;; esac [ -z "$context_regex" ] && context_regex='/^((([a-zA-Z0-9])+(-{1}([a-zA-Z0-9])+)+)|([a-zA-Z0-9]+))$/p;' if [[ -z $($SED -nre "$context_regex" <<< $context ) ]] then writeJSONResponseErr "result=>4079" "message=>Invalid context name specified" ; exit 1; fi [ "x${COMPUTE_TYPE}" == "xapache-ruby" -o "x${COMPUTE_TYPE}" == "xnginx-ruby" ] && { if ! $GREP -q ${context} <<< "development production test" ; then writeJSONResponseErr "result=>4079" "message=>Invalid context name specified" ; exit 1; fi } applyHook ${context} preDeploy || { writeJSONResponseErr "result=>4125" "message=>Pre-deploy hook execution failed. See hooks log for details: ${HOOKS_LOG}"; return 1; }; local vcs_project_properties="/var/lib/jelastic/vcs/${context}.properties"; [ -f "$vcs_project_properties" ] && { set -f; rm -f "$vcs_project_properties"; set +f; } deploy_function="deploy" [ "x${COMPUTE_TYPE}" == "xcartridge" ] && { isFunction "_deploy" && deploy_function="_deploy"; CARTRIDGE_STDERR_REDIRECT="2>&1"; } ${deploy_function} "$package_url" "$context" "$ext" >> "$ACTIONS_LOG" "$CARTRIDGE_STDERR_REDIRECT" || { result=$?; [ $result -eq 156 ] && result=4078; [ $result -eq 56 ] && result=4071; [ ! -z "$result" ] && [ $result -lt 4000 ] && result=4060; writeJSONResponseErr "result=>$result" "message=>Deploy failed" ; return 1; }; if [ "x${COMPUTE_TYPE}" == "xcartridge" ]; then ${SUDO_COMMAND} service cartridge build ; ${SUDO_COMMAND} service cartridge deploy; fi applyHook ${context} postDeploy || { local hook_error_message="message=>Post-deploy hook execution failed. See hooks log for details: ${HOOKS_LOG}" if [ "x${atomic_deploy}" == "xtrue" ]; 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); PREVIOUS_DIR=$(ls -1 ${WEBROOT} | grep "^ROOT_[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}-[0-9]\{2\}.[0-9]\{2\}.[0-9]\{2\}$" | tail -n2|head -n 1); if [ -n "${PREVIOUS_DIR}" ]; then ln -sfT ${WEBROOT}/${PREVIOUS_DIR} ${WEBROOT}/ROOT hook_error_message="${hook_error_message}. ROOT context now points to directory ${WEBROOT}/${PREVIOUS_DIR}." if [ "${PREVIOUS_DIR}" != "${CURRENT_DIR}" ]; then rm -rf ${WEBROOT}/${CURRENT_DIR} fi fi fi writeJSONResponseErr "result=>4126" "${hook_error_message}"; return 1; } writeJSONResponseOut "result=>0" "message=>Application deployed successfully" } function doUndeploy(){ ensureDiskSpaceIsOK; local temp=$(getopt -o c: -- $@); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while [ $# -gt 0 ] do case "$1" in -c) context=$2; [ "x$context" == "xroot" ] && context='ROOT'; [ "x$context" == "x/" ] && context='ROOT'; shift; ;; --) shift; break; ;; esac; shift; done; lUndeploy="undeploy" #added for backwards compatibility with Openshift cartridge templates isFunction "_undeploy" && lUndeploy="_undeploy" #must be removed after the cartridge support is finished "$lUndeploy" "$context" && removeHooks "$context" && writeJSONResponseOut "result=>0" "message=>Application removed successfully" || writeJSONResponseErr "result=>4061" "message=>Undeploy failed" ; } function doRenameContext(){ ensureDiskSpaceIsOK; local temp=$(getopt -o e:,n:,o: -- $@); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while [ $# -gt 0 ] do case "$1" in -n|--newContext) newContext=$2; [ "x$newcontext" == "xroot" ] && newcontext='ROOT'; shift; ;; -o|--oldContext) oldContext=$2; [ "x$oldcontext" == "xroot" ] && oldcontext='ROOT'; shift; ;; --) shift; break; ;; esac; shift; done; if [ "x$newContext" == "x$oldContext" ]; then writeJSONResponseOut "result=>0" "message=>Context renamed successfully"; else renameContext "$newContext" "$oldContext" && renameHooks "$newContext" "$oldContext" && writeJSONResponseOut "result=>0" "message=>Context renamed successfully" || writeJSONResponseErr "result=>4062" "message=>Context rename failed"; fi } function doEnableReplication(){ while [ $# -gt 0 ] do case "$1" in -h) local host=$2; shift; ;; --) shift; break; ;; esac; shift; done; [ "x${COMPUTE_TYPE}" == "xapache-ruby" ] && { return 0; } enableReplication "$host"; } function doDisableReplication(){ [ "x${COMPUTE_TYPE}" == "xapache-ruby" ] && { return 0; } disableReplication; } function doAddToCluster(){ local res=0 decryptPassword $@ res=$? [ $res -eq 0 ] || die -q set -- ${JEM_PARAMS[@]} while [ $# -gt 0 ] do case "$1" in -p) node_password=$2; shift; ;; -i) node_ip_address=$2; shift; ;; --) shift; break; ;; esac; shift; done; echo "$node_ip_address $node_password" >> "$password_storage"; } function doCleanUpCluster(){ #~ $glassfish_tools -m cleanup; rm -f "$password_storage"; restartServiceSilent iptables ; } function doBuildCluster(){ $glassfish_tools -m build; restartServiceSilent iptables ; } function doSetAdminPassword(){ tmp=$(doAction passwd set "$@"); } function doInternalCall(){ $glassfish_tools $@ ; } function doCleanUp(){ $glassfish_tools -m cleanup >> "$JEM_CALLS_LOG" && writeJSONResponseOut "result=>0" "message=>Cleanup successful" || writeJSONResponseErr "result=>4070" "message=>Сleanup failed" ; } function describeAddToCluster() { echo "Add node to cluster"; } function describeAddToClusterParameters() { echo "-p -i "; } function describeAddToClusterOptions() { echo "-p: node password for admin user"; echo "-i: node ip address"; } function describeBuildCluster() { echo "Build cluster"; } function describeCleanUp() { echo "Сleanup configuration"; } function describeCleanUpCluster() { echo "Cleanup password storage"; } function describeDeploy() { echo "Deploy application"; } function describeDeployParameters() { echo "-u -c -a "; } function describeDeployOptions() { echo "-u: url for application deploy "; echo "-c: context name to act with"; echo "-a: use atomic deploy or not"; } function describeDisableReplication() { echo "Disable nodes replication"; } function describeEnableReplication() { echo "Enable nodes replication"; } function describeEnableReplicationParameters() { echo "-h "; } function describeEnableReplicationOptions() { echo "-h: balancer node ip"; } function describeInternalCall() { echo "For JEM internal use"; } function describeRenameContext() { echo "Rename deployed context"; } function describeRenameContextParameters() { echo "-n|--newContext -o|--oldContext "; } function describeRenameContextOptions() { echo "-n|--newContext: new context name"; echo "-o|--oldContext: old context name"; } function describeSetAdminPassword() { echo "Set password for adminstrator user"; } function describeSetAdminPasswordParameters() { echo ""; } function describeSetAdminPasswordOptions() { echo ": user password"; } function describeUndeploy() { echo "Undeploy deployed application"; } function describeUndeployParameters() { echo "-c "; } function describeUndeployOptions() { echo "-c: context name to act with"; }