diff --git a/production/download_site/backup-drupal.sh b/production/download_site/backup-drupal.sh new file mode 100644 index 0000000..48583cd --- /dev/null +++ b/production/download_site/backup-drupal.sh @@ -0,0 +1,185 @@ +#!/bin/bash + +DIR_PATH="$(echo ${1} | sed 's:/*$::')" +DIR=$(basename ${DIR_PATH}) +LOG="${DIR}.log" +TIMESTAMP=`date +%Y/%m/%d' '%H:%M:%S` +echo + +# +# show to screen and also write to log +# +function log() { + echo -e "\e[96m`date +'%d/%m/%Y %H:%M:%S'`\e[39m $1" + echo -e "`date +'%d/%m/%Y %H:%M:%S'` $1" >> $LOG +} + +# +# database - get credentials from settings.php +# +function get_credentials() { + SETTINGS=$(find ${DIR_PATH} -name settings.php | grep default) + DATABASE=$(cat $SETTINGS | tr -d ' ' | grep "^'database'" | awk -F\' '{print $4}') + USERNAME=$(cat $SETTINGS | tr -d ' ' | grep "^'username'" | awk -F\' '{print $4}') + PASSWORD=$(cat $SETTINGS | tr -d ' ' | grep "^'password'" | awk -F\' '{print $4}') + DOMAIN=$(echo ${DIR_PATH} | awk -F/ '{print $5}') + + [[ -z "${SETTINGS}" ]] && log "Empty variable SETTINGS" && return 1 + [[ -z "${DATABASE}" ]] && log "Empty variable DATABASE" && return 1 + [[ -z "${USERNAME}" ]] && log "Empty variable USERNAME" && return 1 + [[ -z "${PASSWORD}" ]] && log "Empty variable PASSWORD" && return 1 + [[ -z "${DOMAIN}" ]] && log "Empty variable DOMAIN" && return 1 + + log "DIR : ${DIR}" + log "SETTINGS : $(basename ${SETTINGS})" + log "DATABASE : ${DATABASE}" + log "USERNAME : ${USERNAME}" + + return 0 +} + +# +# database - verify credentials +# +function verify_credentials() { + mysql -u"${USERNAME}" -p"${PASSWORD}" --batch --skip-column-names -e "SHOW DATABASES;" | grep "^${DATABASE}$" > /dev/null; + + if [ $? -ne 0 ];then + log "Verify database credentials [FAIL]" + return 1 + fi + + log "Verify database credentials [ OK ]" + return 0 +} + +# +# database - export data +# +function export_databse() { + mysqldump -u"${USERNAME}" -p"${PASSWORD}" ${DATABASE} > ${DATABASE}.sql + if [ $? -ne 0 ];then + log "Export database [FAIL]" + return 1 + fi + log "Export database [ OK ]" + return 0 +} + +# +# Create TarBall +# +function create_tarball() { + TARBALL="$(echo $RANDOM | md5sum | head -c 32; echo;)-${DIR}.tar.gz" + tar -czpf ${TARBALL} ${DIR_PATH} ${DATABASE}.sql &> /dev/null + + if [ $? -ne 0 ];then + log "Create tarball [FAIL]" + return 1 + fi + + log "Create tarball [ OK ]" + rm -f "${DATABASE}.sql" + + + # move to download path + DOWNLOAD_PATH=${DIR_PATH} + + if [ -d "${DIR_PATH}/web" ];then + DOWNLOAD_PATH="${DIR_PATH}/web" + fi + + mv ${TARBALL} ${DOWNLOAD_PATH} + + # calculate download time and add 2 minutes for the user to click the download link + INTERNET_Mbps=50000000 # 50Mbps + SIZE=$( du -sh ${DOWNLOAD_PATH}/${TARBALL} | awk '{print $1}' ) + SIZE_BITS=$( du -s ${DOWNLOAD_PATH}/${TARBALL} | awk '{print $1}' ) + DOWNLOAD_SECS=$(( ${SIZE_BITS} / ${INTERNET_Mbps} )) + AVAILABLE_SECS=$(( ${DOWNLOAD_SECS} + 120 )) + AVAILABLE_MINS=$(( ${AVAILABLE_SECS} / 60 )) + + # create download link + log "" + log " 🍓 DOWNLOAD" + log "" + log "URL : https://${DOMAIN}/${TARBALL}" + log "Size : ${SIZE}" + log "Available for : ${AVAILABLE_MINS} minutes" + log "" + + return 0 +} + +# +# Delete tarball +# +function delete_tarball() { + if [ -f ${DOWNLOAD_PATH}/${TARBALL} ];then + log "Start ${AVAILABLE_SECS} seconds timer for deleting ${TARBALL}" + ./safeDelete.sh "${DOWNLOAD_PATH}/${TARBALL}" ${AVAILABLE_SECS} & + else + log "Cannot find "${DOWNLOAD_PATH}/${TARBALL}" for deleting" + fi +} + +function add_server_stats() { + log "" + log " 🍓 SERVER STATUS" + log "" + + log "Users and Uptime" + echo "$(w)" >> ${LOG} + echo "" >> ${LOG} + + log "Disk Usage" + echo "$(df -h)" >> ${LOG} + echo "" >> ${LOG} + + log "Memory Usage" + echo "$(free -g)" >> ${LOG} + echo "" >> ${LOG} + + log "Network Interface" + echo "$(ifconfig eth0)" >> ${LOG} + echo "" >> ${LOG} + + log "System TOP 10 resources" + echo "$(ps -eo pid,%cpu,%mem,user,comm --sort=-%cpu | head -n 11)" >> ${LOG} + echo "" >> ${LOG} +} + +# +# Send mail +# +function send_mail_log() { + SUBJECT="Backup ${DIR}" + RECIPIENTS="stefanos@dotsoft.gr" + cat ${LOG} | mailx -a 'Content-Type: text/html' -s ${SUBJECT} ${RECIPIENTS} +} + +# dont start if you dont have a valid drupal directory +[ $# -lt 1 ] && echo "${TIMESTAMP} Directory argument is missing" > backup.log && exit +[ $# -gt 1 ] && echo "${TIMESTAMP} Too many arguments" > backup.log && exit +[ ! -d ${DIR_PATH} ] && echo "${TIMESTAMP} ${DIR} does not exist" > backup.log && exit + +# Start +function main () { + echo -e "
" > ${LOG}
+ if get_credentials; then
+ if verify_credentials; then
+ if export_databse; then
+ if create_tarball; then
+ delete_tarball
+ fi
+ fi
+ fi
+ fi
+ add_server_stats
+ echo -e "" >> ${LOG}
+ send_mail_log
+}
+
+main
+
+
diff --git a/production/download_site/safeDelete.sh b/production/download_site/safeDelete.sh
new file mode 100644
index 0000000..b69b7cc
--- /dev/null
+++ b/production/download_site/safeDelete.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# Before deleting a file ensure that
+
+# 1. The filename has the right FORMAT
+# 2. The file is a TYPE of compressed file
+# 3. The file has an EXTENSION of compresed file
+
+[ ${#} -ne 2 ] && echo "safedelete.sh: Some Argument is missing" && exit
+[ ! -f ${1} ] && echo "safedelete.sh: Argument is not a file: ${1}" && exit
+[ ${2} -gt 3600 ] && echo "safedelete.sh: Waiting time is more that one hour" && exit
+
+#
+# 1. Check the filename FORMAT
+#
+FORMAT=$(basename ${1} | grep -E "^[a-zA-Z0-9]{32}-.*\.(zip|gz|7zip|tar|tar\.gz|tar\.bz2)$" )
+if [ "${FORMAT}" != "" ];then
+
+ #
+ # 2. Check the file TYPE
+ #
+ TYPE=$(file --mime-type ${1} | awk '{print $2}' | awk -F/ '{print $2}' )
+ if [ "${TYPE}" == "zip" ] ||
+ [ "${TYPE}" == "x-tar" ] ||
+ [ "${TYPE}" == "x-bz2" ] ||
+ [ "${TYPE}" == "gzip" ] ||
+ [ "${TYPE}" == "7zip" ];then
+
+ #
+ # 3. Check the file EXTENSION
+ #
+ EXTENSION=$(echo ${1} | awk -F\. '{print $NF}')
+ if [ "${EXTENSION}" == "zip" ] ||
+ [ "${EXTENSION}" == "tar" ] ||
+ [ "${EXTENSION}" == "bz2" ] ||
+ [ "${EXTENSION}" == "gz" ] ||
+ [ "${EXTENSION}" == "7zip" ];then
+ sleep ${2} && rm -f "${1}"
+ else
+ echo "Wrong file extension" && exit
+ fi
+ else
+ echo "Wrong file type" && exit
+ fi
+else
+ echo "Wrong filename format" && exit
+fi
+
diff --git a/production/download_site/select.sh b/production/download_site/select.sh
new file mode 100644
index 0000000..d22f86b
--- /dev/null
+++ b/production/download_site/select.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+IFS=$'\n'
+ROOT_PATH="/var/www/vhosts"
+
+#
+# get directories
+#
+if [ -f "./vhosts.du" ]; then
+ du_output=$(cat "./vhosts.du")
+else
+ echo
+ echo -e "Reading disk usage for every directory in ${ROOT_PATH}. Please wait..."
+ echo
+ cd ${ROOT_PATH}
+ du_output=$(du -sh */ | column --table -R1)
+fi
+
+#
+# convert directorires into menu items
+#
+index=0
+menu_items=()
+for dir in $du_output; do
+ menu_items+=("$index $dir" "")
+ index=$(expr $index + 1)
+done
+
+#
+# show menu
+#
+dialog --no-lines --menu "Choose a directory from ${ROOT_PATH}:" 0 0 0 "${menu_items[@]}" 2> /tmp/menu_choice
+menu_choice=$(cat /tmp/menu_choice)
+rm -f /tmp/menu_choice
+echo
+#
+# Find the site root directory
+#
+SELECTED_DIR=$(echo ${menu_choice} | awk '{print $3}')
+[ "${SELECTED_DIR}" == "" ] && echo "No directory selected" && exit
+echo "SELECTED_DIR :" $SELECTED_DIR
+
+VHOST_DIR=${ROOT_PATH}/$SELECTED_DIR
+[ ! -d "${ROOT_PATH}/${SELECTED_DIR}" ] && echo "Cannot find selected vhost directory ${VHOST_DIR}" && exit
+echo -e "VHOST_DIR :" $VHOST_DIR
+
+#
+# Find the index.php or index.html, the full path and the dir name
+#
+SITE_INDEX=$(find ${VHOST_DIR} -name index.php -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;' | head -n1)
+if [ "${SITE_INDEX}" == "" ];then
+ SITE_INDEX=$(find ${VHOST_DIR} -name index.html -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;' | head -n1)
+fi
+
+echo -e "INDEX :" $SITE_INDEX
+
+INDEX_PATH=$(dirname $SITE_INDEX)
+echo -e "INDEX_PATH :" $INDEX_PATH
+
+INDEX_DIR=$(echo $INDEX_PATH | awk -F/ '{print $NF}')
+echo -e "INDEX_DIR :" $INDEX_DIR
+
+TARGET_DIR=${INDEX_PATH}
+
+#
+# Determine the type of the site
+#
+SITE_TYPE="unknown"
+[ -d "${INDEX_PATH}/core" ] && [ -d "${INDEX_PATH}/sites" ] && SITE_TYPE="drupal"
+[ -d "${INDEX_PATH}/admin" ] && [ -d "${INDEX_PATH}/mod" ] && SITE_TYPE="moodle"
+
+#
+# If its composer site get the parent directory of web/
+#
+if [ ${INDEX_DIR} == "web" ]; then
+ TARGET_DIR=$(dirname ${INDEX_PATH})
+fi
+
+echo -e "TARGET_DIR :" $TARGET_DIR
+echo
+cd /root
+
+#
+# Confirm this is the right type of site
+#
+read -p "This is a ${SITE_TYPE} site. Continue to backup?" -n 1 -r
+if [[ $REPLY =~ ^[Yy]$ ]]; then
+ echo
+ #
+ # Send path to back script
+ #
+ [ ${SITE_TYPE} == 'drupal' ] && bash ./backup-${SITE_TYPE}.sh ${TARGET_DIR} &
+ [ ${SITE_TYPE} == 'moodle' ] && echo "Backup for type ${SITE_TYPE} not implemented yet!" && exit
+ [ ${SITE_TYPE} == 'unknown' ] && echo "Backup for ${SITE_TYPE} types has not yet implemented!" && exit
+fi
+echo
+
+