diff --git a/CHANGELOG.md b/CHANGELOG.md index c6074c1..bda29eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +### v3.9.8.5 - 2019-08-30 + +#### Changed + +- updated OpCache Control Panel to v0.2.0 + +#### Fixed + +- Fix Netdata install on Raspbian 9/10 +- `wo stack remove/purge` confirmation +- Nginx error after removing a SSL certificate used to secure WordOps backend +- `wo stack install --all` +- ProFTPd fail2ban rules set twice if removed and reinstalled +- `wo site update` + ### v3.9.8.4 - 2019-08-28 #### Added diff --git a/README.md b/README.md index 11642d9..a167a62 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,10 @@ Apps & Tools shipped with WordOps : - [MySQLTuner](https://github.com/major/MySQLTuner-perl/) - [Webgrind](https://github.com/jokkedk/webgrind) - [MySQLTuner](https://github.com/major/MySQLTuner-perl) +- [Fail2Ban](https://github.com/fail2ban/fail2ban) +- [ClamAV](https://github.com/Cisco-Talos/clamav-devel) +- [cheat.sh](https://github.com/chubin/cheat.sh) +- [ProFTPd](https://github.com/proftpd/proftpd) ## License diff --git a/config/bash_completion.d/wo_auto.rc b/config/bash_completion.d/wo_auto.rc index 3520216..d7e3cc9 100644 --- a/config/bash_completion.d/wo_auto.rc +++ b/config/bash_completion.d/wo_auto.rc @@ -159,13 +159,13 @@ _wo_complete() "create") COMPREPLY=( $(compgen \ - -W "--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --proxy= --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le -le=subdomain -le=wildcard --dns --dns=dns_cf --dns=dns_do" \ + -W "--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --proxy= --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard -le=wildcard --dns --dns=dns_cf --dns=dns_do" \ -- $cur) ) ;; "update") COMPREPLY=( $(compgen \ - -W "--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew --letsencrypt=clean -le -le=subdomain -le=wildcard --dns --dns=dns_cf --dns=dns_do" \ + -W "--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=off --letsencrypt=clean -le=wildcard --dns --dns=dns_cf --dns=dns_do" \ -- $cur) ) ;; "delete") @@ -211,9 +211,9 @@ _wo_complete() "--wp") if [ ${COMP_WORDS[1]} != "debug" ]; then if [ ${COMP_WORDS[2]} == "create" ]; then - retlist="--wp --wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce --letsencrypt -le --letsencrypt=subdomain --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do --php73" + retlist="--wp --wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce --letsencrypt -le --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do --php73" elif [ ${COMP_WORDS[2]} == "update" ]; then - retlist="--wp --wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard --letsencrypt=off --letsencrypt=renew --letsencrypt=clean -le -le=off -le=wildcard --dns --dns=dns_cf --dns=dns_do" + retlist="--wp --wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard --letsencrypt=off --letsencrypt=clean -le=off -le=wildcard --dns --dns=dns_cf --dns=dns_do" else retlist="" fi @@ -230,9 +230,9 @@ _wo_complete() "--wpsubdir" | "--wpsubdomain") if [ ${COMP_WORDS[1]} != "debug" ]; then if [ ${COMP_WORDS[2]} == "create" ]; then - retlist="--wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le --php73 --dns --dns=dns_cf --dns=dns_do" + retlist="--wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce --letsencrypt --letsencrypt=wildcard -le --php73 --dns --dns=dns_cf --dns=dns_do" elif [ ${COMP_WORDS[2]} == "update" ]; then - retlist="--wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard --letsencrypt=off --letsencrypt=renew --letsencrypt=clean -le --dns --dns=dns_cf --dns=dns_do" + retlist="--wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do" else retlist="" fi @@ -248,7 +248,7 @@ _wo_complete() "--wpredis --wprocket --wpce" | "--wpfc" | "--wpsc" | "--wpsubdir" | "--wpsubdomain" | "--user" | "--pass" | "--email" | "--wp") if [ ${COMP_WORDS[2]} == "create" ]; then - retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --php73 --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le --dns --dns=dns_cf --dns=dns_do" + retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --php73 -le --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do" else retlist="" fi @@ -261,7 +261,7 @@ _wo_complete() "--wpredis --wprocket --wpce" | "--wpfc") if [ ${COMP_WORDS[2]} == "update" ]; then - retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew --letsencrypt=clean -le --dns --dns=dns_cf --dns=dns_do" + retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do" else retlist="" fi @@ -314,7 +314,7 @@ _wo_complete() elif [ ${COMP_WORDS[2]} == "delete" ]; then retlist="--db --files --force" elif [ ${COMP_WORDS[2]} == "update" ]; then - retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=off --letsencrypt=renew" + retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=off " else retlist="" fi @@ -363,7 +363,7 @@ _wo_complete() case "$mprev" in "--user" | "--email" | "--pass") if [ ${COMP_WORDS[2]} == "create" ]; then - retlist="--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=subdomain --letsencrypt=wildcard -le --dns --dns=dns_cf --dns=dns_do" + retlist="--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=wildcard -le --dns --dns=dns_cf --dns=dns_do" fi ret="${retlist[@]/$prev}" COMPREPLY=( $(compgen \ diff --git a/install b/install index d4da65f..2085b53 100755 --- a/install +++ b/install @@ -9,7 +9,7 @@ # ------------------------------------------------------------------------- # wget -qO wo wops.cc && sudo bash wo # ------------------------------------------------------------------------- -# Version 3.9.8.4 - 2019-08-28 +# Version 3.9.8.5 - 2019-08-28 # ------------------------------------------------------------------------- # CONTENTS @@ -103,7 +103,11 @@ export DEBIAN_FRONTEND=noninteractive apt-get update -qq } -if [ -z "$(command -v curl)" ]; then +command_exists() { + command -v "$@" > /dev/null 2>&1 +} + +if ! command_exists curl; then apt-get -y install curl -qq fi @@ -120,9 +124,9 @@ echo "" ### # 1- Check whether lsb_release is installed, and if not, install it ### -if [ -z "$(command -v lsb_release)" ]; then +if ! command_exists lsb_release; then wo_lib_echo "Installing lsb-release, please wait..." - apt-get -y install lsb-release -qq + apt-get install lsb-release -qq fi ### @@ -191,11 +195,9 @@ fi #### wo_dist_upgrade() { - [ -z "$wo_travis" ] && { - # update server packages - apt-get dist-upgrade --option=Dpkg::options::=--force-confmiss --option=Dpkg::options::=--force-confold --option=Dpkg::options::=--force-unsafe-io --assume-yes --quiet - } >> "$wo_install_log" 2>&1 -} + # update server packages + apt-get dist-upgrade --option=Dpkg::options::=--force-confmiss --option=Dpkg::options::=--force-confold --option=Dpkg::options::=--force-unsafe-io --assume-yes --quiet +} >> "$wo_install_log" 2>&1 wo_install_dep() { @@ -223,17 +225,19 @@ wo_install_dep() { if [ ! -f /etc/apt/apt.conf.d/20auto-upgrades ]; then cp /usr/share/unattended-upgrades/20auto-upgrades /etc/apt/apt.conf.d/20auto-upgrades fi - # set default ntp pools - if ! grep -q "time.cloudflare.com" /etc/systemd/timesyncd.conf; then - sed -e 's/^#NTP=/NTP=time.cloudflare.com 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org 2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org/' -i /etc/systemd/timesyncd.conf - # enable ntp - timedatectl set-ntp 1 - fi - } >> "$wo_install_log" 2>&1 } +wo_timesync() { + # set default ntp pools + if ! grep -q "time.cloudflare.com" /etc/systemd/timesyncd.conf; then + sed -e 's/^#NTP=/NTP=time.cloudflare.com 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org 2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org/' -i /etc/systemd/timesyncd.conf + # enable ntp + timedatectl set-ntp 1 + fi +} + ### # 3 - Create/migrate the essentials ### @@ -499,7 +503,7 @@ wo_upgrade_nginx() { service nginx stop # remove previous package apt-mark unhold nginx-ee nginx-common nginx-custom - apt-get --assume-yes purge nginx-ee nginx-common nginx-custom --allow-change-held-packages + apt-get autoremove nginx-ee nginx-common nginx-custom --allow-change-held-packages --purge -qq # remove previous php-fpm pool configuration if [ -n "$CHECK_PHP72" ]; then apt-get purge php7.2-fpm -y -qq @@ -511,13 +515,11 @@ wo_upgrade_nginx() { /usr/local/bin/wo stack install --nginx --php rm -f /etc/nginx/common/acl.conf /etc/nginx/htpasswd-wo /usr/bin/rsync -au --noatime /var/lib/wo-backup/nginx/ /etc/nginx/ - + /usr/local/bin/wo stack upgrade --nginx --force fi - else - /usr/local/bin/wo stack upgrade --nginx --force fi # restore sites and configuration - [ -f /etc/nginx/htpasswd-ee ] && { mv /etc/nginx/htpasswd-ee /etc/nginx/htpasswd-wo; } + [ -f /etc/nginx/htpasswd-ee ] && { cp -f /etc/nginx/htpasswd-ee /etc/nginx/htpasswd-wo; } sed -i "s/locations.conf/locations-wo.conf/" /etc/nginx/sites-available/* sed -i "s/locations-php7.conf/locations-wo.conf/" /etc/nginx/sites-available/* sed -i "s/locations-php71.conf/locations-wo.conf/" /etc/nginx/sites-available/* @@ -695,14 +697,14 @@ wo_mariadb_tweak() { wo_nginx_tweak() { # increase nginx open_files_limit { - if [ ! -d /etc/systemd/system/nginx.service.d ]; then - mkdir -p /etc/systemd/system/nginx.service.d - if [ ! -f /etc/systemd/system/nginx.service.d/limits.conf ]; then - echo -e '[Service]\nLimitNOFILE=500000' > /etc/systemd/system/nginx.service.d/limits.conf - systemctl daemon-reload - nginx -t && service nginx restart - fi + if [ ! -d /etc/systemd/system/nginx.service.d ]; then + mkdir -p /etc/systemd/system/nginx.service.d + if [ ! -f /etc/systemd/system/nginx.service.d/limits.conf ]; then + echo -e '[Service]\nLimitNOFILE=500000' > /etc/systemd/system/nginx.service.d/limits.conf + systemctl daemon-reload + nginx -t && service nginx restart fi + fi } >> /var/log/wo/install.log 2>&1 } @@ -714,6 +716,12 @@ wo_uninstall() { rm -rf /usr/local/lib/python3.*/dist-packages/{pystache-*,cement-2.*,wo-*} /usr/local/bin/wo /etc/bash_completion.d/wo_auto.rc /var/lib/wo /etc/wo /usr/lib/wo/templates >> /var/log/wo/install.log 2>&1 } +wo_cheat_alias() { + if ! grep -q "cheat" "$HOME/.bashrc"; then + echo "alias cheat='/usr/local/bin/cht.sh'" >> "$HOME/.bashrc" + fi +} + wo_ufw_setup() { # get custom ssh port @@ -792,37 +800,90 @@ if [ "$wo_purge" = "y" ]; then else # 1 - WO already installed if [ -x /usr/local/bin/wo ]; then - if ! { + if { wo -v 2>&1 | grep -q "$wo_version_new" - } || [ "$wo_force_install" = "y" ]; then - wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log - wo_install_dep | tee -ai $wo_install_log - wo_lib_echo "Backing-up WO install" | tee -ai $wo_install_log - wo_backup_wo | tee -ai $wo_install_log - secure_wo_db | tee -ai $wo_install_log - wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log - wo_clean | tee -ai $wo_install_log - if [ "$wo_travis" = "y" ]; then - wo_install_travis | tee -ai $wo_install_log + } && [ -z "$wo_force_install" ]; then + wo_lib_error "You already have WordOps $wo_version_new" + exit 1 + fi + wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log + wo_install_dep | tee -ai $wo_install_log + wo_timesync | tee -ai $wo_install_log + wo_lib_echo "Backing-up WO install" | tee -ai $wo_install_log + wo_backup_wo | tee -ai $wo_install_log + secure_wo_db | tee -ai $wo_install_log + wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log + wo_clean | tee -ai $wo_install_log + if [ "$wo_travis" = "y" ]; then + wo_install_travis | tee -ai $wo_install_log + else + if [ -f "$HOME/.gitconfig" ]; then + wo_install >> $wo_install_log 2>&1 else - if [ -f "$HOME/.gitconfig" ]; then - wo_install >> $wo_install_log 2>&1 - else - wo_install | tee -ai $wo_install_log + wo_install | tee -ai $wo_install_log + fi + fi + wo_update_latest | tee -ai $wo_install_log + if [ ! -d /opt/acme/.sh ]; then + wo_lib_echo "Updating acme.sh" | tee -ai $wo_install_log + wo_install_acme_sh | tee -ai $wo_install_log + fi + wo_lib_echo "Applying Kernel tweaks" | tee -ai $wo_install_log + wo_tweak_kernel | tee -ai $wo_install_log + if [ ! -f /opt/wo-kernel.sh ]; then + wo_lib_echo "Adding systemd service tweak" | tee -ai $wo_install_log + wo_systemd_tweak | tee -ai $wo_install_log + fi + if [ -x /usr/sbin/nginx ]; then + wo_nginx_tweak | tee -ai $wo_install_log + fi + if [ -d /etc/systemd/system/mariadb.service.d ]; then + wo_mariadb_tweak | tee -ai $wo_install_log + fi + wo_cheat_alias | tee -ai $wo_install_log + wo_domain_suffix | tee -ai $wo_install_log + wo_lib_echo "Running post-install steps " | tee -ai $wo_install_log + wo_update_wp_cli | tee -ai $wo_install_log + else + # 2 - Migration from EEv3 + if [ -x /usr/local/bin/ee ]; then + if [ -z "$wo_force_install" ]; then + echo -e "Migrate from EasyEngine to WordOps (y/n): " && read -r WO_ANSWER + if [ "$WO_ANSWER" != "y" ] && [ "$WO_ANSWER" != "Y" ]; then + wo_lib_error "Not installing WordOps, exit status = " 1 + exit 1 fi fi - wo_update_latest | tee -ai $wo_install_log - if [ ! -d /opt/acme/.sh ]; then - wo_lib_echo "Updating acme.sh" | tee -ai $wo_install_log - wo_install_acme_sh | tee -ai $wo_install_log + wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log + wo_install_dep | tee -ai $wo_install_log + wo_timesync | tee -ai $wo_install_log + wo_lib_echo "Backing-up EE install" | tee -ai $wo_install_log + wo_backup_ee | tee -ai $wo_install_log + wo_lib_echo "Removing EasyEngine cronjob" | tee -ai $wo_install_log + wo_remove_ee_cron | tee -ai $wo_install_log + wo_lib_echo "Syncing WO database" | tee -ai $wo_install_log + wo_sync_db | tee -ai $wo_install_log + secure_wo_db | tee -ai $wo_install_log + wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log + if [ -f "$HOME/.gitconfig" ]; then + wo_install >> $wo_install_log 2>&1 + else + wo_install | tee -ai $wo_install_log fi + if command_exists nginx; then + wo_lib_echo "Upgrading Nginx" | tee -ai $wo_install_log + wo_upgrade_nginx | tee -ai $wo_install_log + fi + 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 "Applying Kernel tweaks" | tee -ai $wo_install_log wo_tweak_kernel | tee -ai $wo_install_log if [ ! -f /opt/wo-kernel.sh ]; then wo_lib_echo "Adding systemd service tweak" | tee -ai $wo_install_log wo_systemd_tweak | tee -ai $wo_install_log fi - if [ -x /usr/sbin/nginx ]; then + if command_exists nginx; then wo_nginx_tweak | tee -ai $wo_install_log fi if [ -d /etc/systemd/system/mariadb.service.d ]; then @@ -830,67 +891,19 @@ else fi wo_domain_suffix | 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 - fi - else - # 2 - Migration from EEv3 - if [ -x /usr/local/bin/ee ]; then - if [ -z "$wo_force_install" ]; then - echo -e "Migrate from EasyEngine to WordOps (y/n): " && read -r WO_ANSWER - else - WO_ANSWER="y" - fi - if [ "$WO_ANSWER" = "y" ] || [ "$WO_ANSWER" = "Y" ]; then - wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log - wo_install_dep | tee -ai $wo_install_log - wo_lib_echo "Backing-up EE install" | tee -ai $wo_install_log - wo_backup_ee | tee -ai $wo_install_log - wo_lib_echo "Removing EasyEngine cronjob" | tee -ai $wo_install_log - wo_remove_ee_cron | tee -ai $wo_install_log - wo_lib_echo "Syncing WO database" | tee -ai $wo_install_log - wo_sync_db | tee -ai $wo_install_log - secure_wo_db | tee -ai $wo_install_log - wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log - if [ -f "$HOME/.gitconfig" ]; then - wo_install >> $wo_install_log 2>&1 - else - wo_install | tee -ai $wo_install_log - fi - if [ -n "$(command -v nginx)" ]; then - wo_lib_echo "Upgrading Nginx" | tee -ai $wo_install_log - wo_upgrade_nginx | tee -ai $wo_install_log - fi - 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 "Applying Kernel tweaks" | tee -ai $wo_install_log - wo_tweak_kernel | tee -ai $wo_install_log - if [ ! -f /opt/wo-kernel.sh ]; then - wo_lib_echo "Adding systemd service tweak" | tee -ai $wo_install_log - wo_systemd_tweak | tee -ai $wo_install_log - fi - if [ -x /usr/sbin/nginx ]; then - wo_nginx_tweak | tee -ai $wo_install_log - fi - if [ -d /etc/systemd/system/mariadb.service.d ]; then - wo_mariadb_tweak | tee -ai $wo_install_log - fi - wo_domain_suffix | 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 - wo_lib_echo "Cleaning-up EE previous install" | tee -ai $wo_install_log - wo_clean_ee | tee -ai $wo_install_log - else - wo_lib_error "Not installing WordOps, exit status = " 1 - fi + wo_cheat_alias | tee -ai $wo_install_log + wo_lib_echo "Cleaning-up EE previous install" | tee -ai $wo_install_log + wo_clean_ee | tee -ai $wo_install_log else # 3 - Fresh WO setup wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log - wo_dist_upgrade | tee -ai $wo_install_log + [ -z "$wo_travis" ] && { + wo_dist_upgrade | tee -ai $wo_install_log + } wo_install_dep | tee -ai $wo_install_log + wo_timesync | tee -ai $wo_install_log wo_lib_echo "Installing WordOps " | tee -ai $wo_install_log if [ "$wo_travis" = "y" ]; then wo_install_travis | tee -ai $wo_install_log @@ -915,6 +928,7 @@ else 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_cheat_alias | tee -ai $wo_install_log wo_domain_suffix | tee -ai $wo_install_log wo_git_init | tee -ai $wo_install_log wo_update_wp_cli | tee -ai $wo_install_log diff --git a/setup.py b/setup.py index 361c02d..ff19262 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ if not os.path.isfile('/root/.gitconfig'): shutil.copy2(os.path.expanduser("~")+'/.gitconfig', '/root/.gitconfig') setup(name='wo', - version='3.9.8.4', + version='3.9.8.5', description=long_description, long_description=long_description, classifiers=[], diff --git a/tests/travis.sh b/tests/travis.sh index 3fd6685..4e77573 100644 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -14,6 +14,9 @@ exit_script() { } if ! { + echo -e "${CGREEN}#############################################${CEND}" + echo -e ' stack install ' + echo -e "${CGREEN}#############################################${CEND}" wo --help && wo stack install && wo stack install --proftpd }; then exit_script @@ -43,7 +46,8 @@ if ! { echo -e ' wo site update ' echo -e "${CGREEN}#############################################${CEND}" wo site create 1.com --html && wo site create 2.com --php && wo site create 3.com --mysql - wo site update 1.com --wp && wo site update 2.com --php73 && wo site update 3.com --php73 && wo site update 1.com --wpfc && wo site update 1.com --wpsc && wo site update 1.com --wpredis + wo site update 1.com --wp && wo site update 2.com --php73 && wo site update 3.com --php73 + wo site update 1.com --wp && wo site update 1.com --wpfc && wo site update 1.com --wpsc && wo site update 1.com --wpredis && wo site update 1.com --wpce && wo site update 1.com --wprocket && wo site update 1.com --php73=off }; then exit_script fi @@ -60,9 +64,9 @@ if ! { }; then exit_script fi - echo -e "${CGREEN}#############################################${CEND}" - echo -e ' various informations ' - echo -e "${CGREEN}#############################################${CEND}" +echo -e "${CGREEN}#############################################${CEND}" +echo -e ' various informations ' +echo -e "${CGREEN}#############################################${CEND}" wp --allow-root --info cat /etc/nginx/nginx.conf wo site info wp1.com diff --git a/wo/cli/plugins/clean.py b/wo/cli/plugins/clean.py index 7d7acfa..2638dc3 100644 --- a/wo/cli/plugins/clean.py +++ b/wo/cli/plugins/clean.py @@ -20,7 +20,7 @@ class WOCleanController(CementBaseController): stacked_on = 'base' stacked_type = 'nested' description = ( - 'Clean NGINX FastCGI cache, Opcache, Memcached, Redis Cache') + 'Clean NGINX FastCGI cache, Opcache, Redis Cache') arguments = [ (['--all'], dict(help='Clean all cache', action='store_true')), diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index 6ec5dfc..a5259f1 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -957,10 +957,9 @@ class WOSiteUpdateController(CementBaseController): Log.error(self, 'Unable to input site name, Please try again!') pargs.site_name = pargs.site_name.strip() - (wo_domain, - wo_www_domain, ) = ValidateDomain(pargs.site_name) + (wo_domain, wo_www_domain) = ValidateDomain(pargs.site_name) wo_site_webroot = WOVariables.wo_webroot + wo_domain - wo_domain_type, wo_root_domain = GetDomainlevel(wo_domain) + (wo_domain_type, wo_root_domain) = GetDomainlevel(wo_domain) check_site = getSiteInfo(self, wo_domain) if check_site is None: @@ -1198,14 +1197,14 @@ class WOSiteUpdateController(CementBaseController): return 0 min_expiry_days = 45 if (expiry_days <= min_expiry_days): - renewLetsEncrypt(self, ee_domain) + renewLetsEncrypt(self, wo_domain) if not WOService.reload_service(self, 'nginx'): Log.error(self, "service nginx reload failed. " "check issues with `nginx -t` command") Log.info(self, "SUCCESS: Certificate was successfully " "renewed For https://{0}".format(wo_domain)) elif pargs.force: - renewLetsEncrypt(self, ee_domain) + renewLetsEncrypt(self, wo_domain) Log.info(self, "Certificate was successfully renewed") if not WOService.reload_service(self, 'nginx'): Log.error(self, "service nginx reload failed. " diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index 775afb5..c0b9b17 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -989,8 +989,6 @@ def display_cache_settings(self, data): "page=nginx".format(data['site_name'])) - - def logwatch(self, logfiles): import zlib import base64 @@ -1012,8 +1010,8 @@ def logwatch(self, logfiles): 'caught exception rendering a new log line in %s' % filename) - l = logwatch.LogWatcher(logfiles, callback) - l.loop() + logl = logwatch.LogWatcher(logfiles, callback) + logl.loop() def detSitePar(opts): @@ -1243,10 +1241,19 @@ def removeAcmeConf(self, domain): .format(domain)) WOFileUtils.rm(self, '/etc/nginx/conf.d/force-ssl-{0}.conf.disabled' .format(domain)) - - WOGit.add(self, ["/etc/letsencrypt"], - msg="Deleted {0} " - .format(domain)) + if WOFileUtils.grepcheck(self, '/var/www/22222/conf/nginx/ssl.conf', + '{0}'.format(domain)): + Log.info(self, "Setting back default certificate for WordOps backend") + with open("/var/www/22222/conf/nginx/" + "ssl.conf", "w") as ssl_conf_file: + ssl_conf_file.write("ssl_certificate " + "/var/www/22222/cert/22222.crt;\n" + "ssl_certificate_key " + "/var/www/22222/cert/22222.key;\n") + WOGit.add(self, ["/etc/letsencrypt"], + msg="Deleted {0} " + .format(domain)) + WOService.restart_service(self, "nginx") def site_url_https(self, domain): diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index bafb182..33b6f01 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -14,6 +14,7 @@ import re import requests import psutil + # from pynginxconfig import NginxConfig from wo.cli.plugins.site_functions import * from wo.cli.plugins.sitedb import * @@ -91,7 +92,7 @@ class WOStackController(CementBaseController): (['--utils'], dict(help='Install Utils stack', action='store_true')), (['--cheat'], - dict(help='Install cht.sh stack', action='store_true')), + dict(help='Install cheat.sh stack', action='store_true')), (['--redis'], dict(help='Install Redis', action='store_true')), (['--phpredisadmin'], @@ -114,6 +115,7 @@ class WOStackController(CementBaseController): """Start installation of packages""" self.msg = [] empty_packages = [] + wo_webroot = "/var/www/" pargs = self.app.pargs try: # Default action for stack installation @@ -122,8 +124,8 @@ class WOStackController(CementBaseController): (not pargs.mysql) and (not pargs.wpcli) and (not pargs.phpmyadmin) and (not pargs.composer) and (not pargs.netdata) and (not pargs.dashboard) and - (not pargs.fail2ban) and (not pargs.security) - and (not pargs.mysqlclient) and (not pargs.mysqltuner) and + (not pargs.fail2ban) and (not pargs.security) and + (not pargs.mysqlclient) and (not pargs.mysqltuner) and (not pargs.adminer) and (not pargs.utils) and (not pargs.redis) and (not pargs.proftpd) and (not pargs.extplorer) and @@ -140,7 +142,7 @@ class WOStackController(CementBaseController): pargs.php73 = True pargs.redis = True pargs.proftpd = True - pargs.clamav = True + pargs.security = True if pargs.web: pargs.nginx = True @@ -149,9 +151,9 @@ class WOStackController(CementBaseController): pargs.wpcli = True if pargs.admin: - pargs.web = True pargs.adminer = True pargs.phpmyadmin = True + pargs.composer = True pargs.utils = True pargs.netdata = True pargs.dashboard = True @@ -163,14 +165,6 @@ class WOStackController(CementBaseController): pargs.fail2ban = True pargs.clamav = True - # Redis - if pargs.redis: - if not WOAptGet.is_installed(self, 'redis-server'): - apt_packages = apt_packages + WOVariables.wo_redis - pargs.php = True - else: - Log.info(self, "Redis already installed") - # Nginx if pargs.nginx: Log.debug(self, "Setting apt_packages variable for Nginx") @@ -194,6 +188,14 @@ class WOStackController(CementBaseController): else: Log.debug(self, "Nginx Stable already installed") + # Redis + if pargs.redis: + if not WOAptGet.is_installed(self, 'redis-server'): + apt_packages = apt_packages + WOVariables.wo_redis + pargs.php = True + else: + Log.info(self, "Redis already installed") + # PHP 7.2 if pargs.php: Log.debug(self, "Setting apt_packages variable for PHP 7.2") @@ -226,17 +228,25 @@ class WOStackController(CementBaseController): Log.debug(self, "Setting apt_packages variable for MySQL") if not WOShellExec.cmd_exec(self, "mysqladmin ping"): apt_packages = apt_packages + WOVariables.wo_mysql + else: + Log.debug(self, "MySQL already installed and alive") + Log.info(self, "MySQL already installed and alive") # mysqlclient if pargs.mysqlclient: Log.debug(self, "Setting apt_packages variable " "for MySQL Client") - apt_packages = apt_packages + WOVariables.wo_mysql_client + if not WOShellExec.cmd_exec(self, "mysqladmin ping"): + apt_packages = apt_packages + WOVariables.wo_mysql_client + else: + Log.debug(self, "MySQL already installed and alive") + Log.info(self, "MySQL already installed and alive") # WP-CLI if pargs.wpcli: Log.debug(self, "Setting packages variable for WP-CLI") - if not WOShellExec.cmd_exec(self, "command -v wp"): + if (not os.path.isfile("/usr/local/bin/wp") and not + os.path.isfile("/usr/bin/wp")): packages = packages + [["https://github.com/wp-cli/wp-cli/" "releases/download/v{0}/" "wp-cli-{0}.phar" @@ -276,10 +286,10 @@ class WOStackController(CementBaseController): # PHPMYADMIN if pargs.phpmyadmin: + pargs.composer = True if not os.path.isdir('/var/www/22222/htdocs/db/pma'): Log.debug(self, "Setting packages variable " "for phpMyAdmin ") - pargs.composer = True packages = packages + [["https://github.com/phpmyadmin/" "phpmyadmin/archive/STABLE.tar.gz", "/var/lib/wo/tmp/pma.tar.gz", @@ -288,6 +298,23 @@ class WOStackController(CementBaseController): Log.debug(self, "phpMyAdmin already installed") Log.info(self, "phpMyAdmin already installed") + # PHPREDISADMIN + if pargs.phpredisadmin: + pargs.composer = True + if not os.path.isdir('/var/www/22222/htdocs/' + 'cache/redis/phpRedisAdmin'): + Log.debug( + self, "Setting packages variable for phpRedisAdmin") + packages = packages + [["https://github.com/" + "erikdubbelboer/" + "phpRedisAdmin/archive" + "/v1.11.3.tar.gz", + "/var/lib/wo/tmp/pra.tar.gz", + "phpRedisAdmin"]] + else: + Log.debug(self, "phpRedisAdmin already installed") + Log.info(self, "phpRedisAdmin already installed") + # Composer if pargs.composer: if not os.path.isfile('/usr/local/bin/composer'): @@ -300,59 +327,62 @@ class WOStackController(CementBaseController): Log.debug(self, "Composer already installed") Log.info(self, "Composer already installed") - # PHPREDISADMIN - if pargs.phpredisadmin: - if not os.path.isdir('/var/www/22222/htdocs/' - 'cache/redis/phpRedisAdmin'): - Log.debug( - self, "Setting packages variable for phpRedisAdmin") - pargs.composer = True - packages = packages + [["https://github.com/" - "erikdubbelboer/" - "phpRedisAdmin/archive" - "/v1.11.3.tar.gz", - "/var/lib/wo/tmp/pra.tar.gz", - "phpRedisAdmin"]] - else: - Log.debug(self, "phpRedisAdmin already installed") - Log.info(self, "phpRedisAdmin already installed") - # ADMINER if pargs.adminer: - Log.debug(self, "Setting packages variable for Adminer ") - packages = packages + [["https://github.com/vrana/adminer/" - "releases/download/v{0}" - "/adminer-{0}.php" - .format(WOVariables.wo_adminer), - "{0}22222/" - "htdocs/db/adminer/index.php" - .format(WOVariables.wo_webroot), - "Adminer"], - ["https://raw.githubusercontent.com" - "/vrana/adminer/master/designs/" - "pepa-linha/adminer.css", - "{0}22222/" - "htdocs/db/adminer/adminer.css" - .format(WOVariables.wo_webroot), - "Adminer theme"]] + if not os.path.isfile("{0}22222/htdocs/db/" + "adminer/index.php" + .format(wo_webroot)): + Log.debug(self, "Setting packages variable for Adminer ") + packages = packages + [["https://github.com/vrana/adminer/" + "releases/download/v{0}" + "/adminer-{0}.php" + .format(WOVariables.wo_adminer), + "{0}22222/" + "htdocs/db/adminer/index.php" + .format(WOVariables.wo_webroot), + "Adminer"], + ["https://raw.githubusercontent.com" + "/vrana/adminer/master/designs/" + "pepa-linha/adminer.css", + "{0}22222/" + "htdocs/db/adminer/adminer.css" + .format(WOVariables.wo_webroot), + "Adminer theme"]] + else: + Log.debug(self, "Adminer already installed") + Log.info(self, "Adminer already installed") + # mysqltuner if pargs.mysqltuner: - Log.debug(self, "Setting packages variable for MySQLTuner ") - packages = packages + [["https://raw." - "githubusercontent.com/" - "major/MySQLTuner-perl" - "/master/mysqltuner.pl", - "/usr/bin/mysqltuner", - "MySQLTuner"]] + if not os.path.isfile("/usr/bin/mysqltuner"): + Log.debug(self, "Setting packages variable " + "for MySQLTuner ") + packages = packages + [["https://raw." + "githubusercontent.com/" + "major/MySQLTuner-perl" + "/master/mysqltuner.pl", + "/usr/bin/mysqltuner", + "MySQLTuner"]] + else: + Log.debug(self, "MySQLtuner already installed") + Log.info(self, "MySQLtuner already installed") # Netdata if pargs.netdata: - Log.debug(self, "Setting packages variable for Netdata") - if not os.path.exists('/opt/netdata'): - packages = packages + [['https://my-netdata.io/' - 'kickstart-static64.sh', - '/var/lib/wo/tmp/kickstart.sh', - 'Netdata']] + if (not os.path.isdir('/opt/netdata') and not + os.path.isdir("/etc/netdata")): + Log.debug( + self, "Setting packages variable for Netdata") + if WOVariables.wo_distro == 'raspbian': + packages = packages + [['https://my-netdata.io/' + 'kickstart.sh', + '/var/lib/wo/tmp/kickstart.sh', + 'Netdata']] + else: + packages = packages + [['https://my-netdata.io/' + 'kickstart-static64.sh', + '/var/lib/wo/tmp/kickstart.sh', + 'Netdata']] else: Log.debug(self, "Netdata already installed") Log.info(self, "Netdata already installed") @@ -360,14 +390,16 @@ class WOStackController(CementBaseController): # WordOps Dashboard if pargs.dashboard: if not os.path.isfile('/var/www/22222/htdocs/index.php'): - Log.debug( - self, "Setting packages variable for WO-Dashboard") - packages = packages + \ - [["https://github.com/WordOps/wordops-dashboard/" - "releases/download/v{0}/wordops-dashboard.tar.gz" - .format(WOVariables.wo_dashboard), - "/var/lib/wo/tmp/wo-dashboard.tar.gz", - "WordOps Dashboard"]] + Log.debug(self, + "Setting packages variable for WO-Dashboard") + packages = \ + packages + [["https://github.com/WordOps" + "/wordops-dashboard/" + "releases/download/v{0}/" + "wordops-dashboard.tar.gz" + .format(WOVariables.wo_dashboard), + "/var/lib/wo/tmp/wo-dashboard.tar.gz", + "WordOps Dashboard"]] else: Log.debug(self, "WordOps dashboard already installed") Log.info(self, "WordOps dashboard already installed") @@ -386,6 +418,17 @@ class WOStackController(CementBaseController): Log.debug(self, "eXtplorer is already installed") Log.info(self, "eXtplorer is already installed") + # cheat.sh + if pargs.cheat: + if not os.path.isfile('/usr/local/bin/cht.sh'): + Log.debug(self, "Setting packages variable for cht.sh") + packages = packages + [["https://cht.sh/:cht.sh", + "/usr/local/bin/cht.sh", + "cheat.sh"]] + else: + Log.debug(self, "cheat.sh is already installed") + Log.info(self, "cheat.sh is already installed") + # UTILS if pargs.utils: Log.debug(self, "Setting packages variable for utils") @@ -408,9 +451,8 @@ class WOStackController(CementBaseController): "cache/opcache/opgui.php" .format(WOVariables.wo_webroot), "Opgui"], - ["https://gist.github.com/ck-on/4959032" - "/raw/0b871b345fd6cfcd6d2be030c1f33d1" - "ad6a475cb/ocp.php", + ["https://raw.githubusercontent.com/" + "mlazarov/ocp/master/ocp.php", "{0}22222/htdocs/cache/" "opcache/ocp.php" .format(WOVariables.wo_webroot), @@ -426,41 +468,31 @@ class WOStackController(CementBaseController): ["https://github.com/box/Anemometer/" "archive/master.tar.gz", '/var/lib/wo/tmp/anemometer.tar.gz', - 'Anemometer'] - ] - if pargs.cheat: - if (not os.path.isfile('/usr/local/bin/cht.sh') and - not os.path.isfile('/usr/bin/cht.sh')): - Log.debug(self, "Setting packages variable for cht.sh") - packages = packages + [["https://cht.sh/:cht.sh", - "/usr/local/bin/cht.sh", - "cht.sh"]] - else: - Log.debug(self, "cht.sh is already installed") - Log.info(self, "cht.sh is already installed") + 'Anemometer']] except Exception as e: Log.debug(self, "{0}".format(e)) - if (apt_packages): - Log.debug(self, "Calling pre_pref") - pre_pref(self, apt_packages) - # meminfo = (os.popen('/bin/cat /proc/meminfo ' - # '| grep MemTotal').read()).split(":") - # memsplit = re.split(" kB", meminfo[1]) - # wo_mem = int(memsplit[0]) - # if (wo_mem < 4000000): - # WOSwap.add(self) - Log.info(self, "Updating apt-cache, please wait...") - WOAptGet.update(self) - Log.info(self, "Installing packages, please wait...") - WOAptGet.install(self, apt_packages) - post_pref(self, apt_packages, empty_packages) - if (packages): - Log.debug(self, "Downloading following: {0}".format(packages)) - WODownload.download(self, packages) - Log.debug(self, "Calling post_pref") - post_pref(self, empty_packages, packages) + if (apt_packages) or (packages): + if (apt_packages): + Log.debug(self, "Calling pre_pref") + pre_pref(self, apt_packages) + # meminfo = (os.popen('/bin/cat /proc/meminfo ' + # '| grep MemTotal').read()).split(":") + # memsplit = re.split(" kB", meminfo[1]) + # wo_mem = int(memsplit[0]) + # if (wo_mem < 4000000): + # WOSwap.add(self) + Log.info(self, "Updating apt-cache, please wait...") + WOAptGet.update(self) + Log.info(self, "Installing packages, please wait...") + WOAptGet.install(self, apt_packages) + post_pref(self, apt_packages, empty_packages) + if (packages): + Log.debug(self, "Downloading following: {0}".format(packages)) + WODownload.download(self, packages) + Log.debug(self, "Calling post_pref") + post_pref(self, empty_packages, packages) if disp_msg: if (self.msg): @@ -478,15 +510,17 @@ class WOStackController(CementBaseController): pargs = self.app.pargs if ((not pargs.web) and (not pargs.admin) and (not pargs.nginx) and (not pargs.php) and - (not pargs.php73) and (not pargs.mysql) and - (not pargs.wpcli) and (not pargs.phpmyadmin) and - (not pargs.adminer) and (not pargs.utils) and - (not pargs.composer) and (not pargs.netdata) and - (not pargs.fail2ban) and (not pargs.proftpd) and - (not pargs.security) and (not pargs.mysqltuner) and - (not pargs.mysqlclient) and - (not pargs.all) and (not pargs.redis) and - (not pargs.phpredisadmin)): + (not pargs.mysql) and (not pargs.wpcli) and + (not pargs.phpmyadmin) and (not pargs.composer) and + (not pargs.netdata) and (not pargs.dashboard) and + (not pargs.fail2ban) and (not pargs.security) and + (not pargs.mysqlclient) and (not pargs.mysqltuner) and + (not pargs.adminer) and (not pargs.utils) and + (not pargs.redis) and (not pargs.proftpd) and + (not pargs.extplorer) and + (not pargs.cheat) and (not pargs.clamav) and + (not pargs.phpredisadmin) and + (not pargs.php73)): pargs.web = True pargs.admin = True pargs.security = True @@ -499,8 +533,7 @@ class WOStackController(CementBaseController): pargs.proftpd = True pargs.utils = True pargs.redis = True - packages = \ - packages + ['/var/www/22222/htdocs/*'] + packages = packages + ['/var/www/22222/htdocs/*'] if pargs.web: pargs.nginx = True @@ -516,6 +549,7 @@ class WOStackController(CementBaseController): if pargs.security: pargs.fail2ban = True + pargs.clamav = True # NGINX if pargs.nginx: @@ -553,12 +587,25 @@ class WOStackController(CementBaseController): Log.debug(self, "Removing apt_packages variable of MySQL") apt_packages = apt_packages + WOVariables.wo_mysql + # mysqlclient + if pargs.mysqlclient: + Log.debug(self, "Removing apt_packages variable " + "for MySQL Client") + if WOShellExec.cmd_exec(self, "mysqladmin ping"): + apt_packages = apt_packages + WOVariables.wo_mysql_client + # fail2ban if pargs.fail2ban: if WOAptGet.is_installed(self, 'fail2ban'): Log.debug(self, "Remove apt_packages variable of Fail2ban") apt_packages = apt_packages + WOVariables.wo_fail2ban + # ClamAV + if pargs.clamav: + Log.debug(self, "Setting apt_packages variable for ClamAV") + if WOAptGet.is_installed(self, 'clamav'): + apt_packages = apt_packages + ["clamav"] + # proftpd if pargs.proftpd: if WOAptGet.is_installed(self, 'proftpd-basic'): @@ -592,7 +639,7 @@ class WOStackController(CementBaseController): if os.path.isdir('{0}22222/htdocs/cache/redis' .format(WOVariables.wo_webroot)): packages = packages + ['{0}22222/htdocs/' - 'cache/redis/phpRedisAdmin' + 'cache/redis' .format(WOVariables.wo_webroot)] # ADMINER if pargs.adminer: @@ -625,16 +672,14 @@ class WOStackController(CementBaseController): .format(WOVariables.wo_webroot)] if (packages) or (apt_packages): - if not pargs.force: - wo_prompt = input('Are you sure you to want to' - ' remove from server.' - '\nPackage configuration will remain' - ' on server after this operation.\n' - 'Any answer other than ' - '"yes" will be stop this' - ' operation : ') - if (wo_prompt != 'YES' or wo_prompt != 'yes'): - Log.error(self, "Not removing packages") + if (not pargs.force): + start_remove = input('Are you sure you to want to' + ' remove from server.' + '\nPackage configuration will remain' + ' on server after this operation.\n' + 'Remove stacks [y/N]?') + if start_remove != "Y" and start_remove != "y": + Log.error(self, "Not starting stack removal") if (set(["nginx-custom"]).issubset(set(apt_packages))): WOService.stop_service(self, 'nginx') @@ -642,17 +687,22 @@ class WOStackController(CementBaseController): # Netdata uninstaller if (set(['/var/lib/wo/tmp/' 'kickstart.sh']).issubset(set(packages))): - WOShellExec.cmd_exec(self, "bash /opt/netdata/usr/" - "libexec/netdata-" - "uninstaller.sh -y -f") + if WOVariables.wo_distro == 'Raspbian': + WOShellExec.cmd_exec(self, "bash /usr/" + "libexec/netdata-" + "uninstaller.sh -y -f") + else: + WOShellExec.cmd_exec(self, "bash /opt/netdata/usr/" + "libexec/netdata-" + "uninstaller.sh -y -f") if (packages): + Log.info(self, "Removing packages, please wait...") WOFileUtils.remove(self, packages) - WOAptGet.auto_remove(self) if (apt_packages): Log.debug(self, "Removing apt_packages") - Log.info(self, "Removing packages, please wait...") + Log.info(self, "Removing apt packages, please wait...") WOAptGet.remove(self, apt_packages) WOAptGet.auto_remove(self) @@ -667,15 +717,17 @@ class WOStackController(CementBaseController): # Default action for stack purge if ((not pargs.web) and (not pargs.admin) and (not pargs.nginx) and (not pargs.php) and - (not pargs.php73) and (not pargs.mysql) and - (not pargs.wpcli) and (not pargs.phpmyadmin) and - (not pargs.adminer) and (not pargs.utils) and - (not pargs.composer) and (not pargs.netdata) and - (not pargs.fail2ban) and (not pargs.proftpd) and - (not pargs.security) and (not pargs.mysqltuner) and - (not pargs.mysqlclient) and - (not pargs.all) and (not pargs.redis) and - (not pargs.phpredisadmin)): + (not pargs.mysql) and (not pargs.wpcli) and + (not pargs.phpmyadmin) and (not pargs.composer) and + (not pargs.netdata) and (not pargs.dashboard) and + (not pargs.fail2ban) and (not pargs.security) and + (not pargs.mysqlclient) and (not pargs.mysqltuner) and + (not pargs.adminer) and (not pargs.utils) and + (not pargs.redis) and (not pargs.proftpd) and + (not pargs.extplorer) and + (not pargs.cheat) and (not pargs.clamav) and + (not pargs.phpredisadmin) and + (not pargs.php73)): pargs.web = True pargs.admin = True pargs.security = True @@ -688,8 +740,7 @@ class WOStackController(CementBaseController): pargs.proftpd = True pargs.utils = True pargs.redis = True - packages = \ - packages + ['/var/www/22222/htdocs/*'] + packages = packages + ['/var/www/22222/htdocs/*'] if pargs.web: pargs.nginx = True @@ -702,9 +753,12 @@ class WOStackController(CementBaseController): pargs.composer = True pargs.netdata = True pargs.mysqltuner = True + pargs.cheat = True if pargs.security: pargs.fail2ban = True + pargs.clamav = True + # NGINX if pargs.nginx: if WOAptGet.is_installed(self, 'nginx-custom'): @@ -731,12 +785,35 @@ class WOStackController(CementBaseController): else: apt_packages = apt_packages + WOVariables.wo_php73 + # REDIS + if pargs.redis: + Log.debug(self, "Remove apt_packages variable of Redis") + apt_packages = apt_packages + WOVariables.wo_redis + + # MariaDB + if pargs.mysql: + Log.debug(self, "Removing apt_packages variable of MySQL") + apt_packages = apt_packages + WOVariables.wo_mysql + + # mysqlclient + if pargs.mysqlclient: + Log.debug(self, "Removing apt_packages variable " + "for MySQL Client") + if WOShellExec.cmd_exec(self, "mysqladmin ping"): + apt_packages = apt_packages + WOVariables.wo_mysql_client + # fail2ban if pargs.fail2ban: if WOAptGet.is_installed(self, 'fail2ban'): - Log.debug(self, "Purge apt_packages variable of Fail2ban") + Log.debug(self, "Remove apt_packages variable of Fail2ban") apt_packages = apt_packages + WOVariables.wo_fail2ban + # ClamAV + if pargs.clamav: + Log.debug(self, "Setting apt_packages variable for ClamAV") + if WOAptGet.is_installed(self, 'clamav'): + apt_packages = apt_packages + ["clamav"] + # proftpd if pargs.proftpd: if WOAptGet.is_installed(self, 'proftpd-basic'): @@ -771,7 +848,7 @@ class WOStackController(CementBaseController): if os.path.isdir('{0}22222/htdocs/cache/redis' .format(WOVariables.wo_webroot)): packages = packages + ['{0}22222/htdocs/' - 'cache/redis/phpRedisAdmin' + 'cache/redis' .format(WOVariables.wo_webroot)] # Adminer if pargs.adminer: @@ -806,35 +883,41 @@ class WOStackController(CementBaseController): .format(WOVariables.wo_webroot)] if (packages) or (apt_packages): - if not pargs.force: - wo_prompt = input('Are you sure you to want to purge ' - 'from server ' - 'along with their configuration' - ' packages,\nAny answer other than ' - '"yes" will be stop this ' - 'operation :') - if (wo_prompt != 'YES' or wo_prompt != 'yes'): - Log.error(self, "Not purging packages") + if (not pargs.force): + start_purge = input('Are you sure you to want to' + ' purge stacks from this server ?' + '\nPackage configuration and data ' + 'will not remain' + ' on this server after this operation.\n' + 'Purge stacks [y/N]') + if start_purge != "Y" and start_purge != "y": + Log.error(self, "Not starting stack purge") if (set(["nginx-custom"]).issubset(set(apt_packages))): WOService.stop_service(self, 'nginx') - # Netdata uninstaller - if (set(['/var/lib/wo/tmp/' - 'kickstart.sh']).issubset(set(packages))): - WOShellExec.cmd_exec(self, "bash /opt/netdata/usr/" - "libexec/netdata-" - "uninstaller.sh -y -f") - if (set(["fail2ban"]).issubset(set(apt_packages))): WOService.stop_service(self, 'fail2ban') + # Netdata uninstaller + if (set(['/var/lib/wo/tmp/' + 'kickstart.sh']).issubset(set(packages))): + if WOVariables.wo_distro == 'Raspbian': + WOShellExec.cmd_exec(self, "bash /usr/" + "libexec/netdata-" + "uninstaller.sh -y -f") + else: + WOShellExec.cmd_exec(self, "bash /opt/netdata/usr/" + "libexec/netdata-" + "uninstaller.sh -y -f") + if (apt_packages): - Log.info(self, "Purging packages, please wait...") + Log.info(self, "Purging apt packages, please wait...") WOAptGet.remove(self, apt_packages, purge=True) WOAptGet.auto_remove(self) if (packages): + Log.info(self, "Purging packages, please wait...") WOFileUtils.remove(self, packages) WOAptGet.auto_remove(self) diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index 16add4b..bf1e816 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -146,6 +146,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): if (apt_packages): # Nginx configuration if set(WOVariables.wo_nginx).issubset(set(apt_packages)): + Log.info(self, "Applying Nginx configuration templates") # Nginx main configuration ngxcnf = '/etc/nginx/conf.d' ngxcom = '/etc/nginx/common' @@ -459,23 +460,22 @@ def post_pref(self, apt_packages, packages, upgrade=False): if not os.path.isfile('{0}22222/conf/nginx/ssl.conf' .format(ngxroot)): - with open("/var/www/22222/conf/nginx/" - "ssl.conf", "a") as php_file: + "ssl.conf", "w") as php_file: php_file.write("ssl_certificate " "/var/www/22222/cert/22222.crt;\n" "ssl_certificate_key " "/var/www/22222/cert/22222.key;\n") server_ip = requests.get('http://v4.wordops.eu') - WOTemplate.render(self, '/opt/cf-update.sh', - 'cf-update.mustache', - data, overwrite=False) - WOFileUtils.chmod(self, "/opt/cf-update.sh", 0o775) - WOCron.setcron_weekly(self, '/opt/cf-update.sh ' - '> /dev/null 2>&1', - comment='Cloudflare IP refresh cronjob ' - 'added by WordOps') + if set(["nginx"]).issubset(set(apt_packages)): + print("WordOps backend configuration was successful\n" + "You can access it on : https://{0}:22222" + .format(server_ip)) + print("HTTP Auth User Name: WordOps" + + "\nHTTP Auth Password : {0}".format(passwd)) + WOService.reload_service(self, 'nginx') + else: self.msg = (self.msg + ["HTTP Auth User " "Name: WordOps"] + ["HTTP Auth Password : {0}" @@ -486,6 +486,16 @@ def post_pref(self, apt_packages, packages, upgrade=False): .format(server_ip.text, WOVariables.wo_fqdn)]) + if not os.path.isfile("/opt/cf-update.sh"): + WOTemplate.render(self, '/opt/cf-update.sh', + 'cf-update.mustache', + data, overwrite=False) + WOFileUtils.chmod(self, "/opt/cf-update.sh", 0o775) + WOCron.setcron_weekly(self, '/opt/cf-update.sh ' + '> /dev/null 2>&1', + comment='Cloudflare IP refresh cronjob ' + 'added by WordOps') + if upgrade: try: WOShellExec.cmd_exec(self, 'nginx -t') @@ -501,6 +511,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): WOService.restart_service(self, 'nginx') if set(WOVariables.wo_php).issubset(set(apt_packages)): + Log.info(self, "Configuring php7.2-fpm") ngxroot = '/var/www/' # Create log directories if not os.path.exists('/var/log/php/7.2/'): @@ -673,6 +684,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): # PHP7.3 configuration if set(WOVariables.wo_php73).issubset(set(apt_packages)): + Log.info(self, "Configuring php7.3-fpm") ngxroot = '/var/www/' # Create log directories if not os.path.exists('/var/log/php/7.3/'): @@ -854,6 +866,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): config_file.write(config) config_file.close() elif (not WOFileUtils.grep(self, "/etc/mysql/my.cnf", "WordOps")): + Log.info(self, "Tuning MariaDB configuration") with open("/etc/mysql/my.cnf", "a") as mysql_file: mysql_file.write("\n# WordOps v3.9.8\n") @@ -963,6 +976,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): # create fail2ban configuration files if set(WOVariables.wo_fail2ban).issubset(set(apt_packages)): if not os.path.isfile("/etc/fail2ban/jail.d/custom.conf"): + Log.info(self, "Configuring Fail2Ban") data = dict() WOTemplate.render(self, '/etc/fail2ban/jail.d/custom.conf', @@ -986,6 +1000,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): # Proftpd configuration if set(["proftpd-basic"]).issubset(set(apt_packages)): if os.path.isfile("/etc/proftpd/proftpd.conf"): + Log.info(self, "Configuring ProFTPd") Log.debug(self, "Setting up Proftpd configuration") WOFileUtils.searchreplace(self, "/etc/proftpd/" "proftpd.conf", @@ -1053,7 +1068,9 @@ def post_pref(self, apt_packages, packages, upgrade=False): Log.debug(self, "{0}".format(e)) Log.error(self, "Unable to add UFW rule") - if os.path.isfile("/etc/fail2ban/jail.d/custom.conf"): + if ((os.path.isfile("/etc/fail2ban/jail.d/custom.conf")) and + (not WOFileUtils.grep(self, "/etc/fail2ban/jail.d/custom.conf", + "proftpd"))): with open("/etc/fail2ban/jail.d/custom.conf", encoding='utf-8', mode='a') as f2bproftpd: f2bproftpd.write("\n\n[proftpd]\nenabled = true\n") @@ -1098,6 +1115,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): WOShellExec.cmd_exec(self, "systemctl enable redis-server") if (os.path.isfile("/etc/redis/redis.conf") and not WOFileUtils.grep(self, "/etc/mysql/my.cnf", "WordOps")): + Log.info(self, "Tuning Redis configuration") with open("/etc/redis/redis.conf", "a") as redis_file: redis_file.write("\n# WordOps v3.9.8\n") @@ -1157,11 +1175,13 @@ def post_pref(self, apt_packages, packages, upgrade=False): 'added by WordOps') if (packages): + # WP-CLI if any('/usr/local/bin/wp' == x[1] for x in packages): Log.debug(self, "Setting Privileges" " to /usr/local/bin/wp file ") WOFileUtils.chmod(self, "/usr/local/bin/wp", 0o775) + # PHPMyAdmin if any('/var/lib/wo/tmp/pma.tar.gz' == x[1] for x in packages): WOExtract.extract( @@ -1243,7 +1263,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): 'www-data', 'www-data', recursive=True) - + # MySQLtuner if any('/usr/bin/mysqltuner' == x[1] for x in packages): Log.debug(self, "CHMOD MySQLTuner in /usr/bin/mysqltuner") @@ -1258,18 +1278,25 @@ def post_pref(self, apt_packages, packages, upgrade=False): WOShellExec.cmd_exec(self, "bash /var/lib/wo/tmp/" "kickstart.sh " "--dont-wait") + if WOVariables.wo_distro == 'raspbian': + wo_netdata = "/" + else: + wo_netdata = "/opt/netdata/" # disable mail notifications - WOFileUtils.searchreplace(self, "/opt/netdata/usr/" + WOFileUtils.searchreplace(self, "{0}usr/" "lib/netdata/conf.d/" - "health_alarm_notify.conf", + "health_alarm_notify.conf" + .format(wo_netdata), 'SEND_EMAIL="YES"', 'SEND_EMAIL="NO"') # make changes persistant - WOFileUtils.copyfile(self, "/opt/netdata/usr/" + WOFileUtils.copyfile(self, "{0}usr/" "lib/netdata/conf.d/" - "health_alarm_notify.conf", - "/opt/netdata/etc/netdata/" - "health_alarm_notify.conf") + "health_alarm_notify.conf" + .format(wo_netdata), + "{0}etc/netdata/" + "health_alarm_notify.conf" + .format(wo_netdata)) # check if mysql credentials are available if os.path.isfile('/etc/mysql/conf.d/my.cnf'): try: @@ -1288,7 +1315,8 @@ def post_pref(self, apt_packages, packages, upgrade=False): Log.debug(self, "{0}".format(e)) Log.info( self, "fail to setup mysql user for netdata") - WOFileUtils.chown(self, '/opt/netdata', + WOFileUtils.chown(self, '{0}etc/netdata' + .format(wo_netdata), 'netdata', 'netdata', recursive=True) @@ -1457,10 +1485,6 @@ def post_pref(self, apt_packages, packages, upgrade=False): if any('/usr/local/bin/cht.sh' == x[1] for x in packages): WOFileUtils.chmod(self, "/usr/local/bin/cht.sh", 0o775) - if not WOFileUtils.grep(self, "~/.bashrc", "cheat"): - with open("~/.bashrc", - "a") as wo_bashrc: - wo_bashrc.write("\nalias cheat='cht.sh'\n") # phpredisadmin if any('/var/lib/wo/tmp/pra.tar.gz' == x[1] diff --git a/wo/cli/plugins/stack_services.py b/wo/cli/plugins/stack_services.py index e4585b4..4c5aa2a 100644 --- a/wo/cli/plugins/stack_services.py +++ b/wo/cli/plugins/stack_services.py @@ -89,7 +89,8 @@ class WOStackStatusController(CementBaseController): # netdata if pargs.netdata: - if os.path.isdir("/opt/netdata"): + if (os.path.isdir("/opt/netdata") or + os.path.isdir("/etc/netdata")): services = services + ['netdata'] else: Log.info(self, "Netdata is not installed") @@ -177,7 +178,8 @@ class WOStackStatusController(CementBaseController): # netdata if pargs.netdata: - if os.path.isdir("/opt/netdata"): + if (os.path.isdir("/opt/netdata") or + os.path.isdir("/etc/netdata")): services = services + ['netdata'] else: Log.info(self, "Netdata is not installed") @@ -261,7 +263,8 @@ class WOStackStatusController(CementBaseController): # netdata if pargs.netdata: - if os.path.isdir("/opt/netdata"): + if (os.path.isdir("/opt/netdata") or + os.path.isdir("/etc/netdata")): services = services + ['netdata'] else: Log.info(self, "Netdata is not installed") @@ -345,7 +348,8 @@ class WOStackStatusController(CementBaseController): # netdata if pargs.netdata: - if os.path.isdir("/opt/netdata"): + if (os.path.isdir("/opt/netdata") or + os.path.isdir("/etc/netdata")): services = services + ['netdata'] else: Log.info(self, "Netdata is not installed") @@ -429,7 +433,8 @@ class WOStackStatusController(CementBaseController): # netdata if pargs.netdata: - if os.path.isdir("/opt/netdata"): + if (os.path.isdir("/opt/netdata") or + os.path.isdir("/etc/netdata")): services = services + ['netdata'] else: Log.info(self, "Netdata is not installed") diff --git a/wo/cli/plugins/stack_upgrade.py b/wo/cli/plugins/stack_upgrade.py index efe4855..33a2f9b 100644 --- a/wo/cli/plugins/stack_upgrade.py +++ b/wo/cli/plugins/stack_upgrade.py @@ -3,7 +3,6 @@ import shutil from cement.core.controller import CementBaseController, expose from cement.core import handler, hook -from wo.core.apt_repo import WORepo from wo.core.aptget import WOAptGet from wo.core.download import WODownload from wo.core.extract import WOExtract @@ -77,6 +76,13 @@ class WOStackUpgradeController(CementBaseController): if pargs.all: pargs.web = True + pargs.netdata = True + pargs.composer = True + pargs.dashboard = True + pargs.phpmyadmin = True + pargs.redis = True + pargs.wpcli = True + pargs.php73 = True if pargs.web: if WOAptGet.is_installed(self, 'nginx-custom'): diff --git a/wo/cli/plugins/sync.py b/wo/cli/plugins/sync.py index 8495bec..1f9da5b 100644 --- a/wo/cli/plugins/sync.py +++ b/wo/cli/plugins/sync.py @@ -1,8 +1,8 @@ from cement.core.controller import CementBaseController, expose from cement.core import handler, hook from wo.core.fileutils import WOFileUtils -from wo.cli.plugins.sitedb import * -from wo.core.mysql import * +from wo.cli.plugins.sitedb import updateSiteInfo, getAllsites +from wo.core.mysql import WOMysql, StatementExcecutionError from wo.core.logging import Log import glob diff --git a/wo/core/aptget.py b/wo/core/aptget.py index ce66dff..3e3fe53 100644 --- a/wo/core/aptget.py +++ b/wo/core/aptget.py @@ -148,14 +148,16 @@ class WOAptGet(): try: with open('/var/log/wo/wordops.log', 'a') as f: if purge: - proc = subprocess.Popen('apt-get autoremove --purge ' - '--assume-yes {0}' + proc = subprocess.Popen('DEBIAN_FRONTEND=noninteractive ' + 'apt-get autoremove --purge ' + '-qq {0}' .format(all_packages), shell=True, stdin=None, stdout=f, stderr=f, executable="/bin/bash") else: - proc = subprocess.Popen('apt-get autoremove ' - '--assume-yes {0}' + proc = subprocess.Popen('DEBIAN_FRONTEND=noninteractive ' + 'apt-get autoremove ' + '-qq {0}' .format(all_packages), shell=True, stdin=None, stdout=f, stderr=f, executable="/bin/bash") diff --git a/wo/core/fileutils.py b/wo/core/fileutils.py index efc13c6..85654e2 100644 --- a/wo/core/fileutils.py +++ b/wo/core/fileutils.py @@ -244,6 +244,22 @@ class WOFileUtils(): Log.error(self, "Unable to Search string {0} in {1}" .format(sstr, fnm)) + def grepcheck(self, fnm, sstr): + """ + Searches for string in file and returns True or False. + """ + try: + Log.debug(self, "Finding string {0} to file {1}" + .format(sstr, fnm)) + for line in open(fnm, encoding='utf-8'): + if sstr in line: + return True + return False + except OSError as e: + Log.debug(self, "{0}".format(e.strerror)) + Log.error(self, "Unable to Search string {0} in {1}" + .format(sstr, fnm)) + def rm(self, path): """ Remove files diff --git a/wo/core/variables.py b/wo/core/variables.py index 4fff892..61a06eb 100644 --- a/wo/core/variables.py +++ b/wo/core/variables.py @@ -10,7 +10,7 @@ class WOVariables(): """Intialization of core variables""" # WordOps version - wo_version = "3.9.8.4" + wo_version = "3.9.8.5" # WordOps packages versions wo_wp_cli = "2.2.0" wo_adminer = "4.7.2" @@ -22,7 +22,7 @@ class WOVariables(): wo_wpcli_path = '/usr/local/bin/wp' # Current date and time of System - wo_date = datetime.datetime.now().strftime('%d%b%Y%H%M%S') + wo_date = datetime.datetime.now().strftime('%d%b%Y-%H-%M-%S') # WordOps core variables wo_distro = distro.linux_distribution( @@ -121,12 +121,12 @@ class WOVariables(): wo_php = ["php7.2-fpm", "php7.2-curl", "php7.2-gd", "php7.2-imap", "php7.2-readline", "php7.2-common", "php7.2-recode", - "php7.2-cli", "php7.2-mbstring", + "php7.2-cli", "php7.2-mbstring", "php7.2-intl", "php7.2-bcmath", "php7.2-mysql", "php7.2-opcache", "php7.2-zip", "php7.2-xml", "php7.2-soap"] wo_php73 = ["php7.3-fpm", "php7.3-curl", "php7.3-gd", "php7.3-imap", "php7.3-readline", "php7.3-common", "php7.3-recode", - "php7.3-cli", "php7.3-mbstring", + "php7.3-cli", "php7.3-mbstring", "php7.3-intl", "php7.3-bcmath", "php7.3-mysql", "php7.3-opcache", "php7.3-zip", "php7.3-xml", "php7.3-soap"] wo_php_extra = ["php-memcached", "php-imagick",