Merge pull request #130 from WordOps/updating-configuration

Updating configuration
This commit is contained in:
VirtuBox
2019-08-30 21:29:51 +02:00
committed by GitHub
11 changed files with 404 additions and 242 deletions

View File

@@ -8,6 +8,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### v3.9.x - [Unreleased]
### v3.9.8.6 - 2019-08-30
#### Added
- Subdomains are automatically secured with an existant Wildcard LetsEncrypt SSL certificate.
(If a wildcard certificate exist, WordOps will use this certificate for subdomains instead of issuing new certificates)
- MySQL & Redis stack to `wo stack remove/purge`
#### Changed
- Date format in backup name : /backup/30Aug2019035932 -> /backup/30Aug2019-03-59-32
- Cleanup and update bash_completion
- cheat.sh is installed with WordOps install script, not as a stack because it wasn't downloaded at all by WordOps (unknown reason yet)
#### Fixed
- cache-enabler plugin not installed and configured with `wo site update site.tld --wpce`
- possible issue with domain variable in `--letsencrypt=wildcard`
- python3-mysqldb not available on Debian 8 (Jessie)
- Fix mysql variable skip-name-resolved
- Fix typo in redis tuning directives
### v3.9.8.5 - 2019-08-30
#### Changed

View File

@@ -35,7 +35,7 @@ _wo_complete()
"stack")
COMPREPLY=( $(compgen \
-W "upgrade install purge reload remove restart start status stop migrate" \
-W "upgrade install purge reload remove restart start status stop" \
-- $cur) )
;;
@@ -74,12 +74,12 @@ _wo_complete()
# HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE
"install" | "purge" | "remove" )
COMPREPLY=( $(compgen \
-W "--web --admin --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --all --redis --phpredisadmin --composer --netdata --fail2ban --dashboard --proftpd" \
-W "--recommended --web --admin --security --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --phpredisadmin --composer --netdata --fail2ban --dashboard --proftpd --clamav --mysqlclient --mysqltuner --extplorer --all" \
-- $cur) )
;;
"upgrade" )
COMPREPLY=( $(compgen \
-W "--web --nginx --php --php73 --mysql --all --netdata --composer --phpmyadmin --dashboard --no-prompt --wpcli" \
-W "--web --admin --utils --nginx --php --php73 --mysql --all --netdata --composer --phpmyadmin --dashboard --no-prompt --mysqtuner --wpcli" \
-- $cur) )
;;
"start" | "stop" | "reload" | "restart" | "status")
@@ -87,11 +87,6 @@ _wo_complete()
-W "--nginx --php --php73 --mysql --redis --fail2ban --netdata -proftpd" \
-- $cur) )
;;
"migrate")
COMPREPLY=( $(compgen \
-W "--mariadb" \
-- $cur) )
;;
"list")
COMPREPLY=( $(compgen \
-W "--enabled --disabled" \
@@ -159,13 +154,13 @@ _wo_complete()
"create")
COMPREPLY=( $(compgen \
-W "--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --proxy= --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard -le=wildcard --dns --dns=dns_cf --dns=dns_do" \
-W "--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --proxy= --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard -le=wildcard --dns --dns=dns_cf --dns=dns_do" \
-- $cur) )
;;
"update")
COMPREPLY=( $(compgen \
-W "--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=off --letsencrypt=clean -le=wildcard --dns --dns=dns_cf --dns=dns_do" \
-W "--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=off --letsencrypt --letsencrypt=off --letsencrypt=clean -le=wildcard -le=clean --dns --dns=dns_cf --dns=dns_do" \
-- $cur) )
;;
"delete")
@@ -230,9 +225,9 @@ _wo_complete()
"--wpsubdir" | "--wpsubdomain")
if [ ${COMP_WORDS[1]} != "debug" ]; then
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce --letsencrypt --letsencrypt=wildcard -le --php73 --dns --dns=dns_cf --dns=dns_do"
retlist="--wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce -le -le=wildcard --letsencrypt --letsencrypt=wildcard --php73 --dns --dns=dns_cf --dns=dns_do"
elif [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do"
retlist="--wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le -le=off -le=wildcard --letsencrypt --letsencrypt=wildcard --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do"
else
retlist=""
fi
@@ -248,7 +243,7 @@ _wo_complete()
"--wpredis --wprocket --wpce" | "--wpfc" | "--wpsc" | "--wpsubdir" | "--wpsubdomain" | "--user" | "--pass" | "--email" | "--wp")
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --php73 -le --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do"
retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --php73 -le -le=off -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do"
else
retlist=""
fi
@@ -261,7 +256,7 @@ _wo_complete()
"--wpredis --wprocket --wpce" | "--wpfc")
if [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do"
retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=off --letsencrypt --letsencrypt=off --letsencrypt=clean --dns --dns=dns_cf --dns=dns_do"
else
retlist=""
fi
@@ -274,7 +269,7 @@ _wo_complete()
"--web" | "--admin" | "--nginx" | "--php" | "--php73" | "--mysql" | "--wpcli" | "--phpmyadmin" | "--adminer" | "--utils" | "--fail2ban" | "--redis | --phpredisadmin | --netdata")
if [[ ${COMP_WORDS[2]} == "install" || ${COMP_WORDS[2]} == "purge" || ${COMP_WORDS[2]} == "remove" ]]; then
retlist="--web --admin --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --fail2ban --phpredisadmin --netdata"
retlist="--web --admin --security --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --fail2ban --phpredisadmin --netdata -f --force"
elif [[ ${COMP_WORDS[2]} == "start" || ${COMP_WORDS[2]} == "reload" || ${COMP_WORDS[2]} == "restart" || ${COMP_WORDS[2]} == "stop" ]]; then
retlist="--nginx --php --php73 --mysql --redis --netdata"
elif [[ ${COMP_WORDS[1]} == "debug" ]]; then
@@ -314,7 +309,7 @@ _wo_complete()
elif [ ${COMP_WORDS[2]} == "delete" ]; then
retlist="--db --files --force"
elif [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=off "
retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=off -le=wildcard --letsencrypt --letsencrypt=off "
else
retlist=""
fi
@@ -363,7 +358,7 @@ _wo_complete()
case "$mprev" in
"--user" | "--email" | "--pass")
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --letsencrypt --letsencrypt=wildcard -le --dns --dns=dns_cf --dns=dns_do"
retlist="--user --pass --email --html --php --php73 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_do"
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \

