diff --git a/CHANGELOG.md b/CHANGELOG.md index bda29eb..12876bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +### v3.9.8.6 - 2019-08-30 + +#### Added + +- Subdomains are automatically secured with an existant Wildcard LetsEncrypt SSL certificate. +(If a wildcard certificate exist, WordOps will use this certificate for subdomains instead of issuing new certificates) +- MySQL & Redis stack to `wo stack remove/purge` + +#### Changed + +- Date format in backup name : /backup/30Aug2019035932 -> /backup/30Aug2019-03-59-32 +- Cleanup and update bash_completion +- cheat.sh is installed with WordOps install script, not as a stack because it wasn't downloaded at all by WordOps (unknown reason yet) + +#### Fixed + +- cache-enabler plugin not installed and configured with `wo site update site.tld --wpce` +- possible issue with domain variable in `--letsencrypt=wildcard` +- python3-mysqldb not available on Debian 8 (Jessie) +- Fix mysql variable skip-name-resolved +- Fix typo in redis tuning directives + ### v3.9.8.5 - 2019-08-30 #### Changed diff --git a/config/bash_completion.d/wo_auto.rc b/config/bash_completion.d/wo_auto.rc index d7e3cc9..56ec872 100644 --- a/config/bash_completion.d/wo_auto.rc +++ b/config/bash_completion.d/wo_auto.rc @@ -35,7 +35,7 @@ _wo_complete() "stack") COMPREPLY=( $(compgen \ - -W "upgrade install purge reload remove restart start status stop migrate" \ + -W "upgrade install purge reload remove restart start status stop" \ -- $cur) ) ;; @@ -74,12 +74,12 @@ _wo_complete() # HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE "install" | "purge" | "remove" ) COMPREPLY=( $(compgen \ - -W "--web --admin --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --all --redis --phpredisadmin --composer --netdata --fail2ban --dashboard --proftpd" \ + -W "--recommended --web --admin --security --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --phpredisadmin --composer --netdata --fail2ban --dashboard --proftpd --clamav --mysqlclient --mysqltuner --extplorer --all" \ -- $cur) ) ;; "upgrade" ) COMPREPLY=( $(compgen \ - -W "--web --nginx --php --php73 --mysql --all --netdata --composer --phpmyadmin --dashboard --no-prompt --wpcli" \ + -W "--web --admin --utils --nginx --php --php73 --mysql --all --netdata --composer --phpmyadmin --dashboard --no-prompt --mysqtuner --wpcli" \ -- $cur) ) ;; "start" | "stop" | "reload" | "restart" | "status") @@ -87,11 +87,6 @@ _wo_complete() -W "--nginx --php --php73 --mysql --redis --fail2ban --netdata -proftpd" \ -- $cur) ) ;; - "migrate") - COMPREPLY=( $(compgen \ - -W "--mariadb" \ - -- $cur) ) - ;; "list") COMPREPLY=( $(compgen \ -W "--enabled --disabled" \ @@ -159,13 +154,13 @@ _wo_complete() "create") COMPREPLY=( $(compgen \ - -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" \ + -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 -le --letsencrypt --letsencrypt=off --letsencrypt=clean -le=wildcard --dns --dns=dns_cf --dns=dns_do" \ + -W "--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=off --letsencrypt --letsencrypt=off --letsencrypt=clean -le=wildcard -le=clean --dns --dns=dns_cf --dns=dns_do" \ -- $cur) ) ;; "delete") @@ -230,9 +225,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=wildcard -le --php73 --dns --dns=dns_cf --dns=dns_do" + retlist="--wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce -le -le=wildcard --letsencrypt --letsencrypt=wildcard --php73 --dns --dns=dns_cf --dns=dns_do" elif [ ${COMP_WORDS[2]} == "update" ]; then - retlist="--wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do" + retlist="--wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le -le=off -le=wildcard --letsencrypt --letsencrypt=wildcard --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do" else retlist="" fi @@ -248,7 +243,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 -le --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do" + retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --php73 -le -le=off -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do" else retlist="" fi @@ -261,7 +256,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 -le --letsencrypt --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do" + retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=off --letsencrypt --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do" else retlist="" fi @@ -274,7 +269,7 @@ _wo_complete() "--web" | "--admin" | "--nginx" | "--php" | "--php73" | "--mysql" | "--wpcli" | "--phpmyadmin" | "--adminer" | "--utils" | "--fail2ban" | "--redis | --phpredisadmin | --netdata") if [[ ${COMP_WORDS[2]} == "install" || ${COMP_WORDS[2]} == "purge" || ${COMP_WORDS[2]} == "remove" ]]; then - retlist="--web --admin --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --fail2ban --phpredisadmin --netdata" + retlist="--web --admin --security --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --fail2ban --phpredisadmin --netdata -f --force" elif [[ ${COMP_WORDS[2]} == "start" || ${COMP_WORDS[2]} == "reload" || ${COMP_WORDS[2]} == "restart" || ${COMP_WORDS[2]} == "stop" ]]; then retlist="--nginx --php --php73 --mysql --redis --netdata" elif [[ ${COMP_WORDS[1]} == "debug" ]]; then @@ -314,7 +309,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=off " + retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=off -le=wildcard --letsencrypt --letsencrypt=off " else retlist="" fi @@ -363,7 +358,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=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 -le -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do" fi ret="${retlist[@]/$prev}" COMPREPLY=( $(compgen \ diff --git a/install b/install index 2085b53..f34f842 100755 --- a/install +++ b/install @@ -80,6 +80,10 @@ while [ "$#" -gt 0 ]; do -w | --wufw | --without-ufw) ufw="n" ;; + -v | --version) + wo_version="$2" + shift + ;; *) # positional args ;; esac @@ -438,8 +442,13 @@ wo_install() { { rm -f /etc/bash_completion.d/wo_auto.rc rm -rf /var/lib/wo/tmp/WordOps-* - curl -sL https://github.com/WordOps/WordOps/archive/${wo_branch}.tar.gz | tar -I pigz -xf - -C /var/lib/wo/tmp - cd /var/lib/wo/tmp/WordOps-${wo_branch} || exit 1 + if [ -z "$wo_version" ]; then + curl -sL https://github.com/WordOps/WordOps/archive/${wo_branch}.tar.gz | tar -I pigz -xf - -C /var/lib/wo/tmp + cd "/var/lib/wo/tmp/WordOps-$wo_branch" || exit 1 + else + curl -sL https://github.com/WordOps/WordOps/archive/v${wo_version}.tar.gz | tar -I pigz -xf - -C /var/lib/wo/tmp + cd "/var/lib/wo/tmp/WordOps-$wo_version" || exit 1 + fi } \ >> "$wo_install_log" 2>&1 @@ -716,12 +725,6 @@ 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 @@ -787,6 +790,14 @@ wo_ufw_setup() { } \ >> $wo_install_log +wo_cheat_install() { + curl -sL https://cht.sh/:cht.sh > /usr/local/bin/cht.sh + curl -sL https://cheat.sh/:bash_completion > /etc/bash_completion.d/cht.sh + if ! grep -q "cheat" $HOME/.bashrc; then + echo "alias cheat='/usr/local/bin/cht.sh'" >> "$HOME/.bashrc" + fi +} + ### # 4 - WO MAIN SETUP ### @@ -840,7 +851,7 @@ else 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_cheat_install | 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 @@ -893,7 +904,7 @@ else 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_cheat_alias | tee -ai $wo_install_log + wo_cheat_install | 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 @@ -928,7 +939,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_cheat_install | 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 ff19262..5f3cbd1 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.5', + version='3.9.8.6', description=long_description, long_description=long_description, classifiers=[], diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index a5259f1..9096a94 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -137,7 +137,7 @@ class WOSiteController(CementBaseController): Log.error(self, 'could not input site name') pargs.site_name = pargs.site_name.strip() (wo_domain, wo_www_domain) = ValidateDomain(pargs.site_name) - wo_domain_type, wo_root_domain = GetDomainlevel(wo_domain) + (wo_domain_type, wo_root_domain) = GetDomainlevel(wo_domain) wo_db_name = '' wo_db_user = '' wo_db_pass = '' @@ -162,7 +162,12 @@ class WOSiteController(CementBaseController): ssl = ("enabled" if siteinfo.is_ssl else "disabled") if (ssl == "enabled"): sslprovider = "Lets Encrypt" - sslexpiry = str(SSL.getExpirationDate(self, wo_domain)) + if os.path.islink("{0}/conf/nginx/ssl.conf" + .format(wo_site_webroot)): + sslexpiry = str( + SSL.getExpirationDate(self, wo_root_domain)) + else: + sslexpiry = str(SSL.getExpirationDate(self, wo_domain)) else: sslprovider = '' sslexpiry = '' @@ -424,7 +429,7 @@ class WOSiteCreateController(CementBaseController): pargs.site_name = pargs.site_name.strip() (wo_domain, wo_www_domain) = ValidateDomain(pargs.site_name) - wo_domain_type, wo_root_domain = GetDomainlevel(wo_domain) + (wo_domain_type, wo_root_domain) = GetDomainlevel(wo_domain) if not wo_domain.strip(): Log.error("Invalid domain name, " "Provide valid domain name") @@ -626,84 +631,56 @@ class WOSiteCreateController(CementBaseController): "and please try again") # Setup WordPress if Wordpress site - if (data['wp'] and (not pargs.vhostonly)): - try: - wo_wp_creds = setupwordpress(self, data) - # Add database information for site into database - updateSiteInfo(self, wo_domain, - db_name=data['wo_db_name'], - db_user=data['wo_db_user'], - db_password=data['wo_db_pass'], - db_host=data['wo_db_host']) - except SiteError as e: - # call cleanup actions on failure - Log.debug(self, str(e)) - Log.info(self, Log.FAIL + - "There was a serious error encountered...") - Log.info(self, Log.FAIL + "Cleaning up afterwards...") - doCleanupAction(self, domain=wo_domain, - webroot=data['webroot'], - dbname=data['wo_db_name'], - dbuser=data['wo_db_user'], - dbhost=data['wo_mysql_grant_host']) - deleteSiteInfo(self, wo_domain) - Log.error(self, "Check the log for details: " - "`tail /var/log/wo/wordops.log` " - "and please try again") - - if (data['wp'] and (pargs.vhostonly)): - try: - wo_wp_creds = setupwordpress(self, data) - # Add database information for site into database - updateSiteInfo(self, wo_domain, db_name=data['wo_db_name'], - db_user=data['wo_db_user'], - db_password=data['wo_db_pass'], - db_host=data['wo_db_host']) - except SiteError as e: - # call cleanup actions on failure - Log.debug(self, str(e)) - Log.info(self, Log.FAIL + - "There was a serious error encountered...") - Log.info(self, Log.FAIL + "Cleaning up afterwards...") - doCleanupAction(self, domain=wo_domain, - webroot=data['webroot'], - dbname=data['wo_db_name'], - dbuser=data['wo_db_user'], - dbhost=data['wo_db_host']) - deleteSiteInfo(self, wo_domain) - Log.error(self, "Check the log for details: " - "`tail /var/log/wo/wordops.log` " - "and please try again") - try: - wodbconfig = open("{0}/wo-config.php" - .format(wo_site_webroot), - encoding='utf-8', mode='w') - wodbconfig.write("" - .format(data['wo_db_name'], - data['wo_db_user'], - data['wo_db_pass'], - data['wo_db_host'])) - wodbconfig.close() - - except IOError as e: - Log.debug(self, str(e)) - Log.debug(self, "Error occured while generating " - "wo-config.php") - Log.info(self, Log.FAIL + - "There was a serious error encountered...") - Log.info(self, Log.FAIL + "Cleaning up afterwards...") - doCleanupAction(self, domain=wo_domain, - webroot=data['webroot'], - dbname=data['wo_db_name'], - dbuser=data['wo_db_user'], - dbhost=data['wo_db_host']) - deleteSiteInfo(self, wo_domain) - Log.error(self, "Check the log for details: " - "`tail /var/log/wo/wordops.log` " - "and please try again") + if data['wp']: + if not pargs.vhostonly: + try: + wo_wp_creds = setupwordpress(self, data) + # Add database information for site into database + updateSiteInfo(self, wo_domain, + db_name=data['wo_db_name'], + db_user=data['wo_db_user'], + db_password=data['wo_db_pass'], + db_host=data['wo_db_host']) + except SiteError as e: + # call cleanup actions on failure + Log.debug(self, str(e)) + Log.info(self, Log.FAIL + + "There was a serious error encountered...") + Log.info(self, Log.FAIL + "Cleaning up afterwards...") + doCleanupAction(self, domain=wo_domain, + webroot=data['webroot'], + dbname=data['wo_db_name'], + dbuser=data['wo_db_user'], + dbhost=data['wo_mysql_grant_host']) + deleteSiteInfo(self, wo_domain) + Log.error(self, "Check the log for details: " + "`tail /var/log/wo/wordops.log` " + "and please try again") + else: + try: + wo_wp_creds = setupwordpress( + self, data, vhostonly=True) + # Add database information for site into database + updateSiteInfo(self, wo_domain, + db_name=data['wo_db_name'], + db_user=data['wo_db_user'], + db_password=data['wo_db_pass'], + db_host=data['wo_db_host']) + except SiteError as e: + # call cleanup actions on failure + Log.debug(self, str(e)) + Log.info(self, Log.FAIL + + "There was a serious error encountered...") + Log.info(self, Log.FAIL + "Cleaning up afterwards...") + doCleanupAction(self, domain=wo_domain, + webroot=data['webroot'], + dbname=data['wo_db_name'], + dbuser=data['wo_db_user'], + dbhost=data['wo_mysql_grant_host']) + deleteSiteInfo(self, wo_domain) + Log.error(self, "Check the log for details: " + "`tail /var/log/wo/wordops.log` " + "and please try again") # Service Nginx Reload call cleanup if failed to reload nginx if not WOService.reload_service(self, 'nginx'): @@ -785,12 +762,33 @@ class WOSiteCreateController(CementBaseController): else: wo_wildcard = False wo_subdomain = False + Log.debug(self, "Domain type = {0}" + .format(wo_domain_type)) if ((wo_domain_type == 'subdomain') and (not pargs.letsencrypt == 'wildcard')): wo_subdomain = True - - setupLetsEncrypt(self, wo_domain, wo_subdomain, wo_wildcard, - wo_dns, wo_acme_dns) + # check if a wildcard cert for the root domain exist + Log.debug(self, "checkWildcardExist on *.{0}" + .format(wo_root_domain)) + isWildcard = checkWildcardExist(self, wo_root_domain) + Log.debug(self, "isWildcard = {0}".format(isWildcard)) + if isWildcard: + Log.info(self, "Using existing Wildcard SSL " + "certificate from {0} to secure {1}" + .format(wo_root_domain, wo_domain)) + Log.debug(self, "symlink wildcard " + "cert between {0} & {1}" + .format(wo_domain, wo_root_domain)) + # copy the cert from the root domain + copyWildcardCert(self, wo_domain, wo_root_domain) + else: + Log.debug(self, "Setup Cert with acme.sh for {0}" + .format(wo_domain)) + setupLetsEncrypt(self, wo_domain, wo_subdomain, + wo_wildcard, wo_dns, wo_acme_dns) + else: + setupLetsEncrypt(self, wo_domain, wo_subdomain, + wo_wildcard, wo_dns, wo_acme_dns) httpsRedirect(self, wo_domain, True, wo_wildcard) if pargs.hsts: @@ -855,7 +853,8 @@ class WOSiteUpdateController(CementBaseController): (['--wprocket'], dict(help="update to WP-Rocket cache", action='store_true')), (['--wpce'], - dict(help="update to Cache-Enabler cache", action='store_true')), + dict(help="update to Cache-Enabler cache", + action='store_true')), (['--wpredis'], dict(help="update to redis cache", action='store_true')), (['-le', '--letsencrypt'], @@ -1240,12 +1239,6 @@ class WOSiteUpdateController(CementBaseController): return 0 if pargs.letsencrypt: - if ((wo_domain_type == 'subdomain') and - (not pargs.letsencrypt == 'wildcard') and - (not pargs.letsencrypt == 'off') and - (not pargs.letsencrypt == 'clean') and - (not pargs.letsencrypt == 'purge')): - pargs.letsencrypt == 'subdomain' if pargs.letsencrypt == 'on': data['letsencrypt'] = True letsencrypt = True @@ -1281,14 +1274,15 @@ class WOSiteUpdateController(CementBaseController): wo_subdomain = False wo_wildcard = False - if letsencrypt is check_ssl: - if letsencrypt is False: - Log.error(self, "SSl is not configured for given " - "site") - elif letsencrypt is True: - Log.error(self, "SSl is already configured for given " - "site") - pargs.letsencrypt = False + if not wo_subdomain: + if letsencrypt is check_ssl: + if letsencrypt is False: + Log.error(self, "SSl is not configured for given " + "site") + elif letsencrypt is True: + Log.error(self, "SSl is already configured for given " + "site") + pargs.letsencrypt = False if data and (not pargs.php73): if old_php73 is True: @@ -1382,9 +1376,30 @@ class WOSiteUpdateController(CementBaseController): wo_acme_dns = '' wo_dns = False if not os.path.isfile("{0}/conf/nginx/ssl.conf.disabled"): - setupLetsEncrypt(self, wo_domain, wo_subdomain, - wo_wildcard, - wo_dns, wo_acme_dns) + if wo_subdomain: + # check if a wildcard cert for the root domain exist + Log.debug(self, "checkWildcardExist on *.{0}" + .format(wo_root_domain)) + isWildcard = checkWildcardExist(self, wo_root_domain) + Log.debug(self, "isWildcard = {0}".format(isWildcard)) + if isWildcard: + Log.info(self, "Using existing Wildcard SSL " + "certificate from {0} to secure {1}" + .format(wo_root_domain, wo_domain)) + Log.debug(self, "symlink wildcard " + "cert between {0} & {1}" + .format(wo_domain, wo_root_domain)) + # copy the cert from the root domain + copyWildcardCert(self, wo_domain, wo_root_domain) + else: + Log.debug(self, "Setup Cert with acme.sh for {0}" + .format(wo_domain)) + setupLetsEncrypt(self, wo_domain, wo_subdomain, + wo_wildcard, wo_dns, wo_acme_dns) + else: + setupLetsEncrypt(self, wo_domain, wo_subdomain, + wo_wildcard, wo_dns, wo_acme_dns) + httpsRedirect(self, wo_domain, True, wo_wildcard) site_url_https(self, wo_domain) else: @@ -1405,22 +1420,36 @@ class WOSiteUpdateController(CementBaseController): Log.error(self, "service nginx reload failed. " "check issues with `nginx -t` command") Log.info(self, "Congratulations! Successfully " - "Configured SSl for Site " + "Configured SSL for Site " " https://{0}".format(wo_domain)) - - if (SSL.getExpirationDays(self, wo_domain) > 0): - Log.info(self, "Your cert will expire within " + - str(SSL.getExpirationDays(self, wo_domain)) + - " days.") + if wo_subdomain: + if (SSL.getExpirationDays(self, wo_root_domain) > 0): + Log.info(self, "Your cert will expire within " + + str(SSL.getExpirationDays(self, wo_root_domain)) + + " days.") + else: + Log.warn( + self, "Your cert already EXPIRED ! " + ".PLEASE renew soon . ") else: - Log.warn( - self, "Your cert already EXPIRED ! " - ".PLEASE renew soon . ") + if (SSL.getExpirationDays(self, wo_domain) > 0): + Log.info(self, "Your cert will expire within " + + str(SSL.getExpirationDays(self, wo_domain)) + + " days.") + else: + Log.warn( + self, "Your cert already EXPIRED ! " + ".PLEASE renew soon . ") elif data['letsencrypt'] is False: if pargs.letsencrypt == "off": - if os.path.isfile("{0}/conf/nginx/ssl.conf" + if os.path.islink("{0}/conf/nginx/ssl.conf" .format(wo_site_webroot)): + WOFileUtils.remove_symlink(self, + "{0}/conf/nginx/ssl.conf" + .format(wo_site_webroot)) + elif os.path.isfile("{0}/conf/nginx/ssl.conf" + .format(wo_site_webroot)): Log.info(self, 'Setting Nginx configuration') WOFileUtils.mvfile(self, "{0}/conf/nginx/ssl.conf" .format(wo_site_webroot), @@ -1434,6 +1463,10 @@ class WOSiteUpdateController(CementBaseController): '{0}/conf/nginx/' 'hsts.conf.disabled' .format(wo_site_webroot)) + # find all broken symlinks + sympath = "/var/www" + WOFileUtils.findBrokenSymlink(self, sympath) + elif (pargs.letsencrypt == "clean" or pargs.letsencrypt == "purge"): removeAcmeConf(self, wo_domain) @@ -1557,7 +1590,8 @@ class WOSiteUpdateController(CementBaseController): "and please try again") return 1 - if ((oldcachetype in ['wpsc', 'basic', 'wpredis', 'wprocket', 'wpce'] and + if ((oldcachetype in ['wpsc', 'basic', 'wpredis', 'wprocket', + 'wpce'] and (data['wpfc'])) or (oldsitetype == 'wp' and data['multisite'] and data['wpfc'])): try: @@ -1566,7 +1600,7 @@ class WOSiteUpdateController(CementBaseController): "enable_purge": 1, "enable_map": "0", "enable_log": 0, - "enable_stamp": 0, + "enable_stamp": 1, "purge_homepage_on_new": 1, "purge_homepage_on_edit": 1, "purge_homepage_on_del": 1, @@ -1584,9 +1618,9 @@ class WOSiteUpdateController(CementBaseController): "redis_port": "6379", "redis_prefix": "nginx-cache:"} plugin_data = json.dumps(plugin_data_object) - setupwp_plugin( - self, 'nginx-helper', - 'rt_wp_nginx_helper_options', plugin_data, data) + setupwp_plugin(self, 'nginx-helper', + 'rt_wp_nginx_helper_options', + plugin_data, data) except SiteError as e: Log.debug(self, str(e)) Log.info(self, Log.FAIL + "Update nginx-helper " @@ -1596,7 +1630,8 @@ class WOSiteUpdateController(CementBaseController): "and please try again") return 1 - elif ((oldcachetype in ['wpsc', 'basic', 'wpfc', 'wprocket', 'wpce'] and + elif ((oldcachetype in ['wpsc', 'basic', 'wpfc', + 'wprocket', 'wpce'] and (data['wpredis'])) or (oldsitetype == 'wp' and data['multisite'] and data['wpredis'])): @@ -1606,7 +1641,7 @@ class WOSiteUpdateController(CementBaseController): "enable_purge": 1, "enable_map": "0", "enable_log": 0, - "enable_stamp": 0, + "enable_stamp": 1, "purge_homepage_on_new": 1, "purge_homepage_on_edit": 1, "purge_homepage_on_del": 1, @@ -1624,9 +1659,9 @@ class WOSiteUpdateController(CementBaseController): "redis_port": "6379", "redis_prefix": "nginx-cache:"} plugin_data = json.dumps(plugin_data_object) - setupwp_plugin( - self, 'nginx-helper', - 'rt_wp_nginx_helper_options', plugin_data, data) + setupwp_plugin(self, 'nginx-helper', + 'rt_wp_nginx_helper_options', + plugin_data, data) except SiteError as e: Log.debug(self, str(e)) Log.info(self, Log.FAIL + "Update nginx-helper " @@ -1635,37 +1670,9 @@ class WOSiteUpdateController(CementBaseController): " `tail /var/log/wo/wordops.log` " "and please try again") return 1 - - elif ((oldcachetype in ['wpsc', 'basic', 'wpfc', 'wprocket', 'wpredis'] and - (data['wpce'])) or (oldsitetype == 'wp' and - data['multisite'] and - data['wpce'])): - try: - plugin_data_object = {"expires": 24, - "new_post": 1, - "new_comment": 0, - "webp": 0, - "clear_on_upgrade": 1, - "compress": 0, - "excl_ids": "", - "excl_regexp": "", - "excl_cookies": "", - "incl_attributes": "", - "minify_html": 1} - plugin_data = json.dumps(plugin_data_object) - setupwp_plugin( - self, 'cache-enabler', - 'cache-enabler', plugin_data, data) - except SiteError as e: - Log.debug(self, str(e)) - Log.info(self, Log.FAIL + "Update cache-enabler " - "settings failed. " - "Check the log for details:" - " `tail /var/log/wo/wordops.log` " - "and please try again") - return 1 else: try: + # disable nginx-helper plugin_data_object = {"log_level": "INFO", "log_filesize": 5, "enable_purge": 0, @@ -1701,6 +1708,36 @@ class WOSiteUpdateController(CementBaseController): "and please try again") return 1 + if ((oldcachetype in ['wpsc', 'basic', 'wpfc', 'wprocket', 'wpredis'] and + (data['wpce'])) or (oldsitetype == 'wp' and + data['multisite'] and + data['wpce'])): + try: + installwp_plugin(self, 'cache-enabler', data) + # setup cache-enabler + plugin_data_object = {"expires": 24, + "new_post": 1, + "new_comment": 0, + "webp": 0, + "clear_on_upgrade": 1, + "compress": 0, + "excl_ids": "", + "excl_regexp": "", + "excl_cookies": "", + "incl_attributes": "", + "minify_html": 1} + plugin_data = json.dumps(plugin_data_object) + setupwp_plugin(self, 'cache-enabler', + 'cache-enabler', plugin_data, data) + except SiteError as e: + Log.debug(self, str(e)) + Log.info(self, Log.FAIL + "Update cache-enabler " + "settings failed. " + "Check the log for details:" + " `tail /var/log/wo/wordops.log` " + "and please try again") + return 1 + if oldcachetype == 'wpsc' and not data['wpsc']: try: uninstallwp_plugin(self, 'wp-super-cache', data) @@ -1832,6 +1869,7 @@ class WOSiteDeleteController(CementBaseController): pargs.site_name = (input('Enter site name : ') .strip()) except IOError as e: + Log.debug(self, str(e)) Log.error(self, 'could not input site name') pargs.site_name = pargs.site_name.strip() diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index c0b9b17..1ecec76 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -6,6 +6,7 @@ import json import re import string import subprocess +import csv from subprocess import CalledProcessError from wo.cli.plugins.sitedb import getSiteInfo @@ -229,7 +230,7 @@ def setupdatabase(self, data): return(data) -def setupwordpress(self, data): +def setupwordpress(self, data, vhostonly=False): wo_domain_name = data['site_name'] wo_site_webroot = data['webroot'] prompt_wpprefix = self.app.config.get('wordpress', 'prefix') @@ -531,13 +532,13 @@ def setupwordpress(self, data): "enable_purge": 1, "enable_map": "0", "enable_log": 0, - "enable_stamp": 0, + "enable_stamp": 1, "purge_homepage_on_new": 1, "purge_homepage_on_edit": 1, "purge_homepage_on_del": 1, "purge_archive_on_new": 1, - "purge_archive_on_edit": 0, - "purge_archive_on_del": 0, + "purge_archive_on_edit": 1, + "purge_archive_on_del": 1, "purge_archive_on_new_comment": 0, "purge_archive_on_deleted_comment": 0, "purge_page_on_mod": 1, @@ -557,13 +558,13 @@ def setupwordpress(self, data): "enable_purge": 1, "enable_map": "0", "enable_log": 0, - "enable_stamp": 0, + "enable_stamp": 1, "purge_homepage_on_new": 1, "purge_homepage_on_edit": 1, "purge_homepage_on_del": 1, "purge_archive_on_new": 1, - "purge_archive_on_edit": 0, - "purge_archive_on_del": 0, + "purge_archive_on_edit": 1, + "purge_archive_on_del": 1, "purge_archive_on_new_comment": 0, "purge_archive_on_deleted_comment": 0, "purge_page_on_mod": 1, @@ -588,6 +589,7 @@ def setupwordpress(self, data): """Install Cache-Enabler""" if data['wpce']: + installwp_plugin(self, 'cache-enabler', data) plugin_data_object = {"expires": 24, "new_post": 1, "new_comment": 0, @@ -603,6 +605,15 @@ def setupwordpress(self, data): setupwp_plugin(self, 'cache-enabler', 'cache-enabler', plugin_data, data) + if vhostonly: + try: + WOShellExec.cmd_exec(self, "/bin/bash -c \"{0} --allow-root " + .format(WOVariables.wo_wpcli_path) + + "db clean --yes\"") + WOFileUtils.rm(self, "{0}/htdocs/*".format(wo_site_webroot)) + except CommandExecutionError: + raise SiteError("Cleaning WordPress install failed") + wp_creds = dict(wp_user=wo_wp_user, wp_pass=wo_wp_pass, wp_email=wo_wp_email) @@ -988,6 +999,16 @@ def display_cache_settings(self, data): "\thttp://{0}/wp-admin/options-general.php?" "page=nginx".format(data['site_name'])) + if data['wpce']: + if data['multisite']: + Log.info(self, "Nginx-Helper configuration :" + "\thttp://{0}/wp-admin/network/settings.php?" + "page=cache-enabler".format(data['site_name'])) + else: + Log.info(self, "Nginx-Helper configuration :" + "\thttp://{0}/wp-admin/options-general.php?" + "page=cache-enabler".format(data['site_name'])) + def logwatch(self, logfiles): import zlib @@ -1214,6 +1235,10 @@ def removeNginxConf(self, domain): def removeAcmeConf(self, domain): + sslconf = ("/var/www/{0}/conf/nginx/ssl.conf" + .format(domain)) + sslforce = ("/etc/nginx/conf.d/force-ssl-{0}.conf" + .format(domain)) if os.path.isdir('/etc/letsencrypt/renewal/{0}_ecc' .format(domain)): Log.info(self, "Removing Acme configuration") @@ -1229,18 +1254,27 @@ def removeAcmeConf(self, domain): Log.debug(self, "{0}".format(e)) Log.error(self, "Cert removal failed") - WOFileUtils.rm(self, '/etc/letsencrypt/renewal/{0}_ecc' - .format(domain)) - WOFileUtils.rm(self, '/etc/letsencrypt/live/{0}' - .format(domain)) - WOFileUtils.rm(self, '/var/www/{0}/conf/nginx/ssl.conf' - .format(domain)) - WOFileUtils.rm(self, '/var/www/{0}/conf/nginx/ssl.conf.disabled' - .format(domain)) - WOFileUtils.rm(self, '/etc/nginx/conf.d/force-ssl-{0}.conf' - .format(domain)) - WOFileUtils.rm(self, '/etc/nginx/conf.d/force-ssl-{0}.conf.disabled' + WOFileUtils.rm(self, '{0}/{1}_ecc' + .format(WOVariables.wo_ssl_archive, domain)) + WOFileUtils.rm(self, '{0}/{1}' + .format(WOVariables.wo_ssl_live, domain)) + WOFileUtils.rm(self, '{0}'.format(sslconf)) + WOFileUtils.rm(self, '{0}.disabled'.format(sslconf)) + WOFileUtils.rm(self, '{0}'.format(sslforce)) + WOFileUtils.rm(self, '{0}.disabled' + .format(sslforce)) + WOFileUtils.rm(self, '/etc/letsencrypt/shared/{0}.conf' .format(domain)) + + # find all broken symlinks + sympath = "/var/www" + WOFileUtils.findBrokenSymlink(self, sympath) + + else: + if os.path.islink("{0}".format(sslconf)): + WOFileUtils.remove_symlink(self, "{0}".format(sslconf)) + WOFileUtils.rm(self, '{0}'.format(sslforce)) + if WOFileUtils.grepcheck(self, '/var/www/22222/conf/nginx/ssl.conf', '{0}'.format(domain)): Log.info(self, "Setting back default certificate for WordOps backend") @@ -1339,7 +1373,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False, self, "Validation : DNS mode with {0}".format(wo_acme_dns)) else: acme_mode = "-w /var/www/html" - validation_mode = "Webroot challenge" + validation_mode = "Subdomain Webroot challenge" Log.debug(self, "Validation : Webroot mode") if subdomain: Log.info(self, "Issuing subdomain SSL cert with acme.sh") @@ -1356,7 +1390,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False, Log.info(self, "Validation mode : {0}".format(validation_mode)) ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) + "--issue " - "-d {0} -d *.{0} --dns {1} " + "-d {0} -d '*.{0}' --dns {1} " "-k {2} -f" .format(wo_domain_name, wo_acme_dns, @@ -1435,6 +1469,61 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False, "you are running Let\'s Encrypt Client " "\n to allow it to verify the site automatically.") +# check if a wildcard exist to secure a new subdomain + + +def checkWildcardExist(self, wo_domain_name): + + wo_acme_exec = ("/etc/letsencrypt/acme.sh --config-home " + "'/etc/letsencrypt/config'") + # export certificates list from acme.sh + WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) + + "--list --listraw > /var/lib/wo/cert.csv") + + # define new csv dialect + csv.register_dialect('acmeconf', delimiter='|') + # open file + certfile = open('/var/lib/wo/cert.csv', 'rt') + reader = csv.reader(certfile, 'acmeconf') + wo_wildcard_domain = ("*.{0}".format(wo_domain_name)) + for row in reader: + if wo_wildcard_domain in row[2]: + isWildcard = True + break + else: + isWildcard = False + certfile.close() + + return isWildcard + + +# copy wildcard certificate to a subdomain + + +def copyWildcardCert(self, wo_domain_name, wo_root_domain): + + if os.path.isfile("/var/www/{0}/conf/nginx/ssl.conf" + .format(wo_root_domain)): + try: + if not os.path.isdir("/etc/letsencrypt/shared"): + WOFileUtils.mkdir(self, "/etc/letsencrypt/shared") + if not os.path.isfile("/etc/letsencrypt/shared/{0}.conf" + .format(wo_root_domain)): + WOFileUtils.copyfile(self, "/var/www/{0}/conf/nginx/ssl.conf" + .format(wo_root_domain), + "/etc/letsencrypt/shared/{0}.conf" + .format(wo_root_domain)) + WOFileUtils.create_symlink(self, ["/etc/letsencrypt/shared/" + "{0}.conf" + .format(wo_root_domain), + '/var/www/{0}/conf/nginx/' + 'ssl.conf' + .format(wo_domain_name)]) + except IOError as e: + Log.debug(self, str(e)) + Log.debug(self, "Error occured while " + "creating symlink for ssl cert") + # letsencrypt cert renewal @@ -1514,9 +1603,6 @@ def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False): else: if wildcard: try: - Log.info( - self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf" - .format(wo_domain_name)) sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf" .format(wo_domain_name), encoding='utf-8', mode='w') @@ -1536,10 +1622,6 @@ def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False): else: try: - Log.info( - self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf" - .format(wo_domain_name)) - sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf" .format(wo_domain_name), encoding='utf-8', mode='w') diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 33b6f01..c829708 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -45,7 +45,6 @@ class WOStackController(CementBaseController): label = 'stack' stacked_on = 'base' stacked_type = 'nested' - exit_on_close = True description = 'Stack command manages stack operations' arguments = [ (['--all'], @@ -91,8 +90,6 @@ class WOStackController(CementBaseController): dict(help='Install ClamAV stack', action='store_true')), (['--utils'], dict(help='Install Utils stack', action='store_true')), - (['--cheat'], - dict(help='Install cheat.sh stack', action='store_true')), (['--redis'], dict(help='Install Redis', action='store_true')), (['--phpredisadmin'], @@ -128,8 +125,7 @@ class WOStackController(CementBaseController): (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.extplorer) and (not pargs.clamav) and (not pargs.phpredisadmin) and (not pargs.php73)): pargs.web = True @@ -159,7 +155,6 @@ class WOStackController(CementBaseController): pargs.dashboard = True pargs.phpredisadmin = True pargs.extplorer = True - pargs.cheat = True if pargs.security: pargs.fail2ban = True @@ -418,17 +413,6 @@ 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") @@ -517,8 +501,7 @@ class WOStackController(CementBaseController): (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.extplorer) and (not pargs.clamav) and (not pargs.phpredisadmin) and (not pargs.php73)): pargs.web = True @@ -724,8 +707,7 @@ class WOStackController(CementBaseController): (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.extplorer) and (not pargs.clamav) and (not pargs.phpredisadmin) and (not pargs.php73)): pargs.web = True @@ -753,7 +735,6 @@ class WOStackController(CementBaseController): pargs.composer = True pargs.netdata = True pargs.mysqltuner = True - pargs.cheat = True if pargs.security: pargs.fail2ban = True diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index bf1e816..2be7ad9 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -907,7 +907,8 @@ def post_pref(self, apt_packages, packages, upgrade=False): "wait_timeout " "= 600", "wait_timeout " - "= 120") + "= 120\n" + "skip-name-resolve = 1\n") # disabling mariadb binlog WOFileUtils.searchreplace(self, "/etc/mysql/my.cnf", @@ -957,8 +958,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): "table_open_cache = 16000") WOFileUtils.searchreplace(self, "/etc/mysql/my.cnf", "max_allowed_packet = 16M", - "max_allowed_packet = 64M\n" - "skip-name-resolve=1\n") + "max_allowed_packet = 64M\n") WOService.stop_service(self, 'mysql') WOFileUtils.mvfile(self, '/var/lib/mysql/ib_logfile0', @@ -1114,7 +1114,8 @@ def post_pref(self, apt_packages, packages, upgrade=False): Log.debug(self, "Enabling redis systemd service") 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")): + not WOFileUtils.grep(self, "/etc/redis/redis.conf", + "WordOps")): Log.info(self, "Tuning Redis configuration") with open("/etc/redis/redis.conf", "a") as redis_file: @@ -1481,11 +1482,6 @@ def post_pref(self, apt_packages, packages, upgrade=False): for x in packages): WOFileUtils.chmod(self, "/usr/bin/pt-query-advisor", 0o775) - # cht.sh - if any('/usr/local/bin/cht.sh' == x[1] - for x in packages): - WOFileUtils.chmod(self, "/usr/local/bin/cht.sh", 0o775) - # phpredisadmin if any('/var/lib/wo/tmp/pra.tar.gz' == x[1] for x in packages): diff --git a/wo/core/domainvalidate.py b/wo/core/domainvalidate.py index 9008f82..574f6bc 100644 --- a/wo/core/domainvalidate.py +++ b/wo/core/domainvalidate.py @@ -40,11 +40,11 @@ def GetDomainlevel(domain): for domain_suffix in Suffix_file: if (str(domain_suffix).strip()) == ('.'.join(domain_name[1:])): domain_type = 'domain' - root_domain = domain_name[0:] + root_domain = ('.'.join(domain_name[0:])) break elif (str(domain_suffix).strip()) == ('.'.join(domain_name[2:])): domain_type = 'subdomain' - root_domain = domain_name[1:] + root_domain = ('.'.join(domain_name[1:])) break else: domain_type = 'other' diff --git a/wo/core/fileutils.py b/wo/core/fileutils.py index 85654e2..cc6678f 100644 --- a/wo/core/fileutils.py +++ b/wo/core/fileutils.py @@ -279,3 +279,33 @@ class WOFileUtils(): Log.debug(self, "{0}".format(e)) Log.error(self, "Unable to remove file : {0} " .format(path)) + + def findBrokenSymlink(self, sympath): + """ + Find symlinks + """ + links = [] + broken = [] + + for root, dirs, files in os.walk(sympath): + if root.startswith('./.git'): + # Ignore the .git directory. + continue + for filename in files: + path = os.path.join(root, filename) + if os.path.islink(path): + target_path = os.readlink(path) + # Resolve relative symlinks + if not os.path.isabs(target_path): + target_path = os.path.join(os.path.dirname(path), + target_path) + if not os.path.exists(target_path): + links.append(path) + broken.append(path) + os.remove(path) + else: + links.append(path) + else: + # If it's not a symlink we're not interested. + continue + return True diff --git a/wo/core/variables.py b/wo/core/variables.py index 61a06eb..d31594e 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.5" + wo_version = "3.9.8.6" # WordOps packages versions wo_wp_cli = "2.2.0" wo_adminer = "4.7.2" @@ -147,11 +147,18 @@ class WOVariables(): if wo_distro == 'raspbian': wo_mysql = ["mariadb-server", "percona-toolkit", "python3-mysqldb"] + elif wo_distro == 'debian': + if wo_platform_codename == 'jessie': + wo_mysql = ["mariadb-server", "percona-toolkit", + "python3-mysql.connector"] else: wo_mysql = ["mariadb-server", "percona-toolkit", "python3-mysqldb", "mariadb-backup"] - wo_mysql_client = ["mariadb-client", "python3-mysqldb"] + if wo_platform_codename == 'jessie': + wo_mysql_client = ["mariadb-client", "python3-mysqldb"] + else: + wo_mysql_client = ["mariadb-client", "python3-mysql.connector"] wo_fail2ban = ["fail2ban"]