#!/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 "${EXCEPTORLIB_VERSION:-}" ] && return 0; EXCEPTORLIB_VERSION="0.1"; DF_TIMEOUT_SEC=120 inherit fsutils; include output; $PROGRAM 'curl'; $PROGRAM 'gzip'; $PROGRAM 'grep'; $PROGRAM 'file'; $PROGRAM 'awk'; $PROGRAM 'unzip'; $PROGRAM 'sed'; function ensureDiskSpaceIsOK() { resfile=$(mktemp 2>/dev/null) [ -z "$resfile" ] && return 1 timeout -s 9 $DF_TIMEOUT_SEC cat <( local disk_space_usage_critical_state=97 local disk_inode_usage_critical_state=97 if [[ -f /proc/vz/version ]]; then local disk_space_error=4204 local disk_inodes_error=4205 local additional_text=" on host" else local disk_space_error=4075 local disk_inodes_error=4076 fi local fstype="$(getFSType '/')" local disk_space_usage_percentage=$(df -h / 2>/dev/null | tail -1 | $GREP -o [[:alnum:]]*% | $SED 's/%//g') local disk_inode_usage_percentage=$(df -i / 2>/dev/null | tail -1 | $GREP -o [[:alnum:]]*% | $SED 's/%//g') [[ ${disk_space_usage_percentage} -lt ${disk_space_usage_critical_state} ]] || { writeJSONResponseErr "result=>$disk_space_error" "message=>No free diskspace$additional_text"; echo 1 > $resfile; exit; } [[ "${fstype}" == "reiserfs" ]] && { echo 0 > $resfile; exit; } [[ ${disk_inode_usage_percentage} -lt ${disk_inode_usage_critical_state} ]] || { writeJSONResponseErr "result=>$disk_inodes_error" "message=>No free inodes$additional_text"; echo 1 > $resfile; exit; } echo 0 > $resfile ) res=$? [[ $res -eq 137 ]] && { writeJSONResponseErr "result=>4132" "message=>Execution timed out"; die -q; } fres=$(cat $resfile) /bin/rm -f $resfile [ -n "$fres" ] && return $fres return 1 } function ensureFileCanBeUncompressed(){ VERBOSE=1; local fileToUncompress="$1"; local uncompressed_zip_size=0; [ -z "${resource_data_dize}" ] && { resource_data_dize=0; freebytesleft=$(( 1024 * $(df -l / 2>/dev/null | tail -1 | $AWK '{ print $4 }' )-1024*1024)); } local uncompressed_size; mimeType=$($FILE --mime-type "${fileToUncompress}" -b) case ${mimeType} in "application/x-bzip2") uncompressed_size=$(( $($TAR -tvjf "$1" | $AWK '{i+=$3} END{print i}')+1048576)) ;; "application/jar" | "application/zip") uncompressed_size=$(( $($UNZIP -Z "$1" | $GREP uncompress | $AWK '{ print $3 }' | tail -n 1 )+1048576)) ;; "application/x-gzip") uncompressed_size=$(( $($GZIP -l "$1" | $AWK '{ print $2 }' | tail -n 1 )+1048576)) ;; "application/x-tar") uncompressed_size=$(( $($TAR -tvf "$1" | $AWK '{i+=$3} END{print i}')+1048576)) ;; *) log "Unknown mime-type file ${fileToUncompress}"; esac [ -z "${uncompressed_size}" ] && uncompressed_size=0; let "total_deploy_size = $uncompressed_size + $resource_data_dize"; [[ ${total_deploy_size} -lt ${freebytesleft} ]] || { clearCache; writeJSONResponseErr "result=>4075" "message=>No free diskspace"; die -q; } return 0; } function ensureFileCanBeDownloaded(){ local resource_url=$1; resource_data_dize=$($CURL -s --head $resource_url | $GREP -Ei "^Content-Length" | $AWK -F ":" '{ print $2 }'| $SED 's/[^0-9]//g'); freebytesleft=$(( 1024 * $(df -l | $GREP "/$" | $AWK '{ print $4 }' | head -n 1)-1024*1024)); [ -z "${resource_data_dize}" ] && return 0; [[ ${resource_data_dize} -lt ${freebytesleft} ]] || { writeJSONResponseErr "result=>4075" "message=>No free diskspace"; die -q; } return 0; } function getPackageName() { if [ -f "$package_url" ]; then package_name=$(basename "${package_url}") package_path=$(dirname "${package_url}") elif [[ "${package_url}" =~ file://* ]]; then package_name=$(basename "${package_url:7}") package_path=$(dirname "${package_url:7}") [ -f "${package_path}/${package_name}" ] || { writeJSONResponseErr "result=>4078" "message=>Error loading file from URL"; die -q; } else createDownloadsDir; ensureFileCanBeDownloaded $package_url; $WGET --no-check-certificate --content-disposition --directory-prefix="$DOWNLOADS" $package_url >> $ACTIONS_LOG 2>&1 || { writeJSONResponseErr "result=>4078" "message=>Error loading file from URL"; die -q; } sed -i '/ \.\......... ........./d' $ACTIONS_LOG package_name="$(ls ${DOWNLOADS})"; [[ "${package_name}" != "$(ls ${DOWNLOADS} | awk -F? '{print $1}')" ]] && { mv ${DOWNLOADS}/${package_name} ${DOWNLOADS}/$(ls ${DOWNLOADS} | awk -F? '{print $1}'); package_name="$(ls ${DOWNLOADS})"; } package_path=${DOWNLOADS}; [ ! -s "${package_path}/${package_name}" ] && { set -f rm -f "${package_name}"; set +f writeJSONResponseErr "result=>4078" "message=>Error loading file from URL"; die -q; } fi } function createDownloadsDir() { [ ! -d "$DOWNLOADS" ] && ${SUDO_COMMAND} /usr/bin/mkdir -p ${DOWNLOADS} ${SUDO_COMMAND} /usr/bin/setfacl -Rm g:ssh-access:xwr,d:g:ssh-access:xwr,d:u::xwr ${DOWNLOADS} } function clearCache(){ if [[ -d "$DOWNLOADS" ]] then shopt -s dotglob; set -f rm -Rf ${DOWNLOADS}/*; set +f shopt -u dotglob; fi }