33
install
View File

@@ -80,6 +80,10 @@ while [ "$#" -gt 0 ]; do
-w | --wufw | --without-ufw)
ufw="n"
;;
-v | --version)
wo_version="$2"
shift
;;
*) # positional args
;;
esac
@@ -438,8 +442,13 @@ wo_install() {
{
rm -f /etc/bash_completion.d/wo_auto.rc
rm -rf /var/lib/wo/tmp/WordOps-*
curl -sL https://github.com/WordOps/WordOps/archive/${wo_branch}.tar.gz | tar -I pigz -xf - -C /var/lib/wo/tmp
cd /var/lib/wo/tmp/WordOps-${wo_branch} || exit 1
if [ -z "$wo_version" ]; then
curl -sL https://github.com/WordOps/WordOps/archive/${wo_branch}.tar.gz | tar -I pigz -xf - -C /var/lib/wo/tmp
cd "/var/lib/wo/tmp/WordOps-$wo_branch" || exit 1
else
curl -sL https://github.com/WordOps/WordOps/archive/v${wo_version}.tar.gz | tar -I pigz -xf - -C /var/lib/wo/tmp
cd "/var/lib/wo/tmp/WordOps-$wo_version" || exit 1
fi
} \
>> "$wo_install_log" 2>&1
@@ -716,12 +725,6 @@ wo_uninstall() {
rm -rf /usr/local/lib/python3.*/dist-packages/{pystache-*,cement-2.*,wo-*} /usr/local/bin/wo /etc/bash_completion.d/wo_auto.rc /var/lib/wo /etc/wo /usr/lib/wo/templates >> /var/log/wo/install.log 2>&1
}
wo_cheat_alias() {
if ! grep -q "cheat" "$HOME/.bashrc"; then
echo "alias cheat='/usr/local/bin/cht.sh'" >> "$HOME/.bashrc"
fi
}
wo_ufw_setup() {
# get custom ssh port
@@ -787,6 +790,14 @@ wo_ufw_setup() {
} \
>> $wo_install_log
wo_cheat_install() {
curl -sL https://cht.sh/:cht.sh > /usr/local/bin/cht.sh
curl -sL https://cheat.sh/:bash_completion > /etc/bash_completion.d/cht.sh
if ! grep -q "cheat" $HOME/.bashrc; then
echo "alias cheat='/usr/local/bin/cht.sh'" >> "$HOME/.bashrc"
fi
}
###
# 4 - WO MAIN SETUP
###
@@ -840,7 +851,7 @@ else
if [ -d /etc/systemd/system/mariadb.service.d ]; then
wo_mariadb_tweak | tee -ai $wo_install_log
fi
wo_cheat_alias | tee -ai $wo_install_log
wo_cheat_install | tee -ai $wo_install_log
wo_domain_suffix | tee -ai $wo_install_log
wo_lib_echo "Running post-install steps " | tee -ai $wo_install_log
wo_update_wp_cli | tee -ai $wo_install_log
@@ -893,7 +904,7 @@ else
wo_lib_echo "Running post-install steps " | tee -ai $wo_install_log
wo_git_init | tee -ai $wo_install_log
wo_update_wp_cli | tee -ai $wo_install_log
wo_cheat_alias | tee -ai $wo_install_log
wo_cheat_install | tee -ai $wo_install_log
wo_lib_echo "Cleaning-up EE previous install" | tee -ai $wo_install_log
wo_clean_ee | tee -ai $wo_install_log
else
@@ -928,7 +939,7 @@ else
wo_install_acme_sh | tee -ai $wo_install_log
wo_lib_echo "Running post-install steps " | tee -ai $wo_install_log
secure_wo_db | tee -ai $wo_install_log
wo_cheat_alias | tee -ai $wo_install_log
wo_cheat_install | tee -ai $wo_install_log
wo_domain_suffix | tee -ai $wo_install_log
wo_git_init | tee -ai $wo_install_log
wo_update_wp_cli | tee -ai $wo_install_log

View File

@@ -57,7 +57,7 @@ if not os.path.isfile('/root/.gitconfig'):
shutil.copy2(os.path.expanduser("~")+'/.gitconfig', '/root/.gitconfig')
setup(name='wo',
version='3.9.8.5',
version='3.9.8.6',
description=long_description,
long_description=long_description,
classifiers=[],

View File

@@ -137,7 +137,7 @@ class WOSiteController(CementBaseController):
Log.error(self, 'could not input site name')
pargs.site_name = pargs.site_name.strip()
(wo_domain, wo_www_domain) = ValidateDomain(pargs.site_name)
wo_domain_type, wo_root_domain = GetDomainlevel(wo_domain)
(wo_domain_type, wo_root_domain) = GetDomainlevel(wo_domain)
wo_db_name = ''
wo_db_user = ''
wo_db_pass = ''
@@ -162,7 +162,12 @@ class WOSiteController(CementBaseController):
ssl = ("enabled" if siteinfo.is_ssl else "disabled")
if (ssl == "enabled"):
sslprovider = "Lets Encrypt"
sslexpiry = str(SSL.getExpirationDate(self, wo_domain))
if os.path.islink("{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot)):
sslexpiry = str(
SSL.getExpirationDate(self, wo_root_domain))
else:
sslexpiry = str(SSL.getExpirationDate(self, wo_domain))
else:
sslprovider = ''
sslexpiry = ''
@@ -424,7 +429,7 @@ class WOSiteCreateController(CementBaseController):
pargs.site_name = pargs.site_name.strip()
(wo_domain, wo_www_domain) = ValidateDomain(pargs.site_name)
wo_domain_type, wo_root_domain = GetDomainlevel(wo_domain)
(wo_domain_type, wo_root_domain) = GetDomainlevel(wo_domain)
if not wo_domain.strip():
Log.error("Invalid domain name, "
"Provide valid domain name")
@@ -626,84 +631,56 @@ class WOSiteCreateController(CementBaseController):
"and please try again")
# Setup WordPress if Wordpress site
if (data['wp'] and (not pargs.vhostonly)):
try:
wo_wp_creds = setupwordpress(self, data)
# Add database information for site into database
updateSiteInfo(self, wo_domain,
db_name=data['wo_db_name'],
db_user=data['wo_db_user'],
db_password=data['wo_db_pass'],
db_host=data['wo_db_host'])
except SiteError as e:
# call cleanup actions on failure
Log.debug(self, str(e))
Log.info(self, Log.FAIL +
"There was a serious error encountered...")
Log.info(self, Log.FAIL + "Cleaning up afterwards...")
doCleanupAction(self, domain=wo_domain,
webroot=data['webroot'],
dbname=data['wo_db_name'],
dbuser=data['wo_db_user'],
dbhost=data['wo_mysql_grant_host'])
deleteSiteInfo(self, wo_domain)
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
if (data['wp'] and (pargs.vhostonly)):
try:
wo_wp_creds = setupwordpress(self, data)
# Add database information for site into database
updateSiteInfo(self, wo_domain, db_name=data['wo_db_name'],
db_user=data['wo_db_user'],
db_password=data['wo_db_pass'],
db_host=data['wo_db_host'])
except SiteError as e:
# call cleanup actions on failure
Log.debug(self, str(e))
Log.info(self, Log.FAIL +
"There was a serious error encountered...")
Log.info(self, Log.FAIL + "Cleaning up afterwards...")
doCleanupAction(self, domain=wo_domain,
webroot=data['webroot'],
dbname=data['wo_db_name'],
dbuser=data['wo_db_user'],
dbhost=data['wo_db_host'])
deleteSiteInfo(self, wo_domain)
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
try:
wodbconfig = open("{0}/wo-config.php"
.format(wo_site_webroot),
encoding='utf-8', mode='w')
wodbconfig.write("<?php \ndefine('DB_NAME', '{0}');"
"\ndefine('DB_USER', '{1}'); "
"\ndefine('DB_PASSWORD', '{2}');"
"\ndefine('DB_HOST', '{3}');\n?>"
.format(data['wo_db_name'],
data['wo_db_user'],
data['wo_db_pass'],
data['wo_db_host']))
wodbconfig.close()
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"wo-config.php")
Log.info(self, Log.FAIL +
"There was a serious error encountered...")
Log.info(self, Log.FAIL + "Cleaning up afterwards...")
doCleanupAction(self, domain=wo_domain,
webroot=data['webroot'],
dbname=data['wo_db_name'],
dbuser=data['wo_db_user'],
dbhost=data['wo_db_host'])
deleteSiteInfo(self, wo_domain)
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
if data['wp']:
if not pargs.vhostonly:
try:
wo_wp_creds = setupwordpress(self, data)
# Add database information for site into database
updateSiteInfo(self, wo_domain,
db_name=data['wo_db_name'],
db_user=data['wo_db_user'],
db_password=data['wo_db_pass'],
db_host=data['wo_db_host'])
except SiteError as e:
# call cleanup actions on failure
Log.debug(self, str(e))
Log.info(self, Log.FAIL +
"There was a serious error encountered...")
Log.info(self, Log.FAIL + "Cleaning up afterwards...")
doCleanupAction(self, domain=wo_domain,
webroot=data['webroot'],
dbname=data['wo_db_name'],
dbuser=data['wo_db_user'],
dbhost=data['wo_mysql_grant_host'])
deleteSiteInfo(self, wo_domain)
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
else:
try:
wo_wp_creds = setupwordpress(
self, data, vhostonly=True)
# Add database information for site into database
updateSiteInfo(self, wo_domain,
db_name=data['wo_db_name'],
db_user=data['wo_db_user'],
db_password=data['wo_db_pass'],
db_host=data['wo_db_host'])
except SiteError as e:
# call cleanup actions on failure
Log.debug(self, str(e))
Log.info(self, Log.FAIL +
"There was a serious error encountered...")
Log.info(self, Log.FAIL + "Cleaning up afterwards...")
doCleanupAction(self, domain=wo_domain,
webroot=data['webroot'],
dbname=data['wo_db_name'],
dbuser=data['wo_db_user'],
dbhost=data['wo_mysql_grant_host'])
deleteSiteInfo(self, wo_domain)
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
# Service Nginx Reload call cleanup if failed to reload nginx
if not WOService.reload_service(self, 'nginx'):
@@ -785,12 +762,33 @@ class WOSiteCreateController(CementBaseController):
else:
wo_wildcard = False
wo_subdomain = False
Log.debug(self, "Domain type = {0}"
.format(wo_domain_type))
if ((wo_domain_type == 'subdomain') and
(not pargs.letsencrypt == 'wildcard')):
wo_subdomain = True
setupLetsEncrypt(self, wo_domain, wo_subdomain, wo_wildcard,
wo_dns, wo_acme_dns)
# check if a wildcard cert for the root domain exist
Log.debug(self, "checkWildcardExist on *.{0}"
.format(wo_root_domain))
isWildcard = checkWildcardExist(self, wo_root_domain)
Log.debug(self, "isWildcard = {0}".format(isWildcard))
if isWildcard:
Log.info(self, "Using existing Wildcard SSL "
"certificate from {0} to secure {1}"
.format(wo_root_domain, wo_domain))
Log.debug(self, "symlink wildcard "
"cert between {0} & {1}"
.format(wo_domain, wo_root_domain))
# copy the cert from the root domain
copyWildcardCert(self, wo_domain, wo_root_domain)
else:
Log.debug(self, "Setup Cert with acme.sh for {0}"
.format(wo_domain))
setupLetsEncrypt(self, wo_domain, wo_subdomain,
wo_wildcard, wo_dns, wo_acme_dns)
else:
setupLetsEncrypt(self, wo_domain, wo_subdomain,
wo_wildcard, wo_dns, wo_acme_dns)
httpsRedirect(self, wo_domain, True, wo_wildcard)
if pargs.hsts:
@@ -855,7 +853,8 @@ class WOSiteUpdateController(CementBaseController):
(['--wprocket'],
dict(help="update to WP-Rocket cache", action='store_true')),
(['--wpce'],
dict(help="update to Cache-Enabler cache", action='store_true')),
dict(help="update to Cache-Enabler cache",
action='store_true')),
(['--wpredis'],
dict(help="update to redis cache", action='store_true')),
(['-le', '--letsencrypt'],
@@ -1240,12 +1239,6 @@ class WOSiteUpdateController(CementBaseController):
return 0
if pargs.letsencrypt:
if ((wo_domain_type == 'subdomain') and
(not pargs.letsencrypt == 'wildcard') and
(not pargs.letsencrypt == 'off') and
(not pargs.letsencrypt == 'clean') and
(not pargs.letsencrypt == 'purge')):
pargs.letsencrypt == 'subdomain'
if pargs.letsencrypt == 'on':
data['letsencrypt'] = True
letsencrypt = True
@@ -1281,14 +1274,15 @@ class WOSiteUpdateController(CementBaseController):
wo_subdomain = False
wo_wildcard = False
if letsencrypt is check_ssl:
if letsencrypt is False:
Log.error(self, "SSl is not configured for given "
"site")
elif letsencrypt is True:
Log.error(self, "SSl is already configured for given "
"site")
pargs.letsencrypt = False
if not wo_subdomain:
if letsencrypt is check_ssl:
if letsencrypt is False:
Log.error(self, "SSl is not configured for given "
"site")
elif letsencrypt is True:
Log.error(self, "SSl is already configured for given "
"site")
pargs.letsencrypt = False
if data and (not pargs.php73):
if old_php73 is True:
@@ -1382,9 +1376,30 @@ class WOSiteUpdateController(CementBaseController):
wo_acme_dns = ''
wo_dns = False
if not os.path.isfile("{0}/conf/nginx/ssl.conf.disabled"):
setupLetsEncrypt(self, wo_domain, wo_subdomain,
wo_wildcard,
wo_dns, wo_acme_dns)
if wo_subdomain:
# check if a wildcard cert for the root domain exist
Log.debug(self, "checkWildcardExist on *.{0}"
.format(wo_root_domain))
isWildcard = checkWildcardExist(self, wo_root_domain)
Log.debug(self, "isWildcard = {0}".format(isWildcard))
if isWildcard:
Log.info(self, "Using existing Wildcard SSL "
"certificate from {0} to secure {1}"
.format(wo_root_domain, wo_domain))
Log.debug(self, "symlink wildcard "
"cert between {0} & {1}"
.format(wo_domain, wo_root_domain))
# copy the cert from the root domain
copyWildcardCert(self, wo_domain, wo_root_domain)
else:
Log.debug(self, "Setup Cert with acme.sh for {0}"
.format(wo_domain))
setupLetsEncrypt(self, wo_domain, wo_subdomain,
wo_wildcard, wo_dns, wo_acme_dns)
else:
setupLetsEncrypt(self, wo_domain, wo_subdomain,
wo_wildcard, wo_dns, wo_acme_dns)
httpsRedirect(self, wo_domain, True, wo_wildcard)
site_url_https(self, wo_domain)
else:
@@ -1405,22 +1420,36 @@ class WOSiteUpdateController(CementBaseController):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
Log.info(self, "Congratulations! Successfully "
"Configured SSl for Site "
"Configured SSL for Site "
" https://{0}".format(wo_domain))
if (SSL.getExpirationDays(self, wo_domain) > 0):
Log.info(self, "Your cert will expire within " +
str(SSL.getExpirationDays(self, wo_domain)) +
" days.")
if wo_subdomain:
if (SSL.getExpirationDays(self, wo_root_domain) > 0):
Log.info(self, "Your cert will expire within " +
str(SSL.getExpirationDays(self, wo_root_domain)) +
" days.")
else:
Log.warn(
self, "Your cert already EXPIRED ! "
".PLEASE renew soon . ")
else:
Log.warn(
self, "Your cert already EXPIRED ! "
".PLEASE renew soon . ")
if (SSL.getExpirationDays(self, wo_domain) > 0):
Log.info(self, "Your cert will expire within " +
str(SSL.getExpirationDays(self, wo_domain)) +
" days.")
else:
Log.warn(
self, "Your cert already EXPIRED ! "
".PLEASE renew soon . ")
elif data['letsencrypt'] is False:
if pargs.letsencrypt == "off":
if os.path.isfile("{0}/conf/nginx/ssl.conf"
if os.path.islink("{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot)):
WOFileUtils.remove_symlink(self,
"{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot))
elif os.path.isfile("{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot)):
Log.info(self, 'Setting Nginx configuration')
WOFileUtils.mvfile(self, "{0}/conf/nginx/ssl.conf"
.format(wo_site_webroot),
@@ -1434,6 +1463,10 @@ class WOSiteUpdateController(CementBaseController):
'{0}/conf/nginx/'
'hsts.conf.disabled'
.format(wo_site_webroot))
# find all broken symlinks
sympath = "/var/www"
WOFileUtils.findBrokenSymlink(self, sympath)
elif (pargs.letsencrypt == "clean" or
pargs.letsencrypt == "purge"):
removeAcmeConf(self, wo_domain)
@@ -1557,7 +1590,8 @@ class WOSiteUpdateController(CementBaseController):
"and please try again")
return 1
if ((oldcachetype in ['wpsc', 'basic', 'wpredis', 'wprocket', 'wpce'] and
if ((oldcachetype in ['wpsc', 'basic', 'wpredis', 'wprocket',
'wpce'] and
(data['wpfc'])) or (oldsitetype == 'wp' and
data['multisite'] and data['wpfc'])):
try:
@@ -1566,7 +1600,7 @@ class WOSiteUpdateController(CementBaseController):
"enable_purge": 1,
"enable_map": "0",
"enable_log": 0,
"enable_stamp": 0,
"enable_stamp": 1,
"purge_homepage_on_new": 1,
"purge_homepage_on_edit": 1,
"purge_homepage_on_del": 1,
@@ -1584,9 +1618,9 @@ class WOSiteUpdateController(CementBaseController):
"redis_port": "6379",
"redis_prefix": "nginx-cache:"}
plugin_data = json.dumps(plugin_data_object)
setupwp_plugin(
self, 'nginx-helper',
'rt_wp_nginx_helper_options', plugin_data, data)
setupwp_plugin(self, 'nginx-helper',
'rt_wp_nginx_helper_options',
plugin_data, data)
except SiteError as e:
Log.debug(self, str(e))
Log.info(self, Log.FAIL + "Update nginx-helper "
@@ -1596,7 +1630,8 @@ class WOSiteUpdateController(CementBaseController):
"and please try again")
return 1
elif ((oldcachetype in ['wpsc', 'basic', 'wpfc', 'wprocket', 'wpce'] and
elif ((oldcachetype in ['wpsc', 'basic', 'wpfc',
'wprocket', 'wpce'] and
(data['wpredis'])) or (oldsitetype == 'wp' and
data['multisite'] and
data['wpredis'])):
@@ -1606,7 +1641,7 @@ class WOSiteUpdateController(CementBaseController):
"enable_purge": 1,
"enable_map": "0",
"enable_log": 0,
"enable_stamp": 0,
"enable_stamp": 1,
"purge_homepage_on_new": 1,
"purge_homepage_on_edit": 1,
"purge_homepage_on_del": 1,
@@ -1624,9 +1659,9 @@ class WOSiteUpdateController(CementBaseController):
"redis_port": "6379",
"redis_prefix": "nginx-cache:"}
plugin_data = json.dumps(plugin_data_object)
setupwp_plugin(
self, 'nginx-helper',
'rt_wp_nginx_helper_options', plugin_data, data)
setupwp_plugin(self, 'nginx-helper',
'rt_wp_nginx_helper_options',
plugin_data, data)
except SiteError as e:
Log.debug(self, str(e))
Log.info(self, Log.FAIL + "Update nginx-helper "
@@ -1635,37 +1670,9 @@ class WOSiteUpdateController(CementBaseController):
" `tail /var/log/wo/wordops.log` "
"and please try again")
return 1
elif ((oldcachetype in ['wpsc', 'basic', 'wpfc', 'wprocket', 'wpredis'] and
(data['wpce'])) or (oldsitetype == 'wp' and
data['multisite'] and
data['wpce'])):
try:
plugin_data_object = {"expires": 24,
"new_post": 1,
"new_comment": 0,
"webp": 0,
"clear_on_upgrade": 1,
"compress": 0,
"excl_ids": "",
"excl_regexp": "",
"excl_cookies": "",
"incl_attributes": "",
"minify_html": 1}
plugin_data = json.dumps(plugin_data_object)
setupwp_plugin(
self, 'cache-enabler',
'cache-enabler', plugin_data, data)
except SiteError as e:
Log.debug(self, str(e))
Log.info(self, Log.FAIL + "Update cache-enabler "
"settings failed. "
"Check the log for details:"
" `tail /var/log/wo/wordops.log` "
"and please try again")
return 1
else:
try:
# disable nginx-helper
plugin_data_object = {"log_level": "INFO",
"log_filesize": 5,
"enable_purge": 0,
@@ -1701,6 +1708,36 @@ class WOSiteUpdateController(CementBaseController):
"and please try again")
return 1
if ((oldcachetype in ['wpsc', 'basic', 'wpfc', 'wprocket', 'wpredis'] and
(data['wpce'])) or (oldsitetype == 'wp' and
data['multisite'] and
data['wpce'])):
try:
installwp_plugin(self, 'cache-enabler', data)
# setup cache-enabler
plugin_data_object = {"expires": 24,
"new_post": 1,
"new_comment": 0,
"webp": 0,
"clear_on_upgrade": 1,
"compress": 0,
"excl_ids": "",
"excl_regexp": "",
"excl_cookies": "",
"incl_attributes": "",
"minify_html": 1}
plugin_data = json.dumps(plugin_data_object)
setupwp_plugin(self, 'cache-enabler',
'cache-enabler', plugin_data, data)
except SiteError as e:
Log.debug(self, str(e))
Log.info(self, Log.FAIL + "Update cache-enabler "
"settings failed. "
"Check the log for details:"
" `tail /var/log/wo/wordops.log` "
"and please try again")
return 1
if oldcachetype == 'wpsc' and not data['wpsc']:
try:
uninstallwp_plugin(self, 'wp-super-cache', data)
@@ -1832,6 +1869,7 @@ class WOSiteDeleteController(CementBaseController):
pargs.site_name = (input('Enter site name : ')
.strip())
except IOError as e:
Log.debug(self, str(e))
Log.error(self, 'could not input site name')
pargs.site_name = pargs.site_name.strip()

View File

@@ -6,6 +6,7 @@ import json
import re
import string
import subprocess
import csv
from subprocess import CalledProcessError
from wo.cli.plugins.sitedb import getSiteInfo
@@ -229,7 +230,7 @@ def setupdatabase(self, data):
return(data)
def setupwordpress(self, data):
def setupwordpress(self, data, vhostonly=False):
wo_domain_name = data['site_name']
wo_site_webroot = data['webroot']
prompt_wpprefix = self.app.config.get('wordpress', 'prefix')
@@ -531,13 +532,13 @@ def setupwordpress(self, data):
"enable_purge": 1,
"enable_map": "0",
"enable_log": 0,
"enable_stamp": 0,
"enable_stamp": 1,
"purge_homepage_on_new": 1,
"purge_homepage_on_edit": 1,
"purge_homepage_on_del": 1,
"purge_archive_on_new": 1,
"purge_archive_on_edit": 0,
"purge_archive_on_del": 0,
"purge_archive_on_edit": 1,
"purge_archive_on_del": 1,
"purge_archive_on_new_comment": 0,
"purge_archive_on_deleted_comment": 0,
"purge_page_on_mod": 1,
@@ -557,13 +558,13 @@ def setupwordpress(self, data):
"enable_purge": 1,
"enable_map": "0",
"enable_log": 0,
"enable_stamp": 0,
"enable_stamp": 1,
"purge_homepage_on_new": 1,
"purge_homepage_on_edit": 1,
"purge_homepage_on_del": 1,
"purge_archive_on_new": 1,
"purge_archive_on_edit": 0,
"purge_archive_on_del": 0,
"purge_archive_on_edit": 1,
"purge_archive_on_del": 1,
"purge_archive_on_new_comment": 0,
"purge_archive_on_deleted_comment": 0,
"purge_page_on_mod": 1,
@@ -588,6 +589,7 @@ def setupwordpress(self, data):
"""Install Cache-Enabler"""
if data['wpce']:
installwp_plugin(self, 'cache-enabler', data)
plugin_data_object = {"expires": 24,
"new_post": 1,
"new_comment": 0,
@@ -603,6 +605,15 @@ def setupwordpress(self, data):
setupwp_plugin(self, 'cache-enabler', 'cache-enabler',
plugin_data, data)
if vhostonly:
try:
WOShellExec.cmd_exec(self, "/bin/bash -c \"{0} --allow-root "
.format(WOVariables.wo_wpcli_path) +
"db clean --yes\"")
WOFileUtils.rm(self, "{0}/htdocs/*".format(wo_site_webroot))
except CommandExecutionError:
raise SiteError("Cleaning WordPress install failed")
wp_creds = dict(wp_user=wo_wp_user, wp_pass=wo_wp_pass,
wp_email=wo_wp_email)
@@ -988,6 +999,16 @@ def display_cache_settings(self, data):
"\thttp://{0}/wp-admin/options-general.php?"
"page=nginx".format(data['site_name']))
if data['wpce']:
if data['multisite']:
Log.info(self, "Nginx-Helper configuration :"
"\thttp://{0}/wp-admin/network/settings.php?"
"page=cache-enabler".format(data['site_name']))
else:
Log.info(self, "Nginx-Helper configuration :"
"\thttp://{0}/wp-admin/options-general.php?"
"page=cache-enabler".format(data['site_name']))
def logwatch(self, logfiles):
import zlib
@@ -1214,6 +1235,10 @@ def removeNginxConf(self, domain):
def removeAcmeConf(self, domain):
sslconf = ("/var/www/{0}/conf/nginx/ssl.conf"
.format(domain))
sslforce = ("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(domain))
if os.path.isdir('/etc/letsencrypt/renewal/{0}_ecc'
.format(domain)):
Log.info(self, "Removing Acme configuration")
@@ -1229,18 +1254,27 @@ def removeAcmeConf(self, domain):
Log.debug(self, "{0}".format(e))
Log.error(self, "Cert removal failed")
WOFileUtils.rm(self, '/etc/letsencrypt/renewal/{0}_ecc'
.format(domain))
WOFileUtils.rm(self, '/etc/letsencrypt/live/{0}'
.format(domain))
WOFileUtils.rm(self, '/var/www/{0}/conf/nginx/ssl.conf'
.format(domain))
WOFileUtils.rm(self, '/var/www/{0}/conf/nginx/ssl.conf.disabled'
.format(domain))
WOFileUtils.rm(self, '/etc/nginx/conf.d/force-ssl-{0}.conf'
.format(domain))
WOFileUtils.rm(self, '/etc/nginx/conf.d/force-ssl-{0}.conf.disabled'
WOFileUtils.rm(self, '{0}/{1}_ecc'
.format(WOVariables.wo_ssl_archive, domain))
WOFileUtils.rm(self, '{0}/{1}'
.format(WOVariables.wo_ssl_live, domain))
WOFileUtils.rm(self, '{0}'.format(sslconf))
WOFileUtils.rm(self, '{0}.disabled'.format(sslconf))
WOFileUtils.rm(self, '{0}'.format(sslforce))
WOFileUtils.rm(self, '{0}.disabled'
.format(sslforce))
WOFileUtils.rm(self, '/etc/letsencrypt/shared/{0}.conf'
.format(domain))
# find all broken symlinks
sympath = "/var/www"
WOFileUtils.findBrokenSymlink(self, sympath)
else:
if os.path.islink("{0}".format(sslconf)):
WOFileUtils.remove_symlink(self, "{0}".format(sslconf))
WOFileUtils.rm(self, '{0}'.format(sslforce))
if WOFileUtils.grepcheck(self, '/var/www/22222/conf/nginx/ssl.conf',
'{0}'.format(domain)):
Log.info(self, "Setting back default certificate for WordOps backend")
@@ -1339,7 +1373,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
self, "Validation : DNS mode with {0}".format(wo_acme_dns))
else:
acme_mode = "-w /var/www/html"
validation_mode = "Webroot challenge"
validation_mode = "Subdomain Webroot challenge"
Log.debug(self, "Validation : Webroot mode")
if subdomain:
Log.info(self, "Issuing subdomain SSL cert with acme.sh")
@@ -1356,7 +1390,7 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
Log.info(self, "Validation mode : {0}".format(validation_mode))
ssl = WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) +
"--issue "
"-d {0} -d *.{0} --dns {1} "
"-d {0} -d '*.{0}' --dns {1} "
"-k {2} -f"
.format(wo_domain_name,
wo_acme_dns,
@@ -1435,6 +1469,61 @@ def setupLetsEncrypt(self, wo_domain_name, subdomain=False, wildcard=False,
"you are running Let\'s Encrypt Client "
"\n to allow it to verify the site automatically.")
# check if a wildcard exist to secure a new subdomain
def checkWildcardExist(self, wo_domain_name):
wo_acme_exec = ("/etc/letsencrypt/acme.sh --config-home "
"'/etc/letsencrypt/config'")
# export certificates list from acme.sh
WOShellExec.cmd_exec(self, "{0} ".format(wo_acme_exec) +
"--list --listraw > /var/lib/wo/cert.csv")
# define new csv dialect
csv.register_dialect('acmeconf', delimiter='|')
# open file
certfile = open('/var/lib/wo/cert.csv', 'rt')
reader = csv.reader(certfile, 'acmeconf')
wo_wildcard_domain = ("*.{0}".format(wo_domain_name))
for row in reader:
if wo_wildcard_domain in row[2]:
isWildcard = True
break
else:
isWildcard = False
certfile.close()
return isWildcard
# copy wildcard certificate to a subdomain
def copyWildcardCert(self, wo_domain_name, wo_root_domain):
if os.path.isfile("/var/www/{0}/conf/nginx/ssl.conf"
.format(wo_root_domain)):
try:
if not os.path.isdir("/etc/letsencrypt/shared"):
WOFileUtils.mkdir(self, "/etc/letsencrypt/shared")
if not os.path.isfile("/etc/letsencrypt/shared/{0}.conf"
.format(wo_root_domain)):
WOFileUtils.copyfile(self, "/var/www/{0}/conf/nginx/ssl.conf"
.format(wo_root_domain),
"/etc/letsencrypt/shared/{0}.conf"
.format(wo_root_domain))
WOFileUtils.create_symlink(self, ["/etc/letsencrypt/shared/"
"{0}.conf"
.format(wo_root_domain),
'/var/www/{0}/conf/nginx/'
'ssl.conf'
.format(wo_domain_name)])
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while "
"creating symlink for ssl cert")
# letsencrypt cert renewal
@@ -1514,9 +1603,6 @@ def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False):
else:
if wildcard:
try:
Log.info(
self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
@@ -1536,10 +1622,6 @@ def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False):
else:
try:
Log.info(
self, "Adding /etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')

View File

@@ -45,7 +45,6 @@ class WOStackController(CementBaseController):
label = 'stack'
stacked_on = 'base'
stacked_type = 'nested'
exit_on_close = True
description = 'Stack command manages stack operations'
arguments = [
(['--all'],
@@ -91,8 +90,6 @@ class WOStackController(CementBaseController):
dict(help='Install ClamAV stack', action='store_true')),
(['--utils'],
dict(help='Install Utils stack', action='store_true')),
(['--cheat'],
dict(help='Install cheat.sh stack', action='store_true')),
(['--redis'],
dict(help='Install Redis', action='store_true')),
(['--phpredisadmin'],
@@ -128,8 +125,7 @@ class WOStackController(CementBaseController):
(not pargs.mysqlclient) and (not pargs.mysqltuner) and
(not pargs.adminer) and (not pargs.utils) and
(not pargs.redis) and (not pargs.proftpd) and
(not pargs.extplorer) and
(not pargs.cheat) and (not pargs.clamav) and
(not pargs.extplorer) and (not pargs.clamav) and
(not pargs.phpredisadmin) and
(not pargs.php73)):
pargs.web = True
@@ -159,7 +155,6 @@ class WOStackController(CementBaseController):
pargs.dashboard = True
pargs.phpredisadmin = True
pargs.extplorer = True
pargs.cheat = True
if pargs.security:
pargs.fail2ban = True
@@ -418,17 +413,6 @@ class WOStackController(CementBaseController):
Log.debug(self, "eXtplorer is already installed")
Log.info(self, "eXtplorer is already installed")
# cheat.sh
if pargs.cheat:
if not os.path.isfile('/usr/local/bin/cht.sh'):
Log.debug(self, "Setting packages variable for cht.sh")
packages = packages + [["https://cht.sh/:cht.sh",
"/usr/local/bin/cht.sh",
"cheat.sh"]]
else:
Log.debug(self, "cheat.sh is already installed")
Log.info(self, "cheat.sh is already installed")
# UTILS
if pargs.utils:
Log.debug(self, "Setting packages variable for utils")
@@ -517,8 +501,7 @@ class WOStackController(CementBaseController):
(not pargs.mysqlclient) and (not pargs.mysqltuner) and
(not pargs.adminer) and (not pargs.utils) and
(not pargs.redis) and (not pargs.proftpd) and
(not pargs.extplorer) and
(not pargs.cheat) and (not pargs.clamav) and
(not pargs.extplorer) and (not pargs.clamav) and
(not pargs.phpredisadmin) and
(not pargs.php73)):
pargs.web = True
@@ -724,8 +707,7 @@ class WOStackController(CementBaseController):
(not pargs.mysqlclient) and (not pargs.mysqltuner) and
(not pargs.adminer) and (not pargs.utils) and
(not pargs.redis) and (not pargs.proftpd) and
(not pargs.extplorer) and
(not pargs.cheat) and (not pargs.clamav) and
(not pargs.extplorer) and (not pargs.clamav) and
(not pargs.phpredisadmin) and
(not pargs.php73)):
pargs.web = True
@@ -753,7 +735,6 @@ class WOStackController(CementBaseController):
pargs.composer = True
pargs.netdata = True
pargs.mysqltuner = True
pargs.cheat = True
if pargs.security:
pargs.fail2ban = True

View File

@@ -907,7 +907,8 @@ def post_pref(self, apt_packages, packages, upgrade=False):
"wait_timeout "
"= 600",
"wait_timeout "
"= 120")
"= 120\n"
"skip-name-resolve = 1\n")
# disabling mariadb binlog
WOFileUtils.searchreplace(self,
"/etc/mysql/my.cnf",
@@ -957,8 +958,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
"table_open_cache = 16000")
WOFileUtils.searchreplace(self, "/etc/mysql/my.cnf",
"max_allowed_packet = 16M",
"max_allowed_packet = 64M\n"
"skip-name-resolve=1\n")
"max_allowed_packet = 64M\n")
WOService.stop_service(self, 'mysql')
WOFileUtils.mvfile(self, '/var/lib/mysql/ib_logfile0',
@@ -1114,7 +1114,8 @@ def post_pref(self, apt_packages, packages, upgrade=False):
Log.debug(self, "Enabling redis systemd service")
WOShellExec.cmd_exec(self, "systemctl enable redis-server")
if (os.path.isfile("/etc/redis/redis.conf") and
not WOFileUtils.grep(self, "/etc/mysql/my.cnf", "WordOps")):
not WOFileUtils.grep(self, "/etc/redis/redis.conf",
"WordOps")):
Log.info(self, "Tuning Redis configuration")
with open("/etc/redis/redis.conf",
"a") as redis_file:
@@ -1481,11 +1482,6 @@ def post_pref(self, apt_packages, packages, upgrade=False):
for x in packages):
WOFileUtils.chmod(self, "/usr/bin/pt-query-advisor", 0o775)
# cht.sh
if any('/usr/local/bin/cht.sh' == x[1]
for x in packages):
WOFileUtils.chmod(self, "/usr/local/bin/cht.sh", 0o775)
# phpredisadmin
if any('/var/lib/wo/tmp/pra.tar.gz' == x[1]
for x in packages):

View File

@@ -40,11 +40,11 @@ def GetDomainlevel(domain):
for domain_suffix in Suffix_file:
if (str(domain_suffix).strip()) == ('.'.join(domain_name[1:])):
domain_type = 'domain'
root_domain = domain_name[0:]
root_domain = ('.'.join(domain_name[0:]))
break
elif (str(domain_suffix).strip()) == ('.'.join(domain_name[2:])):
domain_type = 'subdomain'
root_domain = domain_name[1:]
root_domain = ('.'.join(domain_name[1:]))
break
else:
domain_type = 'other'

View File

@@ -279,3 +279,33 @@ class WOFileUtils():
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to remove file : {0} "
.format(path))
def findBrokenSymlink(self, sympath):
"""
Find symlinks
"""
links = []
broken = []
for root, dirs, files in os.walk(sympath):
if root.startswith('./.git'):
# Ignore the .git directory.
continue
for filename in files:
path = os.path.join(root, filename)
if os.path.islink(path):
target_path = os.readlink(path)
# Resolve relative symlinks
if not os.path.isabs(target_path):
target_path = os.path.join(os.path.dirname(path),
target_path)
if not os.path.exists(target_path):
links.append(path)
broken.append(path)
os.remove(path)
else:
links.append(path)
else:
# If it's not a symlink we're not interested.
continue
return True

View File

@@ -10,7 +10,7 @@ class WOVariables():
"""Intialization of core variables"""
# WordOps version
wo_version = "3.9.8.5"
wo_version = "3.9.8.6"
# WordOps packages versions
wo_wp_cli = "2.2.0"
wo_adminer = "4.7.2"
@@ -147,11 +147,18 @@ class WOVariables():
if wo_distro == 'raspbian':
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb"]
elif wo_distro == 'debian':
if wo_platform_codename == 'jessie':
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysql.connector"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb", "mariadb-backup"]
wo_mysql_client = ["mariadb-client", "python3-mysqldb"]
if wo_platform_codename == 'jessie':
wo_mysql_client = ["mariadb-client", "python3-mysqldb"]
else:
wo_mysql_client = ["mariadb-client", "python3-mysql.connector"]
wo_fail2ban = ["fail2ban"]