diff --git a/.travis.yml b/.travis.yml index f06e849..55e40ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ script: - sudo wo stack install --admin || sudo tail -n50 /var/log/wo/wordops.log - sudo wo site create html.net --html && sudo wo site create php.com --php && sudo wo site create mysql.com --mysql || sudo tail -n50 /var/log/wo/wordops.log + - sudo wo site create proxy.com --proxy=127.0.0.1:3000 || sudo tail -n50 /var/log/wo/wordops.log - sudo wo site create wp1.com --wp || sudo tail -n50 /var/log/wo/wordops.log - sudo wo site create wpsc1.net --wpsc && sudo wo site create wpfc1.com --wpfc || sudo tail -n50 /var/log/wo/wordops.log @@ -60,4 +61,4 @@ script: - sudo wp --allow-root --info - sudo bash -c 'nginx -T 2>&1 > /var/log/wo/nginx.log 2>&1' || sudo tail -n50 /var/log/wo/wordops.log - sudo bash -c 'tar -I pigz -cf wordops.tar.gz /var/log/wo' - - sudo curl --progress-bar --upload-file "wordops.tar.gz" https://transfer.sh/$(basename wordops.tar.gz) && echo "" || sudo echo "transfer.sh is down" + - sudo curl --progress-bar --upload-file "wordops.tar.gz" https://transfer.vtbox.net/$(basename wordops.tar.gz) && echo "" || sudo echo "transfer.sh is down" diff --git a/CHANGELOG.md b/CHANGELOG.md index 710f261..4ce7d25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,12 +14,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - IPv6 support with HTTPS - Brotli support in Nginx +- Let's Encrypt support with --proxy +- Install script handle migration from EEv3 +- load-balancing on unix socket for php-fpm +- stub_status vhost for metrics +- opcache optimization for php-fpm #### Changed - letsencrypt stack refactored with acme.sh +- letsencrypt validation with webroot folder - "--letsencrypt=subdomain" option - hardened nginx ssl_ecdh_curve +- Update phpredisadmin #### Fixed @@ -27,6 +34,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - acme.sh installation - acme.sh alias with config home variable - deb.sury.org repository gpg key +- Nginx upgrade from previous WordOps release +- Force new Nginx templates during update +- Error message about missing my.cnf file during upgrade ### v3.9.4 - 2019-03-15 diff --git a/install b/install index 55c5329..99b7dee 100644 --- a/install +++ b/install @@ -10,7 +10,7 @@ # Version 3.9.4 - 2019-03-15 # ------------------------------------------------------------------------- readonly wo_version_old="2.2.3" -readonly wo_version_new="3.9.4.1" +readonly wo_version_new="3.9.4.2" # CONTENTS # --- # 1. VARIABLES AND DECLARATIONS @@ -27,20 +27,21 @@ TPUT_FAIL=$(tput setaf 1) TPUT_INFO=$(tput setaf 7) TPUT_ECHO=$(tput setaf 4) + wo_lib_echo () { - - echo "${*}${TPUT_RESET}" + + echo "${TPUT_ECHO}${*}${TPUT_RESET}" } wo_lib_echo_info() { - + echo "${TPUT_INFO}${*}${TPUT_RESET}" } wo_lib_echo_fail() { - + echo "${TPUT_FAIL}${*}${TPUT_RESET}" } @@ -71,7 +72,7 @@ echo "" # 1- Update the apt sewers with fresh info ### wo_lib_echo "Updating apt-get repository info" -apt-get update &>> /dev/null +apt-get update -qq &>> /dev/null ### # 1- Check whether lsb_release is installed, and if not, install it @@ -91,7 +92,7 @@ readonly wo_linux_distro=$(lsb_release -is) readonly wo_distro_version=$(lsb_release -sc) readonly wo_distro_id=$(lsb_release -rs) -if [ -x /usr/loca/bin/ee ]; then +if [ -x /usr/local/bin/ee ]; then migration=1 else migration=0 @@ -116,13 +117,13 @@ fi ### # 1 - To prevent errors or unexpected behaviour, create the log and ACL it ### -if [ ! -d $wo_log_dir ]; then - +if [ ! -d "$wo_log_dir" ]; then + wo_lib_echo "Creating WordOps log directory, just a second..." - mkdir -p $wo_log_dir || wo_lib_error "Whoops - seems we are unable to create the log directory $wo_log_dir, exit status " $? - + mkdir -p "$wo_log_dir" || wo_lib_error "Whoops - seems we are unable to create the log directory $wo_log_dir, exit status " $? + touch /var/log/wo/{wordops.log,install.log} - + chmod -R 700 /var/log/wo || wo_lib_error "Whoops, there was an error setting the permissions on the WordOps log folder, exit status " $? fi @@ -131,15 +132,15 @@ fi #### wo_install_dep() { - + { if [ "$wo_linux_distro" == "Ubuntu" ]; then - DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install build-essential curl gzip python3 python3-apt python3-setuptools python3-dev sqlite3 git tar software-properties-common pigz gnupg2 fail2ban cron ccze > /dev/null 2>&1 + DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install build-essential curl gzip python3 python3-apt python3-setuptools python3-dev sqlite3 git tar software-properties-common pigz gnupg2 fail2ban cron ccze rsync tree > /dev/null 2>&1 else wget -qO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg - DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install build-essential curl gzip dirmngr sudo python3 python3-apt python3-setuptools python3-dev ca-certificates sqlite3 git tar software-properties-common pigz apt-transport-https gnupg2 fail2ban cron ccze > /dev/null 2>&1 + DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install build-essential curl gzip dirmngr sudo python3 python3-apt python3-setuptools python3-dev ca-certificates sqlite3 git tar software-properties-common pigz apt-transport-https gnupg2 fail2ban cron ccze rsync tree > /dev/null 2>&1 fi - + locale-gen en } >> /var/log/wo/install.log 2>&1 # Support PFS @@ -150,7 +151,7 @@ wo_install_dep() # Change the TLS protocols sed -i "s/ssl_protocols\ \(.*\);/ssl_protocols TLSv1.2;/" /etc/nginx/nginx.conf fi - + # Let's Encrypt .well-known folder setup if [ ! -d /var/www/html/.well-known/acme-challenge ]; then mkdir -p /var/www/html/.well-known/acme-challenge @@ -166,28 +167,27 @@ wo_sync_db() ### # Switching from EE -> WO ### - if [ -f /var/lib/ee/ee.db ]; then + if [ ! -f /var/lib/wo/dbase.db ]; then # Create the WordOps folder mkdir -p /var/lib/wo - - # Backup the nginx directory - tar -cvf - /etc/nginx /etc/ee /var/lib/ee | pigz -9 > /var/lib/wo/ee-backup.tgz - - # Copy the EasyEngine database - cp /var/lib/ee/ee.db /var/lib/wo/dbase-ee.db - - # Set the migration variable for the closing text - migration=1 - - ### - # Clean WO installation - ### - elif [ ! -d /var/lib/wo ]; then - # Create the directory holding the WordOps database - mkdir -p /var/lib/wo - - # Create an empty database for WordOps - echo "CREATE TABLE sites ( + + if [ -f /var/lib/ee/ee.db ]; then + # Copy the EasyEngine database + cp /var/lib/ee/ee.db /var/lib/wo/dbase-ee.db + + # Set the migration variable for the closing text + migration=1 + + ### + # Clean WO installation + ### + + cp /var/lib/ee/ee.db /var/lib/wo/dbase.db + rm -rf /var/lib/ee + else + + # Create an empty database for WordOps + echo "CREATE TABLE sites ( id INTEGER PRIMARY KEY AUTOINCREMENT, sitename UNIQUE, site_type CHAR, @@ -204,103 +204,97 @@ wo_sync_db() db_host VARCHAR, is_hhvm INT INT DEFAULT '0', php_version VARCHAR - );" | sqlite3 /var/lib/wo/dbase.db - - if [ -f /var/lib/wo/dbase-ee.db ]; then - # Copy the main EasyEngine database over since we are migrating - cp /var/lib/wo/dbase-ee.db /var/lib/wo/dbase.db - fi - - # Check site is enable/live or disable - cd /etc/nginx/sites-available || exit 1 - for site in $(echo \* | grep -v default); - do - if [ -f "/etc/nginx/sites-enabled/$site" ]; then - wo_site_status='1' - else - wo_site_status='0' - fi - - # Acquire information about the current nginx configuration - wo_site_current_type=$(head -n1 "/etc/nginx/sites-available/$site" | grep "NGINX CONFIGURATION" | rev | cut -d' ' -f3,4,5,6,7 | rev | cut -d ' ' -f2,3,4,5) - - # Sniff out the vhost type and cache configuration - if [ "$wo_site_current_type" = "HTML" ]; then - wo_site_current="html" - wo_site_current_cache="basic" - elif [ "$wo_site_current_type" = "PHP" ]; then - wo_site_current="php" - wo_site_current_cache="basic" - elif [ "$wo_site_current_type" = "MYSQL" ]; then - wo_site_current="mysql" - wo_site_current_cache="basic" - - # Caching types on a single WordPress installation - elif [ "$wo_site_current_type" = "WPSINGLE BASIC" ]; then - wo_site_current="wp" - wo_site_current_cache="basic" - elif [ "$wo_site_current_type" = "WPSINGLE WP SUPER CACHE" ]; then - wo_site_current="wp" - wo_site_current_cache="wpsc" - elif [ "$wo_site_current_type" = "WPSINGLE FAST CGI" ] || [ "$wo_site_current_type" = "WPSINGLE FASTCGI" ]; then - wo_site_current="wp" - wo_site_current_cache="wpfc" - - # Caching types on a single, subdirectory WordPress installation - elif [ "$wo_site_current_type" = "WPSUBDIR BASIC" ]; then - wo_site_current="wpsubdir" - wo_site_current_cache="basic" - elif [ "$wo_site_current_type" = "WPSUBDIR WP SUPER CACHE" ]; then - wo_site_current="wpsubdir" - wo_site_current_cache="wpsc" - elif [ "$wo_site_current_type" = "WPSUBDIR FAST CGI" ] || [ "$wo_site_current_type" = "WPSUBDIR FASTCGI" ]; then - wo_site_current="wpsubdir" - wo_site_current_cache="wpfc" - - # Caching types on a single, subdomain WordPress installation - elif [ "$wo_site_current_type" = "WPSUBDOMAIN BASIC" ]; then - wo_site_current="wpsubdomain" - wo_site_current_cache="basic" - elif [ "$wo_site_current_type" = "WPSUBDOMAIN WP SUPER CACHE" ]; then - wo_site_current="wpsubdomain" - wo_site_current_cache="wpsc" - elif [ "$wo_site_current_type" = "WPSUBDOMAIN FAST CGI" ] || [ "$wo_site_current_type" = "WPSUBDOMAIN FASTCGI" ]; then - wo_site_current="wpsubdomain" - wo_site_current_cache="wpfc" - fi - + );" | sqlite3 /var/lib/wo/dbase.db + + # Check site is enable/live or disable + AV_SITES="$(basename -a /etc/nginx/sites-available/* | grep -v default)" + for site in $AV_SITES; + do + if [ -h "/etc/nginx/sites-enabled/$site" ]; then + wo_site_status='1' + else + wo_site_status='0' + fi + + # Acquire information about the current nginx configuration + + wo_site_current_type=$(grep "common/" /etc/nginx/sites-available/$site | awk -F "/" '{print $2}') + + if [ "$(echo "$wo_site_current_type" | grep php)" ]; then + if [ "$(echo "$wo_site_current_type" | grep php7)" ]; then + wo_php_version="7.0" + else + wo_php_version="5.6" + fi + else + wo_php_version="" + fi + + if [ "$(echo "$wo_site_current_type" | grep redis)" ]; then + wo_site_current_cache="wpredis" + elif [ -z "$(echo "$wo_site_current_type" | grep wpsc)" ]; then + wo_site_current_cache="wpsc" + elif [ -z "$(echo "$wo_site_current_type" | grep wpfc)" ]; then + wo_site_current_cache="wpfc" + else + wo_site_current_cache="basic" + fi + + if [ "$(echo "$wo_site_current_type" | grep wp)" ]; then + if [ -z "$(echo "$wo_site_current_type" | grep wpsubdir)" ]; then + wo_site_current="wpsubdir" + elif [ -z "$(echo "$wo_site_current_type" | grep wpsudomain)" ]; then + wo_site_current="wpsubdomain" + else + wo_site_current="wp" + fi + else + if [ -z "$(echo "$wo_site_current_type" | grep location)" ]; then + wo_site_current="proxy" + elif [ -z "$(echo "$wo_site_current_type" | grep php)" ]; then + wo_site_current="html" + else + if [ -f /var/www/${site}/ee-config.php ] || [ -f /var/www/${site}/wo-config.php ]; then + wo_site_current="mysql" + else + wo_site_current="php" + fi + fi + fi + + done + wo_webroot="/var/www/$site" - + # Import the configuration into the WordOps SQLite database echo "INSERT INTO sites (sitename, site_type, cache_type, site_path, is_enabled, is_ssl, storage_fs, storage_db) VALUES (\"$site\", \"$wo_site_current\", \"$wo_site_current_cache\", \"$wo_webroot\", \"$wo_site_status\", 0, 'ext4', 'mysql');" | sqlite3 /var/lib/wo/dbase.db - done - else - wo_php_version="7.2" - wo_lib_echo "Updating WordOps Database" - echo "ALTER TABLE sites ADD COLUMN db_name varchar;" | sqlite3 /var/lib/wo/dbase.db - echo "ALTER TABLE sites ADD COLUMN db_user varchar; " | sqlite3 /var/lib/wo/dbase.db - echo "ALTER TABLE sites ADD COLUMN db_password varchar;" | sqlite3 /var/lib/wo/dbase.db - echo "ALTER TABLE sites ADD COLUMN db_host varchar;" | sqlite3 /var/lib/wo/dbase.db - echo "ALTER TABLE sites ADD COLUMN is_hhvm INT DEFAULT '0';" | sqlite3 /var/lib/wo/dbase.db - echo "ALTER TABLE sites ADD COLUMN php_version varchar DEFAULT \"$wo_php_version\";" | sqlite3 /var/lib/wo/dbase.db + + + wo_lib_echo "Updating WordOps Database" + echo "ALTER TABLE sites ADD COLUMN db_name varchar;" | sqlite3 /var/lib/wo/dbase.db + echo "ALTER TABLE sites ADD COLUMN db_user varchar; " | sqlite3 /var/lib/wo/dbase.db + echo "ALTER TABLE sites ADD COLUMN db_password varchar;" | sqlite3 /var/lib/wo/dbase.db + echo "ALTER TABLE sites ADD COLUMN db_host varchar;" | sqlite3 /var/lib/wo/dbase.db + echo "ALTER TABLE sites ADD COLUMN is_hhvm INT DEFAULT '0';" | sqlite3 /var/lib/wo/dbase.db + echo "ALTER TABLE sites ADD COLUMN php_version varchar DEFAULT \"$wo_php_version\";" | sqlite3 /var/lib/wo/dbase.db + fi + + + # echo "UPDATE sites SET php_version = REPLACE(php_version, '5.6', '7.2');" | sqlite3 /var/lib/wo/dbase.db + # echo "UPDATE sites SET php_version = REPLACE(php_version, '7.0', '7.3');" | sqlite3 /var/lib/wo/dbase.db fi - - - echo "UPDATE sites SET php_version = REPLACE(php_version, '5.6', '7.2');" | sqlite3 /var/lib/wo/dbase.db - echo "UPDATE sites SET php_version = REPLACE(php_version, '7.0', '7.3');" | sqlite3 /var/lib/wo/dbase.db - } # Once again, set the proper ACL on the WordOps configuration directory secure_wo_db() { - + # The owner is root chown -R root:root /var/lib/wo/ # Only allow access by root, block others chmod -R 600 /var/lib/wo/ - + } # Update the WP-CLI version @@ -350,13 +344,13 @@ wo_install_acme_sh() { --cert-home /etc/letsencrypt/renewal # enable auto-upgrade /etc/letsencrypt/acme.sh --config-home /etc/letsencrypt/config --upgrade --auto-upgrade - + # Let's Encrypt .well-known folder setup if [ ! -d /var/www/html/.well-known/acme-challenge ]; then mkdir -p /var/www/html/.well-known/acme-challenge chown -R www-data:www-data /var/www/html /var/www/html/.well-known fi - + } >> /var/log/wo/install.log 2>&1 fi } @@ -367,84 +361,122 @@ wo_install() { rm -rf /tmp/easyengine rm -rf /tmp/wordops - + [ -z "$wo_branch" ] && { wo_branch=master } - + git clone -b "$wo_branch" https://github.com/WordOps/WordOps.git /tmp/wordops --quiet - + cd /tmp/wordops || exit 1 } >> /var/log/wo/install.log 2>&1; python3 setup.py install - - + + } wo_upgrade_nginx() { - # chec if the package nginx-ee is installed - CHECK_NGINX_EE=$(dpkg --list | grep nginx-ee) - if [ -n "$CHECK_NGINX_EE" ]; then - { - # add new Nginx repository - if [ "$wo_linux_distro" = "Ubuntu" ]; then - echo "deb http://download.opensuse.org/repositories/home:/virtubox:/WordOps/xUbuntu_${wo_distro_id}/ /" >> /etc/apt/sources.list.d/wo-repo.list - wget -qO /tmp/nginx-wo.key "https://download.opensuse.org/repositories/home:virtubox:WordOps/xUbuntu_${wo_distro_id}/Release.key" + + { + + + # chec if the package nginx-ee is installed + CHECK_NGINX_EE=$(dpkg --list | grep nginx-ee) + CHECK_NGINX_WO=$(dpkg --list | grep nginx-wo) + CHECK_PHP72=$(dpkg --list | grep php7.2-fpm) + CHECK_PHP73=$(dpkg --list | grep php7.3-fpm) + + # add new Nginx repository + if [ "$wo_linux_distro" = "Ubuntu" ]; then + wget -qO /tmp/nginx-wo.key "https://download.opensuse.org/repositories/home:virtubox:WordOps/xUbuntu_${wo_distro_id}/Release.key" + else + if [ "$wo_distro_version" == "jessie" ]; then + wget -qO /tmp/nginx-wo.key https://download.opensuse.org/repositories/home:virtubox:WordOps/Debian_8.0/Release.key else - if [ "$wo_distro_version" == "jessie" ]; then - echo "deb http://download.opensuse.org/repositories/home:/virtubox:/WordOps/Debian_8.0/ /" >> /etc/apt/sources.list.d/wo-repo.list - wget -qO /tmp/nginx-wo.key https://download.opensuse.org/repositories/home:virtubox:WordOps/Debian_8.0/Release.key - else - echo "deb http://download.opensuse.org/repositories/home:/virtubox:/WordOps/Debian_9.0/ /" >> /etc/apt/sources.list.d/wo-repo.list - wget -qO /tmp/nginx-wo.key https://download.opensuse.org/repositories/home:virtubox:WordOps/Debian_9.0/Release.key + wget -qO /tmp/nginx-wo.key https://download.opensuse.org/repositories/home:virtubox:WordOps/Debian_9.0/Release.key + fi + fi + # import the respository key for updates + apt-key add - < /tmp/nginx-wo.key + rm -f /tmp/nginx-wo.key + sudo apt-get update + + if [ -x /usr/sbin/nginx ] ; then + CHECK_BROTLI="$(nginx -V 2>&1 | grep brotli)" + if [ -z "$CHECK_BROTLI" ]; then + + # stop nginx + service nginx stop + + # prevent apt preference to block install + [ -f /etc/apt/preferences.d/nginx-block ] && { + mv /etc/apt/preferences.d/nginx-block "$HOME/nginx-block" + } + + if [ -n "$CHECK_NGINX_EE" ]; then + # remove previous package + apt-mark unhold nginx-ee nginx-common nginx-custom + apt-get -y -qq autoremove nginx-ee nginx-common nginx-custom --purge + elif [ -n "$CHECK_NGINX_WO" ]; then + apt-mark unhold nginx-wo nginx-common nginx-custom + apt-get -y -qq autoremove nginx-wo nginx-common nginx-custom --purge fi + + + + + # install new nginx package + if [ -x /usr/local/bin/wo ]; then + # remove previous php-fpm pool configuration + if [ -n "$CHECK_PHP72" ]; then + apt-get remove php7.2-fpm -y -qq --purge + rm -f /etc/php/7.2/fpm/pool.d/* + fi + /usr/local/bin/wo stack install --nginx --php + if [ -n "$CHECK_PHP73" ]; then + apt-get remove php7.3-fpm -y -qq --purge + rm -f /etc/php/7.3/fpm/pool.d/* + /usr/local/bin/wo stack install --php73 + fi + fi + + # restore sites and configuration + /usr/bin/rsync -auz /var/lib/wo/backup/nginx/ /etc/nginx/ + + # update redis.conf headers + if [ -f /etc/nginx/common/redis.conf ]; then + sed -i "s/X-Cache /X-SRCache-Fetch-Status /g" /etc/nginx/common/redis.conf &>> /dev/null + sed -i "s/X-Cache-2 /X-SRCache-Store-Status /g" /etc/nginx/common/redis.conf &>> /dev/null + fi + + VERIFY_NGINX_CONFIG=$(nginx -t 2>&1 | grep failed) + # check if nginx -t do not return errors + if [ -z "$VERIFY_NGINX_CONFIG" ]; then + systemctl stop nginx + systemctl start nginx + else + VERIFY_NGINX_BUCKET=$(nginx -t 2>&1 | grep "server_names_hash_bucket_size") + if [ -n "$VERIFY_NGINX_BUCKET" ]; then + sed -i "s/# server_names_hash_bucket_size 64;/server_names_hash_bucket_size 64;/g" /etc/nginx/nginx.conf + fi + systemctl stop nginx + systemctl start nginx + fi + + # set back apt preference + [ -f "$HOME/nginx-block" ] && { + mv "$HOME/nginx-block" /etc/apt/preferences.d/nginx-block + } fi - # prevent apt preference to block install - [ -f /etc/apt/preferences.d/nginx-block ] && { - mv /etc/apt/preferences.d/nginx-block "$HOME/nginx-block" - } - # import the respository key for updates - apt-key add - < /tmp/nginx-wo.key - rm -f /tmp/nginx-wo.key - sudo apt-get update - # stop nginx - service nginx stop - # remove previous package - apt-mark unhold nginx-ee nginx-common nginx-custom - apt-get -y -qq autoremove nginx-ee nginx-common nginx-custom - # install new nginx package - if [ -x /usr/local/bin/wo ]; then - rm -f /etc/nginx/conf.d/{upstream.conf,redis.conf,fastcgi.conf} - rm -f /etc/nginx/*.default - /usr/local/bin/wo stack install - else - DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confnew" -y install nginx-custom nginx-wo - fi - # set back apt preference - [ -f "$HOME/nginx-block" ] && { - mv "$HOME/nginx-block" /etc/apt/preferences.d/nginx-block - } - # update nginx headers and ssl_ciphers - if [ -f /etc/nginx/nginx.conf ]; then - sed -i "s/.*X-Powered-By.*/\tadd_header X-Powered-By \"WordOps $wo_version_new\";/" /etc/nginx/nginx.conf &>> /dev/null - new_ciphers="EECDH+CHACHA20:EECDH+AESGCM:EECDH+AES" - sed -i "s/ssl_ciphers\ \(\"\|.\|'\)\(.*\)\(\"\|.\|'\);/ssl_ciphers \"$new_ciphers\";/" /etc/nginx/nginx.conf - fi - # update redis.conf headers - if [ -f /etc/nginx/common/redis.conf ]; then - sed -i "s/X-Cache /X-SRCache-Fetch-Status /g" /etc/nginx/common/redis.conf &>> /dev/null - sed -i "s/X-Cache-2 /X-SRCache-Store-Status /g" /etc/nginx/common/redis.conf &>> /dev/null - fi - systemctl enable nginx - systemctl restart nginx - } >> /var/log/wo/install.log 2>&1 - fi + fi + } >> /var/log/wo/install.log 2>&1 + } wo_update_latest() { - + if [ -f /etc/nginx/fastcgi_params ] then grep -q 'HTTP_PROXY' /etc/nginx/fastcgi_params @@ -454,7 +486,7 @@ wo_update_latest() service nginx restart &>> /dev/null fi fi - + if [ -f /etc/ImageMagick/policy.xml ] then if [ ! -f /etc/ImageMagick/patch.txt ] @@ -463,40 +495,36 @@ wo_update_latest() sed -i '//r /etc/ImageMagick/patch.txt' /etc/ImageMagick/policy.xml fi fi - + # Move ~/.my.cnf to /etc/mysql/conf.d/my.cnf - if [ ! -f /etc/mysql/conf.d/my.cnf ] - then + if [ ! -f /etc/mysql/conf.d/my.cnf ]; then # create conf.d folder if not exist - if [ ! -d /etc/mysql/conf.d ]; then + [ ! -d /etc/mysql/conf.d ] && { mkdir -p /etc/mysql/conf.d chmod 755 /etc/mysql/conf.d + } + if [ -f $HOME/.my.cnf ]; then + cp -f $HOME/.my.cnf /etc/mysql/conf.d/my.cnf + chmod 600 /etc/mysql/conf.d/my.cnf + + elif [ -f /root/.my.cnf ]; then + cp -f /root/.my.cnf /etc/mysql/conf.d/my.cnf + chmod 600 /etc/mysql/conf.d/my.cnf fi - if [ -d /etc/mysql/conf.d ] - then - if [ -f ~/.my.cnf ] - then - cp ~/.my.cnf /etc/mysql/conf.d/my.cnf &>> /dev/null - chmod 600 /etc/mysql/conf.d/my.cnf - else - if [ -f /root/.my.cnf ] - then - cp /root/.my.cnf /etc/mysql/conf.d/my.cnf &>> /dev/null - chmod 600 /etc/mysql/conf.d/my.cnf - else - wo_lib_echo_fail ".my.cnf cannot be located in your current user or root folder..." - fi - fi + else + if [ ! -f /root/.my.cnf ]; then + cp /etc/mysql/conf.d/my.cnf /root/.my.cnf + chmod 600 /root/.my.cnf fi fi - + # Fix WordPress example.html issue # Ref: http://wptavern.com/xss-vulnerability-in-jetpack-and-the-twenty-fifteen-default-theme-affects-millions-of-wordpress-users dpkg --get-selections | grep -v deinstall | grep nginx &>> /dev/null if [ $? -eq 0 ]; then cp /usr/lib/wo/templates/locations.mustache /etc/nginx/common/locations-php72.conf &>> /dev/null fi - + # Fix Redis-server security issue # http://redis.io/topics/security if [ -f /etc/redis/redis.conf ]; then @@ -506,7 +534,7 @@ wo_update_latest() service redis-server restart &>> /dev/null fi fi - + } # Do git intialisation @@ -551,13 +579,19 @@ if [ -x /usr/local/bin/wo ]; then if [[ $? -ne 0 ]];then read -p "Update WordOps to $wo_version_new (y/n): " wo_ans if [ "$wo_ans" = "y" ] || [ "$wo_ans" = "Y" ]; then + wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log wo_install_dep | tee -ai $wo_install_log + wo_lib_echo "Syncing WO database" | tee -ai $wo_install_log wo_sync_db >> $wo_install_log 2>&1 secure_wo_db | tee -ai $wo_install_log + wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log wo_install | tee -ai $wo_install_log + wo_lib_echo "Upgrading Nginx" | tee -ai $wo_install_log wo_upgrade_nginx | tee -ai $wo_install_log wo_update_latest | tee -ai $wo_install_log + wo_lib_echo "Installing acme.sh" | tee -ai $wo_install_log wo_install_acme_sh | tee -ai $wo_install_log + wo_lib_echo "Running post-install steps " | tee -ai $wo_install_log wo_git_init | tee -ai $wo_install_log wo_update_wp_cli | tee -ai $wo_install_log else @@ -569,25 +603,25 @@ if [ -x /usr/local/bin/wo ]; then else # 2 - Migration from EEv3 if [ -x /usr/local/bin/ee ]; then - ee -v 2>&1 | grep $wo_version_new &>> /dev/null - if [[ $? -ne 0 ]];then - read -p "Update WordOps to $wo_version_new (y/n): " wo_ans - if [ "$wo_ans" = "y" ] || [ "$wo_ans" = "Y" ]; then - wo_install_dep | tee -ai $wo_install_log - wo_sync_db >> $wo_install_log 2>&1 - secure_wo_db | tee -ai $wo_install_log - wo_install | tee -ai $wo_install_log - wo_upgrade_nginx | tee -ai $wo_install_log - wo_update_latest | tee -ai $wo_install_log - wo_install_acme_sh | tee -ai $wo_install_log - wo_git_init | tee -ai $wo_install_log - service nginx reload &>> /dev/null - wo_update_wp_cli | tee -ai $wo_install_log - else - wo_lib_error "Not updating WordOps to $wo_version_new, exit status = " 1 - fi + read -p "Migrate from EasyEngine to WordOps (y/n): " wo_ans + if [ "$wo_ans" = "y" ] || [ "$wo_ans" = "Y" ]; then + wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log + wo_install_dep | tee -ai $wo_install_log + wo_lib_echo "Syncing WO database" | tee -ai $wo_install_log + wo_sync_db >> $wo_install_log 2>&1 + secure_wo_db | tee -ai $wo_install_log + wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log + wo_install | tee -ai $wo_install_log + wo_lib_echo "Upgrading Nginx" | tee -ai $wo_install_log + wo_upgrade_nginx | tee -ai $wo_install_log + wo_update_latest | tee -ai $wo_install_log + wo_lib_echo "Installing acme.sh" | tee -ai $wo_install_log + wo_install_acme_sh | tee -ai $wo_install_log + wo_lib_echo "Running post-install steps " | tee -ai $wo_install_log + wo_git_init | tee -ai $wo_install_log + wo_update_wp_cli | tee -ai $wo_install_log else - wo_lib_error "You already have WordOps $wo_version_new, exit status = " 1 + wo_lib_error "Not installing WordOps, exit status = " 1 fi else # 3 - Fresh WO setup @@ -595,10 +629,11 @@ else wo_install_dep | tee -ai $wo_install_log wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log wo_install | tee -ai $wo_install_log + wo_lib_echo "Installing acme.sh" | tee -ai $wo_install_log + wo_install_acme_sh | tee -ai $wo_install_log wo_lib_echo "Running post-install steps " | tee -ai $wo_install_log secure_wo_db | tee -ai $wo_install_log wo_git_init | tee -ai $wo_install_log - wo_install_acme_sh | tee -ai $wo_install_log wo_update_wp_cli | tee -ai $wo_install_log fi fi diff --git a/wo/cli/plugins/clean.py b/wo/cli/plugins/clean.py index b94e5f8..6400c13 100644 --- a/wo/cli/plugins/clean.py +++ b/wo/cli/plugins/clean.py @@ -19,7 +19,8 @@ class WOCleanController(CementBaseController): label = 'clean' stacked_on = 'base' stacked_type = 'nested' - description = ('Clean NGINX FastCGI cache, Opcache, Memcached, Redis Cache') + description = ( + 'Clean NGINX FastCGI cache, Opcache, Memcached, Redis Cache') arguments = [ (['--all'], dict(help='Clean all cache', action='store_true')), @@ -31,7 +32,7 @@ class WOCleanController(CementBaseController): dict(help='Clean OpCache', action='store_true')), (['--redis'], dict(help='Clean Redis Cache', action='store_true')), - ] + ] usage = "wo clean [options]" @expose(hide=True) @@ -90,13 +91,13 @@ class WOCleanController(CementBaseController): wp = urllib.request.urlopen(" https://127.0.0.1:22222/cache" "/opcache/opgui.php?page=reset").read() except Exception as e: - Log.debug(self, "{0}".format(e)) - Log.debug(self, "Unable hit url, " - " https://127.0.0.1:22222/cache/opcache/opgui.php?page=reset," - " please check you have admin tools installed") - Log.debug(self, "please check you have admin tools installed," - " or install them with `wo stack install --admin`") - Log.error(self, "Unable to clean opcache", False) + Log.debug(self, "{0}".format(e)) + Log.debug(self, "Unable hit url, " + " https://127.0.0.1:22222/cache/opcache/opgui.php?page=reset," + " please check you have admin tools installed") + Log.debug(self, "please check you have admin tools installed," + " or install them with `wo stack install --admin`") + Log.error(self, "Unable to clean opcache", False) def load(app): diff --git a/wo/cli/plugins/info.py b/wo/cli/plugins/info.py index 16309a3..467334a 100644 --- a/wo/cli/plugins/info.py +++ b/wo/cli/plugins/info.py @@ -41,9 +41,9 @@ class WOInfoController(CementBaseController): @expose(hide=True) def info_nginx(self): """Display Nginx information""" - version = os.popen("nginx -v 2>&1 | cut -d':' -f2 | cut -d' ' -f2 | " - "cut -d'/' -f2 | tr -d '\n'").read() - allow = os.popen("grep ^allow /etc/nginx/common/acl.conf | " + version = os.popen("nginx -v 2 > &1 | awk - F '/' '{print $2}' | '" + "awk -F ' ' '{print $1}'").read() + allow = os.popen("grep allow /etc/nginx/common/acl.conf | " "cut -d' ' -f2 | cut -d';' -f1 | tr '\n' ' '").read() nc = NginxConfig() nc.loadf('/etc/nginx/nginx.conf') @@ -242,8 +242,8 @@ class WOInfoController(CementBaseController): @expose(hide=True) def default(self): """default function for info""" - if (not self.app.pargs.nginx and not self.app.pargs.php - and not self.app.pargs.mysql and not self.app.pargs.php73): + if (not self.app.pargs.nginx and not self.app.pargs.php and + not self.app.pargs.mysql and not self.app.pargs.php73): self.app.pargs.nginx = True self.app.pargs.php = True self.app.pargs.mysql = True @@ -251,7 +251,8 @@ class WOInfoController(CementBaseController): self.app.pargs.php73 = True if self.app.pargs.nginx: - if WOAptGet.is_installed(self, 'nginx-custom') or WOAptGet.is_installed(self, 'nginx-common'): + if (WOAptGet.is_installed(self, 'nginx-custom') or + WOAptGet.is_installed(self, 'nginx-common')): self.info_nginx() else: Log.error(self, "Nginx is not installed") diff --git a/wo/cli/plugins/log.py b/wo/cli/plugins/log.py index 14579e9..5f7436f 100644 --- a/wo/cli/plugins/log.py +++ b/wo/cli/plugins/log.py @@ -57,7 +57,7 @@ class WOLogShowController(CementBaseController): action='store_true')), (['site_name'], dict(help='Website Name', nargs='?', default=None)) - ] + ] usage = "wo log show [] [options]" @expose(hide=True) @@ -68,17 +68,17 @@ class WOLogShowController(CementBaseController): if self.app.pargs.php: self.app.pargs.nginx = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (not self.app.pargs.site_name)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (not self.app.pargs.site_name)): self.app.pargs.nginx = True self.app.pargs.fpm = True self.app.pargs.mysql = True self.app.pargs.access = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (self.app.pargs.site_name)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (self.app.pargs.site_name)): self.app.pargs.nginx = True self.app.pargs.wp = True self.app.pargs.access = True @@ -185,7 +185,7 @@ class WOLogResetController(CementBaseController): action='store_true')), (['site_name'], dict(help='Website Name', nargs='?', default=None)) - ] + ] usage = "wo log reset [] [options]" @expose(hide=True) @@ -196,20 +196,20 @@ class WOLogResetController(CementBaseController): if self.app.pargs.php: self.app.pargs.nginx = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (not self.app.pargs.site_name) - and (not self.app.pargs.slow_log_db)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (not self.app.pargs.site_name) and + (not self.app.pargs.slow_log_db)): self.app.pargs.nginx = True self.app.pargs.fpm = True self.app.pargs.mysql = True self.app.pargs.access = True self.app.pargs.slow_log_db = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (self.app.pargs.site_name) - and (not self.app.pargs.slow-log-db)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (self.app.pargs.site_name) and + (not self.app.pargs.slow-log-db)): self.app.pargs.nginx = True self.app.pargs.wp = True self.app.pargs.access = True @@ -324,7 +324,7 @@ class WOLogGzipController(CementBaseController): action='store_true')), (['site_name'], dict(help='Website Name', nargs='?', default=None)) - ] + ] usage = "wo log gzip [] [options]" @expose(hide=True) @@ -335,17 +335,17 @@ class WOLogGzipController(CementBaseController): if self.app.pargs.php: self.app.pargs.nginx = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (not self.app.pargs.site_name)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (not self.app.pargs.site_name)): self.app.pargs.nginx = True self.app.pargs.fpm = True self.app.pargs.mysql = True self.app.pargs.access = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (self.app.pargs.site_name)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (self.app.pargs.site_name)): self.app.pargs.nginx = True self.app.pargs.wp = True self.app.pargs.access = True @@ -461,7 +461,7 @@ class WOLogMailController(CementBaseController): (['--to'], dict(help='Email addresses to send log files', action='append', dest='to', nargs=1, required=True)), - ] + ] usage = "wo log mail [] [options]" @expose(hide=True) @@ -472,17 +472,17 @@ class WOLogMailController(CementBaseController): if self.app.pargs.php: self.app.pargs.nginx = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (not self.app.pargs.site_name)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (not self.app.pargs.site_name)): self.app.pargs.nginx = True self.app.pargs.fpm = True self.app.pargs.mysql = True self.app.pargs.access = True - if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) - and (not self.app.pargs.mysql) and (not self.app.pargs.access) - and (not self.app.pargs.wp) and (self.app.pargs.site_name)): + if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm) and + (not self.app.pargs.mysql) and (not self.app.pargs.access) and + (not self.app.pargs.wp) and (self.app.pargs.site_name)): self.app.pargs.nginx = True self.app.pargs.wp = True self.app.pargs.access = True diff --git a/wo/cli/plugins/secure.py b/wo/cli/plugins/secure.py index 8050ade..ae2b9eb 100644 --- a/wo/cli/plugins/secure.py +++ b/wo/cli/plugins/secure.py @@ -38,19 +38,19 @@ class WOSecureController(CementBaseController): @expose(hide=True) def default(self): - if self.app.pargs.auth: - self.secure_auth() - if self.app.pargs.port: - self.secure_port() - if self.app.pargs.ip: - self.secure_ip() + if self.app.pargs.auth: + self.secure_auth() + if self.app.pargs.port: + self.secure_port() + if self.app.pargs.ip: + self.secure_ip() @expose(hide=True) def secure_auth(self): """This function secures authentication""" passwd = ''.join([random.choice - (string.ascii_letters + string.digits) - for n in range(6)]) + (string.ascii_letters + string.digits) + for n in range(6)]) if not self.app.pargs.user_input: username = input("Provide HTTP authentication user " "name [{0}] :".format(WOVariables.wo_user)) @@ -125,7 +125,7 @@ class WOSecureController(CementBaseController): user_ip = ['127.0.0.1'] for ip_addr in user_ip: if not ("exist_ip_address "+ip_addr in open('/etc/nginx/common/' - 'acl.conf').read()): + 'acl.conf').read()): WOShellExec.cmd_exec(self, "sed -i " "\"/deny/i allow {whitelist_address}\;\"" " /etc/nginx/common/acl.conf" diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index 5794b5d..92dcf5f 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -326,7 +326,8 @@ class WOSiteCreateController(CementBaseController): dict(help="create WordPress single/multi site with wpsc cache", action='store_true')), (['--wpredis'], - dict(help="create WordPress single/multi site with redis cache", + dict(help="create WordPress single/multi site " + "with redis cache", action='store_true')), (['-le', '--letsencrypt'], dict(help="configure letsencrypt ssl for the site", @@ -342,8 +343,9 @@ class WOSiteCreateController(CementBaseController): dest='wppass')), (['--proxy'], dict(help="create proxy for site", nargs='+')), - (['--vhostonly'], - dict(help="only create vhost and database without installing WordPress", nargs='+')), + (['--vhostonly'], dict(help="only create vhost and database " + "without installing WordPress", + action='store_true')), (['--experimental'], dict(help="Enable Experimental packages without prompt", action='store_true')), @@ -406,7 +408,7 @@ class WOSiteCreateController(CementBaseController): data['proxy'] = True data['host'] = host data['port'] = port - wo_site_webroot = "" + wo_site_webroot = WOVariables.wo_webroot + wo_domain if self.app.pargs.php73: data = dict(site_name=wo_domain, www_domain=wo_www_domain, @@ -461,10 +463,10 @@ class WOSiteCreateController(CementBaseController): data['basic'] = True if (cache == 'wpredis'): - cache = 'wpredis' - data['wpredis'] = True - data['basic'] = False - self.app.pargs.wpredis = True + cache = 'wpredis' + data['wpredis'] = True + data['basic'] = False + self.app.pargs.wpredis = True # Check rerequired packages are installed or not wo_auth = site_package_check(self, stype) @@ -1097,7 +1099,7 @@ class WOSiteUpdateController(CementBaseController): else: data['letsencrypt'] = True letsencrypt = True - wildcard = True + wildcard = False if pargs.wpredis and data['currcachetype'] != 'wpredis': data['wpredis'] = True diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index 98d20e2..e84226c 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -107,9 +107,6 @@ def setupdomain(self, data): '/etc/nginx/sites-enabled/{0}' .format(wo_domain_name)]) - if 'proxy' in data.keys() and data['proxy']: - return - # Creating htdocs & logs directory Log.info(self, "Setting up webroot \t\t", end='') try: @@ -297,17 +294,15 @@ def setupwordpress(self, data): if not data['multisite']: Log.debug(self, "Generating wp-config for WordPress Single site") Log.debug(self, "bash -c \"php {0} --allow-root " - .format(WOVariables.wo_wpcli_path) - + "core config " - + "--dbname=\'{0}\' --dbprefix=\'{1}\' --dbuser=\'{2}\' " + .format(WOVariables.wo_wpcli_path) + + "core config " + + "--dbname=\'{0}\' --dbprefix=\'{1}\' --dbuser=\'{2}\' " "--dbhost=\'{3}\' " .format(data['wo_db_name'], wo_wp_prefix, - data['wo_db_user'], data['wo_db_host']) - + "--dbpass=\'{0}\' " + data['wo_db_user'], data['wo_db_host']) + + "--dbpass=\'{0}\' " "--extra-php<