From b8623f0e3247cf94e78e3fc698536daba989e014 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sat, 31 Aug 2019 17:15:38 +0200 Subject: [PATCH 01/20] Fix vhostonly and exit status in install --- install | 11 +++++------ wo/cli/plugins/site.py | 2 -- wo/cli/plugins/site_functions.py | 5 ++++- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/install b/install index 438411d..742e6d2 100755 --- a/install +++ b/install @@ -151,7 +151,8 @@ readonly TIME=$(date +"$TIME_FORMAT") readonly NGINX_BACKUP_FILE="/var/lib/wo-backup/nginx-backup.$TIME.tar.gz" readonly EE_BACKUP_FILE="/var/lib/wo-backup/ee-backup.$TIME.tar.gz" readonly WO_BACKUP_FILE="/var/lib/wo-backup/wo-backup.$TIME.tar.gz" -readonly wo_env=$(grep "container=lxc" /proc/1/environ) +readonly wo_lxc=$(grep "container=lxc" /proc/1/environ) +readonly wo_wsl=$(grep "wsl" /proc/1/environ) WO_ARCH="$(uname -m)" if [ -x /usr/local/bin/ee ]; then @@ -653,7 +654,7 @@ wo_remove_ee_cron() { wo_tweak_kernel() { - if [ "$WO_ARCH" = "x86_64" ] && [ -z "$wo_env" ]; then + if [ "$WO_ARCH" = "x86_64" ] && [ -z "$wo_lxc" ] && [ -z "$wo_wsl" ]; then rm -f /etc/sysctl.d/60-ubuntu-nginx-web-server.conf wget -qO /etc/sysctl.d/60-wo-tweaks.conf https://raw.githubusercontent.com/WordOps/WordOps/"$wo_branch"/wo/cli/templates/sysctl.mustache if [ "$wo_distro_version" = "bionic" ] || [ "$wo_distro_version" = "disco" ] || [ "$wo_distro_version" = "buster" ]; then @@ -813,8 +814,7 @@ else if [ -x /usr/local/bin/wo ]; then if [ -z "$wo_force_install" ]; then if { wo -v 2>&1 | grep -q "$wo_version_new"; }; then - wo_lib_error "You already have WordOps $wo_version_new" - exit 1 + wo_lib_error "You already have WordOps $wo_version_new" 1 fi fi wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log @@ -861,8 +861,7 @@ else 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 + wo_lib_error "Not installing WordOps" 1 fi fi wo_lib_echo "Installing wo dependencies " | tee -ai $wo_install_log diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index 9096a94..e3a4248 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -499,10 +499,8 @@ class WOSiteCreateController(CementBaseController): if data and pargs.php73: data['php73'] = True - php73 = 1 elif data: data['php73'] = False - php73 = 0 if ((not pargs.wpfc) and (not pargs.wpsc) and diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index 201d37e..2afa650 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -610,7 +610,10 @@ def setupwordpress(self, data, vhostonly=False): 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)) + WOFileUtils.rm(self, "{0}/htdocs".format(wo_site_webroot)) + WOFileUtils.mkdir(self, "{0}/htdocs".format(wo_site_webroot)) + WOFileUtils.chown(self, "{0}/htdocs".format(wo_site_webroot), + 'www-data', 'www-data') except CommandExecutionError: raise SiteError("Cleaning WordPress install failed") From e0e2ab21c03c8a2fdb792fa1bcc3db163bfef764 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 13:59:27 +0200 Subject: [PATCH 02/20] Several fixes --- CHANGELOG.md | 7 ++ wo/cli/plugins/stack.py | 3 + wo/cli/plugins/stack_pref.py | 164 ++++++++++++++++++----------------- wo/core/fileutils.py | 6 +- 4 files changed, 98 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99250b1..5705bc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +#### Fixed + +- ufw rules for proftpd not applied +- phpredisadmin install +- netdata configuration + + ### v3.9.8.7 - 2019-08-31 #### Changed diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index d9feefc..8416ab1 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -312,6 +312,9 @@ class WOStackController(CementBaseController): # Composer if pargs.composer: + if ((not WOAptGet.is_installed(self, 'php7.2-fpm')) and + (not WOAptGet.is_installed(self, 'php7.3-fpm'))): + pargs.php = True if not os.path.isfile('/usr/local/bin/composer'): Log.debug(self, "Setting packages variable for Composer ") packages = packages + [["https://getcomposer.org/" diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index 375c44d..0d2a58f 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -47,11 +47,13 @@ def pre_pref(self, apt_packages): if set(WOVariables.wo_mysql).issubset(set(apt_packages)): # generate random 24 characters root password chars = ''.join(random.sample(string.ascii_letters, 24)) + # configure MySQL non-interactive install - if (not WOVariables.wo_distro == 'raspbian'): - mariadb_ver = '10.3' - else: + if ((WOVariables.wo_distro == 'raspbian') and + (WOVariables.wo_platform_codename == 'stretch')): mariadb_ver = '10.1' + else: + mariadb_ver = '10.3' Log.debug(self, "Pre-seeding MySQL") Log.debug(self, "echo \"mariadb-server-{0} " @@ -1072,17 +1074,20 @@ def post_pref(self, apt_packages, packages, upgrade=False): WOService.restart_service(self, 'proftpd') # add rule for proftpd with UFW - if WOAptGet.is_installed(self, 'ufw'): + if os.path.isdir('/etc/ufw'): try: - WOShellExec.cmd_exec(self, "/usr/bin/ufw allow " - "49000:50000/tcp") + WOShellExec.cmd_exec( + self, "ufw allow 49000:50000/tcp") + WOShellExec.cmd_exec( + self, "ufw reload") except CommandExecutionError as e: Log.debug(self, "{0}".format(e)) Log.error(self, "Unable to add UFW rule") if ((os.path.isfile("/etc/fail2ban/jail.d/custom.conf")) and - (not WOFileUtils.grep(self, "/etc/fail2ban/jail.d/custom.conf", - "proftpd"))): + (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") @@ -1108,17 +1113,13 @@ def post_pref(self, apt_packages, packages, upgrade=False): if not os.path.isfile("/etc/nginx/conf.d/redis.conf"): with open("/etc/nginx/conf.d/redis.conf", "a") as redis_file: - redis_file.write("# Log format Settings\n" - "log_format rt_cache_redis " - "'$remote_addr " - "$upstream_response_time " - "$srcache_fetch_status " - "[$time_local]" - " '\n '$http_host" - " \"$request\" " - "$status $body_bytes_sent '\n" - "'\"$http_referer\" " - "\"$http_user_agent\"';\n") + redis_file.write( + "# Log format Settings\n" + "log_format rt_cache_redis '$remote_addr " + "$upstream_response_time $srcache_fetch_status " + "[$time_local] '\n '$http_host \"$request\" " + "$status $body_bytes_sent '\n'\"$http_referer\" " + "\"$http_user_agent\"';\n") # set redis.conf parameter # set maxmemory 10% for ram below 512MB and 20% for others # set maxmemory-policy allkeys-lru @@ -1158,12 +1159,10 @@ def post_pref(self, apt_packages, packages, upgrade=False): Log.debug( self, "Setting maxmemory-policy variable to " "allkeys-lru in redis.conf") - WOFileUtils.searchreplace(self, - "/etc/redis/redis.conf", - "# maxmemory-policy " - "noeviction", - "maxmemory-policy " - "allkeys-lru") + WOFileUtils.searchreplace( + self, "/etc/redis/redis.conf", + "# maxmemory-policy noeviction", + "maxmemory-policy allkeys-lru") Log.debug( self, "Setting tcp-backlog variable to " "in redis.conf") @@ -1268,7 +1267,9 @@ def post_pref(self, apt_packages, packages, upgrade=False): shutil.copyfile('/var/lib/wo/tmp/composer.phar', '/usr/local/bin/composer') WOFileUtils.chmod(self, "/usr/local/bin/composer", 0o775) - if os.path.isdir("/var/www/22222/htdocs/db/pma"): + if ((os.path.isdir("/var/www/22222/htdocs/db/pma")) and + (not os.path.isfile('/var/www/22222/htdocs/db/' + 'pma/composer.lock'))): Log.info(self, "Updating phpMyAdmin, please wait...") WOShellExec.cmd_exec( self, "/usr/local/bin/composer update " @@ -1289,11 +1290,19 @@ def post_pref(self, apt_packages, packages, upgrade=False): .format(WOVariables.wo_webroot)) os.makedirs('{0}22222/htdocs/cache/redis/phpRedisAdmin' .format(WOVariables.wo_webroot)) - WOFileUtils.chown(self, '{0}22222/htdocs' - .format(WOVariables.wo_webroot), - 'www-data', - 'www-data', - recursive=True) + if not os.path.isfile('/var/www/22222/htdocs/cache/redis/' + 'phpRedisAdmin/composer.lock'): + WOShellExec.cmd_exec(self, "/usr/local/bin/composer" + "create-project --no-plugins " + "--no-scripts -n -s dev " + "erik-dubbelboer/php-redis-admin " + "/var/www/22222/htdocs/cache" + "/redis/phpRedisAdmin ") + WOFileUtils.chown(self, '{0}22222/htdocs' + .format(WOVariables.wo_webroot), + 'www-data', + 'www-data', + recursive=True) # MySQLtuner if any('/usr/bin/mysqltuner' == x[1] @@ -1304,54 +1313,51 @@ def post_pref(self, apt_packages, packages, upgrade=False): # netdata install if any('/var/lib/wo/tmp/kickstart.sh' == x[1] for x in packages): - if ((not os.path.exists('/opt/netdata')) and - (not os.path.exists('/etc/netdata'))): - Log.info(self, "Installing Netdata, please wait...") - 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, "{0}usr/" - "lib/netdata/conf.d/health_alarm_notify.conf" - .format(wo_netdata), - 'SEND_EMAIL="YES"', - 'SEND_EMAIL="NO"') - # make changes persistant - WOFileUtils.copyfile( - self, "{0}usr/lib/netdata/conf.d/" - "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: - WOMysql.execute( - self, - "create user 'netdata'@'localhost';", - log=False) - WOMysql.execute( - self, - "grant usage on *.* to 'netdata'@'localhost';", - log=False) - WOMysql.execute( - self, "flush privileges;", - log=False) - except CommandExecutionError as e: - Log.debug(self, "{0}".format(e)) - Log.info( - self, "fail to setup mysql user for netdata") - WOFileUtils.chown(self, '{0}etc/netdata' - .format(wo_netdata), - 'netdata', - 'netdata', - recursive=True) - WOService.restart_service(self, 'netdata') + Log.info(self, "Installing Netdata, please wait...") + WOShellExec.cmd_exec(self, "bash /var/lib/wo/tmp/" + "kickstart.sh " + "--dont-wait") + if os.path.isdir('/etc/netdata'): + wo_netdata = "/" + elif os.path.isdir('/opt/netdata'): + wo_netdata = "/opt/netdata/" + # disable mail notifications + WOFileUtils.searchreplace( + self, "{0}etc/netdata/orig/health_alarm_notify.conf" + .format(wo_netdata), + 'SEND_EMAIL="YES"', + 'SEND_EMAIL="NO"') + # make changes persistant + WOFileUtils.copyfile( + self, "{0}etc/netdata/orig/" + "health_alarm_notify.conf" + .format(wo_netdata), + "{0}etc/netdata/health_alarm_notify.conf" + .format(wo_netdata)) + # check if mysql credentials are available + if WOShellExec.cmd_exec(self, "mysqladmin ping"): + try: + WOMysql.execute( + self, + "create user 'netdata'@'localhost';", + log=False) + WOMysql.execute( + self, + "grant usage on *.* to 'netdata'@'localhost';", + log=False) + WOMysql.execute( + self, "flush privileges;", + log=False) + except CommandExecutionError as e: + Log.debug(self, "{0}".format(e)) + Log.info( + self, "fail to setup mysql user for netdata") + WOFileUtils.chown(self, '{0}etc/netdata' + .format(wo_netdata), + 'netdata', + 'netdata', + recursive=True) + WOService.restart_service(self, 'netdata') # WordOps Dashboard if any('/var/lib/wo/tmp/wo-dashboard.tar.gz' == x[1] diff --git a/wo/core/fileutils.py b/wo/core/fileutils.py index cc6678f..07ef9a4 100644 --- a/wo/core/fileutils.py +++ b/wo/core/fileutils.py @@ -80,7 +80,7 @@ class WOFileUtils(): except IOError as e: Log.debug(self, "{0}".format(e.strerror)) Log.error(self, "Unable to copy files from {0} to {1}" - .format(src, dest)) + .format(src, dest), exit=False) def copyfile(self, src, dest): """ @@ -99,7 +99,7 @@ class WOFileUtils(): except IOError as e: Log.debug(self, "{0}".format(e.strerror)) Log.error(self, "Unable to copy file from {0} to {1}" - .format(src, dest)) + .format(src, dest), exit=False) def searchreplace(self, fnm, sstr, rstr): """ @@ -118,7 +118,7 @@ class WOFileUtils(): except Exception as e: Log.debug(self, "{0}".format(e)) Log.error(self, "Unable to search {0} and replace {1} {2}" - .format(fnm, sstr, rstr)) + .format(fnm, sstr, rstr), exit=False) def mvfile(self, src, dst): """ From 3e3401bb1999580580c4d24276f704e629d27bc8 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 14:02:59 +0200 Subject: [PATCH 03/20] Fix proftpd port --- wo/cli/plugins/stack_pref.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index 0d2a58f..dff1e56 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -1076,6 +1076,8 @@ def post_pref(self, apt_packages, packages, upgrade=False): # add rule for proftpd with UFW if os.path.isdir('/etc/ufw'): try: + WOShellExec.cmd_exec( + self, "ufw allow 21") WOShellExec.cmd_exec( self, "ufw allow 49000:50000/tcp") WOShellExec.cmd_exec( From fef8eeaa7390434f72ec70676a6d832ff6e2fa20 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 14:19:28 +0200 Subject: [PATCH 04/20] Update travis --- tests/travis.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/travis.sh b/tests/travis.sh index 74806d1..7176198 100644 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -131,6 +131,7 @@ echo -e "${CGREEN}#############################################${CEND}" echo -e ' various informations ' echo -e "${CGREEN}#############################################${CEND}" wp --allow-root --info -cat /etc/nginx/nginx.conf +cat /etc/nginx/nginx.conf | ccze -A wo site info wp1.com -cat /etc/mysql/my.cnf +cat /etc/mysql/my.cnf | ccze -A +cat /var/log/wo/wordops.log | ccze -A \ No newline at end of file From cda05da286a60f3eda01158fec608041e194cde2 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 14:31:12 +0200 Subject: [PATCH 05/20] Add links to cache plugins --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index a167a62..faca027 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,14 @@ Apps & Tools shipped with WordOps : - [cheat.sh](https://github.com/chubin/cheat.sh) - [ProFTPd](https://github.com/proftpd/proftpd) +Cache Plugins supported by WordOps : + +- [Nginx-helper](https://github.com/rtCamp/nginx-helper) +- [Cache-Enabler](https://github.com/keycdn/cache-enabler) +- [Redis-object-cache](https://github.com/tillkruss/redis-cache) +- [WP-Super-Cache](https://github.com/Automattic/wp-super-cache) +- [WP-Rocket](https://github.com/wp-media/wp-rocket) + ## License - [MIT](http://opensource.org/licenses/MIT) © [WordOps](https://wordops.net) From f10bcc124d640a3e567077d8fb3e485d9dcedecd Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 16:50:13 +0200 Subject: [PATCH 06/20] Fix extplorer & simplify stack_pref --- wo/cli/plugins/stack.py | 2 +- wo/cli/plugins/stack_pref.py | 230 +++++++++++++++++------------------ 2 files changed, 113 insertions(+), 119 deletions(-) diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 8416ab1..4f715cf 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -403,7 +403,7 @@ class WOStackController(CementBaseController): Log.info(self, "WordOps dashboard already installed") # eXtplorer - if pargs.explorer: + if pargs.extplorer: if not os.path.isdir('/var/www/22222/htdocs/files'): Log.debug(self, "Setting packages variable for eXtplorer") packages = packages + \ diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index dff1e56..0f114ea 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -217,98 +217,96 @@ def post_pref(self, apt_packages, packages, upgrade=False): '/etc/nginx/common') os.makedirs('/etc/nginx/common') - if os.path.exists('/etc/nginx/common'): - data = dict() + data = dict() - # Common Configuration - WOTemplate.render(self, - '{0}/locations-wo.conf' - .format(ngxcom), - 'locations.mustache', data) + # Common Configuration + WOTemplate.render(self, + '{0}/locations-wo.conf' + .format(ngxcom), + 'locations.mustache', data) - WOTemplate.render(self, - '{0}/wpsubdir.conf' - .format(ngxcom), - 'wpsubdir.mustache', data) - data = dict(upstream="php72") - # PHP 7.2 conf - WOTemplate.render(self, - '{0}/php72.conf' - .format(ngxcom), - 'php.mustache', data) + WOTemplate.render(self, + '{0}/wpsubdir.conf' + .format(ngxcom), + 'wpsubdir.mustache', data) + data = dict(upstream="php72") + # PHP 7.2 conf + WOTemplate.render(self, + '{0}/php72.conf' + .format(ngxcom), + 'php.mustache', data) - WOTemplate.render(self, - '{0}/redis-php72.conf' - .format(ngxcom), - 'redis.mustache', data) + WOTemplate.render(self, + '{0}/redis-php72.conf' + .format(ngxcom), + 'redis.mustache', data) - WOTemplate.render(self, - '{0}/wpcommon-php72.conf' - .format(ngxcom), - 'wpcommon.mustache', data) + WOTemplate.render(self, + '{0}/wpcommon-php72.conf' + .format(ngxcom), + 'wpcommon.mustache', data) - WOTemplate.render(self, - '{0}/wpfc-php72.conf' - .format(ngxcom), - 'wpfc.mustache', data) - WOTemplate.render(self, - '{0}/wpsc-php72.conf' - .format(ngxcom), - 'wpsc.mustache', data) + WOTemplate.render(self, + '{0}/wpfc-php72.conf' + .format(ngxcom), + 'wpfc.mustache', data) + WOTemplate.render(self, + '{0}/wpsc-php72.conf' + .format(ngxcom), + 'wpsc.mustache', data) - WOTemplate.render(self, - '{0}/wprocket-php72.conf' - .format(ngxcom), - 'wprocket.mustache', data) + WOTemplate.render(self, + '{0}/wprocket-php72.conf' + .format(ngxcom), + 'wprocket.mustache', data) - WOTemplate.render(self, - '{0}/wpce-php72.conf' - .format(ngxcom), - 'wpce.mustache', data) + WOTemplate.render(self, + '{0}/wpce-php72.conf' + .format(ngxcom), + 'wpce.mustache', data) # PHP 7.3 conf - if os.path.isdir("/etc/nginx/common"): - data = dict(upstream="php73") + data = dict(upstream="php73") - WOTemplate.render(self, - '{0}/php73.conf' - .format(ngxcom), - 'php.mustache', data) + WOTemplate.render(self, + '{0}/php73.conf' + .format(ngxcom), + 'php.mustache', data) - WOTemplate.render(self, - '{0}/redis-php73.conf' - .format(ngxcom), - 'redis.mustache', data) + WOTemplate.render(self, + '{0}/redis-php73.conf' + .format(ngxcom), + 'redis.mustache', data) - WOTemplate.render(self, - '{0}/wpcommon-php73.conf' - .format(ngxcom), - 'wpcommon.mustache', data) + WOTemplate.render(self, + '{0}/wpcommon-php73.conf' + .format(ngxcom), + 'wpcommon.mustache', data) - WOTemplate.render(self, - '{0}/wpfc-php73.conf' - .format(ngxcom), - 'wpfc.mustache', data) - WOTemplate.render(self, - '{0}/wpsc-php73.conf' - .format(ngxcom), - 'wpsc.mustache', data) + WOTemplate.render(self, + '{0}/wpfc-php73.conf' + .format(ngxcom), + 'wpfc.mustache', data) + WOTemplate.render(self, + '{0}/wpsc-php73.conf' + .format(ngxcom), + 'wpsc.mustache', data) - WOTemplate.render(self, - '{0}/wprocket-php73.conf' - .format(ngxcom), - 'wprocket.mustache', data) + WOTemplate.render(self, + '{0}/wprocket-php73.conf' + .format(ngxcom), + 'wprocket.mustache', data) - WOTemplate.render(self, - '{0}/wpce-php73.conf' - .format(ngxcom), - 'wpce.mustache', data) + WOTemplate.render(self, + '{0}/wpce-php73.conf' + .format(ngxcom), + 'wpce.mustache', data) - with open("/etc/nginx/common/release", - "w") as release_file: - release_file.write("v{0}" - .format(WOVariables.wo_version)) - release_file.close() + with open("/etc/nginx/common/release", + "w") as release_file: + release_file.write("v{0}" + .format(WOVariables.wo_version)) + release_file.close() # Following files should not be overwrited @@ -324,7 +322,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): WOTemplate.render(self, '{0}/fastcgi.conf' .format(ngxcnf), - 'fastcgi.mustache', data, overwrite=False) + 'fastcgi.mustache', data, overwrite=True) # add redis cache format if not already done if (os.path.isfile("/etc/nginx/nginx.conf") and @@ -1364,49 +1362,24 @@ def post_pref(self, apt_packages, packages, upgrade=False): # WordOps Dashboard if any('/var/lib/wo/tmp/wo-dashboard.tar.gz' == x[1] for x in packages): - if not os.path.isfile('{0}22222/htdocs/index.php' - .format(WOVariables.wo_webroot)): - Log.debug(self, "Extracting wo-dashboard.tar.gz " - "to location {0}22222/htdocs/" - .format(WOVariables.wo_webroot)) - WOExtract.extract(self, '/var/lib/wo/tmp/' - 'wo-dashboard.tar.gz', - '{0}22222/htdocs' - .format(WOVariables.wo_webroot)) - wo_wan = os.popen("/sbin/ip -4 route get 8.8.8.8 | " - "grep -oP \"dev [^[:space:]]+ \" " - "| cut -d ' ' -f 2").read() - if (wo_wan != 'eth0' and wo_wan != ''): - WOFileUtils.searchreplace(self, - "{0}22222/htdocs/index.php" - .format(WOVariables.wo_webroot), - "eth0", - "{0}".format(wo_wan)) - Log.debug(self, "Setting Privileges to " - "{0}22222/htdocs" + Log.debug(self, "Extracting wo-dashboard.tar.gz " + "to location {0}22222/htdocs/" + .format(WOVariables.wo_webroot)) + WOExtract.extract(self, '/var/lib/wo/tmp/' + 'wo-dashboard.tar.gz', + '{0}22222/htdocs' .format(WOVariables.wo_webroot)) - WOFileUtils.chown(self, '{0}22222/htdocs' - .format(WOVariables.wo_webroot), - 'www-data', - 'www-data', - recursive=True) - - # Extplorer FileManager - if any('/var/lib/wo/tmp/extplorer.tar.gz' == x[1] - for x in packages): - if not os.path.exists('{0}22222/htdocs/files' - .format(WOVariables.wo_webroot)): - Log.debug(self, "Extracting explorer.tar.gz " - "to location {0}22222/htdocs/files" - .format(WOVariables.wo_webroot)) - WOExtract.extract(self, '/var/lib/wo/tmp/extplorer.tar.gz', - '/var/lib/wo/tmp/') - shutil.move('/var/lib/wo/tmp/extplorer-{0}' - .format(WOVariables.wo_extplorer), - '{0}22222/htdocs/files' - .format(WOVariables.wo_webroot)) + wo_wan = os.popen("/sbin/ip -4 route get 8.8.8.8 | " + "grep -oP \"dev [^[:space:]]+ \" " + "| cut -d ' ' -f 2").read() + if (wo_wan != 'eth0' and wo_wan != ''): + WOFileUtils.searchreplace(self, + "{0}22222/htdocs/index.php" + .format(WOVariables.wo_webroot), + "eth0", + "{0}".format(wo_wan)) Log.debug(self, "Setting Privileges to " - "{0}22222/htdocs/files" + "{0}22222/htdocs" .format(WOVariables.wo_webroot)) WOFileUtils.chown(self, '{0}22222/htdocs' .format(WOVariables.wo_webroot), @@ -1414,6 +1387,27 @@ def post_pref(self, apt_packages, packages, upgrade=False): 'www-data', recursive=True) + # Extplorer FileManager + if any('/var/lib/wo/tmp/extplorer.tar.gz' == x[1] + for x in packages): + Log.debug(self, "Extracting extplorer.tar.gz " + "to location {0}22222/htdocs/files" + .format(WOVariables.wo_webroot)) + WOExtract.extract(self, '/var/lib/wo/tmp/extplorer.tar.gz', + '/var/lib/wo/tmp/') + shutil.move('/var/lib/wo/tmp/extplorer-{0}' + .format(WOVariables.wo_extplorer), + '{0}22222/htdocs/files' + .format(WOVariables.wo_webroot)) + Log.debug(self, "Setting Privileges to " + "{0}22222/htdocs/files" + .format(WOVariables.wo_webroot)) + WOFileUtils.chown(self, '{0}22222/htdocs' + .format(WOVariables.wo_webroot), + 'www-data', + 'www-data', + recursive=True) + # webgrind if any('/var/lib/wo/tmp/webgrind.tar.gz' == x[1] for x in packages): From d4cb9501cfbeb11bfbde62c71e9b3fd5abdbf4fb Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 20:39:12 +0200 Subject: [PATCH 07/20] Improve stack_pref.py --- CHANGELOG.md | 7 +- install | 2 + wo/cli/plugins/stack_pref.py | 213 ++++++++++++++++--------------- wo/cli/templates/wo-ufw.mustache | 4 + 4 files changed, 121 insertions(+), 105 deletions(-) create mode 100644 wo/cli/templates/wo-ufw.mustache diff --git a/CHANGELOG.md b/CHANGELOG.md index 5705bc2..412f661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +#### Changed + +- do not terminate stack install process on errors + #### Fixed - ufw rules for proftpd not applied - phpredisadmin install - netdata configuration - +- extplorer installation +- add LANG='en_US.UTF-8' in install script ### v3.9.8.7 - 2019-08-31 diff --git a/install b/install index 742e6d2..0957024 100755 --- a/install +++ b/install @@ -103,6 +103,8 @@ fi # 1- Update the apt sewers with fresh info ### export DEBIAN_FRONTEND=noninteractive +export LANG='en_US.UTF-8' + [ -z "$wo_travis" ] && { apt-get update -qq } diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index 0f114ea..2582499 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -184,32 +184,34 @@ def post_pref(self, apt_packages, packages, upgrade=False): encoding='utf-8', mode='a') as wo_nginx: wo_nginx.write('fastcgi_param \tSCRIPT_FILENAME ' '\t$request_filename;\n') + try: + data = dict(php="9000", debug="9001", + php7="9070", debug7="9170") + WOTemplate.render( + self, '{0}/upstream.conf'.format(ngxcnf), + 'upstream.mustache', data, overwrite=True) - data = dict(php="9000", debug="9001", - php7="9070", debug7="9170") - WOTemplate.render( - self, '{0}/upstream.conf'.format(ngxcnf), - 'upstream.mustache', data, overwrite=True) + data = dict(phpconf=True if + WOAptGet.is_installed(self, 'php7.2-fpm') + else False) + WOTemplate.render(self, + '{0}/stub_status.conf'.format(ngxcnf), + 'stub_status.mustache', data) + data = dict() + WOTemplate.render(self, + '{0}/webp.conf'.format(ngxcnf), + 'webp.mustache', data, overwrite=False) - data = dict(phpconf=True if - WOAptGet.is_installed(self, 'php7.2-fpm') - else False) - WOTemplate.render(self, - '{0}/stub_status.conf'.format(ngxcnf), - 'stub_status.mustache', data) - data = dict() - WOTemplate.render(self, - '{0}/webp.conf'.format(ngxcnf), - 'webp.mustache', data) + WOTemplate.render(self, + '{0}/cloudflare.conf'.format(ngxcnf), + 'cloudflare.mustache', data) - WOTemplate.render(self, - '{0}/cloudflare.conf'.format(ngxcnf), - 'cloudflare.mustache', data) - - WOTemplate.render(self, - '{0}/map-wp-fastcgi-cache.conf'.format( - ngxcnf), - 'map-wp.mustache', data) + WOTemplate.render(self, + '{0}/map-wp-fastcgi-cache.conf'.format( + ngxcnf), + 'map-wp.mustache', data) + except CommandExecutionError as e: + Log.debug(self, "{0}".format(e)) # Setup Nginx common directory if not os.path.exists('{0}'.format(ngxcom)): @@ -217,90 +219,92 @@ def post_pref(self, apt_packages, packages, upgrade=False): '/etc/nginx/common') os.makedirs('/etc/nginx/common') - data = dict() + try: + data = dict() - # Common Configuration - WOTemplate.render(self, - '{0}/locations-wo.conf' - .format(ngxcom), - 'locations.mustache', data) + # Common Configuration + WOTemplate.render(self, + '{0}/locations-wo.conf' + .format(ngxcom), + 'locations.mustache', data) - WOTemplate.render(self, - '{0}/wpsubdir.conf' - .format(ngxcom), - 'wpsubdir.mustache', data) - data = dict(upstream="php72") - # PHP 7.2 conf - WOTemplate.render(self, - '{0}/php72.conf' - .format(ngxcom), - 'php.mustache', data) + WOTemplate.render(self, + '{0}/wpsubdir.conf' + .format(ngxcom), + 'wpsubdir.mustache', data) + data = dict(upstream="php72") + # PHP 7.2 conf + WOTemplate.render(self, + '{0}/php72.conf' + .format(ngxcom), + 'php.mustache', data) - WOTemplate.render(self, - '{0}/redis-php72.conf' - .format(ngxcom), - 'redis.mustache', data) + WOTemplate.render(self, + '{0}/redis-php72.conf' + .format(ngxcom), + 'redis.mustache', data) - WOTemplate.render(self, - '{0}/wpcommon-php72.conf' - .format(ngxcom), - 'wpcommon.mustache', data) + WOTemplate.render(self, + '{0}/wpcommon-php72.conf' + .format(ngxcom), + 'wpcommon.mustache', data) - WOTemplate.render(self, - '{0}/wpfc-php72.conf' - .format(ngxcom), - 'wpfc.mustache', data) - WOTemplate.render(self, - '{0}/wpsc-php72.conf' - .format(ngxcom), - 'wpsc.mustache', data) + WOTemplate.render(self, + '{0}/wpfc-php72.conf' + .format(ngxcom), + 'wpfc.mustache', data) + WOTemplate.render(self, + '{0}/wpsc-php72.conf' + .format(ngxcom), + 'wpsc.mustache', data) - WOTemplate.render(self, - '{0}/wprocket-php72.conf' - .format(ngxcom), - 'wprocket.mustache', data) + WOTemplate.render(self, + '{0}/wprocket-php72.conf' + .format(ngxcom), + 'wprocket.mustache', data) - WOTemplate.render(self, - '{0}/wpce-php72.conf' - .format(ngxcom), - 'wpce.mustache', data) + WOTemplate.render(self, + '{0}/wpce-php72.conf' + .format(ngxcom), + 'wpce.mustache', data) + # PHP 7.3 conf + data = dict(upstream="php73") - # PHP 7.3 conf - data = dict(upstream="php73") + WOTemplate.render(self, + '{0}/php73.conf' + .format(ngxcom), + 'php.mustache', data) - WOTemplate.render(self, - '{0}/php73.conf' - .format(ngxcom), - 'php.mustache', data) + WOTemplate.render(self, + '{0}/redis-php73.conf' + .format(ngxcom), + 'redis.mustache', data) - WOTemplate.render(self, - '{0}/redis-php73.conf' - .format(ngxcom), - 'redis.mustache', data) + WOTemplate.render(self, + '{0}/wpcommon-php73.conf' + .format(ngxcom), + 'wpcommon.mustache', data) - WOTemplate.render(self, - '{0}/wpcommon-php73.conf' - .format(ngxcom), - 'wpcommon.mustache', data) + WOTemplate.render(self, + '{0}/wpfc-php73.conf' + .format(ngxcom), + 'wpfc.mustache', data) + WOTemplate.render(self, + '{0}/wpsc-php73.conf' + .format(ngxcom), + 'wpsc.mustache', data) - WOTemplate.render(self, - '{0}/wpfc-php73.conf' - .format(ngxcom), - 'wpfc.mustache', data) - WOTemplate.render(self, - '{0}/wpsc-php73.conf' - .format(ngxcom), - 'wpsc.mustache', data) + WOTemplate.render(self, + '{0}/wprocket-php73.conf' + .format(ngxcom), + 'wprocket.mustache', data) - WOTemplate.render(self, - '{0}/wprocket-php73.conf' - .format(ngxcom), - 'wprocket.mustache', data) - - WOTemplate.render(self, - '{0}/wpce-php73.conf' - .format(ngxcom), - 'wpce.mustache', data) + WOTemplate.render(self, + '{0}/wpce-php73.conf' + .format(ngxcom), + 'wpce.mustache', data) + except CommandExecutionError as e: + Log.debug(self, "{0}".format(e)) with open("/etc/nginx/common/release", "w") as release_file: @@ -477,6 +481,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): "/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') if set(["nginx"]).issubset(set(apt_packages)): @@ -665,12 +670,12 @@ def post_pref(self, apt_packages, packages, upgrade=False): .format(ngxroot)) os.makedirs('{0}22222/htdocs/fpm/status/' .format(ngxroot)) - open('{0}22222/htdocs/fpm/status/debug72' - .format(ngxroot), - encoding='utf-8', mode='a').close() - open('{0}22222/htdocs/fpm/status/php72' - .format(ngxroot), - encoding='utf-8', mode='a').close() + open('{0}22222/htdocs/fpm/status/debug72' + .format(ngxroot), + encoding='utf-8', mode='a').close() + open('{0}22222/htdocs/fpm/status/php72' + .format(ngxroot), + encoding='utf-8', mode='a').close() # Write info.php if not os.path.exists('{0}22222/htdocs/php/' @@ -681,10 +686,10 @@ def post_pref(self, apt_packages, packages, upgrade=False): os.makedirs('{0}22222/htdocs/php' .format(ngxroot)) - with open("{0}22222/htdocs/php/info.php" - .format(ngxroot), - encoding='utf-8', mode='w') as myfile: - myfile.write("") + with open("{0}22222/htdocs/php/info.php" + .format(ngxroot), + encoding='utf-8', mode='w') as myfile: + myfile.write("") WOFileUtils.chown(self, "{0}22222/htdocs" .format(ngxroot), diff --git a/wo/cli/templates/wo-ufw.mustache b/wo/cli/templates/wo-ufw.mustache new file mode 100644 index 0000000..2ffc453 --- /dev/null +++ b/wo/cli/templates/wo-ufw.mustache @@ -0,0 +1,4 @@ +[WordOps] +title=WordOps(WO) +description=Command-line tool that ease WordPress site and server management +ports=22222/tcp \ No newline at end of file From 0ee116bd6cda5764683d77ab8c3db58fea389129 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 22:02:00 +0200 Subject: [PATCH 08/20] Add sendmail --- wo/cli/plugins/stack.py | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 4f715cf..49e88fb 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -34,6 +34,7 @@ from wo.core.mysql import WOMysql from wo.core.services import WOService from wo.core.shellexec import CommandExecutionError, WOShellExec from wo.core.variables import WOVariables +from wo.core.template import WOTemplate def wo_stack_hook(app): @@ -88,6 +89,8 @@ class WOStackController(CementBaseController): dict(help='Install Fail2ban stack', action='store_true')), (['--clamav'], dict(help='Install ClamAV stack', action='store_true')), + (['--sendmail'], + dict(help='Install Sendmail stack', action='store_true')), (['--utils'], dict(help='Install Utils stack', action='store_true')), (['--redis'], @@ -126,7 +129,7 @@ class WOStackController(CementBaseController): (not pargs.adminer) and (not pargs.utils) and (not pargs.redis) and (not pargs.proftpd) and (not pargs.extplorer) and (not pargs.clamav) and - (not pargs.phpredisadmin) and + (not pargs.phpredisadmin) and (not pargs.sendmail) and (not pargs.php73)): pargs.web = True pargs.admin = True @@ -145,8 +148,10 @@ class WOStackController(CementBaseController): pargs.php = True pargs.mysql = True pargs.wpcli = True + pargs.sendmail = True if pargs.admin: + pargs.web = True pargs.adminer = True pargs.phpmyadmin = True pargs.composer = True @@ -185,9 +190,12 @@ class WOStackController(CementBaseController): # Redis if pargs.redis: + pargs.php = True + WOTemplate.addAptPackage( + self, 'redis-server', WOVariables.wo_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") @@ -270,6 +278,15 @@ class WOStackController(CementBaseController): Log.debug(self, "ClamAV already installed") Log.info(self, "ClamAV already installed") + # sendmail + if pargs.sendmail: + Log.debug(self, "Setting apt_packages variable for Sendmail") + if not WOAptGet.is_installed(self, 'sendmail'): + apt_packages = apt_packages + ["sendmail"] + else: + Log.debug(self, "Sendmail already installed") + Log.info(self, "Sendmail already installed") + # proftpd if pargs.proftpd: Log.debug(self, "Setting apt_packages variable for ProFTPd") @@ -505,7 +522,7 @@ class WOStackController(CementBaseController): (not pargs.adminer) and (not pargs.utils) and (not pargs.redis) and (not pargs.proftpd) and (not pargs.extplorer) and (not pargs.clamav) and - (not pargs.phpredisadmin) and + (not pargs.phpredisadmin) and (not pargs.sendmail) and (not pargs.php73)): pargs.web = True pargs.admin = True @@ -526,6 +543,7 @@ class WOStackController(CementBaseController): pargs.php = True pargs.mysql = True pargs.wpcli = True + pargs.sendmail = True if pargs.admin: pargs.composer = True @@ -592,6 +610,12 @@ class WOStackController(CementBaseController): if WOAptGet.is_installed(self, 'clamav'): apt_packages = apt_packages + WOVariables.wo_clamav + # sendmail + if pargs.sendmail: + Log.debug(self, "Setting apt_packages variable for Sendmail") + if WOAptGet.is_installed(self, 'sendmail'): + apt_packages = apt_packages + ["sendmail"] + # proftpd if pargs.proftpd: if WOAptGet.is_installed(self, 'proftpd-basic'): @@ -711,7 +735,7 @@ class WOStackController(CementBaseController): (not pargs.adminer) and (not pargs.utils) and (not pargs.redis) and (not pargs.proftpd) and (not pargs.extplorer) and (not pargs.clamav) and - (not pargs.phpredisadmin) and + (not pargs.phpredisadmin) and (not pargs.sendmail) and (not pargs.php73)): pargs.web = True pargs.admin = True @@ -732,6 +756,7 @@ class WOStackController(CementBaseController): pargs.php = True pargs.mysql = True pargs.wpcli = True + pargs.sendmail = True if pargs.admin: pargs.utils = True @@ -798,6 +823,12 @@ class WOStackController(CementBaseController): if WOAptGet.is_installed(self, 'clamav'): apt_packages = apt_packages + WOVariables.wo_clamav + # sendmail + if pargs.sendmail: + Log.debug(self, "Setting apt_packages variable for Sendmail") + if WOAptGet.is_installed(self, 'sendmail'): + apt_packages = apt_packages + ["sendmail"] + # proftpd if pargs.proftpd: if WOAptGet.is_installed(self, 'proftpd-basic'): From 1e6d41d3d8001405cdf9c0a0fe72c8bbc6bc540b Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 22:02:52 +0200 Subject: [PATCH 09/20] Open files in mode utf8 --- wo/cli/plugins/site_functions.py | 2 +- wo/core/domainvalidate.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index 2afa650..e18f446 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -1486,7 +1486,7 @@ def checkWildcardExist(self, wo_domain_name): # define new csv dialect csv.register_dialect('acmeconf', delimiter='|') # open file - certfile = open('/var/lib/wo/cert.csv', 'rt') + certfile = open('/var/lib/wo/cert.csv', mode='rt', encoding='utf-8') reader = csv.reader(certfile, 'acmeconf') wo_wildcard_domain = ("*.{0}".format(wo_domain_name)) for row in reader: diff --git a/wo/core/domainvalidate.py b/wo/core/domainvalidate.py index 574f6bc..36b8af0 100644 --- a/wo/core/domainvalidate.py +++ b/wo/core/domainvalidate.py @@ -32,10 +32,11 @@ def GetDomainlevel(domain): domain_name = domain.split('.') if domain_name[0] == 'www': domain_name = domain_name[1:] + domain_type = '' if os.path.isfile("/var/lib/wo/public_suffix_list.dat"): # Read mode opens a file for reading only. Suffix_file = open( - "/var/lib/wo/public_suffix_list.dat", "r") + "/var/lib/wo/public_suffix_list.dat", mode='rt', encoding='utf-8') # Read all the lines into a list. for domain_suffix in Suffix_file: if (str(domain_suffix).strip()) == ('.'.join(domain_name[1:])): From e9d59dacf127c565fd490371567e2ca5e9f4c128 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 22:56:17 +0200 Subject: [PATCH 10/20] Fix phpRedisAdmin typo --- wo/cli/plugins/stack_pref.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index 2582499..e3fab80 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -1297,7 +1297,7 @@ def post_pref(self, apt_packages, packages, upgrade=False): .format(WOVariables.wo_webroot)) if not os.path.isfile('/var/www/22222/htdocs/cache/redis/' 'phpRedisAdmin/composer.lock'): - WOShellExec.cmd_exec(self, "/usr/local/bin/composer" + WOShellExec.cmd_exec(self, "/usr/local/bin/composer " "create-project --no-plugins " "--no-scripts -n -s dev " "erik-dubbelboer/php-redis-admin " From e4f686a9f43f405ce239b2a4c5f59bc690cdf921 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 23:29:23 +0200 Subject: [PATCH 11/20] Fix utf8 encoding when reading files --- CHANGELOG.md | 1 + install | 2 + wo/cli/plugins/site.py | 102 ++++++++++++++++--------------- wo/cli/plugins/site_functions.py | 8 +-- wo/cli/plugins/stack.py | 6 +- wo/core/apt_repo.py | 2 +- wo/core/domainvalidate.py | 4 +- wo/core/fileutils.py | 2 +- 8 files changed, 65 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 412f661..8701eb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - netdata configuration - extplorer installation - add LANG='en_US.UTF-8' in install script +- Read public_suffix list with utf8 encoding. Issue [#128](https://github.com/WordOps/WordOps/issues/128) ### v3.9.8.7 - 2019-08-31 diff --git a/install b/install index 0957024..d10db07 100755 --- a/install +++ b/install @@ -103,7 +103,9 @@ fi # 1- Update the apt sewers with fresh info ### export DEBIAN_FRONTEND=noninteractive +unset LANG export LANG='en_US.UTF-8' +export LC_ALL='C.UTF-8' [ -z "$wo_travis" ] && { apt-get update -qq diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index e3a4248..dc52686 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -429,7 +429,6 @@ 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) if not wo_domain.strip(): Log.error("Invalid domain name, " "Provide valid domain name") @@ -566,8 +565,10 @@ class WOSiteCreateController(CementBaseController): if data['php73']: php_version = "7.3" + php73 = 1 else: php_version = "7.2" + php73 = 0 addNewSite(self, wo_domain, stype, cache, wo_site_webroot, php_version=php_version) @@ -742,6 +743,7 @@ class WOSiteCreateController(CementBaseController): "`tail /var/log/wo/wordops.log` and please try again") if pargs.letsencrypt: + (wo_domain_type, wo_root_domain) = GetDomainlevel(wo_domain) data['letsencrypt'] = True letsencrypt = True if data['letsencrypt'] is True: @@ -956,7 +958,6 @@ class WOSiteUpdateController(CementBaseController): pargs.site_name = pargs.site_name.strip() (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) check_site = getSiteInfo(self, wo_domain) if check_site is None: @@ -1149,6 +1150,53 @@ class WOSiteUpdateController(CementBaseController): "site") pargs.php73 = False + if pargs.letsencrypt: + (wo_domain_type, wo_root_domain) = GetDomainlevel(wo_domain) + if pargs.letsencrypt == 'on': + data['letsencrypt'] = True + letsencrypt = True + if ((wo_domain_type == 'subdomain') and + (not pargs.letsencrypt == 'wildcard')): + wo_subdomain = True + else: + wo_subdomain = False + wo_wildcard = False + elif pargs.letsencrypt == 'subdomain': + data['letsencrypt'] = True + letsencrypt = True + wo_subdomain = True + wo_wildcard = False + elif pargs.letsencrypt == 'wildcard': + data['letsencrypt'] = True + letsencrypt = True + wo_wildcard = True + wo_subdomain = False + elif pargs.letsencrypt == 'off': + data['letsencrypt'] = False + letsencrypt = False + wo_subdomain = False + wo_wildcard = False + elif pargs.letsencrypt == 'clean': + data['letsencrypt'] = False + letsencrypt = False + wo_subdomain = False + wo_wildcard = False + elif pargs.letsencrypt == 'purge': + data['letsencrypt'] = False + letsencrypt = False + wo_subdomain = False + wo_wildcard = 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 + # --letsencrypt=renew code goes here if pargs.letsencrypt == "renew" and not pargs.all: expiry_days = SSL.getExpirationDays(self, wo_domain) @@ -1236,52 +1284,6 @@ class WOSiteUpdateController(CementBaseController): "site", False) return 0 - if pargs.letsencrypt: - if pargs.letsencrypt == 'on': - data['letsencrypt'] = True - letsencrypt = True - if ((wo_domain_type == 'subdomain') and - (not pargs.letsencrypt == 'wildcard')): - wo_subdomain = True - else: - wo_subdomain = False - wo_wildcard = False - elif pargs.letsencrypt == 'subdomain': - data['letsencrypt'] = True - letsencrypt = True - wo_subdomain = True - wo_wildcard = False - elif pargs.letsencrypt == 'wildcard': - data['letsencrypt'] = True - letsencrypt = True - wo_wildcard = True - wo_subdomain = False - elif pargs.letsencrypt == 'off': - data['letsencrypt'] = False - letsencrypt = False - wo_subdomain = False - wo_wildcard = False - elif pargs.letsencrypt == 'clean': - data['letsencrypt'] = False - letsencrypt = False - wo_subdomain = False - wo_wildcard = False - elif pargs.letsencrypt == 'purge': - data['letsencrypt'] = False - letsencrypt = False - wo_subdomain = False - wo_wildcard = 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: data['php73'] = True @@ -1468,6 +1470,9 @@ class WOSiteUpdateController(CementBaseController): elif (pargs.letsencrypt == "clean" or pargs.letsencrypt == "purge"): removeAcmeConf(self, wo_domain) + # find all broken symlinks + sympath = "/var/www" + WOFileUtils.findBrokenSymlink(self, sympath) if not WOService.reload_service(self, 'nginx'): Log.error(self, "service nginx reload failed. " "check issues with `nginx -t` command") @@ -1872,7 +1877,6 @@ class WOSiteDeleteController(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_db_name = '' wo_prompt = '' wo_nginx_prompt = '' diff --git a/wo/cli/plugins/site_functions.py b/wo/cli/plugins/site_functions.py index e18f446..ccf7575 100644 --- a/wo/cli/plugins/site_functions.py +++ b/wo/cli/plugins/site_functions.py @@ -1335,10 +1335,8 @@ def doCleanupAction(self, domain='', webroot='', dbname='', dbuser='', if os.path.isfile('/etc/nginx/sites-available/{0}' .format(domain)): removeNginxConf(self, domain) - if (os.path.isdir('/etc/letsencrypt/renewal/{0}_ecc' - .format(domain)) or - os.path.isdir('/etc/letsencrypt/live/{0}' - .format(domain))): + if os.path.isdir('/etc/letsencrypt/renewal/{0}_ecc' + .format(domain)): removeAcmeConf(self, domain) if webroot: @@ -1486,7 +1484,7 @@ def checkWildcardExist(self, wo_domain_name): # define new csv dialect csv.register_dialect('acmeconf', delimiter='|') # open file - certfile = open('/var/lib/wo/cert.csv', mode='rt', encoding='utf-8') + certfile = open('/var/lib/wo/cert.csv', mode='r', encoding='utf-8') reader = csv.reader(certfile, 'acmeconf') wo_wildcard_domain = ("*.{0}".format(wo_domain_name)) for row in reader: diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 49e88fb..1fa46e0 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -191,8 +191,6 @@ class WOStackController(CementBaseController): # Redis if pargs.redis: pargs.php = True - WOTemplate.addAptPackage( - self, 'redis-server', WOVariables.wo_redis) if not WOAptGet.is_installed(self, 'redis-server'): apt_packages = apt_packages + WOVariables.wo_redis @@ -248,8 +246,8 @@ class WOStackController(CementBaseController): # WP-CLI if pargs.wpcli: Log.debug(self, "Setting packages variable for WP-CLI") - if (not os.path.isfile("/usr/local/bin/wp") and not - os.path.isfile("/usr/bin/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" diff --git a/wo/core/apt_repo.py b/wo/core/apt_repo.py index e5610e7..44f53df 100644 --- a/wo/core/apt_repo.py +++ b/wo/core/apt_repo.py @@ -47,7 +47,7 @@ class WORepo(): Log.debug(self, "{0}".format(e)) Log.error(self, "Unable to add repo") if ppa is not None: - WOShellExec.cmd_exec(self, "add-apt-repository -yu '{ppa_name}'" + WOShellExec.cmd_exec(self, "LC_ALL=C.UTF-8 add-apt-repository -yu '{ppa_name}'" .format(ppa_name=ppa)) def remove(self, ppa=None, repo_url=None): diff --git a/wo/core/domainvalidate.py b/wo/core/domainvalidate.py index 36b8af0..06855b8 100644 --- a/wo/core/domainvalidate.py +++ b/wo/core/domainvalidate.py @@ -29,14 +29,14 @@ def GetDomainlevel(domain): """ This function returns the domain type : domain, subdomain, """ - domain_name = domain.split('.') + domain_name = domain.split('.').lower() if domain_name[0] == 'www': domain_name = domain_name[1:] domain_type = '' if os.path.isfile("/var/lib/wo/public_suffix_list.dat"): # Read mode opens a file for reading only. Suffix_file = open( - "/var/lib/wo/public_suffix_list.dat", mode='rt', encoding='utf-8') + "/var/lib/wo/public_suffix_list.dat", encoding='utf-8', ) # Read all the lines into a list. for domain_suffix in Suffix_file: if (str(domain_suffix).strip()) == ('.'.join(domain_name[1:])): diff --git a/wo/core/fileutils.py b/wo/core/fileutils.py index 07ef9a4..cf44ab3 100644 --- a/wo/core/fileutils.py +++ b/wo/core/fileutils.py @@ -109,7 +109,7 @@ class WOFileUtils(): rstr: replace string """ try: - Log.debug(self, "Doning search and replace, File:{0}," + Log.debug(self, "Doing search and replace, File:{0}," "Source string:{1}, Dest String:{2}" .format(fnm, sstr, rstr)) for line in fileinput.input(fnm, inplace=True): From 619d83116c5bcc84dae458f98f9ccb4536820efd Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 23:34:22 +0200 Subject: [PATCH 12/20] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8701eb4..9b362c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - extplorer installation - add LANG='en_US.UTF-8' in install script - Read public_suffix list with utf8 encoding. Issue [#128](https://github.com/WordOps/WordOps/issues/128) +- Netdata uninstall script path. PR [#135](https://github.com/WordOps/WordOps/pull/135) ### v3.9.8.7 - 2019-08-31 From 29d2af4d7e363dd92c34eaa7b415a097c9da3e78 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sun, 1 Sep 2019 23:47:13 +0200 Subject: [PATCH 13/20] Backup MySQL databases before purging stack --- CHANGELOG.md | 5 +++++ wo/cli/plugins/stack.py | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b362c6..c982290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +#### Added + +- Sendmail stack to send WordPress welcome email properly +- Backup all MySQL databases before removing/purging MySQL stack + #### Changed - do not terminate stack install process on errors diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 901e0dc..1a9ae5c 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -692,6 +692,10 @@ class WOStackController(CementBaseController): if (set(["nginx-custom"]).issubset(set(apt_packages))): WOService.stop_service(self, 'nginx') + if (set(WOVariables.wo_mysql).issubset(set(apt_packages))): + WOMysql.backupAll(self) + WOService.stop_service(self, 'mysql') + # Netdata uninstaller if (set(['/var/lib/wo/tmp/' 'kickstart.sh']).issubset(set(packages))): @@ -912,6 +916,10 @@ class WOStackController(CementBaseController): if (set(["fail2ban"]).issubset(set(apt_packages))): WOService.stop_service(self, 'fail2ban') + if (set(WOVariables.wo_mysql).issubset(set(apt_packages))): + WOMysql.backupAll(self) + WOService.stop_service(self, 'mysql') + # Netdata uninstaller if (set(['/var/lib/wo/tmp/' 'kickstart.sh']).issubset(set(packages))): From 45d926af7e7e0011115a82dfa962762c921afa69 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Mon, 2 Sep 2019 00:54:22 +0200 Subject: [PATCH 14/20] Move display log in after_script --- .travis.yml | 5 +++++ tests/travis.sh | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a78e956..e0235ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,3 +38,8 @@ script: - sudo wo stack status - sudo wo stack purge --all --force - sudo bash install --purge + +after_script: + - sudo cat /etc/nginx/nginx.conf | ccze -A + - sudo cat /var/log/wo/wordops.log | ccze -A + - sudo cat /etc/mysql/my.cnf | ccze -A diff --git a/tests/travis.sh b/tests/travis.sh index 7176198..0ea2467 100644 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -131,7 +131,4 @@ echo -e "${CGREEN}#############################################${CEND}" echo -e ' various informations ' echo -e "${CGREEN}#############################################${CEND}" wp --allow-root --info -cat /etc/nginx/nginx.conf | ccze -A wo site info wp1.com -cat /etc/mysql/my.cnf | ccze -A -cat /var/log/wo/wordops.log | ccze -A \ No newline at end of file From 525dc5494cde388b020ff2dfee59daa0879bd653 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Mon, 2 Sep 2019 02:13:29 +0200 Subject: [PATCH 15/20] Fix netdata purge --- .travis.yml | 14 +++++++------- tests/travis.sh | 1 + wo/cli/plugins/stack.py | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index e0235ad..5445688 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,13 @@ before_script: - unset LANG - sudo apt-get install --assume-yes --quiet git python3-setuptools python3-dev python3-apt ccze tree +after_script: + - sudo cat /etc/nginx/nginx.conf | ccze -A + - sudo cat /var/log/wo/wordops.log | ccze -A + - sudo cat /etc/mysql/my.cnf | ccze -A + - sudo bash install --purge + + script: - lsb_release -a - sudo bash -c 'echo -e "[user]\n\tname = abc\n\temail = root@localhost.com" > /home/travis/.gitconfig' @@ -36,10 +43,3 @@ script: - sudo wo update --travis - sudo wo stack status - - sudo wo stack purge --all --force - - sudo bash install --purge - -after_script: - - sudo cat /etc/nginx/nginx.conf | ccze -A - - sudo cat /var/log/wo/wordops.log | ccze -A - - sudo cat /etc/mysql/my.cnf | ccze -A diff --git a/tests/travis.sh b/tests/travis.sh index 0ea2467..d4b74b3 100644 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -132,3 +132,4 @@ echo -e ' various informations ' echo -e "${CGREEN}#############################################${CEND}" wp --allow-root --info wo site info wp1.com +wo stack purge --all --force \ No newline at end of file diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 1a9ae5c..833750e 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -925,11 +925,11 @@ class WOStackController(CementBaseController): 'kickstart.sh']).issubset(set(packages))): if WOVariables.wo_distro == 'Raspbian': WOShellExec.cmd_exec(self, "bash /usr/" - "libexec/netdata-" + "libexec/netdata/netdata-" "uninstaller.sh -y -f") else: WOShellExec.cmd_exec(self, "bash /opt/netdata/usr/" - "libexec/netdata-" + "libexec/netdata/netdata-" "uninstaller.sh -y -f") if (apt_packages): From 680947374b8cdc9537429c09e5fc9c7dad16a354 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Mon, 2 Sep 2019 02:20:12 +0200 Subject: [PATCH 16/20] Fix .lower --- wo/core/domainvalidate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wo/core/domainvalidate.py b/wo/core/domainvalidate.py index 06855b8..5d1d65d 100644 --- a/wo/core/domainvalidate.py +++ b/wo/core/domainvalidate.py @@ -29,7 +29,7 @@ def GetDomainlevel(domain): """ This function returns the domain type : domain, subdomain, """ - domain_name = domain.split('.').lower() + domain_name = domain.lower().split('.') if domain_name[0] == 'www': domain_name = domain_name[1:] domain_type = '' From 0a4ff1e962ee5f9fe5682b8311926321046e1973 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Mon, 2 Sep 2019 02:29:45 +0200 Subject: [PATCH 17/20] Fix displaying cert expiration --- wo/cli/plugins/site.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index dc52686..2a1ec33 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -1375,13 +1375,14 @@ class WOSiteUpdateController(CementBaseController): else: wo_acme_dns = '' wo_dns = False + 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 not os.path.isfile("{0}/conf/nginx/ssl.conf.disabled"): 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}" @@ -1422,7 +1423,7 @@ class WOSiteUpdateController(CementBaseController): Log.info(self, "Congratulations! Successfully " "Configured SSL for Site " " https://{0}".format(wo_domain)) - if wo_subdomain: + if wo_subdomain and isWildcard: if (SSL.getExpirationDays(self, wo_root_domain) > 0): Log.info(self, "Your cert will expire within " + str(SSL.getExpirationDays(self, wo_root_domain)) + From 8610f10b240474afa20ea2a706aa432b619b5b0b Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Mon, 2 Sep 2019 02:40:32 +0200 Subject: [PATCH 18/20] Increase log rotation limit to 1MB --- config/wo.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/wo.conf b/config/wo.conf index 8d4a3ad..f0d077c 100644 --- a/config/wo.conf +++ b/config/wo.conf @@ -33,7 +33,7 @@ to_console = false rotate = true ### Max size in bytes that a log file can grow until it is rotated. -max_bytes = 512000 +max_bytes = 1000000 ### The maximun number of log files to maintain when rotating max_files = 7 From c87a4da2617b291ec25b71b30949f8cae4cb6389 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Mon, 2 Sep 2019 02:44:43 +0200 Subject: [PATCH 19/20] Update changelog, improve netdata stack upgrade --- CHANGELOG.md | 2 ++ wo/cli/plugins/stack_upgrade.py | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c982290..0526cfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), #### Changed - do not terminate stack install process on errors +- WordOps internal log rotation limit increased to 1MB #### Fixed @@ -26,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - add LANG='en_US.UTF-8' in install script - Read public_suffix list with utf8 encoding. Issue [#128](https://github.com/WordOps/WordOps/issues/128) - Netdata uninstall script path. PR [#135](https://github.com/WordOps/WordOps/pull/135) +- SSL Certificates expiration for subdomains ### v3.9.8.7 - 2019-08-31 diff --git a/wo/cli/plugins/stack_upgrade.py b/wo/cli/plugins/stack_upgrade.py index 3809d6f..606998f 100644 --- a/wo/cli/plugins/stack_upgrade.py +++ b/wo/cli/plugins/stack_upgrade.py @@ -145,7 +145,8 @@ class WOStackUpgradeController(CementBaseController): Log.info(self, "WPCLI is not installed with WordOps") if pargs.netdata: - if os.path.isdir('/opt/netdata'): + if (os.path.isdir('/opt/netdata') or + os.path.isdir('/etc/netdata')): packages = packages + [['https://my-netdata.io/' 'kickstart-static64.sh', '/var/lib/wo/tmp/kickstart.sh', @@ -223,9 +224,16 @@ class WOStackUpgradeController(CementBaseController): if pargs.netdata: Log.info(self, "Upgrading Netdata, please wait...") - WOShellExec.cmd_exec(self, "/bin/bash /var/lib/wo/tmp/" - "kickstart.sh " - "--dont-wait") + if os.path.isdir('/opt/netdata'): + WOShellExec.cmd_exec( + self, "bash /opt/netdata/usr/" + "libexec/netdata/netdata-" + "updater.sh") + elif os.path.isdir('/etc/netdata'): + WOShellExec.cmd_exec( + self, "bash /usr/" + "libexec/netdata/netdata-" + "updater.sh") if pargs.dashboard: Log.debug(self, "Extracting wo-dashboard.tar.gz " From 953a1b0b06e92e65cd60bd71b65646e7f0456217 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Mon, 2 Sep 2019 03:41:02 +0200 Subject: [PATCH 20/20] Bump release to v3.9.8.8 --- CHANGELOG.md | 2 ++ setup.py | 2 +- wo/core/variables.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0526cfc..3c64539 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +### v3.9.8.8 - 2019-09-02 + #### Added - Sendmail stack to send WordPress welcome email properly diff --git a/setup.py b/setup.py index 30aeadf..2989001 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.7', + version='3.9.8.8', description=long_description, long_description=long_description, classifiers=[], diff --git a/wo/core/variables.py b/wo/core/variables.py index 11547bb..a06fb2e 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.7" + wo_version = "3.9.8.8" # WordOps packages versions wo_wp_cli = "2.2.0" wo_adminer = "4.7.2"