webinoly/lib/general
Cristhian Martínez Ochoa 88e7581511 messages
Messages improved for a better experience.
2024-02-24 10:53:49 -07:00

1969 lines
82 KiB
Bash

#!/bin/bash
# Don't remove dumb re-check!
# Prevent 'tput' errors when running from Cron
[[ -z $TERM || $TERM == "unknown" || $TERM == "dumb" ]] && export TERM=dumb
readonly app_version="1.17.9"
readonly svr_version="1.8"
readonly os_ubuntu_supported=(bionic focal jammy) # https://ubuntu.com/about/release-cycle
readonly php_supported=(7.4 8.0 8.1 8.2 8.3) # https://www.php.net/supported-versions.php
readonly php_default="8.2"
readonly mariadb_supported=(10.6 10.11) # https://mariadb.com/kb/en/mariadb-server-release-dates/
readonly mariadb_default="10.11"
readonly mysql_supported=(8.0)
readonly mysql_default="8.0"
readonly datadog_agent_ver="7"
readonly tools_port_default="22222"
# echo colors
readonly red=$(tput setaf 1)
readonly gre=$(tput setaf 2)
readonly blu=$(tput setaf 6)
readonly end=$(tput sgr0)
readonly bol=$(tput bold)
readonly dim=$(tput dim)
readonly hid=$(tput setaf 6)$(tput setab 6)
readonly hidend=$(tput sgr0)$(tput el)
# ***********************************************
# Configuration Management Functions **********
# ***********************************************
conf_read() {
if [[ ! -f /opt/webinoly/webinoly.conf ]]; then # Double check!
echo "${red}[ERROR] Webinoly Configuration file not found!${end}"
exit 1
fi
echo $(grep -w -m 1 "^${1}:.*" /opt/webinoly/webinoly.conf | cut -f 2- -d ':')
}
conf_delete() {
if [[ ! -f /opt/webinoly/webinoly.conf ]]; then # Double check!
echo "${red}[ERROR] Webinoly Configuration file not found!${end}"
exit 1
fi
if [[ $2 == "-commented" ]]; then
# Remove it, then add it again to prevent multiple # for each server-reset
sudo sed -i "/^${1}:/s/^/#/" /opt/webinoly/webinoly.conf
else
sed -i "/^${1}:/d" /opt/webinoly/webinoly.conf
fi
}
conf_write() {
if [[ ! -f /opt/webinoly/webinoly.conf ]]; then
sudo touch /opt/webinoly/webinoly.conf
sudo cat /opt/webinoly/templates/general/conf >> /opt/webinoly/webinoly.conf
fi
# If exists modify just the line, if not then add it.
if [[ -n $(sudo grep -E "^[# \t]?${1}\:.*$" /opt/webinoly/webinoly.conf) ]]; then
sudo sed -i -E "/^[# \t]?${1}\:.*$/c $1:$2" /opt/webinoly/webinoly.conf
else
echo "$1:$2" >> /opt/webinoly/webinoly.conf
fi
}
# ***********************************************
# Useful variables ****************************
# ***********************************************
# STOP and exit if not root or sudo.
if [[ $(whoami) != "root" ]]; then
echo "${red}Please run this script as root or using sudo.${end}"
exit 1
fi
# Check for BASH Shell
# This is a very "shity" method, but checking if file exists is very reliable
# If modified: this same script is in installer, general lib and verify
if [[ $(conf_read shell-check) != "false" && -n $(echo $(tty) | grep -Eo "pts/[0-9]+") && -n $(logname) ]]; then
pre_pid=$(ps -au | grep -E "pts/[0-9]+[ ]+S[s]?[ ]+" | sed '/sudo/d' | tail -n 1)
[[ -n $pre_pid ]] && shell_pid=$(echo $pre_pid | awk '{print $2}')
[[ -n $shell_pid && -f /proc/$shell_pid/cmdline ]] && shell_current=$(tr -d '\000' < /proc/$shell_pid/cmdline)
[[ -n $shell_pid && -f /proc/$shell_pid/status ]] && shell_status=$(grep -Eo '^Name:.*bash.*' /proc/$shell_pid/status) # Double check!!!
if [[ -n $shell_current && $shell_current != *"bash"* && -z $shell_status ]]; then
echo "${red}[WARNING] Seems like you are using an interactive shell different than BASH! ${dim}($(echo $pre_pid | awk '{print $1}'):${shell_current}) ${end}"
fi
fi
# MySQL folder
if [[ $(conf_read db-engine) == "mysql" ]]; then
readonly MYSQL_CONF_PATH="/etc/mysql/mysql.conf.d"
readonly MYSQL_CONF_PREF="xx"
else
readonly MYSQL_CONF_PATH="/etc/mysql/mariadb.conf.d"
readonly MYSQL_CONF_PREF="90"
fi
# Current LoggedIn User!
if [[ -n $(logname) && -d $(eval echo ~$(logname)) ]]; then # You better double check...
readonly CURRENT_HOME=$(eval echo ~$(logname))
readonly CURRENT_USER=$(logname)
else
readonly CURRENT_HOME="/root"
readonly CURRENT_USER="root"
fi
# Admin Tools Path
if [[ -n $(conf_read tools-port) && -n $(conf_read tools-site) && -f /etc/nginx/sites-available/$(conf_read tools-site) ]]; then
readonly ADMIN_TOOLS_SITE="$(conf_read tools-site):$(conf_read tools-port)"
else
if [[ -n $(conf_read tools-port) ]]; then
readonly ADMIN_TOOLS_SITE="default:$(conf_read tools-port)"
else
# Fresh installation, dynvar is empty!
readonly ADMIN_TOOLS_SITE="default:${tools_port_default}"
fi
fi
# ***********************************************
# General Functions ***************************
# ***********************************************
check_ubuntu_release() {
local check="false"
for val in "${os_ubuntu_supported[@]}"
do
[[ $val == $(lsb_release -c | cut -d':' -f 2 | xargs) ]] && check="true"
done
echo $check
}
check_php_version() {
local check="false"
for val in "${php_supported[@]}"
do
[[ $val == $1 ]] && check="true"
done
echo $check
}
check_mysql_version() {
local check="false"
# It works for both MySQL and MariaDB!
if [[ $(conf_read db-engine) == "mysql" ]]; then
for val in "${mysql_supported[@]}"
do
[[ $val == $1 ]] && check="true"
done
else
for val in "${mariadb_supported[@]}"
do
[[ $val == $1 ]] && check="true"
done
fi
echo $check
}
check_osname() {
if ! [[ $(lsb_release -i | cut -d':' -f 2 | xargs) == "Ubuntu" && $(check_ubuntu_release) == "true" ]]; then
echo "${red}" >&2
echo "****************************************************************************" >&2
echo "**** This OS is not supported by Webinoly and could not work properly ****" >&2
echo "****************************************************************************" >&2
echo "${end}" >&2
else
echo $(lsb_release -c | cut -d':' -f 2 | xargs)
fi
}
check_for_nginx() {
if [[ $(conf_read nginx) != "true" && $1 == "-ask" ]]; then
echo "${red}"
echo "+ NGINX Not Found!"
echo "${blu}Do you want to install it now? [y/N]? ${end}"
while read -r -n 1 -s answer; do
answer=${answer:-n}
echo ""
[[ $answer = [YyNn] ]] && break
done
[[ $answer == [Yy] ]] && sudo stack -nginx
fi
if [[ $(conf_read nginx) != "true" ]]; then
echo "${red}[ERROR] NGINX is required and not found! ${end}"
exit 1
fi
}
check_for_nginx_tool_ssl() {
check_for_nginx
if [[ $(conf_read nginx-tool-ssl) != "true" && $1 == "-ask" ]]; then
echo "${red}"
echo "+ Let's Encrypt Not Found!"
echo "${blu}Do you want to install it now? [y/N]? ${end}"
while read -r -n 1 -s answer; do
answer=${answer:-n}
echo ""
[[ $answer = [YyNn] ]] && break
done
[[ $answer == [Yy] ]] && sudo stack -letsencrypt
fi
if [[ $(conf_read nginx-tool-ssl) != "true" ]]; then
echo "${red}[ERROR] Let's Encrypt is required and not found! ${end}"
exit 1
fi
}
check_for_nginx_tool_bkp() {
#check_for_nginx # Backups doesn't need nginx, can be installed alone!
if [[ $(conf_read nginx-tool-bkp) != "true" && $1 == "-ask" ]]; then
echo "${red}"
echo "+ BackUp packages Not Found!"
echo "${blu}Do you want to install it now? [y/N]? ${end}"
while read -r -n 1 -s answer; do
answer=${answer:-n}
echo ""
[[ $answer = [YyNn] ]] && break
done
[[ $answer == [Yy] ]] && sudo stack -backups
fi
if [[ $(conf_read nginx-tool-bkp) != "true" ]]; then
echo "${red}[ERROR] BackUp packages are required and not found! ${end}"
exit 1
fi
}
check_for_php() {
if [[ $(conf_read php) != "true" && $1 == "-ask" ]]; then
echo "${red}"
echo "+ PHP Not Found!"
echo "${blu}Do you want to install it now? [y/N]? ${end}"
while read -r -n 1 -s answer; do
answer=${answer:-n}
echo ""
[[ $answer = [YyNn] ]] && break
done
[[ $answer == [Yy] ]] && sudo stack -php
fi
if [[ $(conf_read php) != "true" ]]; then
echo "${red}[ERROR] PHP is required and not found! ${end}"
exit 1
fi
}
check_for_php_tool_postfix() {
check_for_php
if [[ $(conf_read php-tool-postfix) != "true" && $1 == "-ask" ]]; then
echo "${red}"
echo "+ Postfix Not Found!"
echo "${blu}Do you want to install it now? [y/N]? ${end}"
while read -r -n 1 -s answer; do
answer=${answer:-n}
echo ""
[[ $answer = [YyNn] ]] && break
done
[[ $answer == [Yy] ]] && sudo stack -postfix
fi
if [[ $(conf_read php-tool-postfix) != "true" ]]; then
echo "${red}[ERROR] Postfix is required and not found! ${end}"
exit 1
fi
}
check_for_php_tool_redis() {
check_for_php
if [[ $(conf_read php-tool-redis) != "true" && $1 == "-ask" ]]; then
echo "${red}"
echo "+ Redis Not Found!"
echo "${blu}Do you want to install it now? [y/N]? ${end}"
while read -r -n 1 -s answer; do
answer=${answer:-n}
echo ""
[[ $answer = [YyNn] ]] && break
done
[[ $answer == [Yy] ]] && sudo stack -redis
fi
if [[ $(conf_read php-tool-redis) != "true" ]]; then
echo "${red}[ERROR] Redis is required and not found! ${end}"
exit 1
fi
}
check_for_mysql() {
if [[ $(conf_read mysql) != "true" && $1 == "-ask" ]]; then
echo "${red}"
echo "+ MySQL/MariaDB Not Found!"
echo "${blu}Do you want to install it now? [y/N]? ${end}"
while read -r -n 1 -s answer; do
answer=${answer:-n}
echo ""
[[ $answer = [YyNn] ]] && break
done
[[ $answer == [Yy] ]] && sudo stack -mysql
fi
if [[ $(conf_read mysql) != "true" ]]; then
echo "${red}[ERROR] MySQL/MariaDB is required and not found! ${end}"
exit 1
fi
}
check_for_mysql_client() {
if [[ $(conf_read mysql-client) != "true" ]]; then
echo "${gre}${dim}MySQL/MariaDB Client is not installed and we need it to stablish a connection with your external server.${end}" >&2
echo "${dim}Wait while we install MySQL/MariaDB Client...${end}" >&2
sudo stack -mysql=client > /dev/null 2>&1 &
wait $!
echo "${gre}MySQL/MariaDB Client has been successfully installed!${end}" >&2
fi
}
check_mysql_connection() {
# Examples for admin connection:
# Localhost: $(check_mysql_connection localhost)
# Unix socket: $(check_mysql_connection localhost /var/run/mysqld/mysqld.sock)
# Custom port: $(check_mysql_connection localhost 3307)
# External DB: $(check_mysql_connection $dburl $dbport $dburoot $dbproot)
# External DB if login group exist: $(check_mysql_connection $dburl $dbport $dburoot -login-file)
# External DB if login group exist and is master-admin: $(check_mysql_connection $dburl $dbport any -login-file -master-admin)
# External DB check and save it as master-admin: $(check_mysql_connection $dburl $dbport $dburoot $dbproot -master-admin)
# Examples for especific User connection:
# Localhost: $(check_mysql_connection localhost $wp_dbuser $wp_dbpass)
# Unix socket: $(check_mysql_connection localhost $wp_dbuser $wp_dbpass /var/run/mysqld/mysqld.sock)
# Custom port: $(check_mysql_connection localhost $wp_dbuser $wp_dbpass 3307)
# External DB: $(check_mysql_connection $extdb_url $extdb_port $wp_dbuser $wp_dbpass)
# External DB if login group exist: $(check_mysql_connection $extdb_url $extdb_port $wp_dbuser -login-file)
# External DB if login group exist and is master-admin: $(check_mysql_connection $extdb_url $extdb_port any -login-file -master-admin)
# External DB check and save it as master-admin: $(check_mysql_connection $extdb_url $extdb_port $wp_dbuser $wp_dbpass -master-admin)
# Examples for especific DBname/User connection:
# Note: Error message is not displayed!
# Localhost: $(check_mysql_connection localhost $wp_dbuser $wp_dbpass $wp_dbname)
# Unix socket: $(check_mysql_connection localhost $wp_dbuser $wp_dbpass $wp_dbname /var/run/mysqld/mysqld.sock)
# Custom port: $(check_mysql_connection localhost $wp_dbuser $wp_dbpass $wp_dbname 3307)
# External DB: $(check_mysql_connection $extdb_url $extdb_port $wp_dbuser $wp_dbpass $wp_dbname)
# External DB if login group exist: $(check_mysql_connection $extdb_url $extdb_port $wp_dbuser -login-file $wp_dbname)
# Master-admin not needed here for specific dbs.
# Note: You can always use the dynvar 'quiet' set to 'true' to not display messages.
# In this especific case ONLY, there is a third value: false, true and truebutnotmaster (External DB connection successfull but not enough privileges for master-admin)
local query="quit"
local error_display="true"
if [[ -n $1 && ${1,,} != "localhost" && $(is_url $1) =~ ^(http|https|true|http\+ip|https\+ip|ip)$ && -n $2 && -n $3 && -n $4 ]]; then
check_for_mysql_client
local suffix_group_name="${1}:${2}_${3}"
local user_param="-u${3}"
if [[ -n $5 && $5 == "-master-admin" ]]; then
# 'default' is a reserved word, real usernames should never use it, it's possible, but not practical!
local suffix_group_name="${1}:${2}_default"
elif [[ -n $5 ]]; then
local query="use $5"
local error_display="false"
fi
# Create or update the login file
if [[ $4 != "-login-file" ]]; then
mysql_login_cnf
sudo sed -i "/\[client_${suffix_group_name}\]/,/# ClientEnd/{/.*/d}" $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf
echo "[client_${suffix_group_name}]
host = $1
port = $2
user = $3
password = $4
# ClientEnd" >> $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf
else
[[ $5 == "-master-admin" ]] && unset user_param # take the user from the login group!
local error_display="false"
fi
# Just for the record: We don't use the 'mysql_conf_editor' just because it can not be unattended :(
# --defaults-group-suffix should always be at the beginning, otherwise it fails.
sudo mysql --defaults-group-suffix=_${suffix_group_name} --connect-timeout=10 -h "$1" -P "$2" $user_param -e "$query" 2>/dev/null
if [[ $? != "0" ]]; then
local out="false"
[[ -f $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf ]] && sudo sed -i "/\[client_${suffix_group_name}\]/,/# ClientEnd/{/.*/d}" $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf
else
# Display a warning message when not enough privileges!
if [[ $5 == "-master-admin" ]]; then
local priv=$(sudo mysql --defaults-group-suffix=_${suffix_group_name} --connect-timeout=10 -h "$1" -P "$2" -e "SHOW GRANTS FOR CURRENT_USER();")
if ! [[ -n $(echo $priv | grep -Fo "WITH GRANT OPTION") && ( -n $(echo $priv | grep -Fo "GRANT ALL PRIVILEGES") || ( -n $(echo $priv | grep -Fo "CREATE USER") && -n $(echo $priv | grep -Fo "ALTER"))) ]]; then
if [[ $(conf_read quiet) != "true" ]]; then
echo "${red}${dim}[WARNING] Seems like '$(echo $priv | grep -oP -m 1 'Grants for \K\w+')' is not a Master user!${end}" >&2
else
local master_priv="false"
fi
fi
fi
fi
elif [[ ${1,,} == "localhost" && $(conf_read mysql) == "true" ]]; then
if [[ -n $2 && -n $3 ]]; then
if [[ -S $4 ]]; then
local mysql_params="-S${4}"
elif [[ $4 =~ ^[0-9]+$ && $4 -ge 0 && $4 -le 65535 ]]; then
local mysql_params=(-P${4} --protocol=TCP)
elif [[ -n $4 ]]; then
local query="use $4"
[[ -S $5 ]] && local mysql_params="-S${5}"
[[ $5 =~ ^[0-9]+$ && $5 -ge 0 && $5 -le 65535 ]] && local mysql_params=(-P${5} --protocol=TCP)
fi
# We need the protocol socket fixed to prevent warnings when custom port is used.
sudo mysql --connect-timeout=10 --user=$2 -p$3 -e "$query" "${mysql_params[@]}" 2>/dev/null
[[ $? != "0" ]] && local out="false"
local error_display="false"
else
# In case of Unix socket or localhost with custom port
[[ -S $2 ]] && local mysql_params="-S${2}"
[[ $2 =~ ^[0-9]+$ && $2 -ge 0 && $2 -le 65535 ]] && local mysql_params=(-P${2} --protocol=TCP)
sudo mysql --connect-timeout=10 --user=admin -e "$query" "${mysql_params[@]}" 2>/dev/null
[[ $? != "0" ]] && local out="false"
fi
else
local out="false"
fi
if [[ $out == "false" && $error_display != "false" && $(conf_read quiet) != "true" ]]; then
echo "${red}===================================================" >&2
echo " [Error] Database conection failed! (${1})" >&2
echo "===================================================${end}" >&2
echo "" >&2
echo "false"
elif [[ $out == "false" ]]; then
echo "false"
else
[[ $master_priv == "false" ]] && echo "truebutnotmaster" || echo "true"
fi
}
check_external_db_saved() {
if [[ -n $(conf_read external-dbh) && -n $(conf_read external-dbu) && -n $(conf_read external-dbp) && -n $(conf_read external-dbx) ]]; then
external_db="[$(conf_read external-dbu),$(conf_read external-dbp),$(conf_read external-dbh):$(conf_read external-dbx)]"
[[ $(conf_read quiet) != "true" ]] && echo "${blu}${dim}External DB credentials found in your saved configuration! ($(conf_read external-dbh):$(conf_read external-dbx))${end}" >&2
fi
}
external_db_parse() {
if [[ -n $external_db ]]; then
# Prevent errors
if [[ ${#external_db} -lt 2 ]]; then
echo "${red}[ERROR] Invalid data for External Database!${end}"
return
fi
local dbdata=${external_db:1:-1}
local user=$(echo "${dbdata}" | cut -d',' -f 1 -s)
local pass=$(echo "${dbdata}" | cut -d',' -f 2 -s)
local host=$(echo "${dbdata}" | cut -d',' -f 3 -s)
[[ -z $host && -n $wp_dbhost ]] && local host=$wp_dbhost # This is very shitty!
local url=$(echo "$host" | cut -f 1 -d ':')
local port=$(echo "$host" | cut -f 2 -d ':' -s)
if [[ $(echo "${external_db}" | cut -c-1) != "[" || $(echo "${external_db}" | rev | cut -c-1) != "]" ]]; then
echo "${red}[ERROR] Invalid syntax for External Database!${end}"
return
elif [[ -z $user || -z $pass ]]; then
echo "${red}[ERROR] Invalid data for External Database!${end}"
return
fi
if [[ $(check_mysql_connection $url $port $user $pass -master-admin) != "true" ]]; then
echo "${red}[ERROR] Cannot connect with your External Database!${end}"
return
else
# Make it global only after verification
extdb_user=$user
extdb_pass=$pass
extdb_host=$host
extdb_url=$url
extdb_port=$port
fi
else
echo "${red}[ERROR] External DB parameter not found!${end}"
return
fi
}
wp_config_path() {
# If this file exist is because is WP parked
# We can not use is_parked here because it will cause an infinite loop (is_parked uses this function)
# if parked: check if parked before use this path value
if [[ -f /etc/nginx/sites-available/$1 ]]; then
local parpath="$(grep -G "root .*;" /etc/nginx/sites-available/$1 | sed -r 's/^.*root (.*)htdocs;$/\1/')wp-config.php"
if [[ -n $2 && $2 != "false" && -f /var/www/$1/htdocs$2/wp-config.php ]]; then
echo "/var/www/$1/htdocs$2/wp-config.php"
# WP take this file first (if exist) and then look one folder below.
# Webinoly check one folder below first and give priority because is our default file, no matter if you manually add a different one.
# If user want to use their own file is ok, but they should remove the Webinoly default WP conf file.
elif [[ ( -z $2 || $2 == "false" ) && -f /var/www/$1/wp-config.php ]]; then
echo "/var/www/$1/wp-config.php"
elif [[ ( -z $2 || $2 == "false" ) && -f /var/www/$1/htdocs/wp-config.php ]]; then
echo "/var/www/$1/htdocs/wp-config.php"
elif [[ ( -z $2 || $2 == "false" ) && -f $parpath ]]; then
echo "$parpath"
else
return
fi
fi
}
wp_config_read() {
# Example: wp_config_read example.com WP_DEBUG
# Example: wp_config_read example.com WP_DEBUG /subfolder
local path=$(wp_config_path $1 $3)
# Last sed is to remove ^M (carriege return character) I don't know why is introduced.
[[ -n $1 && -n $2 && -n $path ]] && echo $(grep -iE "^define\([ ]*[\"'\'']$2[\"'\''][ ]*,.*\);.*$" $path | cut -f 2 -d "," -s | sed 's/[ ;")'\'']//g' | sed -e "s/\r//g" ) || return
}
wp_config_delete() {
# Example: wp_config_delete example.com WP_DEBUG
# Example: wp_config_delete example.com WP_DEBUG /subfolder
local path=$(wp_config_path $1 $3)
[[ -n $1 && -n $2 && -n $path ]] && local str=$(grep -iE "^define\([ ]*[\"'\'']$2[\"'\''][ ]*,.*\);.*$" $path)
[[ -n $str ]] && sudo sed -i "/$str/d" $path
}
wp_config_write() {
# Example: wp_config_write example.com WP_DEBUG $value
# Example: wp_config_write example.com WP_DEBUG $value /subfolder
# Example: wp_config_write example.com WP_DEBUG \'test\' <- escaped quotes needed
local path=$(wp_config_path $1 $4)
# If variable is already defined, update it, if not exist then add a new var at the bottom.
if [[ -n $path && -n $(wp_config_read $1 $2 $4) ]]; then
sudo sed -i "/$(grep -iE "^define[ ]?\([ ]?[\"'\'']$2[\"'\''].*$" $path)/c \define('$2', $3);" $path
elif [[ -n $path ]]; then
sudo sed -i "/ stop editing! /i \define('$2', $3);" $path
fi
}
wp_conf_retrieve() {
# wp_conf_retrieve example.com
# wp_conf_retrieve example.com false false /subfolder
# $1 is domain
# $2 set to false if you want to skip external_db questions. ONLY NEEDED (true) when you need master-admin privileges for your DB queries!
# $3 set to false if you want to disable WP Domain Mapping check (wp_pref will be for the main site when disabled, wp_ instead of wp_3_).
# $4 is subfolder
# Prevent unwanted values when called multiple times
unset wp_config
unset wp_dbname
unset wp_dbuser
unset wp_dbhost
unset wp_dbpass
unset wp_dbpref
unset wp_dbhost_host
unset wp_dbhost_port
unset wp_dbhost_socket
unset wp_dbpref_main
unset wp_blogid
unset mysql_params
unset mysql_param
wp_config=$(wp_config_path $1 $4)
# Just in case: We should always check is_wp before calling this function
# The best error message is the one that never shows up! :)
if [[ -z $wp_config || ! -f $wp_config ]]; then
echo "${red}[ERROR] WordPress configuration file not found!${end}" >&2
return
fi
wp_dbname=$( wp_config_read $1 DB_NAME $4 )
wp_dbuser=$( wp_config_read $1 DB_USER $4 )
wp_dbhost=$( wp_config_read $1 DB_HOST $4 )
wp_dbpass=$( wp_config_read $1 DB_PASSWORD $4 )
wp_dbpref=$( grep -F "table_prefix" $wp_config | cut -f 2 -d "'" -s)
# wp_dbhost - Always contains the complete string
# wp_dbhost_host - Only the host part
# wp_dbhost_port - Only the port part (default: 3306)
# wp_dbhost_socket - Only the socket path if exist (default: empty)
# Example: localhost:3307 (host: localhost, port:3307)
# Example: localhost:/var/run/mysqld/mysqld.sock (host: localhost, socket:/var/run/mysqld/mysqld.sock)
# Example: mysql.example.com:3306 (host: mysql.example.com, port:3307)
wp_dbhost_host=$(echo "$wp_dbhost" | cut -f 1 -d ':')
local host_pars=$(echo "$wp_dbhost" | cut -f 2 -d ':' -s)
if [[ $host_pars =~ ^[0-9]+$ && $host_pars -ge 0 && $host_pars -le 65535 ]]; then
wp_dbhost_port=$host_pars
mysql_params=(-P${wp_dbhost_port} --protocol=TCP) # Array because it fails to split the args in MySQL http://mywiki.wooledge.org/BashFAQ/050
mysql_param="$wp_dbhost_port"
elif [[ -S $host_pars ]]; then
wp_dbhost_socket=$host_pars
mysql_params="-S${wp_dbhost_socket}"
mysql_param="$wp_dbhost_socket"
else
wp_dbhost_host=$wp_dbhost
fi
wp_dbpref_main=${wp_dbpref} # In case of domain mapping this variable always remains with the main site info
[[ ${wp_dbhost,,} == "localhost" ]] && wp_dbhost=${wp_dbhost,,}
#[[ -z $wp_dbhost_port ]] && wp_dbhost_port="3306"
# Only used when External DB and Master-Admin privileges are required!
# Example: Cloning site because its needed to create new dbs and users.
# Example: Delete site because its required to drop users.
if [[ $2 != "false" && $wp_dbhost_host != "localhost" && -z $wp_dbhost_socket && $(is_url $wp_dbhost) =~ ^(http|https|true|http\+ip|https\+ip|ip)$ ]]; then
# Don't needed if already exist a login-file with master-admin privileges!
# -external-db have priority, mainly to rewrite or update old/wrong credentials.
if [[ -n $external_db || $(check_mysql_connection $wp_dbhost_host $wp_dbhost_port any -login-file -master-admin) != "true" ]]; then
if [[ -z $external_db && -n $(conf_read external-dbh) && -n $(conf_read external-dbx) && $wp_dbhost == "$(conf_read external-dbh):$(conf_read external-dbx)" ]]; then
check_external_db_saved
elif [[ -z $external_db && -n $(conf_read external-dbh) ]]; then
echo "${dim}[INFO] External Database saved credentials found, but we cannot use it because not the same host!${end}" >&2
fi
if [[ -n $external_db ]]; then
external_db_parse
if [[ $wp_dbhost != $extdb_host ]]; then
unset external_db
unset extdb_user
unset extdb_pass
unset extdb_host
unset extdb_url
unset extdb_port
echo "${red}${dim}[ERROR] External DB credentials cannot be used! (host mismatch)${end}"
fi
fi
if [[ -z $external_db ]]; then
local done="0"
while [[ $done -lt "3" ]]
do
echo "" >&2
echo "${gre}External DB${blu} '${wp_dbhost}' ${gre}found in:${blu}${dim} ${1}${4} ${end}" >&2
read -p "${blu}External DB Master Username: ${end}" extdb_user
read -p "${blu}External DB password: ${hid}" extdb_pass
echo "${hidend}"
if [[ $(check_mysql_connection $wp_dbhost_host $wp_dbhost_port $extdb_user $extdb_pass -master-admin) == "true" ]]; then
extdb_host=$wp_dbhost
extdb_url=$wp_dbhost_host
extdb_port=$wp_dbhost_port
external_db="[${extdb_user},${extdb_pass},${extdb_host}]"
break
fi
local done=$(($done+1))
done
fi
else
# We always need these variables for non-WP sites!
unset external_db
unset extdb_user
unset extdb_pass
extdb_host=$wp_dbhost
extdb_url=$wp_dbhost_host
extdb_port=$wp_dbhost_port
echo "${blu}${dim}External DB Credentials found! (${wp_dbhost})${end}" >&2
fi
fi
# In case of parked sites with WP domain mapping
#if [[ $3 != "false" && $(is_parked $1) == "true" ]]; then # Modified recently, not sure the impact!
if [[ $3 != "false" ]]; then
# If domain doesn't exist, check if it's a subsite of a subdomain Multisite network.
if [[ ! -f /etc/nginx/sites-available/$1 && -f /etc/nginx/sites-available/$(echo $1 | cut -d "." -f 2- -s) ]]; then
local maindom=$(echo $1 | cut -d "." -f 2- -s)
else
local maindom=$1
fi
# Parked site don't have support for subfolders, but we send it here as double check.
# If we send only the domain and the original request contains the subfolder, we can get a wrong value in return.
if [[ $(is_wp_multisite $maindom $4) =~ ^(subdomain|subdirectory)$ ]]; then
local dbq="USE $wp_dbname; SELECT blog_id FROM ${wp_dbpref}blogs WHERE domain='$1' OR domain='www.$1';"
if [[ $wp_dbhost_host == "localhost" && $(check_mysql_connection localhost $mysql_param) == "true" ]]; then
local bid=$(sudo mysql --connect-timeout=10 --user=admin -e "$dbq" "${mysql_params[@]}")
elif [[ $(check_mysql_connection $wp_dbhost_host $wp_dbhost_port $wp_dbuser $wp_dbpass) == "true" ]]; then
local bid=$(sudo mysql --defaults-group-suffix=_${wp_dbhost_host}:${wp_dbhost_port}_${wp_dbuser} --connect-timeout=10 -h "$wp_dbhost_host" -P "$wp_dbhost_port" -u"$wp_dbuser" -e "$dbq")
fi
wp_blogid=$(echo $bid | cut -f 2 -d " " -s)
# Number 1 is main site, so we don't need to change the WP prefix.
if [[ $wp_blogid =~ ^[0-9]+$ && $wp_blogid -gt 1 ]]; then
wp_dbpref="${wp_dbpref}${wp_blogid}_"
echo "${blu}${dim}Site${end}${dim} ${1}${4} ${blu}is a subsite (${wp_dbpref}) in a WP Multisite Network!${end}" >&2
elif [[ $wp_blogid == 1 ]]; then
echo "${blu}${dim}Site${end}${dim} ${1}${4} ${blu}is the main site in a WP Multisite Network!${end}" >&2
else
[[ $wp_blogid != 1 ]] && wp_blogid=""
fi
fi
fi
}
# Remove Installation Files
app_purge() {
sudo rm $HOME/webinoly.tar
sudo rm -rf /opt/webinoly/usr
}
api-events_update() {
conf_write status-api $1
if [[ -f /opt/webinoly/lib/api-events ]]; then
source /opt/webinoly/lib/api-events
api-events_catch_status $1
fi
}
remove_nginx_default_server() {
if [[ -n $1 && -f /etc/nginx/sites-available/$1 ]]; then
sudo sed -i "s/listen 80 default_server;/listen 80;/" /etc/nginx/sites-available/$1
sudo sed -i "s/listen \[::\]:80 default_server;/listen [::]:80;/" /etc/nginx/sites-available/$1
sudo sed -i "s/listen 443 ssl http2 default_server;/listen 443 ssl http2;/" /etc/nginx/sites-available/$1
sudo sed -i "s/listen \[::\]:443 ssl http2 default_server;/listen [::]:443 ssl http2;/" /etc/nginx/sites-available/$1
sudo sed -i '/WebinolyStartBlackhole/,/WebinolyEndBlackhole/{/.*/d}' /etc/nginx/sites-available/$1
fi
}
check_for_parameters() {
# Global variables: domain, domain_name, domain_port, tld, subdomain, main_domain, sub_domain, empty_param
# Note: domain and domain_name are the same except when port is present (example.com:22), then port is removed from domain_name (example.com)
# Check for domain parameter if is first parameter and have no hyphen at the begining.
if [[ -n $1 && $(echo $1 | cut -c-1) != "-" ]]; then
domain=$1
domain_name=$1
shift
# Check for port and remove it!
domain_port=$(echo $domain | cut -d':' -f 2- -s)
if [[ $domain_port =~ ^[0-9]+$ && $domain_port -ge 0 && $domain_port -le 65535 ]]; then
domain_name=$(echo $domain | cut -d':' -f 1 -s)
else
unset domain_port
fi
local count=1
while true; do
tld=$(echo $domain_name | cut -d'.' -f ${count}- -s)
if grep -Fxq "$tld" /opt/webinoly/lib/public_suffix_list.dat || [ -z $tld ]; then
break
fi
count=$[$count+1]
done
[[ $count -gt 2 ]] && subdomain="true" || subdomain="false"
if [[ $subdomain == "true" && -n $tld ]]; then
main_domain=$(echo $domain_name | cut -d'.' -f $[$count-1]- -s)
sub_domain=$(echo $domain_name | cut -d'.' -f -$[$count-2] -s)
fi
fi
for arg in $@; do
local check=$(echo "${arg}" | cut -c-1)
local arg=${arg:1}
local par=$(echo "${arg}" | cut -d'=' -f 1 -s)
local val=$(echo "${arg}" | cut -d'=' -f 2- -s)
[[ -z $par ]] && par=$arg
[[ -z $val ]] && val=true
# Convert to lowercase and support for hyphen in arguments.
par=${par,,}
par=$(echo $par | sed "s/-/_/g")
# Only valid variables names and check for begin with hyphen.
if [[ $check == "-" && $par =~ ^[a-zA-Z_][a-zA-Z_0-9]*$ ]]; then
[[ -n $par ]] && eval $par=\$val
else
echo "${red}[ERROR] Invalid parameters! ${end}"
exit 1
fi
done
[[ -z $@ ]] && empty_param="true"
}
is_ip() {
# Check for valid IPv4 and IPv6 values, including CIDR.
if [[ -n $1 && $1 =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\/([0-9]|[1-2][0-9]|3[0-2]))?$ || $1 =~ ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(\/([0-9]|[1-9][0-9]|1[0-2][0-8]))?$ ]]; then
echo "true"
else
echo "false"
fi
}
is_domain() {
# Only numerals 0-9, basic Latin letters, both lowercase and uppercase, hyphen.
if ! [[ $1 =~ ^[\.0-9A-Za-z\-]+$ ]]; then
echo "false"
# Check Lenght
elif [[ ${#1} -gt 67 ]]; then
echo "false"
# Can not start or end with a hyphen
elif [[ $(echo "${1}" | cut -c-1) == "-" || $(echo "${1}" | rev | cut -c-1) == "-" ]]; then
echo "false"
# Can not contain two points together and can not start or end with a point
elif [[ $1 == *..* || $(echo "${1}" | cut -c-1) == "." || $(echo "${1}" | rev | cut -c-1) == "." ]]; then
echo "false"
# Check if IP address
elif [[ $(is_ip $1) == "true" ]]; then
echo "false"
else
echo "true"
fi
}
is_url_path() {
# Should start with / and after that all should be valid characters.
# https://stackoverflow.com/questions/4669692/valid-characters-for-directory-part-of-a-url-for-short-links
if [[ -n $1 && $1 =~ ^\/([\]A-Za-z0-9_\/\.:\!\*\'\[\(\)\;@\&\=\+\$\,\?#\~\%\-]+)?$ ]]; then
echo "true"
else
echo "false"
fi
}
is_url() {
# Output: http,https,true,http+ip,https+ip,ip,http+unix,https+unix,unix,false - Example: $(is_url $domain)
# Global variables when -split is set: url_type, url_scheme, url_host, url_path, url_port - Example: is_url $domain -split
# Examples:
# example.com -> true
# http://example.com -> http
# https://example.com -> https
# 1.1.1.1 -> ip
# http://1.1.1.1 -> http+ip
# https://1.1.1.1 -> https+ip
# unix:/tmp/backend.socket:/uri/ -> unix
# http://unix:/tmp/backend.socket:/uri/ -> http+unix
# https://unix:/tmp/backend.socket:/uri/ -> https+unix
# Unix sockets are mainly used in upstream and proxy_pass
# http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
# http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
# Important, because they can have a previous value when runs multiple times.
unset url_scheme
unset url_host
unset url_path
unset url_port
unset url_type
# Here we are assuming URL with scheme
local scheme=$(echo "${1,,}" | cut -d':' -f 1 -s)
local host=$(echo "${1,,}" | cut -d'/' -f 3 -s)
[[ $(echo $host | cut -d':' -f 2 -s) =~ ^[0-9]+$ ]] && local host=$(echo $host | cut -d':' -f 1) # We need this 2dn step to prevent http://example.com:/tmp (empty port)
local path=$(echo "${1,,}" | cut -d'/' -f 4- -s)
local port=$(echo "${1,,}" | cut -d'/' -f 3 -s | cut -d':' -f 2 -s)
local out="false"
# In case of URL with no-scheme
local hosted=$(echo "${1,,}" | cut -d'/' -f 1)
[[ $(echo $hosted | cut -d':' -f 2 -s) =~ ^[0-9]+$ ]] && hosted=$(echo $hosted | cut -d':' -f 1)
if [[ $1 =~ ^((http|https)+\:\/\/)?unix:\/[^\:]+(:\/.*)?$ ]]; then
unset port
if [[ $scheme == "unix" ]]; then
local host="$(echo "${1,,}" | cut -d':' -f 1-2 -s)"
local path=$(echo "${1,,}" | cut -d':' -f 3- -s)
local out="unix"
unset scheme
else
local host="$(echo "${1,,}" | cut -d':' -f 2-3 -s)"
local host=${host:2}
local path=$(echo "${1,,}" | cut -d':' -f 4- -s)
local out="${scheme}+unix"
fi
elif [[ $scheme =~ ^(http|https)$ ]]; then
if [[ $(is_domain $host) != "true" && $(is_ip $host) != "true" ]]; then
local out="false"
elif [[ -n $path && $(is_url_path /$path) != "true" ]]; then
local out="false"
elif [[ -n $port ]] && ! [[ $port =~ ^[0-9]+$ && $port -ge 0 && $port -le 65535 ]]; then
local out="false"
elif [[ $(is_ip $host) == "true" ]]; then
local out="${scheme}+ip"
else
local out="${scheme}"
fi
elif [[ $(is_domain $hosted) == "true" || $(is_ip $hosted) == "true" ]]; then
local scheme=""
local host=$hosted
local path=$(echo "${1,,}" | cut -d'/' -f 2- -s)
local port=$(echo "${1,,}" | cut -d'/' -f 1 | cut -d':' -f 2 -s)
if [[ -n $path && $(is_url_path /$path) != "true" ]]; then
local out="false"
elif [[ -n $port ]] && ! [[ $port =~ ^[0-9]+$ && $port -ge 0 && $port -le 65535 ]]; then
local out="false"
elif [[ $(is_ip $hosted) == "true" ]]; then
local out="ip"
else
local out="true"
fi
else
local out="false"
fi
# If path doesn't begin with /, then add it!
# If there is no path, but the url ends with /, then / is a valid path, so show it as path!
[[ ( -n $path && $(echo "$path" | cut -c-1) != "/" ) || ( -z $path && $(echo "${1}" | rev | cut -c-1) == "/" ) ]] && local path="/$path"
[[ -n $path && $out =~ ^(unix|http\+unix|https\+unix)$ ]] && local path=":${path}"
# Final validation, just because we need to be really sure! (double check!!)
if [[ -n $scheme && -n $host && -n $port ]]; then
local url_final="${scheme}://${host}:${port}${path}"
elif [[ -z $scheme && -n $host && -n $port ]]; then
local url_final="${host}:${port}${path}"
elif [[ -n $scheme && -n $host && -z $port ]]; then
local url_final="${scheme}://${host}${path}"
elif [[ -z $scheme && -n $host && -z $port ]]; then
local url_final="${host}${path}"
fi
[[ $url_final != ${1,,} ]] && out="false" # SHORT CIRCUIT!!!
# Final output!
if [[ $2 == "-split" && $out != "false" ]]; then
[[ -n $scheme ]] && url_scheme=$scheme
[[ -n $path ]] && url_path=$path
[[ -n $port ]] && url_port=$port
url_host=$host # We are very sure these two vars are never empty! ;)
url_type=$out # empty/unset when false
elif [[ $2 != "-split" ]]; then
echo $out
fi
}
is_ssl() {
[[ -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F "ssl_certificate_key") ]] && echo "true" || echo "false"
}
is_ssl_le() {
[[ -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F "ssl_certificate_key /etc/letsencrypt/live/") && -z $(grep -F "WebinolySSLCustomCert" /etc/nginx/sites-available/$1) ]] && echo "true" || echo "false"
}
is_ssl_staging() {
[[ -f /etc/letsencrypt/renewal/$1.conf && -n $(grep -E "^server = " /etc/letsencrypt/renewal/$1.conf | cut -d'=' -f 2 -s | grep -F "acme-staging-") ]] && echo "true" || echo "false"
}
is_ssl_wildcard() {
[[ -f /etc/letsencrypt/renewal/$1.conf && -n $(sudo certbot certificates --cert-name $1 2>/dev/null | grep -E "Domains:.* \*.$1") ]] && echo "true" || echo "false"
}
is_html() {
# $1 = domain, $2 = subfolder
[[ -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F "location $2/ { try_files ") ]] && echo "true" || echo "false"
}
is_php() {
# $1 = domain, $2 = subfolder
if [[ -f /etc/nginx/sites-available/$1 ]]; then
local isphp=$(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -E " common/phpx?\.conf;")
[[ -n $2 ]] && local subn=$(echo $2 | sed "s/\//_/g")
if [[ -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -E " apps.d/$1$subn-phpcache.conf;") ]]; then
echo "true"
elif [[ -n $2 && $(is_wp $1 $2) == "false" ]]; then
if [[ -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -E " apps\.d/$1$subn-phpx?\.conf;") ]]; then
echo "true"
else
echo "false"
fi
elif [[ -n $isphp && $(is_wp $1) == "false" ]]; then
echo "true"
else
echo "false"
fi
else
echo "false"
fi
}
is_proxy() {
# $1 = domain, $2 = subfolder
[[ -n $2 ]] && local subn=$(echo $2 | sed "s/\//_/g")
[[ -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F " apps.d/$1$subn-proxy.conf;") ]] && echo "true" || echo "false"
}
is_dedicated_proxy() {
# $1 = domain, $2 = subfolder
[[ -n $2 ]] && local subn=$(echo $2 | sed "s/\//_/g")
[[ -f /etc/nginx/sites-available/$1 && -z $(grep -F " common/locations.conf;" /etc/nginx/sites-available/$1) && -z $(grep -E "include common/headers-.*.conf;" /etc/nginx/sites-available/$1) && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F " apps.d/$1$subn-proxy.conf;") ]] && echo "true" || echo "false"
}
is_dedicated_proxy_domain() {
# $1 = domain
[[ -f /etc/nginx/sites-available/$1 && -z $(grep -F " common/locations.conf;" /etc/nginx/sites-available/$1) && -z $(grep -E "include common/headers-.*.conf;" /etc/nginx/sites-available/$1) && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -E " apps.d/${1}.*-proxy.conf;") ]] && echo "true" || echo "false"
}
is_forward() {
if [[ -f /etc/nginx/sites-available/$1 ]]; then
local index=$(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F "index ")
local return=$(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F "return 301 ")
[[ ! -d /var/www/$1 && -z $index && -n $return ]] && echo "true" || echo "false"
else
echo "false"
fi
}
is_parked() {
# Last weird proxy check is for parked with proxy main site
[[ -f /etc/nginx/sites-available/$1 && ! -d /var/www/$1 && $(is_proxy $1) == "false" && $(is_forward $1) == "false" && ( $(is_html $1) == "true" || $(is_php $1) == "true" || $(is_wp $1) == "true" || $(is_proxy $(grep -E "include /var/www/.*/\*-nginx.conf;" /etc/nginx/sites-available/$1 | cut -d'/' -f 4 -s)) == "true" ) ]] && echo "true" || echo "false"
}
is_wp() {
# $1 = domain, $2 = WP subfolder
[[ -n $2 ]] && local subn=$(echo $2 | sed "s/\//_/g")
if [[ -z $2 && -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F " common/wpcommon") ]]; then
[[ -f $(wp_config_path $1) ]] && echo "true" || echo "false"
elif [[ -n $2 && -f /etc/nginx/sites-available/$1 && -f /etc/nginx/apps.d/$1$subn-wpcommon.conf ]]; then
[[ -f $(wp_config_path $1 $2) ]] && echo "true" || echo "false"
else
echo "false"
fi
}
is_cache() {
# $1 = domain, $2 = WP subfolder
[[ -n $2 ]] && local subn=$(echo $2 | sed "s/\//_/g")
if [[ -z $2 && -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F " common/wpfc.conf;") ]]; then
echo "wp"
elif [[ -n $2 && -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/# WebinolyCustom/,$p' /etc/nginx/sites-available/$1 | grep -F "$1$subn-wpfc.conf;") ]]; then
echo "wp"
elif [[ -z $2 && -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -E " apps.d/$1-(wp|php)cache.conf;") ]]; then
echo "custom"
elif [[ -n $2 && -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/# WebinolyCustom/,$p' /etc/nginx/sites-available/$1 | grep -E "$1$subn-(wp|php)cache.conf;") ]]; then
echo "custom"
elif [[ -f /etc/nginx/apps.d/$1$subn-proxy.conf && -n $(grep -F "# WebinolyProxyCacheStart" /etc/nginx/apps.d/$1$subn-proxy.conf) && -z $(grep -F "proxy_cache off;" /etc/nginx/apps.d/$1$subn-proxy.conf) ]]; then
echo "proxy"
else
echo "false"
fi
}
is_wp_multisite() {
if [[ $(is_wp $1 $2) == "true" ]]; then
wp_conf_retrieve $1 false false $2 # 3th parameter should always be 'false' to prevent an infinite loop!
if [[ -n $wp_dbhost_host && -n $wp_dbname && -n $wp_dbpref ]]; then
local dbsetup="SELECT * FROM information_schema.tables WHERE table_schema = '$wp_dbname' AND table_name = '${wp_dbpref}sitemeta' LIMIT 1;"
local dbsetuc="USE $wp_dbname; SELECT meta_value FROM ${wp_dbpref}sitemeta where meta_key='subdomain_install';"
if [[ $wp_dbhost_host == "localhost" && $(check_mysql_connection localhost $mysql_param) == "true" ]]; then
wpmu=$(sudo mysql --connect-timeout=10 --user=admin -e "$dbsetup" "${mysql_params[@]}")
[[ -n $wpmu ]] && mutype=$(sudo mysql --connect-timeout=10 --user=admin -e "$dbsetuc" "${mysql_params[@]}")
elif [[ $(check_mysql_connection $wp_dbhost_host $wp_dbhost_port $wp_dbuser $wp_dbpass) == "true" ]]; then
wpmu=$(sudo mysql --defaults-group-suffix=_${wp_dbhost_host}:${wp_dbhost_port}_${wp_dbuser} --connect-timeout=10 -h "$wp_dbhost_host" -P "$wp_dbhost_port" -u"$wp_dbuser" -e "$dbsetup")
[[ -n $wpmu ]] && mutype=$(sudo mysql --defaults-group-suffix=_${wp_dbhost_host}:${wp_dbhost_port}_${wp_dbuser} --connect-timeout=10 -h "$wp_dbhost_host" -P "$wp_dbhost_port" -u"$wp_dbuser" -e "$dbsetuc")
fi
if [[ $(echo $mutype | cut -f 2 -d " " -s) == "1" ]]; then
echo "subdomain"
elif [[ -n $wpmu ]]; then
echo "subdirectory"
else
echo "false"
fi
else
echo "false"
fi
else
echo "false"
fi
}
is_wp_installed() {
# This function check if WP db exists.
# When you create a WP site, DB is created only after the initial WP installation wizard is completed.
if [[ $(is_wp $1 $2) == "true" ]]; then
wp_conf_retrieve $1 false false $2
# It makes no sense checking for mapped domains, that's why is set to false.
# is_wp_installed will return true even if domain is not mapped, only a domain parked pointing to a WP site.
# if we want to check for mapped domains: wp_conf_retrieve $1 true false $2 > /dev/null (silenced echoed messages because affects this function)
# but that makes no-sense because even if it's not mapped, it will return the main site data
# Until now, we don't need a "is_domain_mapped" function, maybe we can change "is_wp_installed" to only be true for main domain sites, not parked (if it's not mapped). This can change in the future!!!
if [[ -n $wp_dbhost_host && -n $wp_dbname && -n $wp_dbpref ]]; then
local dbsetup="SELECT * FROM information_schema.tables WHERE table_schema = '$wp_dbname' AND table_name = '${wp_dbpref}options' LIMIT 1;"
if [[ $wp_dbhost_host == "localhost" && $(check_mysql_connection localhost $mysql_param) == "true" ]]; then
[[ -n $(sudo mysql --connect-timeout=10 --user=admin -e "$dbsetup" "${mysql_params[@]}") ]] && echo "true" || echo "false"
elif [[ $(check_mysql_connection $wp_dbhost_host $wp_dbhost_port $wp_dbuser $wp_dbpass) == "true" ]]; then
[[ -n $(sudo mysql --defaults-group-suffix=_${wp_dbhost_host}:${wp_dbhost_port}_${wp_dbuser} --connect-timeout=10 -h "$wp_dbhost_host" -P "$wp_dbhost_port" -u"$wp_dbuser" -e "$dbsetup") ]] && echo "true" || echo "false"
else
echo "false"
fi
else
echo "false"
fi
else
echo "false"
fi
}
is_wp_debug() {
[[ $( wp_config_read $1 WP_DEBUG $2 ) == "true" ]] && echo "true" || echo "false"
}
is_wp_auth() {
[[ -n $2 ]] && local subn=$(echo $2 | sed "s/\//_/g")
if [[ -z $2 && -f /etc/nginx/sites-available/$1 && -n $( grep -F "wpcommon.conf;" /etc/nginx/sites-available/$1 ) ]]; then
echo "true"
elif [[ -n $2 && -f /etc/nginx/sites-available/$1 && -n $( grep -F "wpcommon.conf;" /etc/nginx/apps.d/$domain$subn-php.conf ) ]]; then
echo "true"
else
echo "false"
fi
}
is_force_redirect() {
if [[ -f /etc/nginx/sites-available/$1 && -n $( grep -F "WebinolyWWWredirectStart" /etc/nginx/sites-available/$1 ) ]]; then
[[ -n $(sed -n -e '/WebinolyWWWredirectStart/,/WebinolyWWWredirectEnd/p' /etc/nginx/sites-available/$1 | grep -F "server_name www.${1};") ]] && echo "root" || echo "www"
else
echo "off"
fi
}
is_subfolder() {
# $1 = domain, $2 = subfolder
if [[ -n $1 && -n $2 ]]; then
if [[ $(is_wp $1 $2) == "true" ]]; then
echo "wp"
elif [[ $(is_php $1 $2) == "true" ]]; then
echo "php"
elif [[ $(is_proxy $1 $2) == "true" ]]; then
echo "proxy"
elif [[ $(is_html $1 $2) == "true" ]]; then
echo "html"
elif [[ -d /var/www/${1}/htdocs${2} && -z $(find /var/www/${1}/htdocs${2} -maxdepth 1 -type f | head -n 1) ]]; then
echo "empty"
elif [[ -d /var/www/${1}/htdocs${2} ]]; then
echo "true"
else
echo "false"
fi
else
echo "false"
fi
}
is_empty_root_site() {
# $1 = domain
if [[ -n $1 ]]; then
if [[ -f /etc/nginx/sites-available/$1 && -z $(grep -F " common/locations.conf;" /etc/nginx/sites-available/$1) && -z $(grep -E "include common/headers-.*.conf;" /etc/nginx/sites-available/$1) ]]; then
echo "full"
elif [[ $(is_wp $1) == "true" || $(is_php $1) == "true" || $(is_proxy $1) == "true" || $(is_html $1) == "true" || $(is_parked $1) == "true" || $(is_forward $1) == "true" ]]; then
echo "false"
elif [[ -f /etc/nginx/sites-available/$1 ]]; then
echo "true"
else
echo "false"
fi
else
echo "false"
fi
}
is_dd_log() {
if [[ $1 == "nginx" ]]; then
local ddpath="/etc/datadog-agent/conf.d/nginx.d/conf.yaml"
elif [[ $1 == "fpm" ]]; then
local ddpath="/etc/datadog-agent/conf.d/php_fpm.d/conf.yaml"
elif [[ $1 == "mysql" ]]; then
local ddpath="/etc/datadog-agent/conf.d/mysql.d/conf.yaml"
elif [[ $1 == "redis" ]]; then
local ddpath="/etc/datadog-agent/conf.d/redisdb.d/conf.yaml"
elif [[ $1 == "global" ]]; then
[[ -f /etc/datadog-agent/datadog.yaml && -n $(grep -F "WebinolyLogsStart" /etc/datadog-agent/datadog.yaml) ]] && local global="true"
else
local ddpath=""
fi
[[ -n $global || ( -n $ddpath && -f $ddpath && -n $(grep -F "WebinolyDatadogLogsStart" $ddpath)) ]] && echo "true" || echo "false"
}
is_log() {
[[ -f /etc/nginx/sites-available/$1 && -n $(sed -n -e '/WebinolyNginxServerStart/,$p' /etc/nginx/sites-available/$1 | grep -F "nginx/$1.access.log ") ]] && echo "true" || echo "false"
}
escaped_string() {
# Escaped characters: Put a backslash before $.*/[\]^()+
echo $(echo $1 | sed "s#/#\\\/#g" | sed "s/\./\\\./g" | sed "s/\\$/\\\\$/g" | sed "s/\*/\\\*/g" | sed "s/\\\/\\\\/g" | sed "s/\[/\\\[/g" | sed "s/\]/\\\]/g" | sed "s/\^/\\\^/g" | sed -E "s/\(/\\\(/g" | sed -E "s/\)/\\\)/g" | sed "s/\+/\\\+/g")
}
site_type() {
if [[ -z $1 ]]; then
echo "false"
elif [[ $(is_parked $1) == "true" ]]; then
echo "Parked"
elif [[ $(is_wp $1) == "true" ]]; then
echo "WordPress"
elif [[ $(is_php $1) == "true" ]]; then
echo "PHP"
elif [[ $(is_html $1) == "true" ]]; then
echo "HTML"
elif [[ $(is_dedicated_proxy_domain $1) == "true" ]]; then
echo "Dedicated Reverse Proxy"
elif [[ $(is_proxy $1) == "true" ]]; then
echo "Reverse Proxy"
elif [[ $(is_forward $1) == "true" ]]; then
echo "Forward"
elif [[ $(is_empty_root_site $1) == "full" ]]; then
echo "Empty Blank"
elif [[ $(is_empty_root_site $1) == "true" ]]; then
echo "Subfolders"
else
echo "Unknown"
fi
}
email_update() {
echo "${blu}"
if [[ -z $1 && ( -z $email || $email == "true" ) ]]; then
read -p "Email address: ${end}" mail
else
[[ -z $1 ]] && local mail=$email || local mail=$1
fi
if [[ $mail =~ ^[a-z0-9_\+-]+(\.[a-z0-9_\+-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*\.([a-z]{2,4})$ ]]; then
conf_write mail $mail
[[ ! -f /root/.forward ]] && sudo touch /root/.forward || sudo truncate -s 0 /root/.forward
sudo echo "$mail" >> /root/.forward
if [[ -s /var/spool/cron/crontabs/root && -n $( sudo grep -F "MAILTO=" /var/spool/cron/crontabs/root ) ]]; then
sudo sed -i "/MAILTO=/c \MAILTO=${mail}" /var/spool/cron/crontabs/root
echo "${gre}${dim}Cronjob (root) MAILTO has been updated!${end}"
fi
if [[ -d /etc/letsencrypt/renewal ]]; then
sudo certbot update_account --email $mail --no-eff-email
echo "${gre}${dim}Let's Encrypt account email address has been updated!${end}"
fi
echo "${gre}Email address has been successfuly validated, updated and saved!"
else
echo "${red}Please enter a valid email address!"
fi
echo "${end}"
}
edit_wp_db_url_multisite() {
#Subfolder is not allowed here because is not needed, parked and force-www are not allowed in subfolders.
#Example: edit_wp_db_url_multisite olddomain.com newdomain.com 2
# $3 - WP BlogID to force (optional)
if [[ -n $1 && -n $2 && $(is_wp_multisite $1) =~ ^(subdomain|subdirectory)$ ]]; then
wp_conf_retrieve $1 false true $subfolder
# Force WP blogID
if [[ -n $3 && $3 =~ ^[0-9]+$ ]]; then
local wp_dbpref="${wp_dbpref}${3}_"
local wp_blogid=$3
local dbsetup="SELECT * FROM information_schema.tables WHERE table_schema = '$wp_dbname' AND table_name = '${wp_dbpref}options' LIMIT 1;"
if [[ $wp_dbhost_host == "localhost" && -n $(sudo mysql --connect-timeout=10 --user=admin -e "$dbsetup" "${mysql_params[@]}") ]]; then
echo "${blu}${dim}WordPress blog ID (${wp_dbpref}) found and validated in a WP Multisite Network!${end}" >&2
elif [[ $wp_dbhost_host != "localhost" && -n $(sudo mysql --defaults-group-suffix=_${wp_dbhost_host}:${wp_dbhost_port}_${wp_dbuser} --connect-timeout=10 -h "$wp_dbhost_host" -P "$wp_dbhost_port" -u"$wp_dbuser" -e "$dbsetup") ]]; then
echo "${blu}${dim}WordPress blog ID (${wp_dbpref}) found and validated in a WP Multisite Network!${end}" >&2
else
echo "${red}${dim}[ERROR] WordPress blog ID (${wp_dbpref}) not found!${end}" >&2
wp_dbpref=""
wp_blogid=""
fi
fi
if [[ -n $wp_dbhost_host && -n $wp_dbname && -n $wp_dbpref_main && -n $wp_blogid ]]; then
if [[ $wp_dbhost_host == "localhost" && $(check_mysql_connection localhost $mysql_param) == "true" ]]; then
sudo mysql --connect-timeout=10 --user=admin "${mysql_params[@]}" <<_EOF_
USE $wp_dbname;
UPDATE ${wp_dbpref_main}blogs SET domain='$2' WHERE blog_id='${wp_blogid}';
UPDATE ${wp_dbpref_main}blogs SET path='/' WHERE blog_id='${wp_blogid}';
_EOF_
elif [[ $(check_mysql_connection $wp_dbhost_host $wp_dbhost_port $wp_dbuser $wp_dbpass) == "true" ]]; then
sudo mysql --defaults-group-suffix=_${wp_dbhost_host}:${wp_dbhost_port}_${wp_dbuser} --connect-timeout=10 -h "$wp_dbhost_host" -P "$wp_dbhost_port" -u"$wp_dbuser" <<_EOF_
USE $wp_dbname;
UPDATE ${wp_dbpref_main}blogs SET domain='$2' WHERE blog_id='${wp_blogid}';
UPDATE ${wp_dbpref_main}blogs SET path='/' WHERE blog_id='${wp_blogid}';
_EOF_
else
echo "${red}${dim}[ERROR] WordPress Multisite database cannot be updated!${end}" >&2
return 1
fi
else
echo "${red}${dim}[ERROR] WordPress Multisite database cannot be updated!${end}" >&2
return 1
fi
fi
}
edit_wp_db_url() {
#Example: edit_wp_db_url example.com "http://${domain}${subfolder}"
#Example: edit_wp_db_url example.com "http://${domain}${subfolder}" /subfolder
#IMPORTANT NOTE: Always be sure to take "www" Force-Redirect into consideration before updating WP Url in database.
if [[ -n $1 && -n $2 && $(is_wp_installed $1 $3) == "true" ]]; then
wp_conf_retrieve $1 false true $3
if [[ -n $wp_dbhost_host && -n $wp_dbname && -n $wp_dbpref ]]; then
if [[ $wp_dbhost_host == "localhost" && $(check_mysql_connection localhost $mysql_param) == "true" ]]; then
sudo mysql --connect-timeout=10 --user=admin "${mysql_params[@]}" <<_EOF_
USE $wp_dbname;
UPDATE ${wp_dbpref}options SET option_value='$2' WHERE option_name='home';
UPDATE ${wp_dbpref}options SET option_value='$2' WHERE option_name='siteurl';
_EOF_
echo "${gre}${dim}WordPress site${blu} ${1}${3} ${gre}database URL updated! ${blu}(${2})${end}"
elif [[ $(check_mysql_connection $wp_dbhost_host $wp_dbhost_port $wp_dbuser $wp_dbpass) == "true" ]]; then
sudo mysql --defaults-group-suffix=_${wp_dbhost_host}:${wp_dbhost_port}_${wp_dbuser} --connect-timeout=10 -h "$wp_dbhost_host" -P "$wp_dbhost_port" -u"$wp_dbuser" <<_EOF_
USE $wp_dbname;
UPDATE ${wp_dbpref}options SET option_value='$2' WHERE option_name='home';
UPDATE ${wp_dbpref}options SET option_value='$2' WHERE option_name='siteurl';
_EOF_
echo "${gre}${dim}WordPress site${blu} ${1}${3} ${gre}database URL updated! ${blu}(${2})${end}"
else
echo "${red}${dim}[ERROR] WordPress database cannot be updated!${end}" >&2
fi
else
echo "${red}${dim}[ERROR] WordPress database cannot be updated!${end}" >&2
fi
fi
}
wp_db_update() {
# Same as edit_wp_db_url, but it also check and includes WP in subfolders.
# if main site is WP.
[[ $(is_wp $1) == "true" ]] && edit_wp_db_url $1 $2
# Check if site contains WP in subfolders.
for site in "/etc/nginx/apps.d/${1}_"*-wpcommon.conf
do
local subwp="/$(echo $site | cut -f 2- -d "_" -s | cut -f -1 -d "-" -s | sed "s/_/\//g")"
[[ -n $subwp && -f /var/www/${1}/htdocs$subwp/wp-config.php ]] && edit_wp_db_url $1 ${2}${subwp} $subwp
done
}
db_role_check() {
if ! [[ $1 =~ ^(basic|limited|extra|complete|full|all|grant)$ ]]; then
echo "${red}[ERROR] Please, enter a valid database role!${end}"
[[ -n $db_role ]] && db_role=""
[[ $2 == "unattended" ]] && echo "${dim}We will use the default db role!${end}" || exit 1
elif [[ $1 == "basic" ]]; then
echo "${dim}[WARNING] You have set basic privileges for your databases. Some sites, like WordPress, could NOT work properly!${end}"
fi
}
db_user_role() {
# Can't be used on not global users: FILE,REPLICATION CLIENT,REPLICATION SLAVE,PROCESS,SHOW DATABASES,CREATE USER,RELOAD,GRANT,SUPER,SHUTDOWN
# FILE Privilege not supported by external DB's: http://cloudofnines.blogspot.com/2014/09/in-rds-instances-file-privilege-for.html
# AWS RDS Reference: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.MasterAccounts.html
# ALL PRIVILEGES not supported for external DB's.
[[ -z $db_role ]] && db_role=$(conf_read dbrole)
if [[ $db_role == "all" ]]; then
local priv="ALL PRIVILEGES"
elif [[ $db_role == "basic" ]]; then
local priv="SELECT,INSERT,UPDATE,DELETE"
elif [[ $db_role == "limited" ]]; then
local priv="SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER"
elif [[ $db_role == "extra" ]]; then
local priv="SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,LOCK TABLES"
elif [[ $db_role == "complete" ]]; then
local priv="SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,CREATE TEMPORARY TABLES,EXECUTE,CREATE VIEW,SHOW VIEW,CREATE ROUTINE,ALTER ROUTINE,EVENT,TRIGGER"
elif [[ $db_role == "grant" ]]; then
local priv="SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,CREATE TEMPORARY TABLES,EXECUTE,CREATE VIEW,SHOW VIEW,CREATE ROUTINE,ALTER ROUTINE,EVENT,TRIGGER,REFERENCES,LOCK TABLES,GRANT OPTION"
else # full (DEFAULT)
local priv="SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,CREATE TEMPORARY TABLES,EXECUTE,CREATE VIEW,SHOW VIEW,CREATE ROUTINE,ALTER ROUTINE,EVENT,TRIGGER,REFERENCES,LOCK TABLES"
fi
echo $priv
}
dbword_check() {
local win="$1"
local RANDOM_NAME="Webinoly_$(pwgen -s -1)"
# Trim start/end spaces and quotes
win=$(echo ${win//\'})
win=$(echo ${win//\"} | xargs)
# Check Lenght
# MySQL user names are up to 32 characters long.
# MariaDB - Usernames can be up to 80 characters long before 10.6 and starting from 10.6 it can be 128 characters long.
# DB name is 64 for both!
[[ ( ${#win} -gt 64 && $2 != "user" ) ]] && win=$RANDOM_NAME
[[ ( ${#win} -gt 32 && $2 == "user" ) && $(conf_read db-engine) == "mysql" ]] && win=$RANDOM_NAME
[[ ( ${#win} -gt 80 && $2 == "user" ) && $(conf_read db-engine) != "mysql" ]] && win=$RANDOM_NAME
# Reserved words - https://mariadb.com/kb/en/library/reserved-words/ https://dev.mysql.com/doc/mysqld-version-reference/en/keywords-8-0.html
# https://mariadb.com/kb/en/library/identifier-names/
# We have both MySQL and MariaDB reserved words.
# We have information_schema.keywords, but we prefer do this check manually because mariadb doesn't have a way to know which keywords are reserved.
if [[ ${win^^} =~ ^(ACCESSIBLE|ADD|ALL|ALTER|ANALYZE|AND|AS|ASC|ASENSITIVE|BEFORE|BETWEEN|BIGINT|BINARY|BLOB|BOTH|BY|CALL|CASCADE|CASE|CHANGE|CHAR|CHARACTER|CHECK|COLLATE|COLUMN|CONDITION|CONSTRAINT|CONTINUE|CONVERT|CREATE|CROSS|CUBE|CUME_DIST|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DATABASES|DAY_HOUR|DAY_MICROSECOND|DAY_MINUTE|DAY_SECOND|DEC|DECIMAL|DECLARE|DEFAULT|DELAYED|DELETE|DENSE_RANK|DESC|DESCRIBE|DETERMINISTIC|DISTINCT|DISTINCTROW|DIV|DOUBLE|DROP|DUAL|EACH|ELSE|ELSEIF|EMPTY|ENCLOSED|ESCAPED|EXCEPT|EXISTS|EXIT|EXPLAIN|FALSE|FETCH|FIRST_VALUE|FLOAT|FLOAT4|FLOAT8|FOR|FORCE|FOREIGN|FROM|FULLTEXT|FUNCTION|GENERATED|GET|GRANT|GROUP|GROUPING|GROUPS|HAVING|HIGH_PRIORITY|HOUR_MICROSECOND|HOUR_MINUTE|HOUR_SECOND|IF|IGNORE|IN|INDEX|INFILE|INNER|INOUT|INSENSITIVE|INSERT|INT|INT1|INT2|INT3|INT4|INT8|INTEGER|INTERSECT|INTERVAL|INTO|IO_AFTER_GTIDS|IO_BEFORE_GTIDS|IS|ITERATE|JOIN|JSON_TABLE|KEY|KEYS|KILL|LAG|LAST_VALUE|LATERAL|LEAD|LEADING|LEAVE|LEFT|LIKE|LIMIT|LINEAR|LINES|LOAD|LOCALTIME|LOCALTIMESTAMP|LOCK|LONG|LONGBLOB|LONGTEXT|LOOP|LOW_PRIORITY|MASTER_BIND|MASTER_SSL_VERIFY_SERVER_CERT|MATCH|MAXVALUE|MEDIUMBLOB|MEDIUMINT|MEDIUMTEXT|MIDDLEINT|MINUTE_MICROSECOND|MINUTE_SECOND|MOD|MODIFIES|NATURAL|NOT|NO_WRITE_TO_BINLOG|NTH_VALUE|NTILE|NULL|NUMERIC|OF|ON|OPTIMIZE|OPTIMIZER_COSTS|OPTION|OPTIONALLY|OR|ORDER|OUT|OUTER|OUTFILE|OVER|PARTITION|PERCENT_RANK|PRECISION|PRIMARY|PROCEDURE|PURGE|RANGE|RANK|READ|READS|READ_WRITE|REAL|RECURSIVE|REFERENCES|REGEXP|RELEASE|RENAME|REPEAT|REPLACE|REQUIRE|RESIGNAL|RESTRICT|RETURN|REVOKE|RIGHT|RLIKE|ROW|ROWS|ROW_NUMBER|SCHEMA|SCHEMAS|SECOND_MICROSECOND|SELECT|SENSITIVE|SEPARATOR|SET|SHOW|SIGNAL|SMALLINT|SPATIAL|SPECIFIC|SQL|SQLEXCEPTION|SQLSTATE|SQLWARNING|SQL_BIG_RESULT|SQL_CALC_FOUND_ROWS|SQL_SMALL_RESULT|SSL|STARTING|STORED|STRAIGHT_JOIN|SYSTEM|TABLE|TERMINATED|THEN|TINYBLOB|TINYINT|TINYTEXT|TO|TRAILING|TRIGGER|TRUE|UNDO|UNION|UNIQUE|UNLOCK|UNSIGNED|UPDATE|USAGE|USE|USING|UTC_DATE|UTC_TIME|UTC_TIMESTAMP|VALUES|VARBINARY|VARCHAR|VARCHARACTER|VARYING|VIRTUAL|WHEN|WHERE|WHILE|WINDOW|WITH|WRITE|XOR|YEAR_MONTH|ZEROFILL|CURRENT_ROLE|DELETE_DOMAIN_ID|DO_DOMAIN_IDS|GENERAL|IGNORE_DOMAIN_IDS|IGNORE_SERVER_IDS|MASTER_HEARTBEAT_PERIOD|OFFSET|PAGE_CHECKSUM|PARSE_VCOL_EXPR|POSITION|REF_SYSTEM_ID|RETURNING|SLOW|STATS_AUTO_RECALC|STATS_PERSISTENT|STATS_SAMPLE_PAGES)$ ]]; then
win=$RANDOM_NAME
fi
# Only numerals 0-9, basic Latin letters, both lowercase and uppercase, dollar sign, underscore.
[[ $win =~ ^[0-9A-Za-z\$_]+$ ]] || win=$RANDOM_NAME
# Dollar sign at the beggining not allowed.
[[ $(echo "${win}" | cut -c-1) == "$" ]] && win=$RANDOM_NAME
# Can not contain only numbers
[[ $win =~ ^[0-9]+$ ]] && win=$RANDOM_NAME
# Floating point number confusing
[[ ${win:0:1} =~ ^[0-9]+$ && ${win:1:1} == "e" ]] && win=$RANDOM_NAME
echo $win
}
cnf_delete() {
#Example: cnf_delete error_log
[[ -f $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf ]] && sudo sed -i "/^$1 /d" $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf
}
cnf_write() {
#Example: cnf_write error_log /var/log/mysql/error.log
cnf_delete $1
mysql_default_cnf
[[ -n $2 ]] && local value="= $2"
echo "$1 $value" >> $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf
}
cnf_read() {
#Example: cnf_read error_log
[[ -f $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf ]] && echo $( grep -P "^$1 = " $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf | cut -f 2 -d "=" -s | sed 's/ //g' )
}
mysql_default_cnf() {
# Creates the default Webinoly Configuration File (.cnf) for mysql if not exists.
if [[ ! -f $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf ]]; then
sudo touch $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf
sudo chmod 644 $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf
sudo chown -R root:root $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf
echo "# Webinoly MySQL/MariaDB Configuration File
######################################################################
# Webinoly (This configuration file is only for internal use) #
# Please, DO NOT MODIFY this file, it can cause unexpected behavior. #
######################################################################
[mysqld]
log_error = /var/log/mysql/error.log" >> $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly.cnf
fi
}
mysql_login_cnf() {
# MySQL login data
if [[ ! -f $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf ]]; then
sudo touch $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf
sudo chmod 644 $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf
sudo chown -R root:root $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf
echo "# Webinoly MySQL/MariaDB Login Configuration File
######################################################################
# Webinoly (This configuration file is only for internal use) #
# Please, DO NOT MODIFY this file, it can cause unexpected behavior. #
######################################################################
" >> $MYSQL_CONF_PATH/${MYSQL_CONF_PREF}-webinoly-login.cnf
fi
}
check_var() {
# fastcgi_read_timeout,max_execution_time,request_terminate_timeout
if [[ $1 == "php-max-time" ]]; then
[[ -n $(conf_read php-max-time) && $(conf_read php-max-time) =~ ^[0-9]+$ && $(conf_read php-max-time) -gt 0 ]] && local out=$(conf_read php-max-time) || local out=60
# PHP Memory limit
elif [[ $1 == "php-max-mem" ]]; then
[[ -n $(conf_read php-max-mem) && $(conf_read php-max-mem) =~ ^[0-9]+$ && $(conf_read php-max-mem) -gt 0 ]] && local out=$(conf_read php-max-mem) || local out=192
# PHP simultaneous file uploads
elif [[ $1 == "php-max-files" ]]; then
[[ -n $(conf_read php-max-files) && $(conf_read php-max-files) =~ ^[0-9]+$ && $(conf_read php-max-files) -gt 0 ]] && local out=$(conf_read php-max-files) || local out=20
# PHP Process Manager
elif [[ $1 == "php-pm" ]]; then
if [[ $(conf_read php-pm) =~ ^(static|ondemand|dynamic)$ ]]; then
local out=$(conf_read php-pm)
else
[[ $ram -gt 1 ]] && local out="static" || local out="dynamic"
fi
# PHP Workers
elif [[ $1 == "php-max-child" ]]; then
if [[ -n $(conf_read php-max-child) && $(conf_read php-max-child) =~ ^[0-9]+$ && $(conf_read php-max-child) -ge 3 ]]; then
local out=$(conf_read php-max-child)
else
[[ $((3*$cores)) =~ ^[0-9]+ && $((3*$cores)) -ge 6 ]] && local out=$((3*$cores)) || local out=6
fi
# PHP max input vars
elif [[ $1 == "php-max-input-vars" ]]; then
[[ -n $(conf_read php-max-input-vars) && $(conf_read php-max-input-vars) =~ ^[0-9]+$ && $(conf_read php-max-input-vars) -gt 0 ]] && local out=$(conf_read php-max-input-vars) || local out=5000
# PHP opcache validate timestamps
elif [[ $1 == "php-opcache-timestamps" ]]; then
local out="false"
[[ $(conf_read php-opcache-timestamps) == "true" ]] && local out="1"
[[ $(conf_read php-opcache-timestamps) == "false" ]] && local out="0"
# PHP opcache revalidate frequency
elif [[ $1 == "php-opcache-reval" ]]; then
[[ -n $(conf_read php-opcache-reval) && $(conf_read php-opcache-reval) =~ ^[0-9]+$ && $(conf_read php-opcache-reval) -ge 0 ]] && local out=$(conf_read php-opcache-reval) || local out="false"
# Redis Memory
elif [[ $1 == "redis-max-mem" ]]; then
[[ -n $(conf_read redis-max-mem) && $(conf_read redis-max-mem) =~ ^[0-9]+$ && $(conf_read redis-max-mem) -le 100 ]] && local out=$(conf_read redis-max-mem) || local out=10
# client_max_body_size,upload_max_filesize,post_max_size
elif [[ $1 == "max-mb-uploads" ]]; then
[[ -n $(conf_read max-mb-uploads) && $(conf_read max-mb-uploads) =~ ^[0-9]+$ && $(conf_read max-mb-uploads) -gt 0 ]] && local out=$(conf_read max-mb-uploads) || local out=100
# FastCGI Cache size
elif [[ $1 == "run-folder-size" ]]; then
[[ -n $(conf_read run-folder-size) && $(conf_read run-folder-size) =~ ^[0-9]+$ && $(conf_read run-folder-size) -gt 10 && $(conf_read run-folder-size) -le "70" ]] && local out=$(conf_read run-folder-size) || local out=25
# FastCGI Cache: Query Strings
elif [[ $1 == "wpcache-query-strings" ]]; then
if [[ $(conf_read wpcache-query-strings) =~ ^(all|never)$ ]]; then
local out=$(conf_read wpcache-query-strings)
else
local out="false"
fi
# Locations: Deny Extensions
elif [[ $1 == "locations-deny-extensions" ]]; then
if [[ -z $(conf_read locations-deny-extensions) ]]; then
local out="7z|asc|asp|aspx|ba|bak|bash|bat|bin|bz2|c|cfg|cgi|class|com|conf|cpp|crt|cs|dat|db|dbf|deb|der|dll|dmg|dmp|dump|ear|exe|git|gz|h|hg|hqx|img|ini|iso|jar|jsp|log|mdb|msi|msm|msp|old|orig|original|out|pem|php#|php_bak|php~|pkg|pl|ppk|py|rar|rdf|rpm|run|save|sh|sql|srv|svn|swo|swp|sys|tar|taz|tcl|tgz|tk|tmp|tpl|tz|vb|war|wsf|z|zip"
else
local out=$(conf_read locations-deny-extensions)
fi
# Locations: Deny Files
elif [[ $1 == "locations-deny-files" ]]; then
if [[ -z $(conf_read locations-deny-files) ]]; then
local out="changelog|example|installation|legalnotice|license|readme|wp-config"
else
local out=$(conf_read locations-deny-files)
fi
# FastCGI Cache: Exclude URL
elif [[ $1 == "wpcache-exclude-url" ]]; then
if [[ -z $(conf_read wpcache-exclude-url) ]]; then
local out="/wp-admin/|/xmlrpc.php|wp-.*.php|index.php|/feed/|.*sitemap.*\.xml|/feed/|/account/|/add_to_cart/|/cart/|/my-account/|/checkout/|/logout/"
else
local out=$(conf_read wpcache-exclude-url)
fi
# FastCGI Cache: Exclude Cookie
elif [[ $1 == "wpcache-exclude-cookie" ]]; then
if [[ -z $(conf_read wpcache-exclude-cookie) ]]; then
local out="comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|[a-z0-9]+_items_in_cart|[a-z0-9]+_cart_hash"
else
local out=$(conf_read wpcache-exclude-cookie)
fi
# Nginx Error Log Level
elif [[ $1 == "nginx-error-log-level" ]]; then
[[ -n $(conf_read nginx-error-log-level) && $(conf_read nginx-error-log-level) =~ ^(info|notice|warn|error|crit|alert|emerg)$ ]] && local out=$(conf_read nginx-error-log-level) || local out="false"
# Nginx Log Format
elif [[ $1 == "nginx-log-format" ]]; then
local out="we_log" # Basic is fallback!
[[ $(conf_read nginx-log-format) == "extended" ]] && local out="we_log_ext"
[[ $(conf_read nginx-log-format) == "custom" ]] && local out="we_log_custom"
else
local out="false"
fi
echo $out
}
config_fastcgi_cache() {
# This function is used alone by webinoly command.
# For a particular site you can use it as follows:
#Example: config_fastcgi_cache -site
#Example: config_fastcgi_cache -site [1h,1d,1m]
local pref="fastcgi"
if [[ $1 == "-site" && -f /etc/nginx/sites-available/$domain ]]; then
if [[ $(is_wp $domain $subfolder) == "true" && -f /etc/nginx/apps.d/$domain$subname-wpcache.conf ]]; then
local timefile="/etc/nginx/apps.d/$domain$subname-wpcache.conf"
elif [[ $(is_php $domain $subfolder) == "true" && -f /etc/nginx/apps.d/$domain$subname-phpcache.conf ]]; then
local timefile="/etc/nginx/apps.d/$domain$subname-phpcache.conf"
elif [[ $(is_proxy $domain $subfolder) == "true" && -f /etc/nginx/apps.d/$domain$subname-proxy.conf ]]; then
if [[ -n $(grep -F "# WebinolyProxyCacheStart" /etc/nginx/apps.d/$domain$subname-proxy.conf) ]]; then
local timefile="/etc/nginx/apps.d/$domain$subname-proxy.conf"
local pref="proxy"
else
echo "${red}[ERROR] Custom Proxy Cache not found! ${dim}(Must be enabled at least once before you can add these custom values)${end}"
exit 1
fi
else
echo "${red}[ERROR] Unexpected internal error! (Wrong sitetype for custom cache)${end}"
exit 1
fi
local mainfile="/etc/nginx/conf.d/webinoly.conf"
local cache_valid=$2
else
local timefile="/etc/nginx/conf.d/fastcgi.conf"
local mainfile="/etc/nginx/conf.d/fastcgi.conf"
fi
if [[ $(conf_read nginx) == "true" ]]; then
hitline=$( grep -F "${pref}_cache_valid 200" $timefile )
hitval=$(echo "${hitline//;}" | rev | cut -d' ' -f 1 | rev)
inaline=$( grep -F "${pref}_cache_path" $mainfile )
inactive=$(echo "${inaline//;}" | rev | cut -d' ' -f 1 | rev)
inaval=$(echo "${inactive}" | cut -d'=' -f 2)
maxsize=$(echo "${inaline}" | rev | cut -d' ' -f 2 | rev)
othline=$( grep -F "${pref}_cache_valid 301 302 303 307 308 404 410 451" $timefile )
othval=$(echo "${othline//;}" | rev | cut -d' ' -f 1 | rev)
elif [[ -n $(conf_read fastcgi-conf) ]]; then
hitval=$( echo $(conf_read fastcgi-conf) | cut -d',' -f 1 -s )
inaval=$( echo $(conf_read fastcgi-conf) | cut -d',' -f 2 -s )
othval=$( echo $(conf_read fastcgi-conf) | cut -d',' -f 3 -s )
else
hitval="Not yet defined"
inaval="Not yet defined"
othval="Not yet defined"
fi
if [[ $cache_valid == true ]]; then
echo "${gre}"
echo "**********************************************************************"
echo "************* Set Nginx Cache new time values **************"
echo "***** Example: 30d = 30days | 3h = 3hours | 5m = 5minutes ******"
echo "**********************************************************************"
echo "${blu}"
echo "Nginx Cache Valid for Pages (HttpCode: 200) actual value is: $hitval"
read -p " Set new value: " hit
hit=${hit:-$hitval}
echo ""
echo "Purge Cache for inactive pages actual value is: $inaval"
read -p " Set new value: " ina
ina=${ina:-$inaval}
echo ""
echo "Nginx Cache Valid for Errors and Redirections (301 302 303 307 308 404 410 451) actual value is: $othval"
read -p " Set new value: " oth
oth=${oth:-$othval}
echo ""
elif [[ $(echo "${cache_valid}" | cut -c-1) == "[" && $(echo "${cache_valid}" | rev | cut -c-1) == "]" ]]; then
custombegin=$(echo "${cache_valid}" | cut -c-1)
customlast=$(echo "${cache_valid}" | rev | cut -c-1)
# No need for check var lenght to prevent errors, the previous condition is enough in this case.
cachedata=${cache_valid:1:-1}
hit=$(echo "${cachedata}" | cut -d',' -f 1 )
ina=$(echo "${cachedata}" | cut -d',' -f 2 )
oth=$(echo "${cachedata}" | cut -d',' -f 3 )
else
echo "${red}[ERROR] Please enter a valid value!${end}"
exit 1
fi
if [[ "$hit" =~ ^[0-9]+[smhdwMy]$ && "$ina" =~ ^[0-9]+[smhdwMy]$ && "$oth" =~ ^[0-9]+[smhdwMy]$ ]]; then
if [[ $(conf_read nginx) == "true" ]]; then
[[ $1 == "-site" ]] && local path="/run/nginx-cache/$(echo $domain | sed 's/[^0-9A-Za-z]/_/g')$subname" || local path="/run/nginx-cache"
local cachepath=$(grep -F "${pref}_cache_path $path " $mainfile)
local newcachepath=$(echo $cachepath | sed "s/ inactive=.*[a-z]/ inactive=$ina/")
if [[ -n $cachepath && -n $newcachepath ]]; then
sudo sed -i "s#$cachepath#$newcachepath#" $mainfile
else
echo "${red}[ERROR] Unexpected error! (Cache configuration corrupted)${end}"
exit 1
fi
sudo sed -i "/${pref}_cache_valid 200/c ${pref}_cache_valid 200 ${hit};" $timefile
sudo sed -i "/${pref}_cache_valid 301 302 /c ${pref}_cache_valid 301 302 303 307 308 404 410 451 ${oth};" $timefile
sudo sed -i "/^${pref}_/s/^/ /" $timefile
fi
[[ $1 == "-site" ]] || conf_write fastcgi-conf ${hit},${ina},${oth}
echo "${gre}Nginx Cache values has been successfully updated!${end}"
else
echo "${red}[ERROR] Invalid values!${end}"
exit 1
fi
}
custom_cache_global() {
# This function is used alone by webinoly command.
# For a particular site you can use it as follows:
# Example: custom_cache_global -site
if [[ $1 == "-site" && -f /etc/nginx/sites-available/$domain ]]; then
if [[ ( $(is_wp $domain $subfolder) == "true" && -f /etc/nginx/apps.d/$domain$subname-wpcache.conf ) || ( $(is_php $domain $subfolder) == "true" && -f /etc/nginx/apps.d/$domain$subname-phpcache.conf ) || ( $(is_proxy $domain $subfolder) == "true" && -f /etc/nginx/apps.d/$domain$subname-proxy.conf ) ]]; then
local confile="/etc/nginx/apps.d/${domain}${subname}-site_custom_cache.conf"
local mark="_$(echo $domain | sed "s/[^0-9A-Za-z]/_/g")${subname}"
else
echo "${red}[ERROR] Custom Cache not found! ${dim}(Must be enabled at least once before you can add these custom rules)${end}"
exit 1
fi
else
local confile="/etc/nginx/apps.d/global_custom_cache.conf"
fi
if [[ -n $list ]]; then
[[ -n $raw || $list == "raw" ]] && echo "" || echo "${gre}"
if [[ -f $confile ]]; then
[[ -n $query_string_never_cache ]] && local id="NeverCacheQueryString"
[[ -n $query_string_cache ]] && local id="CacheQueryString"
[[ -n $skip_cookie_cache ]] && local id="CacheSkipCookie"
[[ -n $skip_cache ]] && local id="CacheSkipURL"
local isem=$(sudo sed -n "/# Value: /{h;d;}; H; /# $id/{x;p;}" $confile)
if [[ -n $raw || $list == "raw" ]]; then
sudo sed -n "/# Value: /{h;d;}; H; /# $id/{x;p;}" $confile | sed -n '/# Value:/p' | sed 's/# Value: //g'
else
sudo sed -n "/# Value: /{h;d;}; H; /# $id/{x;p;}" $confile | sed -n '/# Value:/p' | sed 's/# Value: /+ /g'
fi
fi
[[ -z $isem && -z $raw && $list != "raw" ]] && echo "${blu}[Empty] No Cache Rules were found!${end}"
[[ -n $raw || $list == "raw" ]] && echo "" || echo "${end}"
elif [[ -n $delete ]]; then
echo ""
[[ $skip_cache == "true" ]] && read -p "${blu}Cache Skip URL to delete: ${end}" skip_cache
[[ $skip_cookie_cache == "true" ]] && read -p "${blu}Cache Skip Cookie to delete: ${end}" skip_cookie_cache
[[ $query_string_cache == "true" ]] && read -p "${blu}Cache Query String to delete: ${end}" query_string_cache
[[ $query_string_never_cache == "true" ]] && read -p "${blu}Never Cache this Query String to delete: ${end}" query_string_never_cache
if [[ -z $query_string_cache && -z $query_string_never_cache && -z $skip_cache && -z $skip_cookie_cache ]]; then
echo "${red}[ERROR] Please, enter a valid value!${end}"
exit 1
fi
if [[ -f $confile ]]; then
[[ -n $query_string_never_cache ]] && local value=$query_string_never_cache
[[ -n $query_string_cache ]] && local value=$query_string_cache
[[ -n $skip_cookie_cache ]] && local value=$skip_cookie_cache
[[ -n $skip_cache ]] && local value=$skip_cache
sudo sed -Ei "/^# Value: $(escaped_string $value)( .*)?$/,/^# CacheRuleEnd/{/.*/d}" $confile
[[ -f $confile && ( ! -s $confile || -z $(cat -v $confile | grep -m 1 '[^[:space:]]')) ]] && sudo rm $confile # Better because also check for files containing only empty-spaces!
fi
echo "${gre}Cache rule successfully removed!${end}"
else
echo ""
[[ $skip_cache == "true" ]] && read -p "${blu}Cache Skip URL: ${end}" skip_cache
[[ $skip_cookie_cache == "true" ]] && read -p "${blu}Cache Skip Cookie: ${end}" skip_cookie_cache
[[ $query_string_cache == "true" ]] && read -p "${blu}Cache Query String: ${end}" query_string_cache
[[ $query_string_never_cache == "true" ]] && read -p "${blu}Never Cache this Query String: ${end}" query_string_never_cache
echo ""
if [[ -z $query_string_cache && -z $query_string_never_cache && -z $skip_cache && -z $skip_cookie_cache ]]; then
echo "${red}[ERROR] Please, enter a valid value!${end}"
exit 1
elif [[ -n $regex && ( -n $query_string_cache || -n $query_string_never_cache ) ]]; then
echo "${red}[ERROR] Regex not allowed for Query-String custom rules!${end}"
exit 1
elif [[ $skip_cache == "/" && -z $regex ]]; then
echo "${red}[ERROR] Root folder not allowed, use regex or disable site cache!${end}"
exit 1
elif [[ -n $regex ]] && ! [[ $regex =~ ^(sensitive|insensitive)$ ]]; then
echo "${red}[ERROR] Invalid regex value!${end}"
exit 1
elif [[ -z $regex && -n $skip_cache && $(is_url_path $skip_cache) != "true" ]]; then
echo "${red}[ERROR] Invalid URL!${end}"
exit 1
elif [[ -z $regex && -n $skip_cookie_cache ]] && ! [[ $skip_cookie_cache =~ ^([\]A-Za-z0-9_\/\.:\!\*\'\[\(\)\;@\&\=\+\$\,\?#\~\%\-]+)?$ ]]; then
echo "${red}[ERROR] Invalid Cookie String!${end}"
exit 1
elif [[ -z $regex && -n $query_string_cache ]] && ! [[ $query_string_cache =~ ^([\]A-Za-z0-9_\/\.:\!\*\'\[\(\)\;@\&\=\+\$\,\?#\~\%\-]+)?$ ]]; then
echo "${red}[ERROR] Invalid Query String!${end}"
exit 1
elif [[ -z $regex && -n $query_string_never_cache ]] && ! [[ $query_string_never_cache =~ ^([\]A-Za-z0-9_\/\.:\!\*\'\[\(\)\;@\&\=\+\$\,\?#\~\%\-]+)?$ ]]; then
echo "${red}[ERROR] Invalid Query String!${end}"
exit 1
fi
if [[ ! -f $confile ]]; then
sudo touch $confile
sudo chmod 644 $confile
sudo chown -R root:root $confile
fi
[[ -n $query_string_never_cache ]] && local value=$query_string_never_cache
[[ -n $query_string_cache ]] && local value=$query_string_cache
[[ -n $skip_cookie_cache ]] && local value=$skip_cookie_cache
[[ -n $skip_cache ]] && local value=$skip_cache
local exist=$( grep -E "^# Value: $(escaped_string $value)( .*)?$" $confile )
if [[ -z $exist ]]; then
if [[ $regex == "sensitive" ]]; then
sign="~"
code="$value (Regex)"
elif [[ $regex == "insensitive" ]]; then
sign="~*"
code="$value (Regex)"
else
sign="="
code="$value"
fi
if [[ -n $query_string_never_cache ]]; then
echo "# Value: $code
# NeverCacheQueryString
if (\$arg_${value}) {
set \$skip_cache${mark} 1;
}
# CacheRuleEnd" >> $confile
elif [[ -n $skip_cookie_cache ]]; then
echo "# Value: $code
# CacheSkipCookie
if (\$http_cookie $sign $value) {
set \$skip_cache${mark} 1;
}
# CacheRuleEnd" >> $confile
elif [[ -n $query_string_cache ]]; then
# Sed can not write when file is empty
[[ ! -s $confile ]] && echo ' ' >> $confile
sudo sed -i "1i # Value: $code\n# CacheQueryString\nif (\$arg_${value}) {\n set \$skip_cache${mark} 0;\n}\n# CacheRuleEnd" $confile
elif [[ -n $skip_cache ]]; then
[[ ! -s $confile ]] && echo ' ' >> $confile
sudo sed -i "1i # Value: $code\n# CacheSkipURL\nif (\$request_uri $sign $value) {\n set \$skip_cache${mark} 1;\n}\n# CacheRuleEnd" $confile
fi
# Last verification
if ! sudo nginx -t > /dev/null 2>&1; then
if [[ $1 == "-site" && -n $subfolder ]]; then
[[ -n $query_string_never_cache ]] && sudo site $domain -subfolder=$subfolder -cache=custom -query-string-never-cache=$query_string_never_cache -delete > /dev/null 2>&1
[[ -n $query_string_cache ]] && sudo site $domain -subfolder=$subfolder -cache=custom -query-string-cache=$query_string_cache -delete > /dev/null 2>&1
[[ -n $skip_cookie_cache ]] && sudo site $domain -subfolder=$subfolder -cache=custom -skip-cookie-cache=$skip_cookie_cache -delete > /dev/null 2>&1
[[ -n $skip_cache ]] && sudo site $domain -subfolder=$subfolder -cache=custom -skip-cache=$skip_cache -delete > /dev/null 2>&1
elif [[ $1 == "-site" ]]; then
[[ -n $query_string_never_cache ]] && sudo site $domain -cache=custom -query-string-never-cache=$query_string_never_cache -delete > /dev/null 2>&1
[[ -n $query_string_cache ]] && sudo site $domain -cache=custom -query-string-cache=$query_string_cache -delete > /dev/null 2>&1
[[ -n $skip_cookie_cache ]] && sudo site $domain -cache=custom -skip-cookie-cache=$skip_cookie_cache -delete > /dev/null 2>&1
[[ -n $skip_cache ]] && sudo site $domain -cache=custom -skip-cache=$skip_cache -delete > /dev/null 2>&1
else
[[ -n $query_string_never_cache ]] && sudo webinoly -query-string-never-cache=$query_string_never_cache -delete > /dev/null 2>&1
[[ -n $query_string_cache ]] && sudo webinoly -query-string-cache=$query_string_cache -delete > /dev/null 2>&1
[[ -n $skip_cookie_cache ]] && sudo webinoly -skip-cookie-cache=$skip_cookie_cache -delete > /dev/null 2>&1
[[ -n $skip_cache ]] && sudo webinoly -skip-cache=$skip_cache -delete > /dev/null 2>&1
fi
echo "${red}[ERROR] Seems like you are using some invalid Nginx values or characters!${end}"
exit 1
fi
echo "${gre}Cache rule successfully added!${end}"
else
echo "${gre}Cache rule already exists!${end}"
fi
fi
}
smtp_backup() {
if [[ $(conf_read smtp) == "true" ]]; then
sudo touch /var/www/webinoly_backup_smtp
echo "$(sudo sed -n 1p /etc/mailname) $(sudo sed -n 1p /etc/postfix/sasl_passwd)" > /var/www/webinoly_backup_smtp
fi
}
smtp_backup_recovery() {
if [[ -s /var/www/webinoly_backup_smtp ]]; then
local smtpdata=$(sudo sed -n 1p /var/www/webinoly_backup_smtp)
local main=$(echo $smtpdata | cut -d' ' -f 1 -s)
local host=$(echo $smtpdata | cut -d' ' -f 2 -s | cut -d':' -f 1 -s)
local user=$(echo $smtpdata | cut -d' ' -f 3 -s | cut -d':' -f 1 -s)
local pass=$(echo $smtpdata | cut -d' ' -f 3 -s | cut -d':' -f 2 -s)
sudo rm -rf /var/www/webinoly_backup_smtp
if [[ -n $host && -n $user && -n $pass && -n $main ]]; then
sudo webinoly -smtp=[$host,$user,$pass,$main]
else
echo "${red}[ERROR] SMTP Configuration recovery failed! ${end}"
fi
fi
}
help_message() {
echo ""
echo "${blu}${bol}Thanks for using Webinoly!${end}"
echo "${blu}We have put a lot of time and effort into creating the most awesome, detailed and extensive documentation just for you."
echo "${dim}Link: https://webinoly.com/documentation/ ${end}"
echo ""
}
ads_donate() {
# Donations message displayed once a day!
# Note: Don't run when stdout is redirected to /dev/null: https://unix.stackexchange.com/questions/484228/how-to-check-if-stdin-is-dev-null-from-the-shell
if [[ -z $(conf_read cron-ads) && -n $EPOCHSECONDS ]]; then
conf_write cron-ads $EPOCHSECONDS
elif ! [[ $(conf_read cron-ads) =~ ^[0-9]+$ ]] || [[ $(conf_read cron-ads) -gt $EPOCHSECONDS ]]; then # Autofix! (Just in case!)
conf_write cron-ads $EPOCHSECONDS
elif [[ $TERM != "dumb" && -n $EPOCHSECONDS && -n $(conf_read cron-ads) && $(($EPOCHSECONDS-$(conf_read cron-ads))) -gt 86400 ]] && ! [[ /dev/stdout -ef /dev/null ]]; then
echo "${blu}"
echo "****************************************************************************"
echo "******************** ${bol}Are you enjoying Webinoly?${end}${blu} ********************"
echo "*** ${dim}With just \$1 you can make a difference to keep this project alive!${end}${blu} ***"
echo "*********** ${bol}Donate Now!${end}${blu}${dim} https://github.com/sponsors/QROkes${end}${blu} ***********"
echo "****************************************************************************"
echo "${end}"
conf_write cron-ads $EPOCHSECONDS
fi
}