From acdc85ec2d93d918e3926d7281303b8651aabb7e Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 03:26:40 +0100 Subject: [PATCH 01/23] Fix wo maintenance --- wo/core/aptget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wo/core/aptget.py b/wo/core/aptget.py index 6a7ce3e..2fc6277 100644 --- a/wo/core/aptget.py +++ b/wo/core/aptget.py @@ -189,7 +189,7 @@ class WOAptGet(): """ try: orig_out = sys.stdout - sys.stdout = open(self.app.config.get('log.logging', 'file'), + sys.stdout = open(self.app.config.get('log.colorlog', 'file'), encoding='utf-8', mode='a') apt_get.autoclean("-y") sys.stdout = orig_out From 5aa3de8c8b239112ef0ac39fd472de44172e07e1 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 03:40:17 +0100 Subject: [PATCH 02/23] Fix wo clean --- wo/cli/plugins/clean.py | 4 ++-- wo/cli/templates/stub_status.mustache | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/wo/cli/plugins/clean.py b/wo/cli/plugins/clean.py index a0b8338..33c8bbd 100644 --- a/wo/cli/plugins/clean.py +++ b/wo/cli/plugins/clean.py @@ -78,13 +78,13 @@ class WOCleanController(CementBaseController): try: Log.info(self, "Cleaning opcache") opgui = requests.get( - "https://127.0.0.1:22222/cache/opcache/opgui.php?reset=1") + "http://127.0.0.1/cache/opcache/opgui.php?reset=1") if opgui.status_code != '200': Log.warn(self, 'Cleaning opcache failed') except Exception as e: Log.debug(self, "{0}".format(e)) Log.debug(self, "Unable hit url, " - " https://127.0.0.1:22222/cache/opcache/" + " https://127.0.0.1/cache/opcache/" "opgui.php?reset=1," " please check you have admin tools installed") Log.debug(self, "please check you have admin tools installed," diff --git a/wo/cli/templates/stub_status.mustache b/wo/cli/templates/stub_status.mustache index 82bbde7..9e6ae96 100644 --- a/wo/cli/templates/stub_status.mustache +++ b/wo/cli/templates/stub_status.mustache @@ -10,7 +10,9 @@ server { server_name 127.0.0.1 localhost; access_log off; log_not_found off; - root /var/www/html; + root /var/www/22222/htdocs; + allow 127.0.0.1; + deny all; location ~ /(stub_status|nginx_status) { stub_status on; allow 127.0.0.1; @@ -21,7 +23,16 @@ server { {{#phpconf}} location ~ /(status|ping) { include fastcgi_params; - allow 127.0.0.1; + fastcgi_pass phpstatus; + access_log off; + log_not_found off; + } + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + location ~ \.php$ { + try_files $uri =404; + include fastcgi_params; deny all; fastcgi_pass phpstatus; access_log off; From e01ecaa782d7ef289ec256933cce61c6766a87a1 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 03:42:35 +0100 Subject: [PATCH 03/23] Fix deprecated log --- wo/core/logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wo/core/logging.py b/wo/core/logging.py index bb6cbda..dee2a81 100644 --- a/wo/core/logging.py +++ b/wo/core/logging.py @@ -38,7 +38,7 @@ class Log: Logs warning into log file """ print(Log.WARNING + msg + Log.ENDC) - self.app.log.warn(Log.BOLD + msg + Log.ENDC) + self.app.log.warning(Log.BOLD + msg + Log.ENDC) def debug(self, msg): """ From 43edc325da63b6f77ff62f0edda6df25ebb4936e Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 03:45:07 +0100 Subject: [PATCH 04/23] Fix deny all --- wo/cli/templates/stub_status.mustache | 1 - 1 file changed, 1 deletion(-) diff --git a/wo/cli/templates/stub_status.mustache b/wo/cli/templates/stub_status.mustache index 9e6ae96..cb6c610 100644 --- a/wo/cli/templates/stub_status.mustache +++ b/wo/cli/templates/stub_status.mustache @@ -33,7 +33,6 @@ server { location ~ \.php$ { try_files $uri =404; include fastcgi_params; - deny all; fastcgi_pass phpstatus; access_log off; log_not_found off; From 6159d3d0b2682368cebd92b05a05a081bb6b2d50 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 03:48:59 +0100 Subject: [PATCH 05/23] Fix wo clean --- wo/cli/plugins/clean.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wo/cli/plugins/clean.py b/wo/cli/plugins/clean.py index 33c8bbd..7036583 100644 --- a/wo/cli/plugins/clean.py +++ b/wo/cli/plugins/clean.py @@ -79,7 +79,7 @@ class WOCleanController(CementBaseController): Log.info(self, "Cleaning opcache") opgui = requests.get( "http://127.0.0.1/cache/opcache/opgui.php?reset=1") - if opgui.status_code != '200': + if opgui.status_code != '200' or opgui.status_code != '302': Log.warn(self, 'Cleaning opcache failed') except Exception as e: Log.debug(self, "{0}".format(e)) From 121988f0baf5a883fcc78dae55d9538169693e16 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 03:57:13 +0100 Subject: [PATCH 06/23] Fix redirection --- wo/cli/plugins/clean.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wo/cli/plugins/clean.py b/wo/cli/plugins/clean.py index 7036583..fbb0f4a 100644 --- a/wo/cli/plugins/clean.py +++ b/wo/cli/plugins/clean.py @@ -77,14 +77,15 @@ class WOCleanController(CementBaseController): '/var/www/22222/htdocs/cache/opcache/opgui.php')): try: Log.info(self, "Cleaning opcache") + payload = {'reset': '1'} opgui = requests.get( - "http://127.0.0.1/cache/opcache/opgui.php?reset=1") + "http://127.0.0.1/cache/opcache/opgui.php", params=payload) if opgui.status_code != '200' or opgui.status_code != '302': Log.warn(self, 'Cleaning opcache failed') except Exception as e: Log.debug(self, "{0}".format(e)) Log.debug(self, "Unable hit url, " - " https://127.0.0.1/cache/opcache/" + " http://127.0.0.1/cache/opcache/" "opgui.php?reset=1," " please check you have admin tools installed") Log.debug(self, "please check you have admin tools installed," From 19e595e207975a15e826abad7beab970a6cff233 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 04:01:28 +0100 Subject: [PATCH 07/23] Fix wo clean --- wo/cli/templates/stub_status.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wo/cli/templates/stub_status.mustache b/wo/cli/templates/stub_status.mustache index cb6c610..aa4cb0f 100644 --- a/wo/cli/templates/stub_status.mustache +++ b/wo/cli/templates/stub_status.mustache @@ -28,7 +28,7 @@ server { log_not_found off; } location / { - try_files $uri $uri/ /index.php$is_args$args; + try_files $uri $uri/ /cache/opcache/opgui.php$is_args$args; } location ~ \.php$ { try_files $uri =404; From 1997bedb93433058d259cdfd3e04300cc5f617f0 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 11:12:35 +0100 Subject: [PATCH 08/23] Fix opcache clean --- wo/cli/plugins/clean.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wo/cli/plugins/clean.py b/wo/cli/plugins/clean.py index fbb0f4a..9fc4474 100644 --- a/wo/cli/plugins/clean.py +++ b/wo/cli/plugins/clean.py @@ -77,9 +77,9 @@ class WOCleanController(CementBaseController): '/var/www/22222/htdocs/cache/opcache/opgui.php')): try: Log.info(self, "Cleaning opcache") - payload = {'reset': '1'} + payload = {'RESET': '1'} opgui = requests.get( - "http://127.0.0.1/cache/opcache/opgui.php", params=payload) + "http://127.0.0.1/cache/opcache/ocp.php", params=payload) if opgui.status_code != '200' or opgui.status_code != '302': Log.warn(self, 'Cleaning opcache failed') except Exception as e: From 6ba6939b2bbd19ee4803b40fb5b0dffdfaee79e8 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 12:52:11 +0100 Subject: [PATCH 09/23] Add stack upgrade fail2ban --- wo/cli/plugins/stack_pref.py | 83 ++++++++++++++------------------- wo/cli/plugins/stack_upgrade.py | 52 ++++++++++++--------- wo/core/apt_repo.py | 12 +++++ 3 files changed, 77 insertions(+), 70 deletions(-) diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index d3d2151..2a5bdc5 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -97,12 +97,9 @@ def pre_pref(self, apt_packages): # add nginx repository if set(WOVar.wo_nginx).issubset(set(apt_packages)): if (WOVar.wo_distro == 'ubuntu'): - if not os.path.isfile( - 'wordops-ubuntu-nginx-wo-{0}.list' - .format(WOVar.wo_platform_codename)): - Log.info(self, "Adding repository for NGINX, please wait...") - WORepo.add(self, ppa=WOVar.wo_nginx_repo) - Log.debug(self, 'Adding ppa for Nginx') + Log.info(self, "Adding repository for NGINX, please wait...") + WORepo.add(self, ppa=WOVar.wo_nginx_repo) + Log.debug(self, 'Adding ppa for Nginx') else: if not WOFileUtils.grepcheck( self, '/etc/apt/sources.list/wo-repo.list', @@ -117,11 +114,8 @@ def pre_pref(self, apt_packages): ('php7.2-fpm' in apt_packages) or ('php7.4-fpm' in apt_packages)): if (WOVar.wo_distro == 'ubuntu'): Log.debug(self, 'Adding ppa for PHP') - if not os.path.isfile( - '/etc/apt/sources.list.d/ondrej-ubuntu-php-{0}.list' - .format(WOVar.wo_platform_codename)): - Log.info(self, "Adding repository for PHP, please wait...") - WORepo.add(self, ppa=WOVar.wo_php_repo) + Log.info(self, "Adding repository for PHP, please wait...") + WORepo.add(self, ppa=WOVar.wo_php_repo) else: # Add repository for php if (WOVar.wo_platform_codename == 'buster'): @@ -144,13 +138,9 @@ def pre_pref(self, apt_packages): # add redis repository if set(WOVar.wo_redis).issubset(set(apt_packages)): if WOVar.wo_distro == 'ubuntu': - if not os.path.isfile( - '/etc/apt/sources.list.d/' - 'chris-lea-ubuntu-redis-server-{0}.list' - .format(WOVar.wo_platform_codename)): - Log.info(self, "Adding repository for Redis, please wait...") - Log.debug(self, 'Adding ppa for redis') - WORepo.add(self, ppa=WOVar.wo_redis_repo) + Log.info(self, "Adding repository for Redis, please wait...") + Log.debug(self, 'Adding ppa for redis') + WORepo.add(self, ppa=WOVar.wo_redis_repo) else: if not WOFileUtils.grepcheck( self, '/etc/apt/sources.list/wo-repo.list', @@ -164,12 +154,8 @@ def pre_pref(self, apt_packages): if WOVar.wo_distro == 'ubuntu': if (WOVar.wo_platform_codename == 'bionic' or WOVar.wo_platform_codename == 'xenial'): - if not os.path.exists( - '/etc/apt/sources.list.d/' - 'jonathonf-ubuntu-backports-{0}.list' - .format(WOVar.wo_platform_codename)): - Log.debug(self, 'Adding ppa for nano') - WORepo.add(self, ppa=WOVar.wo_ubuntu_backports) + Log.debug(self, 'Adding ppa for nano') + WORepo.add(self, ppa=WOVar.wo_ubuntu_backports) def post_pref(self, apt_packages, packages, upgrade=False): @@ -997,35 +983,34 @@ def post_pref(self, apt_packages, packages, upgrade=False): WOGit.add(self, ["/etc/mysql"], msg="Adding MySQL into Git") # create fail2ban configuration files - if set(WOVar.wo_fail2ban).issubset(set(apt_packages)): + if "fail2ban" in apt_packages: WOService.restart_service(self, 'fail2ban') WOGit.add(self, ["/etc/fail2ban"], msg="Adding Fail2ban into Git") - if not os.path.isfile("/etc/fail2ban/jail.d/custom.conf"): - Log.info(self, "Configuring Fail2Ban") - data = dict(release=WOVar.wo_version) - WOTemplate.deploy( - self, - '/etc/fail2ban/jail.d/custom.conf', - 'fail2ban.mustache', - data, overwrite=False) - WOTemplate.deploy( - self, - '/etc/fail2ban/filter.d/wo-wordpress.conf', - 'fail2ban-wp.mustache', - data, overwrite=False) - WOTemplate.deploy( - self, - '/etc/fail2ban/filter.d/nginx-forbidden.conf', - 'fail2ban-forbidden.mustache', - data, overwrite=False) + Log.info(self, "Configuring Fail2Ban") + data = dict(release=WOVar.wo_version) + WOTemplate.deploy( + self, + '/etc/fail2ban/jail.d/custom.conf', + 'fail2ban.mustache', + data, overwrite=False) + WOTemplate.deploy( + self, + '/etc/fail2ban/filter.d/wo-wordpress.conf', + 'fail2ban-wp.mustache', + data, overwrite=False) + WOTemplate.deploy( + self, + '/etc/fail2ban/filter.d/nginx-forbidden.conf', + 'fail2ban-forbidden.mustache', + data, overwrite=False) - if not WOService.reload_service(self, 'fail2ban'): - WOGit.rollback( - self, ['/etc/fail2ban'], msg="Rollback f2b config") - else: - WOGit.add(self, ["/etc/fail2ban"], - msg="Adding Fail2ban into Git") + if not WOService.reload_service(self, 'fail2ban'): + WOGit.rollback( + self, ['/etc/fail2ban'], msg="Rollback f2b config") + else: + WOGit.add(self, ["/etc/fail2ban"], + msg="Adding Fail2ban into Git") # Proftpd configuration if "proftpd-basic" in apt_packages: diff --git a/wo/cli/plugins/stack_upgrade.py b/wo/cli/plugins/stack_upgrade.py index 7df87fe..2d8592c 100644 --- a/wo/cli/plugins/stack_upgrade.py +++ b/wo/cli/plugins/stack_upgrade.py @@ -26,6 +26,8 @@ class WOStackUpgradeController(CementBaseController): dict(help='Upgrade web stack', action='store_true')), (['--admin'], dict(help='Upgrade admin tools stack', action='store_true')), + (['--security'], + dict(help='Upgrade security stack', action='store_true')), (['--nginx'], dict(help='Upgrade Nginx stack', action='store_true')), (['--php'], @@ -44,6 +46,8 @@ class WOStackUpgradeController(CementBaseController): dict(help='Upgrade Redis', action='store_true')), (['--netdata'], dict(help='Upgrade Netdata', action='store_true')), + (['--fail2ban'], + dict(help='Upgrade Fail2Ban', action='store_true')), (['--dashboard'], dict(help='Upgrade WordOps Dashboard', action='store_true')), (['--composer'], @@ -71,18 +75,15 @@ class WOStackUpgradeController(CementBaseController): packages = [] self.msg = [] pargs = self.app.pargs - if ((not pargs.web) and (not pargs.nginx) and - (not pargs.php) and - (not pargs.php72) and (not pargs.php73) and - (not pargs.php74) and - (not pargs.mysql) and (not pargs.ngxblocker) and - (not pargs.all) and (not pargs.wpcli) and - (not pargs.netdata) and (not pargs.composer) and - (not pargs.phpmyadmin) and (not pargs.adminer) and - (not pargs.dashboard) and (not pargs.mysqltuner) and - (not pargs.redis)): + if not (pargs.web or pargs.nginx or pargs.php or + pargs.php72 or pargs.php73 or pargs.php74 or pargs.mysql or + pargs.ngxblocker or pargs.all or pargs.netdata or + pargs.wpcli or pargs.composer or pargs.phpmyadmin or + pargs.adminer or pargs.dashboard or pargs.mysqltuner or + pargs.redis or pargs.fail2ban or pargs.security): pargs.web = True pargs.admin = True + pargs.security = True if pargs.php: pargs.php72 = True @@ -90,8 +91,8 @@ class WOStackUpgradeController(CementBaseController): if pargs.all: pargs.web = True pargs.admin = True + pargs.security = True pargs.redis = True - pargs.ngxblocker = True if pargs.web: pargs.nginx = True @@ -110,6 +111,10 @@ class WOStackUpgradeController(CementBaseController): pargs.adminer = True pargs.mysqltuner = True + if pargs.security: + pargs.ngxblocker = True + pargs.fail2ban = True + # nginx if pargs.nginx: if WOAptGet.is_installed(self, 'nginx-custom'): @@ -149,6 +154,11 @@ class WOStackUpgradeController(CementBaseController): if WOAptGet.is_installed(self, 'redis-server'): apt_packages = apt_packages + ['redis-server'] + # fail2ban + if pargs.fail2ban: + if WOAptGet.is_installed(self, 'fail2ban'): + apt_packages = apt_packages + ['fail2ban'] + # wp-cli if pargs.wpcli: if os.path.isfile('/usr/local/bin/wp'): @@ -267,26 +277,26 @@ class WOStackUpgradeController(CementBaseController): else: pre_stack(self) if (apt_packages): - if (("php7.2-fpm" not in apt_packages) and - ("php7.3-fpm" not in apt_packages) and - ("php7.4-fpm" not in apt_packages) and - ("redis-server" not in apt_packages) and - ("nginx-custom" not in apt_packages) and - ("mariadb-server" not in apt_packages)): + if not ("php7.2-fpm" in apt_packages or + "php7.3-fpm" in apt_packages or + "php7.4-fpm" in apt_packages or + "redis-server" in apt_packages or + "nginx-custom" in apt_packages or + "mariadb-server" in apt_packages): pass else: - Log.info( + Log.warn( self, "Your sites may be down for few seconds if " "you are upgrading Nginx, PHP-FPM, MariaDB or Redis") # Check prompt - if ((not pargs.no_prompt) and (not pargs.force)): + if not (pargs.no_prompt or pargs.force): start_upgrade = input("Do you want to continue:[y/N]") if start_upgrade != "Y" and start_upgrade != "y": Log.error(self, "Not starting package update") - Log.wait(self, "Updating APT packages") + Log.wait(self, "Updating APT cache") # apt-get update WOAptGet.update(self) - Log.valide(self, "Updating APT packages") + Log.valide(self, "Updating APT cache") # additional pre_pref if "nginx-custom" in apt_packages: diff --git a/wo/core/apt_repo.py b/wo/core/apt_repo.py index 470ac4e..e260e4f 100644 --- a/wo/core/apt_repo.py +++ b/wo/core/apt_repo.py @@ -48,9 +48,21 @@ class WORepo(): Log.debug(self, "{0}".format(e)) Log.error(self, "Unable to add repo") if ppa is not None: + ppa_split = ppa.split(':')[1] + ppa_author = ppa_split.split('/')[0] + Log.debug(self, "ppa_author = {0}".format(ppa_author)) + ppa_package = ppa_split.split('/')[1] + Log.debug(self, "ppa_package = {0}".format(ppa_package)) + if os.path.exists( + '/etc/apt/sources.list.d/{0}-ubuntu-{1}-{2}.list' + .format(ppa_author, + ppa_package, WOVar.wo_platform_codename)): + Log.debug(self, "ppa already added") + return True if WOShellExec.cmd_exec( self, "LC_ALL=C.UTF-8 add-apt-repository -y '{ppa_name}'" .format(ppa_name=ppa)): + Log.debug(self, "Added PPA {0}".format(ppa)) return True return False From 96f4332dcea9201032124555200ae5f6afc77d1e Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 13:37:30 +0100 Subject: [PATCH 10/23] Adding adminer & fail2ban to travis --- tests/travis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/travis.sh b/tests/travis.sh index b0754fb..0cb9586 100644 --- a/tests/travis.sh +++ b/tests/travis.sh @@ -203,7 +203,7 @@ if [ -z "$1" ]; then echo -e "${CGREEN}#############################################${CEND}" echo -e ' wo stack upgrade ' echo -e "${CGREEN}#############################################${CEND}" - stack_upgrade='nginx php php72 php73 php74 mysql redis netdata dashboard phpmyadmin composer ngxblocker mysqltuner' + stack_upgrade='nginx php php72 php73 php74 mysql redis netdata dashboard phpmyadmin adminer fail2ban composer ngxblocker mysqltuner' for stack in $stack_upgrade; do echo -ne " Upgrading $stack [..]\r" if { From 732ff51d9fffec5028f2bb7c043bf9a472de649b Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 14:58:04 +0100 Subject: [PATCH 11/23] Remove async variable for compatibility --- wo/core/logging.py | 2 +- wo/core/logwatch.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wo/core/logging.py b/wo/core/logging.py index dee2a81..46a7f61 100644 --- a/wo/core/logging.py +++ b/wo/core/logging.py @@ -44,7 +44,7 @@ class Log: """ Logs debug messages into log file """ - self.app.log.debug(Log.HEADER + msg + Log.ENDC) + self.app.log.debug(Log.HEADER + msg + Log.ENDC, __name__) def wait(self, msg, end='\r', log=True): """ diff --git a/wo/core/logwatch.py b/wo/core/logwatch.py index 0d51440..a42af54 100644 --- a/wo/core/logwatch.py +++ b/wo/core/logwatch.py @@ -65,7 +65,7 @@ class LogWatcher(object): def __del__(self): self.close() - def loop(self, interval=0.1, async=False): + def loop(self, interval=0.1, req_async=False): """Start the loop. If async is True make one loop then return. """ @@ -73,7 +73,7 @@ class LogWatcher(object): self.update_files() for fid, file in list(iter(self.files_map.items())): self.readfile(file) - if async: + if req_async: return time.sleep(interval) From 9a04a0d786ed84c0e4d90190099d620b5c92bd3b Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 16:20:27 +0100 Subject: [PATCH 12/23] fix wo clean --- wo/cli/plugins/clean.py | 7 +++---- wo/cli/plugins/stack_pref.py | 30 +++++++++++++++++++++++++++ wo/cli/templates/stub_status.mustache | 20 +++++++++++++++--- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/wo/cli/plugins/clean.py b/wo/cli/plugins/clean.py index 9fc4474..fd3917e 100644 --- a/wo/cli/plugins/clean.py +++ b/wo/cli/plugins/clean.py @@ -74,19 +74,18 @@ class WOCleanController(CementBaseController): def clean_opcache(self): if (os.path.exists('/usr/sbin/nginx') and os.path.exists( - '/var/www/22222/htdocs/cache/opcache/opgui.php')): + '/var/www/22222/htdocs/cache/opcache/php72.php')): try: Log.info(self, "Cleaning opcache") - payload = {'RESET': '1'} opgui = requests.get( - "http://127.0.0.1/cache/opcache/ocp.php", params=payload) + "http://127.0.0.1/cache/opcache/php72.php") if opgui.status_code != '200' or opgui.status_code != '302': Log.warn(self, 'Cleaning opcache failed') except Exception as e: Log.debug(self, "{0}".format(e)) Log.debug(self, "Unable hit url, " " http://127.0.0.1/cache/opcache/" - "opgui.php?reset=1," + "php72.php," " please check you have admin tools installed") Log.debug(self, "please check you have admin tools installed," " or install them with `wo stack install --admin`") diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index 2a5bdc5..f6a29d7 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -606,6 +606,16 @@ def post_pref(self, apt_packages, packages, upgrade=False): encoding='utf-8', mode='w') as myfile: myfile.write("") + # write opcache clean for php72 + if not os.path.exists('{0}22222/htdocs/cache/opcache' + .format(ngxroot)): + os.makedirs('{0}22222/htdocs/cache/opcache' + .format(ngxroot)) + WOFileUtils.textwrite( + self, '{0}22222/htdocs/cache/opcache/php72.php' + .format(ngxroot), + '') + WOFileUtils.chown(self, "{0}22222/htdocs" .format(ngxroot), 'www-data', @@ -743,6 +753,16 @@ def post_pref(self, apt_packages, packages, upgrade=False): encoding='utf-8', mode='w') as myfile: myfile.write("") + # write opcache clean for php73 + if not os.path.exists('{0}22222/htdocs/cache/opcache' + .format(ngxroot)): + os.makedirs('{0}22222/htdocs/cache/opcache' + .format(ngxroot)) + WOFileUtils.textwrite( + self, '{0}22222/htdocs/cache/opcache/php73.php' + .format(ngxroot), + '') + WOFileUtils.chown(self, "{0}22222/htdocs" .format(ngxroot), 'www-data', @@ -879,6 +899,16 @@ def post_pref(self, apt_packages, packages, upgrade=False): self, "{0}22222/htdocs/php/info.php" .format(ngxroot), "") + # write opcache clean for php74 + if not os.path.exists('{0}22222/htdocs/cache/opcache' + .format(ngxroot)): + os.makedirs('{0}22222/htdocs/cache/opcache' + .format(ngxroot)) + WOFileUtils.textwrite( + self, '{0}22222/htdocs/cache/opcache/php74.php' + .format(ngxroot), + '') + WOFileUtils.chown(self, "{0}22222/htdocs" .format(ngxroot), 'www-data', diff --git a/wo/cli/templates/stub_status.mustache b/wo/cli/templates/stub_status.mustache index aa4cb0f..ccbc255 100644 --- a/wo/cli/templates/stub_status.mustache +++ b/wo/cli/templates/stub_status.mustache @@ -28,12 +28,26 @@ server { log_not_found off; } location / { - try_files $uri $uri/ /cache/opcache/opgui.php$is_args$args; + try_files $uri $uri/ /index.php$is_args$args; } - location ~ \.php$ { + location /cache/opcache/php72.php { try_files $uri =404; include fastcgi_params; - fastcgi_pass phpstatus; + fastcgi_pass php72; + access_log off; + log_not_found off; + } + location /cache/opcache/php73.php { + try_files $uri =404; + include fastcgi_params; + fastcgi_pass php73; + access_log off; + log_not_found off; + } + location /cache/opcache/php74.php { + try_files $uri =404; + include fastcgi_params; + fastcgi_pass php74; access_log off; log_not_found off; } From 6f6c22067ed460822929499f681c7539d84ee3af Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 19:25:56 +0100 Subject: [PATCH 13/23] Add igbinary to php_extra --- wo/cli/plugins/stack.py | 18 ++++++------------ wo/core/variables.py | 2 +- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 46a2643..17f8d63 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -184,10 +184,8 @@ class WOStackController(CementBaseController): if pargs.php72: Log.debug(self, "Setting apt_packages variable for PHP 7.2") if not (WOAptGet.is_installed(self, 'php7.2-fpm')): - apt_packages = apt_packages + WOVar.wo_php72 - if not (WOAptGet.is_installed(self, 'php7.3-fpm') or - WOAptGet.is_installed(self, 'php7.4-fpm')): - apt_packages = apt_packages + WOVar.wo_php_extra + apt_packages = (apt_packages + WOVar.wo_php72 + + WOVar.wo_php_extra) else: Log.debug(self, "PHP 7.2 already installed") Log.info(self, "PHP 7.2 already installed") @@ -196,10 +194,8 @@ class WOStackController(CementBaseController): if pargs.php73: Log.debug(self, "Setting apt_packages variable for PHP 7.3") if not WOAptGet.is_installed(self, 'php7.3-fpm'): - apt_packages = apt_packages + WOVar.wo_php73 - if not (WOAptGet.is_installed(self, 'php7.2-fpm') or - WOAptGet.is_installed(self, 'php7.4-fpm')): - apt_packages = apt_packages + WOVar.wo_php_extra + apt_packages = (apt_packages + WOVar.wo_php73 + + WOVar.wo_php_extra) else: Log.debug(self, "PHP 7.3 already installed") Log.info(self, "PHP 7.3 already installed") @@ -208,10 +204,8 @@ class WOStackController(CementBaseController): if pargs.php74: Log.debug(self, "Setting apt_packages variable for PHP 7.4") if not WOAptGet.is_installed(self, 'php7.4-fpm'): - apt_packages = apt_packages + WOVar.wo_php74 - if not (WOAptGet.is_installed(self, 'php7.3-fpm') or - WOAptGet.is_installed(self, 'php7.2-fpm')): - apt_packages = apt_packages + WOVar.wo_php_extra + apt_packages = (apt_packages + WOVar.wo_php74 + + WOVar.wo_php_extra) else: Log.debug(self, "PHP 7.4 already installed") Log.info(self, "PHP 7.4 already installed") diff --git a/wo/core/variables.py b/wo/core/variables.py index d3d773a..423f141 100644 --- a/wo/core/variables.py +++ b/wo/core/variables.py @@ -150,7 +150,7 @@ class WOVar(): for module in wo_module: wo_php74 = wo_php74 + ["php7.4-{0}".format(module)] - wo_php_extra = ["php-memcached", "php-imagick", + wo_php_extra = ["php-memcached", "php-imagick", "php-igbinary", "graphviz", "php-xdebug", "php-msgpack", "php-redis"] wo_mysql = ["mariadb-server", "percona-toolkit"] From 0568a3dbf96ad634a320c8b04a03c354e3878c02 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Wed, 4 Dec 2019 21:58:53 +0100 Subject: [PATCH 14/23] Bump version de v3.11.1 --- CHANGELOG.md | 12 ++++++++++++ install | 2 +- setup.py | 2 +- wo/core/variables.py | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85cc359..c0ae5a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +### v3.11.1 - 2019-12-04 + +#### Added + +- `--fail2ban` in wo stack upgrade + +#### Fixed + +- error with `wo maintenance` +- php-igbinary missing for php74 (run `wo stack upgrade` to install it) +- opcache reset with `wo clean` + ### v3.11.0 - 2019-12-03 #### Added diff --git a/install b/install index 6c6e4a6..16642d2 100755 --- a/install +++ b/install @@ -9,7 +9,7 @@ # ------------------------------------------------------------------------- # wget -qO wo wops.cc && sudo bash wo # ------------------------------------------------------------------------- -# Version 3.11.0 - 2019-12-03 +# Version 3.11.1 - 2019-12-04 # ------------------------------------------------------------------------- # CONTENTS diff --git a/setup.py b/setup.py index 6af933c..602f4aa 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ if os.geteuid() == 0: os.makedirs('/var/lib/wo/tmp/') setup(name='wordops', - version='3.11.0', + version='3.11.1', description='An essential toolset that eases server administration', long_description=LONG, long_description_content_type='text/markdown', diff --git a/wo/core/variables.py b/wo/core/variables.py index 423f141..afc8dad 100644 --- a/wo/core/variables.py +++ b/wo/core/variables.py @@ -14,7 +14,7 @@ class WOVar(): """Intialization of core variables""" # WordOps version - wo_version = "3.11.0" + wo_version = "3.11.1" # WordOps packages versions wo_wp_cli = "2.4.0" wo_adminer = "4.7.5" From 5282000d4f14a303dbc9798ee93e61dfb4e1ce51 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Thu, 5 Dec 2019 15:56:12 +0100 Subject: [PATCH 15/23] Fix nginx variables_hash_bucket_size --- CHANGELOG.md | 4 ++++ wo/cli/plugins/stack.py | 1 + 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0ae5a9..c06fb09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +#### Changed + +- Install ngxblocker with Nginx to set proper values for variables_hash_bucket_size & variables_hash_max_size without conflicts + ### v3.11.1 - 2019-12-04 #### Added diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 17f8d63..88dd639 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -166,6 +166,7 @@ class WOStackController(CementBaseController): # Nginx if pargs.nginx: + pargs.ngxblocker = True Log.debug(self, "Setting apt_packages variable for Nginx") if not WOAptGet.is_exec(self, 'nginx'): apt_packages = apt_packages + WOVar.wo_nginx From e45955a5138f72780922f724dbb85c5637d129c2 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Thu, 5 Dec 2019 20:36:18 +0100 Subject: [PATCH 16/23] Fix variables_hash_bucket_size --- CHANGELOG.md | 4 ++-- wo/cli/plugins/stack_pref.py | 17 ++++++++++++++--- wo/cli/plugins/stack_upgrade.py | 5 +++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c06fb09..914b470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] -#### Changed +#### Fixed -- Install ngxblocker with Nginx to set proper values for variables_hash_bucket_size & variables_hash_max_size without conflicts +- Issue with Nginx variables_hash_bucket_size & variables_hash_max_size ### v3.11.1 - 2019-12-04 diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index f6a29d7..8237572 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -321,9 +321,15 @@ def post_pref(self, apt_packages, packages, upgrade=False): "'\"$http_referer\" " "\"$http_user_agent\"';\n") - # Nginx-Plus does not have nginx - # package structure like this - # So creating directories + if not os.path.exists('/etc/nginx/bots.d'): + WOFileUtils.textwrite( + self, '/etc/nginx/conf.d/variables-hash.conf', + 'variables_hash_max_size 4096;\n' + 'variables_hash_bucket_size 4096;') + + # Nginx-Plus does not have nginx + # package structure like this + # So creating directories if not os.path.exists('/etc/nginx/sites-available'): Log.debug(self, 'Creating directory' '/etc/nginx/sites-available') @@ -1585,11 +1591,16 @@ def post_pref(self, apt_packages, packages, upgrade=False): # ngxblocker if any('/usr/local/sbin/install-ngxblocker' == x[1] for x in packages): + # remove duplicate directives + if os.path.exists('/etc/nginx/conf.d/variables-hash.conf'): + WOFileUtils.rm(self, '/etc/nginx/conf.d/variables-hash.conf') WOFileUtils.chmod( self, "/usr/local/sbin/install-ngxblocker", 0o700) WOShellExec.cmd_exec(self, '/usr/local/sbin/install-ngxblocker -x') WOFileUtils.chmod( self, "/usr/local/sbin/update-ngxblocker", 0o700) + if not WOService.restart_service(self, 'nginx'): + Log.error(self, 'ngxblocker install failed') def pre_stack(self): diff --git a/wo/cli/plugins/stack_upgrade.py b/wo/cli/plugins/stack_upgrade.py index 2d8592c..be669c5 100644 --- a/wo/cli/plugins/stack_upgrade.py +++ b/wo/cli/plugins/stack_upgrade.py @@ -269,8 +269,6 @@ class WOStackUpgradeController(CementBaseController): '/usr/local/sbin/update-ngxblocker', 'ngxblocker' ]] - else: - Log.info(self, "ngxblocker is not installed") if ((not (apt_packages)) and (not(packages))): self.app.args.print_help() @@ -347,6 +345,9 @@ class WOStackUpgradeController(CementBaseController): WOFileUtils.chmod(self, "/usr/local/bin/wp", 0o775) if WOAptGet.is_selected(self, 'ngxblocker', packages): + if os.path.exists('/etc/nginx/conf.d/variables-hash.conf'): + WOFileUtils.rm( + self, '/etc/nginx/conf.d/variables-hash.conf') WOFileUtils.chmod( self, '/usr/local/sbin/update-ngxblocker', 0o775) WOShellExec.cmd_exec( From 6f86a5d9c330e65725973464f290537d838c1299 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Fri, 6 Dec 2019 01:19:57 +0100 Subject: [PATCH 17/23] Force acme.sh upgrade and force cronjob update --- install | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/install b/install index 16642d2..ae76ba4 100755 --- a/install +++ b/install @@ -411,8 +411,6 @@ wo_install_acme_sh() { mkdir "$HOME/.acme.sh" touch "$HOME/.acme.sh/acme.sh.env" # removing previous cronjob - crontab -l | sed '/41 0 \* \* \* "\/root\/\.acme\.sh"\/acme.sh --cron --home "\/root\/\.acme\.sh" > \/dev\/null/d' | crontab - - fi # Let's Encrypt .well-known folder setup if [ ! -d /var/www/html/.well-known/acme-challenge ]; then @@ -420,6 +418,13 @@ wo_install_acme_sh() { fi chown -R www-data:www-data /var/www/html /var/www/html/.well-known chmod 750 /var/www/html /var/www/html/.well-known + if [ -x /etc/letsencrypt/acme.sh ]; then + export LE_WORKING_DIR="/etc/letsencrypt" + export LE_CONFIG_HOME="/etc/letsencrypt/config" + /etc/letsencrypt/acme.sh --config-home '/etc/letsencrypt/config' --upgrade --auto-upgrade + /etc/letsencrypt/acme.sh --config-home "/etc/letsencrypt/config" --uninstall-cronjob + /etc/letsencrypt/acme.sh --config-home "/etc/letsencrypt/config" --install-cronjob + fi } From a1cf706f9f590c54129096f5aa39e8c06f2f2236 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Fri, 6 Dec 2019 03:04:14 +0100 Subject: [PATCH 18/23] Do not upgrade acme.sh twice --- install | 3 --- 1 file changed, 3 deletions(-) diff --git a/install b/install index ae76ba4..cff0cd2 100755 --- a/install +++ b/install @@ -388,9 +388,6 @@ wo_install_acme_sh() { --home /etc/letsencrypt \ --config-home /etc/letsencrypt/config \ --cert-home /etc/letsencrypt/renewal - # enable auto-upgrade - /etc/letsencrypt/acme.sh --config-home '/etc/letsencrypt/config' --upgrade --auto-upgrade - fi if [ -x "$HOME/.acme.sh/acme.sh" ]; then From d536f57cd98c9b6cc4cf7ef30fe38db59dbf02c1 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Fri, 6 Dec 2019 10:15:49 +0100 Subject: [PATCH 19/23] Fix wo site cd & use proxy_params --- wo/cli/plugins/site.py | 5 +++++ wo/cli/templates/virtualconf.mustache | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/wo/cli/plugins/site.py b/wo/cli/plugins/site.py index 0d63995..426c84a 100644 --- a/wo/cli/plugins/site.py +++ b/wo/cli/plugins/site.py @@ -241,6 +241,11 @@ class WOSiteController(CementBaseController): wo_site_webroot = getSiteInfo(self, wo_domain).site_path if os.path.isdir(wo_site_webroot): WOFileUtils.chdir(self, wo_site_webroot) + + try: + subprocess.call(['/bin/bash']) + except OSError as e: + Log.debug(self, "{0}{1}".format(e.errno, e.strerror)) else: Log.error(self, "unable to change directory") diff --git a/wo/cli/templates/virtualconf.mustache b/wo/cli/templates/virtualconf.mustache index 76be634..e0f2f36 100644 --- a/wo/cli/templates/virtualconf.mustache +++ b/wo/cli/templates/virtualconf.mustache @@ -21,9 +21,7 @@ server { location / { proxy_pass http://{{host}}:{{port}}; proxy_redirect off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + include proxy_params; } # Security settings for better privacy From 0e12bc29db8c65a6c1dd433239e1653002302773 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Fri, 6 Dec 2019 13:09:45 +0100 Subject: [PATCH 20/23] Fix netdata mysql user in case of reinstall --- wo/cli/plugins/stack_pref.py | 8 ++++++-- wo/core/mysql.py | 18 +++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/wo/cli/plugins/stack_pref.py b/wo/cli/plugins/stack_pref.py index 8237572..ddb6636 100644 --- a/wo/cli/plugins/stack_pref.py +++ b/wo/cli/plugins/stack_pref.py @@ -1410,11 +1410,15 @@ def post_pref(self, apt_packages, packages, upgrade=False): try: WOMysql.execute( self, - "create user 'netdata'@'localhost';", + "DELETE FROM mysql.user WHERE User = 'netdata';", log=False) WOMysql.execute( self, - "grant usage on *.* to 'netdata'@'localhost';", + "create user 'netdata'@'127.0.0.1';", + log=False) + WOMysql.execute( + self, + "grant usage on *.* to 'netdata'@'127.0.0.1';", log=False) WOMysql.execute( self, "flush privileges;", diff --git a/wo/core/mysql.py b/wo/core/mysql.py index 907a608..275a56a 100644 --- a/wo/core/mysql.py +++ b/wo/core/mysql.py @@ -108,17 +108,13 @@ class WOMysql(): if dbs == "": continue Log.info(self, "Backing up {0} database".format(dbs)) - p1 = subprocess.Popen("/usr/bin/mysqldump {0}" - " --max_allowed_packet=1024M" - " --single-transaction".format(dbs), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, shell=True) - p2 = subprocess.Popen("/usr/bin/pigz -c > " - "/var/lib/wo-backup/mysql/{0}{1}.sql.gz" - .format(dbs, WOVar.wo_date), - stdin=p1.stdout, - shell=True) - + p1 = subprocess.Popen( + "/usr/bin/mysqldump {0} --max_allowed_packet=1024M " + "--single-transaction ".format(dbs), + stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + p2 = subprocess.Popen( + "/usr/bin/pigz -c > /var/lib/wo-backup/mysql/{0}{1}.sql.gz" + .format(dbs, WOVar.wo_date), stdin=p1.stdout, shell=True) # Allow p1 to receive a SIGPIPE if p2 exits p1.stdout.close() output = p1.stderr.read() From 01897adce6fec7e268e058f042d99a3a1dd21a7c Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Fri, 6 Dec 2019 13:12:01 +0100 Subject: [PATCH 21/23] Remove netdata user in case of stack purge --- wo/cli/plugins/stack.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wo/cli/plugins/stack.py b/wo/cli/plugins/stack.py index 88dd639..f2a5981 100644 --- a/wo/cli/plugins/stack.py +++ b/wo/cli/plugins/stack.py @@ -1140,6 +1140,9 @@ class WOStackController(CementBaseController): WOShellExec.cmd_exec(self, "bash /opt/netdata/usr/" "libexec/netdata/netdata-" "uninstaller.sh -y -f") + if WOShellExec.cmd_exec(self, 'mysqladmin ping'): + WOMysql.execute( + self, "DELETE FROM mysql.user WHERE User = 'netdata';") if (apt_packages): Log.wait(self, "Purging APT Packages ") From 671cfbb7396c639613f2607a84894a678edcc389 Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sat, 7 Dec 2019 04:26:18 +0100 Subject: [PATCH 22/23] Bump version de v3.11.2 --- CHANGELOG.md | 8 ++++++++ install | 2 +- setup.py | 2 +- wo/core/variables.py | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 914b470..abfdaca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### v3.9.x - [Unreleased] +### v3.11.2 - 2019-12-07 + +#### Changed + +- Proxy virtualhost now include proxy_params with X-Forwarded-Proto header +- Acme.sh upgrade + #### Fixed - Issue with Nginx variables_hash_bucket_size & variables_hash_max_size +- Netdata MySQL user error when purging/reinstalling Netdata stack ### v3.11.1 - 2019-12-04 diff --git a/install b/install index cff0cd2..b6f2d7e 100755 --- a/install +++ b/install @@ -9,7 +9,7 @@ # ------------------------------------------------------------------------- # wget -qO wo wops.cc && sudo bash wo # ------------------------------------------------------------------------- -# Version 3.11.1 - 2019-12-04 +# Version 3.11.2 - 2019-12-07 # ------------------------------------------------------------------------- # CONTENTS diff --git a/setup.py b/setup.py index 602f4aa..c0800ad 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ if os.geteuid() == 0: os.makedirs('/var/lib/wo/tmp/') setup(name='wordops', - version='3.11.1', + version='3.11.2', description='An essential toolset that eases server administration', long_description=LONG, long_description_content_type='text/markdown', diff --git a/wo/core/variables.py b/wo/core/variables.py index afc8dad..e943562 100644 --- a/wo/core/variables.py +++ b/wo/core/variables.py @@ -14,7 +14,7 @@ class WOVar(): """Intialization of core variables""" # WordOps version - wo_version = "3.11.1" + wo_version = "3.11.2" # WordOps packages versions wo_wp_cli = "2.4.0" wo_adminer = "4.7.5" From a9fc1ab9d85b6f3796de2ad5c3dd75c565dd8dcd Mon Sep 17 00:00:00 2001 From: VirtuBox Date: Sat, 7 Dec 2019 04:27:31 +0100 Subject: [PATCH 23/23] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index abfdaca..689d2d2 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/), - Issue with Nginx variables_hash_bucket_size & variables_hash_max_size - Netdata MySQL user error when purging/reinstalling Netdata stack +- Fix `wo site cd` ### v3.11.1 - 2019-12-04