wordpress-tools/bin/wp-installer.sh
2022-09-01 15:33:12 -07:00

389 lines
13 KiB
Bash
Executable File

#!/bin/bash
#
# wordpress-tools
# https://git.stack-source.com/msb/wordpress-tools
# Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>\
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# require root
if [ "${EUID}" -ne 0 ]; then
echo "This script must be run as root"
exit
fi
virtualhost_basedir="/srv/www"
virtualhost_htdocsdir="html"
declare -a input_keys_index
input_keys_index=(v r t e u p m d n w x s)
declare -A input_keys_array
input_keys_array[v]="VirtualHost"
input_keys_array[r]="URL"
input_keys_array[t]="Site Title"
input_keys_array[e]="Admin Email"
input_keys_array[u]="Admin Username"
input_keys_array[p]="Admin Password"
input_keys_array[m]="MySQL Hostname"
input_keys_array[d]="MySQL Database"
input_keys_array[n]="MySQL Username"
input_keys_array[w]="MySQL Password"
input_keys_array[x]="MySQL DB Prefix"
input_keys_array[s]="Shell Username"
declare -A input_values_array
help()
{
thisfilename=$(basename -- "$0")
echo "$thisfilename - Install WordPress to a specific VirtualHost."
echo ""
echo "Usage: $thisfilename [-v VirtualHost] [-r URL] [-t Site Title] [-e Admin Email] [-u Admin Username] [-p Admin Password] [-h MySQL Hostname] [-d MySQL Database] [-n MySQL Username] [-w MySQL Password] [-x MySQL DB Prefix] [-s Shell Username]"
echo ""
echo " -v VirtualHost VirtualHost that WordPress install is for, only option that is required - all others have automatic defaults."
echo " -r URL Site URL for WordPress install, defaults to VirtualHost."
echo " -t Site Title Site Title for WordPress install, defaults to VirtualHost."
echo " -e Admin Email Email address for WordPress admin user, defaults to 'Admin username'@'VirtualHost'"
echo " -u Admin Username Username for WordPress admin user, defaults to Shell Username"
echo " -p Admin Password Password for WordPress admin user, random password is generated if not set."
echo " -m MySQL Hostname MySQL Hostname, defaults to 127.0.0.1"
echo " -d MySQL Database MySQL Database, defaults to 'VirtualHost' with dots & dashes changed from symbols to words if not specified."
echo " -n MySQL Username MySQL Username, defaults to 'Shell Username'@'VirtualHost' if not specified."
echo " -w MySQL Password MySQL Hostname, random password is generated if not set."
echo " -x MySQL DB Prefix WordPress db table prefix, defaults to wp_"
echo " -s Shell Username System user that owns website files for this VirtualHost, autodetected and reset if not specified correctly."
echo " -f Force install - skips install confirmation step, for automated installs."
echo " -h Print this help."
echo ""
echo " You will be prompted to any options that were not"
echo " specified on the command line and given a chance"
echo " to confirm before performing the install unless the"
echo " -f option is specified."
exit
}
# force (-f) defaults to false
force=false
# set any options that were passed
while getopts "v:r:t:e:u:p:m:d:n:w:x:s:fh" opt; do
case "${opt}" in
h )
help
exit;;
v )
input_values_array[v]=${OPTARG}
;;
r )
input_values_array[r]=${OPTARG}
;;
t )
input_values_array[t]=${OPTARG}
;;
e )
input_values_array[e]=${OPTARG}
;;
u )
input_values_array[u]=${OPTARG}
;;
p )
input_values_array[p]=${OPTARG}
;;
m )
input_values_array[m]=${OPTARG}
;;
d )
input_values_array[d]=${OPTARG}
;;
n )
input_values_array[n]=${OPTARG}
;;
w )
input_values_array[w]=${OPTARG}
;;
x )
input_values_array[x]=${OPTARG}
;;
s )
input_values_array[s]=${OPTARG}
;;
f )
force=true
;;
\? )
echo "Invalid option: $OPTARG" 1>&2
exit 1;;
: )
echo "Invalid option: $OPTARG requires an argument" 1>&2
exit 1;;
esac
done
# v - virtualhost
function validate_v() {
if [ -d "$virtualhost_basedir/${input_values_array[v]}" ]; then
if [ -d "$virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir" ]; then
# make sure DocumentRoot is empty (except for possible index.html file)
htdocsdir_file_count=`/usr/bin/ls $virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir|grep -v index.html|wc -l`
if [ $htdocsdir_file_count -gt 0 ]; then
echo "$virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir appears to contain an existing website."
echo "Manually remove all files before attempting to install WordPress"
exit
fi
else
echo "${input_values_array[v]} is installed, but DocumentRoot for ${input_values_array[v]} does not exist."
echo "$virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir"
exit
fi
else
echo "VirtualHost ${input_values_array[v]} is not installed on this server."
echo "$virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir"
unset input_values_array[v]
fi
}
if [ -n "${input_values_array[v]}" ] ; then
validate_v
fi
if [ -z "${input_values_array[v]}" ] ; then
while [ -z "${input_values_array[v]}" ]; do
read -p "Enter the VirtualHost for WordPress install: " virtualhost
if [ -n "$virtualhost" ] ; then
input_values_array[v]=$virtualhost
validate_v
fi
done
fi
# s - Shell Username
function validate_s() {
# force shell user value, user can't override
shell_username=$(stat -c '%U' $virtualhost_basedir/${input_values_array[v]})
if [[ ${input_values_array[s]} != $shell_username ]]; then
echo "ERROR: Incorrect Shell Username, forcing value reset."
input_values_array[s]=$shell_username
fi
}
if [ -z "${input_values_array[s]}" ] ; then
input_values_array[s]=$(stat -c '%U' $virtualhost_basedir/${input_values_array[v]})
fi
if [ -n "${input_values_array[e]}" ] ; then
validate_s
fi
# u - URL
function validate_u() {
if [[ ${input_values_array[r]} != *"${input_values_array[v]}"* ]] ; then
echo "URL (${input_values_array[r]}) does not appear to be based on VirtualHost (${input_values_array[v]})"
unset input_values_array[r]
fi
}
if [ -z "${input_values_array[r]}" ] ; then
input_values_array[r]="www.${input_values_array[v]}"
fi
if [ -n "${input_values_array[r]}" ] ; then
validate_u
fi
# t - Site Title
if [ -z "${input_values_array[t]}" ] ; then
input_values_array[t]="${input_values_array[v]}"
fi
# e - Admin Email
function validate_e() {
regex="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$"
if ! [[ ${input_values_array[e]} =~ $regex ]] ; then
read -p "ERROR: Invalid email address, please re-enter: " admin_email
if [ -n "$admin_email" ] ; then
input_values_array[e]=$admin_email
validate_e
fi
fi
}
if [ -z "${input_values_array[e]}" ] ; then
input_values_array[e]="${input_values_array[s]}@${input_values_array[v]}"
fi
if [ -n "${input_values_array[e]}" ] ; then
validate_e
fi
# u - Admin Username
if [ -z "${input_values_array[u]}" ] ; then
input_values_array[u]=${input_values_array[s]}
fi
# p - Admin Password
if [ -z "${input_values_array[p]}" ] ; then
input_values_array[p]=`pwgen -1 8`
fi
# m - MySQL Hostname
if [ -z "${input_values_array[m]}" ] ; then
if [ -f "$virtualhost_basedir/${input_values_array[v]}/.my.cnf" ]; then
input_values_array[m]=`grep ^host= /srv/www/${input_values_array[v]}/.my.cnf |cut -d = -f 2`
else
input_values_array[m]="127.0.0.1"
fi
fi
# d - MySQL Database
if [ -z "${input_values_array[d]}" ] ; then
if [ -f "$virtualhost_basedir/${input_values_array[v]}/.my.cnf" ]; then
input_values_array[d]=`grep ^database= /srv/www/${input_values_array[v]}/.my.cnf |cut -d = -f 2`
else
mysql_database=${input_values_array[v]}
mysql_database=${mysql_database//./dot}
mysql_database=${mysql_database//-/dash}
input_values_array[d]=$mysql_database
fi
fi
# n - MySQL Username
if [ -z "${input_values_array[n]}" ] ; then
if [ -f "$virtualhost_basedir/${input_values_array[v]}/.my.cnf" ]; then
input_values_array[n]=`grep ^user= /srv/www/${input_values_array[v]}/.my.cnf |cut -d = -f 2`
else
input_values_array[n]="${input_values_array[s]}@${input_values_array[v]}"
fi
fi
# w - MySQL Password
if [ -z "${input_values_array[w]}" ] ; then
if [ -f "$virtualhost_basedir/${input_values_array[v]}/.my.cnf" ]; then
input_values_array[w]=`grep ^password= /srv/www/${input_values_array[v]}/.my.cnf |cut -d = -f 2`
else
input_values_array[w]=`pwgen -1 16`
fi
fi
# w - MySQL Password
function validate_w() {
mysql_username_count=`mysql -s -N -e "SELECT COUNT(*) FROM mysql.user WHERE User='${input_values_array[n]}'"`
if [[ "$mysql_username_count" -gt 0 ]]; then
mysql_password_verification=`mysql -s -A -N -e "SELECT COUNT(1) Password_is_OK FROM mysql.user WHERE user='${input_values_array[n]}' AND password=PASSWORD('${input_values_array[w]}')"`
if [[ "$mysql_password_verification" -ne 1 ]]; then
read -p "ERROR: Invalid MySQL Password for existing MySQL User ${input_values_array[n]}, please enter current password: " mysql_password
if [ -n "$mysql_password" ] ; then
input_values_array[w]=$mysql_password
restart_script
fi
fi
fi
}
# x - MySQL DB Prefix
function validate_x() {
if mysql -e "USE ${input_values_array[d]}" 2> /dev/null; then
mysql_db_prefix=`echo ${input_values_array[x]} |sed 's|_|\\\_|g'`
mysql_db_prefix_count=`mysql -s -N -e "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${input_values_array[d]}' AND TABLE_NAME LIKE '$mysql_db_prefix%'"`
if [[ "$mysql_db_prefix_count" -gt 0 ]]; then
read -p "One or more MySQL tables with DB Prefix '${input_values_array[x]}' already exist, please enter new prefix: " mysql_db_prefix
if [ -n "$mysql_db_prefix" ] ; then
input_values_array[x]=$mysql_db_prefix
restart_script
fi
fi
fi
}
if [ -z "${input_values_array[x]}" ] ; then
input_values_array[x]="wp_"
fi
# if [ -n "${input_values_array[x]}" ] ; then
# validate_x
# fi
# display confirmation
function display_confirmation() {
echo
for key in "${!input_keys_index[@]}" ; do
value=${input_keys_index[$key]}
echo "$value - ${input_keys_array[$value]}: ${input_values_array[$value]}"
done
echo
echo "i - install now with these settings"
echo "q - quit without installing"
echo
read -p "Select option to edit or install/quit: " option
echo
}
function restart_script() {
# set command line args
cli_args=
for key in "${!input_values_array[@]}" ; do
value=${input_values_array[$key]}
cli_args="$cli_args -$key '$value'"
done
# echo "${0} $cli_args"
echo
eval ${0} $cli_args
exit
}
if [[ "$force" == "false" ]]; then
display_confirmation
else
option="i"
fi
if [[ "$option" == "i" ]]; then
# validate MySQL DB Prefix
validate_x
# validate MySQL User Password
validate_w
echo
echo "Installing WP for VirtualHost ${input_values_array[v]} now..."
# create database if it doesn't already exist
if ! mysql -e "USE ${input_values_array[d]}" 2> /dev/null; then
mysqladmin create ${input_values_array[d]}
fi
# create mysql user if they don't already exist
if [[ "$mysql_username_count" -eq 0 ]]; then
mysql -e "CREATE USER '${input_values_array[n]}'@'${input_values_array[m]}' IDENTIFIED BY '${input_values_array[w]}'"
fi
# add db privileges for mysql user if no already enabled
if ! mysql --host=${input_values_array[m]} --user=${input_values_array[n]} --password=${input_values_array[w]} -e "USE ${input_values_array[d]}" 2> /dev/null; then
mysql -e "GRANT ALL PRIVILEGES ON ${input_values_array[d]}.* TO '${input_values_array[n]}'@'${input_values_array[m]}'"
mysqladmin flush-privileges
fi
# get server timezone
TIMEZONE=`cat /etc/timezone`
# switch to Shell User and install WordPress
sudo -u ${input_values_array[s]} --shell /bin/bash << EOF
cd $virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir
wp core download
wp config create --dbhost="${input_values_array[m]}" --dbname=${input_values_array[d]} --dbuser="${input_values_array[n]}" --dbpass="${input_values_array[w]}" --dbprefix="${input_values_array[x]}"
wp config set DISALLOW_FILE_EDIT true
wp config set DISABLE_WP_CRON true
wp core install --url="${input_values_array[r]}" --title="${input_values_array[v]}" --admin_user=${input_values_array[u]} --admin_password="${input_values_array[p]}" --admin_email=${input_values_array[e]}
wp option set timezone_string "$TIMEZONE"
wp option set permalink_structure "/%postname%/"
echo "apache_modules:" > wp-cli.local.yml
echo " - mod_rewrite" >> wp-cli.local.yml
wp rewrite flush --hard
rm wp-cli.local.yml
EOF
if [ -f "$virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir/index.html" ]; then
/usr/bin/rm $virtualhost_basedir/${input_values_array[v]}/$virtualhost_htdocsdir/index.html
fi
elif [[ "$option" == "q" ]]; then
echo "Quiting without installing."
elif [[ " ${input_keys_index[@]} " =~ " $option " ]]; then
read -p "Enter new value for ${input_keys_array[$option]} (${input_values_array[$option]}): " new_value
if [ -n "$new_value" ] ; then
input_values_array[$option]=$new_value
fi
restart_script
else
echo "ERROR: Invalid entry, try again."
fi