Skip to content

Instantly share code, notes, and snippets.

@witzawitz
Last active June 27, 2017 16:18
Show Gist options
  • Save witzawitz/8587fcca47415894d943bf5c1029278c to your computer and use it in GitHub Desktop.
Save witzawitz/8587fcca47415894d943bf5c1029278c to your computer and use it in GitHub Desktop.
VPS install script
#!/bin/bash
source config.sh
function error {
echo -e "\033[0;31m$1\033[0m"
}
function info {
echo -e "\033[0;36m$1\033[0m"
}
function message {
echo -e "\033[0;40m$1\033[0m"
}
function success {
echo -e "\033[0;32m$1\033[0m"
}
function warning {
echo -e "\033[0;33m$1\033[0m"
}
function apache_user {
users=(_www apache httpd www-data)
for user in ${users[*]}; do
result=$(groups $user 2>&1)
if [[ ! $result =~ "no such user" ]]; then
echo $user
return
fi
done
while [ 1 ]; do
read -r -p "Enter apache username: " user
result=$(groups $user 2>&1)
if [[ ! "$result" =~ "no such user" ]]; then
echo $user
return
fi
done
}
function check_php_ini {
IFS=' '
read -a ini<<<"${1}"
echo ${1}
echo ${#ini[@]}
if [[ ${#ini[@]} == 2 ]]; then
echo 2
fi
}
function compare_php_ini {
m1=$(convert_to_bytes $1)
m2=$(convert_to_bytes $3)
case $2 in
'>') if [[ $m1 > $m2 ]]; then echo 0;
else echo "more than"; fi
return
;;
'>=') if [[ "$m1" -ge "$m2" ]]; then echo 0;
else echo "at least"; fi
return
;;
'<') if [[ $m1 < $m2 ]]; then echo 0;
else echo "less then"; fi
return
;;
'<=') if [[ "$m1" -le "$m2" ]]; then echo 0;
else echo "less or equal"; fi
return
;;
'==') if [[ "$m1" -eq "$m2" ]]; then echo 0;
else echo "equal"; fi
return
;;
esac
echo "unknown operator"
return
}
function compare_versions {
IFS='.'
read -a version1<<<"${1}"
read -a version2<<<"${2}"
for ((i=0; i<3; i++)); do
if [[ ${version1[$i]}>${version2[$i]} ]]; then
echo 1
return
else
if [[ ${version1[$i]}<${version2[$i]} ]]; then
echo 2
return
fi
fi
done
echo 0
return
}
function convert_to_bytes {
n=`expr ${#1} - 1`
if [[ $n > 0 ]]; then
# Last character of string.
m=$(echo -n $1 | tail -c 1)
# Other symbols
f=$(echo -n $1 | head -c $n)
case $m in
K) echo $((f << 10))
return
;;
M) echo $((f << 20))
return
;;
G) echo $((f << 30))
return
;;
T) echo $((f << 40))
return
;;
esac
fi
echo $1
return
}
function db_load_config {
db_name=""
db_username=""
db_password=""
db_host="localhost"
IFS=$'\t\r\n'
for line in $(cat $1); do
if [[ $line =~ "dbname=" ]]; then
db_name=$(echo $line | sed "s/.*dbname//g" | sed "s/;.*//g" | sed "s/[\"',= ]//g")
fi
if [[ $line =~ "username" ]]; then
db_username=$(echo $line | sed "s/['\"]username['\"] *=> *//" | sed "s/[\"', ]//g")
fi
if [[ $line =~ "password" ]]; then
db_password=$(echo $line | sed "s/['\"]password['\"] *=> *//" | sed "s/[\"', ]//g")
fi
if [[ $line =~ "host=" ]]; then
db_host=$(echo $line | sed "s/.*host=//g" | sed "s/;.*//g" | sed "s/[\"',= ]//g")
fi
done
echo "$db_username|$db_password|$db_name|$db_host"
}
current_dir=$(pwd)
cd ..
dir=$(pwd)
cd $current_dir
# Check if current user is not root.
info "Checking permissions."
if [ "$(id -u)" == "0" ]; then
error "⚡️ Do not run this script as root."
exit
fi
echo "Current user is $(whoami)."
# Requirements.
IFS=' '
if [[ " ${config[*]} " == *" requirements "* ]]; then
info "Checking requirements."
reqOk=1
for item in ${req_command[*]}; do
if hash $item 2>/dev/null; then
echo "✅ $item"
else
error "⚡️ You should install $item before continue."
reqOk=0
fi
done
if (( reqOk == 0 )); then exit; fi
fi
php_ini_command=""
# Ask for other php.ini file
php_ini_file_current=$(php -i | grep /php.ini | awk -F ' => ' '{print $2}')
read -e -p "Current path to php.ini config: $php_ini_file_current. If you want to change this path please enter: " php_ini_file
if [ ! -z "$php_ini_file" ]; then
php_ini_command=" -c $php_ini_file "
fi
# Check PHP version.
IFS=' '
if [[ " ${config[*]} " == *" php-version "* ]]; then
info "Checking PHP version."
php_version_sys=$(php $php_ini_command -v | grep -m 1 -o '[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+')
phpOk=$(compare_versions $php_version_sys $php_version)
if [[ $phpOk == '2' ]]; then
error "⚡️ PHP required version is $php_version. Current version is $php_version_sys."
exit
fi
echo "✅ PHP version."
fi
# PHP extensions
IFS=' '
if [[ " ${config[*]} " == *" php-extensions "* ]]; then
info "Checking PHP extensions."
phpextOk=1
for item in ${php_extensions[*]}; do
if [[ $(php $php_ini_command -m | grep -i $item) == $item ]]; then
echo "✅ php-$item"
else
error "⚡️ You should install php-$item before continue."
phpextOk=0
fi
done
if ((phpextOk == 0)); then exit; fi
fi
# PHP ini
IFS=' '
if [[ " ${config[*]} " == *" php-ini "* ]]; then
info "Checking PHP ini settings."
phpiniOk=1
IFS='*'
for ini_item in ${php_ini[*]}; do
IFS=' '
read -a ini<<<"${ini_item}"
n=${#ini[@]}
if [[ ($n < 2) || (($n > 2) && ($((n%2)) == 0)) ]]; then
error "⚡️ Invalid php ini config for ${ini[0]}."
phpiniOk=0
else
value=$(php $php_ini_command -i | grep ${ini[0]} | awk -F ' => ' '{print $2}')
# Equals
if [[ $n == 2 ]]; then
if [[ $value == ${ini[1]} ]]; then
echo "✅ ${ini[0]}"
else
error "⚡️ You should set ${ini[0]} ini value equal ${ini[1]}."
phpiniOk=0
fi
else
iniOk=1
msg=''
for ((i=1; i<$n; i+=2)); do
k=${ini[$i]} # operator
v=${ini[$i+1]} # value
result=$(compare_php_ini $value $k $v)
msg="$msg (or) $result $v"
if [[ "$result" == "0" ]]; then
iniOk=1
else
iniOk=0
fi
done
if ((iniOk == 0)); then
error "⚡️ ${ini[0]} should be$msg. Current value is $value."
phpiniOk=0
else
echo "✅ ${ini[0]}"
fi
fi
fi
done
if ((phpiniOk == 0)); then exit; fi
fi
# Check composer plugins
IFS=' '
if [[ " ${config[*]} " == *" composer "* ]]; then
info "Checking composer plugins."
for item in ${composer_plugins[*]}; do
if [[ $(composer global show | grep -o $item) == $item ]]; then
echo "✅ $item"
else
warning "Installing $item"
composer global require $item
fi
done
# Composer
info "Installing composer."
cd $dir
composer update $*
fi
# DB config
IFS=' '
if [[ " ${config[*]} " == *" db "* ]]; then
info "Configuring DB."
while true; do
db_overwrite="n"
if [ -f $dir/$db_config_to ]; then
read -p "We found existing configuration for database. Should we overwrite it? 'y' for YES, any other key for NO. [y/n]: " db_overwrite
else
db_overwrite="y"
fi
if [[ $db_overwrite == "y" ]]; then
# Promt for MySQL credential
read -p "Do you prefer manually create MySQL database and user or should we do it for you (in that case you should provide the MySQL root password)? Hit 'm' for manually, any other key for auto creation, then press Enter. [m/a]: " db_way
if [[ $db_way == "m" ]]; then
read -p "Database username: " db_username
read -s -p "Database password: " db_password
echo ""
read -p "Database name: " db_name
else
read -s -p "MySQL root password: " db_root_password
echo ""
if [[ $db_root_password == "" ]]; then
mysql_command="sudo mysql -uroot "
else
mysql_command="sudo mysql -uroot -p$db_root_password "
fi
db_password=$(dd if=/dev/urandom bs=1 count=18 2>/dev/null | base64 | rev | cut -b 2- | rev | sed 's/[^0-9a-zA-Z]*//g' | head -c 16)
# Building command for setting and restoring parameters for password generation.
var_names=(
validate_password_length
validate_password_mixed_case_count
validate_password_number_count
validate_password_special_char_count
)
set_variables=""
restore_variables=""
for name in ${var_names[*]}; do
value=$($mysql_command -s -r -e "SELECT @@$name;" 2>&1 | tail -n 1)
if [[ "$value" != *"ERROR"* ]]; then
set_variables="$set_variables SET GLOBAL $name=0;"
restore_variables="$restore_variables SET GLOBAL $name=$value;"
fi
done
$($mysql_command -e "$set_variables CREATE USER '$db_username'@'localhost' IDENTIFIED BY '$db_password'; CREATE DATABASE $db_name; GRANT ALL PRIVILEGES ON $db_name.* TO '$db_username'@'localhost'; FLUSH PRIVILEGES; $restore_variables")
fi
# Write config to file
db_cfg_dir=$(dirname $db_config_from)
if [ -w $db_cfg_dir ]; then
db_cfg_command=""
else
db_cfg_command="sudo "
fi
IFS=$'\r\n'
db_cfg_lines=$(cat $dir/$db_config_from)
echo -n "" > $dir/$db_config_to
for line in $db_cfg_lines; do
t=$line
if [[ $line =~ "dbname=" ]]; then
t=$(echo $line | sed "s/dbname=[a-zA-Z0-9_]*/dbname=$db_name/")
else
if [[ $line =~ "username" ]]; then
t=$(echo $line | sed "s/['\"]username['\"] *=> *'[a-zA-Z0-9_]*'/'username' => '$db_username'/")
else
if [[ $line =~ "password" ]]; then
t=$(echo $line | sed "s/['\"]password['\"] *=> *'[a-zA-Z0-9_]*'/'password' => '$db_password'/")
fi
fi
fi
echo $t >> $dir/$db_config_to
done
fi
# Read config from file.
db_loaded_config=$(db_load_config $dir/$db_config_to)
IFS='|'
read -a db_cfg_loaded_array<<<"${db_loaded_config}"
db_username=${db_cfg_loaded_array[0]}
db_password=${db_cfg_loaded_array[1]}
db_name=${db_cfg_loaded_array[2]}
db_host=${db_cfg_loaded_array[3]}
#Testing connection.
db_test=$(mysql -h$db_host -u$db_username -p$db_password -e"exit" $db_name 2>&1 | grep ERROR)
echo $db_test
if [[ "$db_test" == "" ]]; then
break
else
db_mysql=$(pgrep mysql | wc -l | sed 's/ //g')
if [[ "$db_mysql" == "0" ]]; then
error "⚡️ MySQL server is not running."
else
db_connect=$(mysql -h$db_host -u$db_username -p$db_password -e"exit" 2>&1 | grep ERROR)
if [[ "$db_connect" == "" ]]; then
error "⚡️ Connection with provided username and password is ok but we cannot access to database $db_name."
else
error "⚡️ Cannot connect to MySQL with provided username and password."
fi
fi
fi
done
# Check sql_mode variable.
sql_mode=$(mysql -h$db_host -u$db_username -p$db_password -e"select @@sql_mode;" -s -N 2>/dev/null)
if [[ "$sql_mode" =~ "ONLY_FULL_GROUP_BY" ]]; then
error "⚡️ You should remove ONLY_FULL_GROUP_BY from @@sql_mode variable."
exit
fi
fi
# Configuring Sphinx - just copy files
IFS=' '
if [[ " ${config[*]} " == *" sphnix "* ]]; then
info "Configuring Sphinx"
if [ ! -f $dir/$sphinx_config_conf_to ]; then
cp $dir/$sphinx_config_conf_from $dir/$sphinx_config_conf_to
fi
if [ ! -f $dir/$sphinx_config_php_to ]; then
cp $dir/$sphinx_config_php_from $dir/$sphinx_config_php_to
fi
fi
# Creating dirs
IFS=' '
if [[ " ${config[*]} " == *" directories "* ]]; then
info "Creating directories"
user="$(apache_user)"
IFS=' '
dir_s="${dirs[*]// /}"
cd $dir
sudo mkdir -p $dir_s
sudo chown -R $user $dir_s
cd $current_dir
# Creating symlinks
n=${#symlinks[@]}
if [[ $((n%2)) != 0 ]];then
error "⚡️ Wrong config for symlinks."
exit
fi
for ((i=0; i<$n; i+=2)); do
to=${symlinks[$i+1]}
if [ ! -L "$dir/$to" ]; then
cd $dir
symlink_dir=$(dirname $to)
symlink_base=$(basename $to)
symlink_level=$(($(grep -o "/" <<< "$symlink_dir" | wc -l)+1))
symlink_level_up=`perl -E "say '../' x $symlink_level"`
if [ ! -f $symlink_dir ]; then
mkdir -p $symlink_dir
fi
cd $symlink_dir
echo -n "Linking ${symlinks[$i]} to $to ... "
sudo ln -s $symlink_level_up${symlinks[$i]} $symlink_base
echo "done."
fi
done
cd $current_dir
fi
# Migrations
IFS=' '
if [[ " ${config[*]} " == *" migrations "* ]]; then
info "Running migrations."
cd "$dir/console"
sudo php yii migrate
fi
# Assets
IFS=' '
if [[ " ${config[*]} " == *" assets "* ]]; then
info "Running assets"
IFS=$'\n'
n=${#assets[*]}
asset_cfg_loaded=false
asset_block=()
for (( i=0; i<$n; i++ )); do
if [[ $asset_cfg_loaded == false ]]; then
if [[ (${assets[$i]} == '-') || ($i == $((n-1))) ]]; then
asset_cfg_loaded=true
else
asset_block+=(${assets[$i]})
fi
fi
if [[ $asset_cfg_loaded == true ]]; then
asset_dir=${asset_block[0]}
message "--- $asset_dir"
cd $dir/$asset_dir
for (( j=1; j<${#asset_block[*]}; j++)); do
eval ${asset_block[$j]}
done
asset_cfg_loaded=false
asset_block=()
fi
done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment