Rollback
This commit is contained in:
@@ -8,6 +8,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|||||||
|
|
||||||
### v3.9.x - [Unreleased]
|
### v3.9.x - [Unreleased]
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- Rate limiter on wp-cron.php and xmlrpc.php
|
||||||
|
- mime.types template to handle missing extension ttf
|
||||||
|
- try_files directive for favicon
|
||||||
|
|
||||||
### v3.9.8.8 - 2019-09-02
|
### v3.9.8.8 - 2019-09-02
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
|
|||||||
3
install
3
install
@@ -217,7 +217,7 @@ wo_install_dep() {
|
|||||||
apt-get -option=Dpkg::options::=--force-confmiss --option=Dpkg::options::=--force-confold --assume-yes install \
|
apt-get -option=Dpkg::options::=--force-confmiss --option=Dpkg::options::=--force-confold --assume-yes install \
|
||||||
build-essential curl gzip python3 python3-apt python3-setuptools python3-requests python3-dev sqlite3 git tar software-properties-common pigz \
|
build-essential curl gzip python3 python3-apt python3-setuptools python3-requests python3-dev sqlite3 git tar software-properties-common pigz \
|
||||||
gnupg2 cron ccze rsync tree haveged ufw unattended-upgrades tzdata ntp > /dev/null 2>&1
|
gnupg2 cron ccze rsync tree haveged ufw unattended-upgrades tzdata ntp > /dev/null 2>&1
|
||||||
add-apt-repository ppa:wordops/nginx-wo -yu
|
add-apt-repository ppa:wordops/nginx-wo -yn
|
||||||
else
|
else
|
||||||
# install dependencies
|
# install dependencies
|
||||||
apt-get -option=Dpkg::options::=--force-confmiss --option=Dpkg::options::=--force-confold --assume-yes install \
|
apt-get -option=Dpkg::options::=--force-confmiss --option=Dpkg::options::=--force-confold --assume-yes install \
|
||||||
@@ -813,6 +813,7 @@ if [ "$wo_purge" = "y" ]; then
|
|||||||
wo_lib_echo "Uninstalling WordOps" | tee -ai $wo_install_log
|
wo_lib_echo "Uninstalling WordOps" | tee -ai $wo_install_log
|
||||||
wo_uninstall | tee -ai $wo_install_log
|
wo_uninstall | tee -ai $wo_install_log
|
||||||
wo_lib_echo "The WordOps backup files can be found in $WO_BACKUP_FILE"
|
wo_lib_echo "The WordOps backup files can be found in $WO_BACKUP_FILE"
|
||||||
|
exit 0
|
||||||
else
|
else
|
||||||
# 1 - WO already installed
|
# 1 - WO already installed
|
||||||
if [ -x /usr/local/bin/wo ]; then
|
if [ -x /usr/local/bin/wo ]; then
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ class WOCleanController(CementBaseController):
|
|||||||
@expose(hide=True)
|
@expose(hide=True)
|
||||||
def default(self):
|
def default(self):
|
||||||
pargs = self.app.pargs
|
pargs = self.app.pargs
|
||||||
if (not (pargs.all or pargs.fastcgi or
|
if (not (pargs.all or pargs.fastcgi
|
||||||
pargs.memcached or pargs.opcache or
|
or pargs.opcache or
|
||||||
pargs.redis)):
|
pargs.redis)):
|
||||||
self.clean_fastcgi()
|
self.clean_fastcgi()
|
||||||
if pargs.all:
|
if pargs.all:
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ class WOSiteCreateController(CementBaseController):
|
|||||||
pargs.site_name = pargs.site_name.strip()
|
pargs.site_name = pargs.site_name.strip()
|
||||||
(wo_domain, wo_www_domain) = ValidateDomain(pargs.site_name)
|
(wo_domain, wo_www_domain) = ValidateDomain(pargs.site_name)
|
||||||
if not wo_domain.strip():
|
if not wo_domain.strip():
|
||||||
Log.error("Invalid domain name, "
|
Log.error(self, "Invalid domain name, "
|
||||||
"Provide valid domain name")
|
"Provide valid domain name")
|
||||||
|
|
||||||
wo_site_webroot = WOVariables.wo_webroot + wo_domain
|
wo_site_webroot = WOVariables.wo_webroot + wo_domain
|
||||||
|
|||||||
@@ -81,10 +81,10 @@ def setupdomain(self, data):
|
|||||||
out=wo_site_nginx_conf)
|
out=wo_site_nginx_conf)
|
||||||
wo_site_nginx_conf.close()
|
wo_site_nginx_conf.close()
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
Log.debug(self, "{0}".format(e))
|
Log.debug(self, str(e))
|
||||||
raise SiteError("create nginx configuration failed for site")
|
raise SiteError("create nginx configuration failed for site")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Log.debug(self, "{0}".format(e))
|
Log.debug(self, str(e))
|
||||||
raise SiteError("create nginx configuration failed for site")
|
raise SiteError("create nginx configuration failed for site")
|
||||||
finally:
|
finally:
|
||||||
# Check nginx -t and return status over it
|
# Check nginx -t and return status over it
|
||||||
@@ -126,7 +126,7 @@ def setupdomain(self, data):
|
|||||||
'{0}/logs/error.log'
|
'{0}/logs/error.log'
|
||||||
.format(wo_site_webroot)])
|
.format(wo_site_webroot)])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Log.debug(self, "{0}".format(e))
|
Log.debug(self, str(e))
|
||||||
raise SiteError("setup webroot failed for site")
|
raise SiteError("setup webroot failed for site")
|
||||||
finally:
|
finally:
|
||||||
# TODO Check if directories are setup
|
# TODO Check if directories are setup
|
||||||
@@ -267,7 +267,7 @@ def setupwordpress(self, data, vhostonly=False):
|
|||||||
raise SiteError("download WordPress core failed")
|
raise SiteError("download WordPress core failed")
|
||||||
except CommandExecutionError:
|
except CommandExecutionError:
|
||||||
Log.info(self, "[" + Log.ENDC + Log.FAIL + "Fail" + Log.OKBLUE + "]")
|
Log.info(self, "[" + Log.ENDC + Log.FAIL + "Fail" + Log.OKBLUE + "]")
|
||||||
raise SiteError(self, "download WordPress core failed")
|
raise SiteError("download WordPress core failed")
|
||||||
|
|
||||||
Log.info(self, "[" + Log.ENDC + "Done" + Log.OKBLUE + "]")
|
Log.info(self, "[" + Log.ENDC + "Done" + Log.OKBLUE + "]")
|
||||||
|
|
||||||
@@ -730,6 +730,7 @@ def setupwp_plugin(self, plugin_name, plugin_option, plugin_data, data):
|
|||||||
def setwebrootpermissions(self, webroot):
|
def setwebrootpermissions(self, webroot):
|
||||||
Log.debug(self, "Setting up permissions")
|
Log.debug(self, "Setting up permissions")
|
||||||
try:
|
try:
|
||||||
|
WOFileUtils.findBrokenSymlink(self, '/var/www/')
|
||||||
WOFileUtils.chown(self, webroot, WOVariables.wo_php_user,
|
WOFileUtils.chown(self, webroot, WOVariables.wo_php_user,
|
||||||
WOVariables.wo_php_user, recursive=True)
|
WOVariables.wo_php_user, recursive=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -917,7 +918,7 @@ def updatewpuserpassword(self, wo_domain, wo_site_webroot):
|
|||||||
try:
|
try:
|
||||||
wo_wp_user = input("Provide WordPress user name [admin]: ")
|
wo_wp_user = input("Provide WordPress user name [admin]: ")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Log.debug(self, "{0}".format(e))
|
Log.debug(self, str(e))
|
||||||
Log.error(self, "\nCould not update password")
|
Log.error(self, "\nCould not update password")
|
||||||
|
|
||||||
if wo_wp_user == "?":
|
if wo_wp_user == "?":
|
||||||
@@ -951,7 +952,7 @@ def updatewpuserpassword(self, wo_domain, wo_site_webroot):
|
|||||||
"{0} user: "
|
"{0} user: "
|
||||||
.format(wo_wp_user))
|
.format(wo_wp_user))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Log.debug(self, "{0}".format(e))
|
Log.debug(self, str(e))
|
||||||
raise SiteError("failed to read password input ")
|
raise SiteError("failed to read password input ")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -1345,15 +1346,15 @@ def doCleanupAction(self, domain='', webroot='', dbname='', dbuser='',
|
|||||||
if dbname:
|
if dbname:
|
||||||
if not dbuser:
|
if not dbuser:
|
||||||
raise SiteError("dbuser not provided")
|
raise SiteError("dbuser not provided")
|
||||||
if not dbhost:
|
if not dbhost:
|
||||||
raise SiteError("dbhost not provided")
|
raise SiteError("dbhost not provided")
|
||||||
deleteDB(self, dbname, dbuser, dbhost)
|
deleteDB(self, dbname, dbuser, dbhost)
|
||||||
|
|
||||||
# setup letsencrypt for domain + www.domain
|
# setup letsencrypt for domain + www.domain
|
||||||
|
|
||||||
|
|
||||||
def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
|
def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
|
||||||
wo_dns=False, wo_acme_dns='dns_cf'):
|
wo_dns=False, wo_acme_dns='dns_cf', backend=False):
|
||||||
|
|
||||||
if os.path.isfile("/etc/letsencrypt/"
|
if os.path.isfile("/etc/letsencrypt/"
|
||||||
"renewal/{0}_ecc/"
|
"renewal/{0}_ecc/"
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ def pre_pref(self, apt_packages):
|
|||||||
log=False)
|
log=False)
|
||||||
except CommandExecutionError as e:
|
except CommandExecutionError as e:
|
||||||
Log.debug(self, "{0}".format(e))
|
Log.debug(self, "{0}".format(e))
|
||||||
Log.error("Failed to initialize MySQL package")
|
Log.error(self, "Failed to initialize MySQL package")
|
||||||
# generate my.cnf root credentials
|
# generate my.cnf root credentials
|
||||||
mysql_config = """
|
mysql_config = """
|
||||||
[client]
|
[client]
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
ignorself = true
|
||||||
|
ignoreip = 127.0.0.1/8 ::1
|
||||||
|
bantime = 60m
|
||||||
|
|
||||||
[recidive]
|
[recidive]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
[nginx-http-auth]
|
[nginx-http-auth]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
|
[nginx-limit-req]
|
||||||
|
enabled = true
|
||||||
|
maxretry = 30
|
||||||
|
|
||||||
[nginx-botsearch]
|
[nginx-botsearch]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,26 @@
|
|||||||
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
|
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
|
||||||
# Basic locations files
|
# Basic locations files
|
||||||
location = /favicon.ico {
|
location = /favicon.ico {
|
||||||
access_log off;
|
try_files /wp-content/uploads/fbrfg/favicon.ico $uri $uri/ /index.php?$args @empty_gif;
|
||||||
log_not_found off;
|
access_log off;
|
||||||
expires max;
|
log_not_found off;
|
||||||
|
expires max;
|
||||||
|
}
|
||||||
|
location @empty_gif {
|
||||||
|
empty_gif;
|
||||||
}
|
}
|
||||||
# Cache static files
|
# Cache static files
|
||||||
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|ttf|m4a|mp4|ttf|rss|atom|jpe?g|gif|cur|heic|png|tiff|ico|webm|mp3|aac|tgz|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf|webp|json|webmanifest)$ {
|
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|woff2|ttf|m4a|mp4|ttf|rss|atom|jpe?g|gif|cur|heic|png|tiff|ico|webm|mp3|aac|tgz|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf|webp|json|webmanifest)$ {
|
||||||
add_header "Access-Control-Allow-Origin" "*";
|
more_set_headers 'Access-Control-Allow-Origin : "*"';
|
||||||
|
more_set_headers "Cache-Control : public, no-transform";
|
||||||
access_log off;
|
access_log off;
|
||||||
log_not_found off;
|
log_not_found off;
|
||||||
expires max;
|
expires max;
|
||||||
}
|
}
|
||||||
# Cache css & js files
|
# Cache css & js files
|
||||||
location ~* \.(?:css(\.map)?|js(\.map)?)$ {
|
location ~* \.(?:css(\.map)?|js(\.map)?)$ {
|
||||||
add_header "Access-Control-Allow-Origin" "*";
|
more_set_headers 'Access-Control-Allow-Origin : "*"';
|
||||||
|
more_set_headers "Cache-Control : public, no-transform";
|
||||||
access_log off;
|
access_log off;
|
||||||
log_not_found off;
|
log_not_found off;
|
||||||
expires 30d;
|
expires 30d;
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ class LogWatcher(object):
|
|||||||
# assert (os.path.isdir(self.folder), "%s does not exists"
|
# assert (os.path.isdir(self.folder), "%s does not exists"
|
||||||
# % self.folder)
|
# % self.folder)
|
||||||
for file in self.filelist:
|
for file in self.filelist:
|
||||||
assert (os.path.isfile(file))
|
if not os.path.isfile(file):
|
||||||
assert callable(callback)
|
if not callable(callback):
|
||||||
self.update_files()
|
self.update_files()
|
||||||
# The first time we run the script we move all file markers at EOF.
|
# The first time we run the script we move all file markers at EOF.
|
||||||
# In case of files created afterwards we don't do this.
|
# In case of files created afterwards we don't do this.
|
||||||
for id, file in list(iter(self.files_map.items())):
|
for id, file in list(iter(self.files_map.items())):
|
||||||
|
|||||||
@@ -48,15 +48,15 @@ class WOShellExec():
|
|||||||
try:
|
try:
|
||||||
subprocess.call(['sensible-editor', filepath])
|
subprocess.call(['sensible-editor', filepath])
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
Log.debug(self, "{0}{1}".format(e.errno, e.strerror))
|
Log.debug(self, "{0}{1}".format(e.errno, e.strerror))
|
||||||
raise CommandExecutionError
|
raise CommandExecutionError
|
||||||
|
|
||||||
def cmd_exec_stdout(self, command, errormsg='', log=True):
|
def cmd_exec_stdout(self, command, errormsg='', log=True):
|
||||||
"""Run shell command from Python"""
|
"""Run shell command from Python"""
|
||||||
try:
|
try:
|
||||||
log and Log.debug(self, "Running command: {0}".format(command))
|
log and Log.debug(self, "Running command: command -v {0}".format(command))
|
||||||
|
check_command = 'command -v' + command
|
||||||
with subprocess.Popen([command], stdout=subprocess.PIPE,
|
with subprocess.Popen([check_command], stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE, shell=True) as proc:
|
stderr=subprocess.PIPE, shell=True) as proc:
|
||||||
(cmd_stdout_bytes, cmd_stderr_bytes) = proc.communicate()
|
(cmd_stdout_bytes, cmd_stderr_bytes) = proc.communicate()
|
||||||
(cmd_stdout, cmd_stderr) = (cmd_stdout_bytes.decode('utf-8',
|
(cmd_stdout, cmd_stderr) = (cmd_stdout_bytes.decode('utf-8',
|
||||||
@@ -73,8 +73,8 @@ class WOShellExec():
|
|||||||
.format(cmd_stdout, cmd_stderr))
|
.format(cmd_stdout, cmd_stderr))
|
||||||
return cmd_stdout
|
return cmd_stdout
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
Log.debug(self, str(e))
|
Log.debug(self, str(e))
|
||||||
raise CommandExecutionError
|
raise CommandExecutionError
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Log.debug(self, str(e))
|
Log.debug(self, str(e))
|
||||||
raise CommandExecutionError
|
raise CommandExecutionError
|
||||||
|
|||||||
Reference in New Issue
Block a user