- PHP 7.4 support
- Improved Webp images support with Cloudflare (Issue [#95](https://github.com/WordOps/WordOps/issues/95)). Nginx will not serve webp images alternative with Cloudflare IP ranges.
- Stack upgrade for adminer
- Check acme.sh installation and setup acme.sh if needed before issuing certificate
- Add `--ufw` to `wo stack status`
- Add Nginx directive `gzip_static on;` to serve precompressed assets with Cache-Enabler or WP-Rocket. (Issue [#207](https://github.com/WordOps/WordOps/issues/207))
- Previous `--php73` & `--php73=off` flags are replaced by `--php72`, `--php73`, `--php74` to switch site's php version
- phpMyAdmin updated to v4.9.2
- Adminer updated to v4.7.5
- Replace dot and dashes by underscores in database names (Issue [#206](https://github.com/WordOps/WordOps/issues/206))
- Increased database name length to 32 characters from domain name + 8 random characters
- typo error in motd-news script (Issue [#204](https://github.com/WordOps/WordOps/issues/204))
- Install Nginx before ngxblocker
- WordOps install/update script text color
- Issue with MySQL stack on Raspbian 9/10
- Typo error  (PR [#205](https://github.com/WordOps/WordOps/pull/205))
- php version in `wo debug` (PR [#209](https://github.com/WordOps/WordOps/pull/209))
- SSL certificates expiration display with shared wildcard certificates
This commit is contained in:
VirtuBox 2019-12-03 19:48:18 +01:00 committed by GitHub
parent 63d2acf7ba
commit 01ee8c0a13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
72 changed files with 3222 additions and 2521 deletions

View File

@ -18,7 +18,7 @@ before_script:
- sudo bash -c 'echo example.com > /etc/hostname'
- unset LANG
- sudo apt-get update --allow-releaseinfo-change -qq
- sudo apt-get -qq purge mysql* graphviz* redis*
- sudo apt-get -qq purge mysql* graphviz* redis* php*
- sudo apt-get -qq autoremove --purge

View File

@ -8,6 +8,35 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### v3.9.x - [Unreleased]
### v3.11.0 - 2019-12-03
#### Added
- PHP 7.4 support
- Improved Webp images support with Cloudflare (Issue [#95](https://github.com/WordOps/WordOps/issues/95)). Nginx will not serve webp images alternative with Cloudflare IP ranges.
- Stack upgrade for adminer
- Check acme.sh installation and setup acme.sh if needed before issuing certificate
- Add `--ufw` to `wo stack status`
- Add Nginx directive `gzip_static on;` to serve precompressed assets with Cache-Enabler or WP-Rocket. (Issue [#207](https://github.com/WordOps/WordOps/issues/207))
#### Changed
- Previous `--php73` & `--php73=off` flags are replaced by `--php72`, `--php73`, `--php74` to switch site's php version
- phpMyAdmin updated to v4.9.2
- Adminer updated to v4.7.5
- Replace dot and dashes by underscores in database names (Issue [#206](https://github.com/WordOps/WordOps/issues/206))
- Increased database name length to 32 characters from domain name + 8 random characters
#### Fixed
- typo error in motd-news script (Issue [#204](https://github.com/WordOps/WordOps/issues/204))
- Install Nginx before ngxblocker
- WordOps install/update script text color
- Issue with MySQL stack on Raspbian 9/10
- Typo error (PR [#205](https://github.com/WordOps/WordOps/pull/205))
- php version in `wo debug` (PR [#209](https://github.com/WordOps/WordOps/pull/209))
- SSL certificates expiration display with shared wildcard certificates
### v3.10.3 - 2019-11-11
#### Added

View File

@ -42,7 +42,7 @@
- **Easy to install** : One step automated installer with migration from EasyEngine v3 support
- **Fast deployment** : Fast and automated WordPress, Nginx, PHP, MySQL & Redis installation
- **Custom Nginx build** : Nginx 1.16.1 - TLS v1.3 Cloudflare HTTP/2 HPACK & Brotli support
- **Up-to-date** : PHP 7.2 & 7.3, MariaDB 10.3 & Redis 5.0
- **Up-to-date** : PHP 7.2, 7.3 & 7.4, MariaDB 10.3 & Redis 5.0
- **Secured** : Hardened WordPress security with strict Nginx location directives
- **Powerful** : Optimized Nginx configurations with multiple cache backends support
- **SSL** : Domain, Subdomain & Wildcard Let's Encrypt SSL certificates with DNS API support
@ -67,11 +67,10 @@
- Debian 9 (Stretch)
- Debian 10 (Buster)
- Raspbian 9 (Stretch)
- Raspbian 10 (Buster) - Testing
- Raspbian 10 (Buster)
## Getting Started
```bash
wget -qO wo wops.cc && sudo bash wo # Install WordOps
sudo wo site create example.com --wp # Install required packages & setup WordPress on example.com
@ -86,6 +85,7 @@ Detailed Getting Started guide with additional installation methods can be found
```bash
wo site create example.com --wp # install wordpress without any page caching
wo site create example.com --wp --php73 # install wordpress with PHP 7.3 without any page caching
wo site create example.com --wp --php74 # install wordpress with PHP 7.4 without any page caching
wo site create example.com --wpfc # install wordpress + nginx fastcgi_cache
wo site create example.com --wpredis # install wordpress + nginx redis_cache
wo site create example.com --wprocket # install wordpress with WP-Rocket plugin
@ -121,11 +121,21 @@ wo site create example.com --wpsubdomain --wpce # install wpmu-subdomain + C
wo site create example.com --html # create example.com for static/html sites
wo site create example.com --php # create example.com with php support
wo site create example.com --php73 # create example.com with php 7.3 support
wo site create example.com --php73 # create example.com with php 7.4 support
wo site create example.com --mysql # create example.com with php & mysql support
wo site create example.com --mysql --php73 # create example.com with php 7.3 & mysql support
wo site create example.com --mysql --php74 # create example.com with php 7.4 & mysql support
wo site create example.com --proxy=127.0.0.1:3000 # create example.com with nginx as reverse-proxy
```
### Switch between PHP versions
```bash
wo site update example/com --php72 # switch to PHP 7.2
wo site update example.com --php73 # switch to PHP 7.3
wo site update example.com --php74 # switch to PHP 7.4
```
### Sites secured with Let's Encrypt
```bash
@ -148,7 +158,7 @@ For any other questions about WordOps or if you need support, please use the [Co
# Contributing
If you'd like to contribute, please fork the repository and make changes as you'd like. Pull requests are warmly welcome.
If you'd like to contribute, please fork the reposi7tory and make changes as you'd like. Pull requests are warmly welcome.
There is no need to be a developer or a system administrator to contribute to WordOps project. You can still contribute by helping us to improve [WordOps documentation](https://github.com/WordOps/docs.wordops.net).
## Credits

View File

@ -53,7 +53,7 @@ _wo_complete()
"info")
COMPREPLY=( $(compgen \
-W "--mysql --php --php73 --nginx" \
-W "--mysql --php --php73 --php74 --nginx" \
-- $cur) )
;;
@ -74,17 +74,17 @@ _wo_complete()
# HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE
"install" | "purge" | "remove" )
COMPREPLY=( $(compgen \
-W "--web --admin --security --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --phpredisadmin --composer --netdata --fail2ban --ufw --dashboard --proftpd --clamav --ngxblocker --mysqlclient --mysqltuner --extplorer --all --force" \
-W "--web --admin --security --nginx --php --php73 --php74 --mysql --wpcli --phpmyadmin --adminer --utils --redis --phpredisadmin --composer --netdata --fail2ban --ufw --dashboard --proftpd --clamav --sendmail --ngxblocker --mysqlclient --mysqltuner --extplorer --nanorc --cheat --all --force" \
-- $cur) )
;;
"upgrade" )
COMPREPLY=( $(compgen \
-W "--web --admin --utils --nginx --php --php73 --mysql --all --netdata --composer --phpmyadmin --dashboard --mysqtuner --wpcli --force" \
-W "--web --admin --utils --nginx --php --php73 --php74 --mysql --all --netdata --composer --phpmyadmin --adminer --dashboard --mysqtuner --wpcli --force" \
-- $cur) )
;;
"start" | "stop" | "reload" | "restart" | "status")
COMPREPLY=( $(compgen \
-W "--nginx --php --php73 --mysql --redis --fail2ban --ufw --netdata -proftpd" \
-W "--nginx --php --php73 --php74 --mysql --redis --fail2ban --ufw --netdata -proftpd" \
-- $cur) )
;;
"list")
@ -154,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_dgon" \
-W "--user --pass --email --html --php --php73 --php74 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --proxy= --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard -le=wildcard --dns --dns=dns_cf --dns=dns_dgon" \
-- $cur) )
;;
"update")
COMPREPLY=( $(compgen \
-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_dgon --ngxblocker --ngxblocker=off" \
-W "--password --php --php72 --php73 --php74 --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_dgon --ngxblocker --ngxblocker=off" \
-- $cur) )
;;
"delete")
@ -206,9 +206,9 @@ _wo_complete()
"--wp")
if [ "${COMP_WORDS[1]}" != "debug" ]; then
if [ "${COMP_WORDS[2]}" == "create" ]; then
retlist="--wp --wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce --letsencrypt -le --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon --php73"
retlist="--wp --wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce --letsencrypt -le --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon --php73 --php74"
elif [ "${COMP_WORDS[2]}" == "update" ]; then
retlist="--wp --wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard -le=wildcard --dns --dns=dns_cf --dns=dns_dgon"
retlist="--wp --wpfc --wpsc --php72 --php73 --php74 --wpredis --wprocket --wpce -le --letsencrypt --letsencrypt=wildcard -le=wildcard --dns --dns=dns_cf --dns=dns_dgon"
else
retlist=""
fi
@ -225,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 -le -le=wildcard --letsencrypt --letsencrypt=wildcard --php73 --dns --dns=dns_cf --dns=dns_dgon"
retlist="--wpsc --wpfc --user --email --pass --wpredis --wprocket --wpce -le -le=wildcard --letsencrypt --letsencrypt=wildcard --php73 --php74 --dns --dns=dns_cf --dns=dns_dgon"
elif [ "${COMP_WORDS[2]}" == "update" ]; then
retlist="--wpfc --wpsc --php73 --php73=off --wpredis --wprocket --wpce -le -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon"
retlist="--wpfc --wpsc --php72 --php73 --php74 --wpredis --wprocket --wpce -le -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon"
else
retlist=""
fi
@ -243,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 -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon"
retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce --php73 --php74 -le -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon"
else
retlist=""
fi
@ -254,9 +254,9 @@ _wo_complete()
-- $cur) )
;;
"--wpredis" | "--wprocket" | "--wpce" | "--wpfc")
"--wpredis" | "--wprocket" | "--wpce" | "--wpfc" | "--wpsc")
if [ "${COMP_WORDS[2]}" == "update" ]; then
retlist="--password --php --php73 --mysql --wp --wpsubdir --wpsubdomain -le --letsencrypt --dns --dns=dns_cf --dns=dns_dgon"
retlist="--password --php72 --php73 --php74 --mysql --wp --wpsubdir --wpsubdomain -le --letsencrypt --dns --dns=dns_cf --dns=dns_dgon"
else
retlist=""
fi
@ -267,11 +267,11 @@ _wo_complete()
-- $cur) )
;;
"--web" | "--admin" | "--nginx" | "--php" | "--php73" | "--mysql" | "--wpcli" | "--phpmyadmin" | "--adminer" | "--utils" | "--fail2ban" | "--ufw" | "--redis | --phpredisadmin | --netdata")
"--web" | "--admin" | "--nginx" | "--php" | "--php73" | "--php74" | "--mysql" | "--wpcli" | "--phpmyadmin" | "--adminer" | "--utils" | "--fail2ban" | "--ufw" | "--redis" | "--phpredisadmin" | "--netdata" | "--sendmail" | "--composer" | "--proftpd" | "--cheat" | "--nanorc" | "--clamav")
if [[ "${COMP_WORDS[2]}" == "install" || "${COMP_WORDS[2]}" == "purge" || "${COMP_WORDS[2]}" == "remove" ]]; then
retlist="--web --admin --security --nginx --php --php73 --mysql --wpcli --phpmyadmin --adminer --utils --redis --fail2ban --ufw --phpredisadmin --netdata --force"
retlist="--web --admin --security --nginx --php --php73 --php74 --mysql --wpcli --phpmyadmin --adminer --utils --redis --fail2ban --ufw --phpredisadmin --netdata --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 --fail2ban --ufw"
retlist="--nginx --php --php73 --php74 --mysql --redis --netdata --fail2ban --ufw"
elif [[ "${COMP_WORDS[1]}" == "debug" ]]; then
retlist="--start --nginx --php --php73 --fpm --fpm7 --mysql -i --interactive -stop --import-slow-log --import-slow-log-interval= -"
if [[ $prev == '--mysql' ]]; then
@ -326,8 +326,8 @@ _wo_complete()
-W "$(echo $ret)" \
-- $cur) )
;;
"--auth" | "--port" | "--ip")
retlist="--auth --port --ip"
"--auth" | "--port" | "--ip" | "--ssh" | "--sshport")
retlist="--auth --port --ip --ssh --sshport"
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
@ -358,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 -le -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon"
retlist="--user --pass --email --html --php --php73 --php74 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --wpredis --wprocket --wpce -le -le=wildcard --letsencrypt --letsencrypt=wildcard --dns --dns=dns_cf --dns=dns_dgon"
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \

View File

@ -18,7 +18,7 @@
# template_dir = /var/lib/wo/templates/
[log.logging]
[log.colorlog]
### Where the log file lives (no log file by default)
file = /var/log/wo/wordops.log
@ -38,6 +38,10 @@ max_bytes = 1000000
### The maximun number of log files to maintain when rotating
max_files = 7
colorize_file_log = true
colorize_console_log = true
[stack]
### IP address that will be used in Nginx configurations while installing

70
install
View File

@ -9,7 +9,7 @@
# -------------------------------------------------------------------------
# wget -qO wo wops.cc && sudo bash wo
# -------------------------------------------------------------------------
# Version 3.10.3 - 2019-11-11
# Version 3.11.0 - 2019-12-03
# -------------------------------------------------------------------------
# CONTENTS
@ -23,25 +23,25 @@
# 1 - Set the CLI output colors
###
TPUT_RESET=$(tput sgr0)
TPUT_FAIL=$(tput setaf 1)
TPUT_INFO=$(tput setaf 7)
TPUT_ECHO=$(tput setaf 4)
TPUT_OK=$(tput setaf 2)
CSI='\033['
TPUT_RESET="${CSI}0m"
TPUT_FAIL="${CSI}1;31m"
TPUT_ECHO="${CSI}1;36m"
TPUT_OK="${CSI}1;32m"
wo_lib_echo() {
echo "${TPUT_ECHO}${*}${TPUT_RESET}"
echo -e "${TPUT_ECHO}${*}${TPUT_RESET}"
}
wo_lib_echo_info() {
echo "${TPUT_INFO}${*}${TPUT_RESET}"
echo -e "$*"
}
wo_lib_echo_fail() {
echo "${TPUT_FAIL}${*}${TPUT_RESET}"
echo -e "${TPUT_FAIL}${*}${TPUT_RESET}"
}
###
@ -49,7 +49,7 @@ wo_lib_echo_fail() {
###
wo_lib_error() {
echo "[ $(date) ] ${TPUT_FAIL}${*}${TPUT_RESET}"
echo -e "[ $(date) ] ${TPUT_FAIL}${*}${TPUT_RESET}"
exit "$2"
}
@ -169,7 +169,8 @@ wo_check_distro() {
else
check_wo_linux_distro=$(lsb_release -sc | grep -E "xenial|bionic|disco|jessie|stretch|buster")
if [ -z "$check_wo_linux_distro" ]; then
wo_lib_echo_fail "WordOps (wo) only supports Ubuntu 16.04/18.04/19.04 LTS, Debian 9.x/10.x and Raspbian 9.x/10x"
wo_lib_echo_fail "WordOps (wo) only supports Ubuntu 16.04/18.04/19.04 LTS, Debian 9.x/10.x and Raspbian 9.x/10x.\n
You can bypass this warning by adding the flag --force to the install command"
exit 100
fi
fi
@ -426,8 +427,10 @@ wo_install_acme_sh() {
wo_install() {
cd /usr/local/lib/python3.*/dist-packages || exit 1
if [ "$wo_branch" = "master" ]; then
python3 -m pip uninstall wo -y
python3 -m pip install --upgrade wordops
else
python3 -m pip uninstall wo -y
python3 -m pip install -U "git+git://github.com/WordOps/WordOps.git@$wo_branch#egg=wordops"
fi
cp -rf /usr/local/lib/python3.*/dist-packages/usr/* /usr/
@ -594,8 +597,7 @@ wo_domain_suffix() {
}
wo_clean() {
echo "pass"
rm -rf /usr/local/lib/python3.*/dist-packages/{wo-*.egg,cement-*.egg,wordops-*.egg}
}
wo_uninstall() {
@ -623,6 +625,14 @@ wo_clean_repo() {
fi
}
wo_woconf() {
if [ -f /etc/wo/wo.conf ]; then
if grep -q "log.logging" /etc/wo/wo.conf; then
sed -i "s/log.logging/log.colorlog/g" /etc/wo/wo.conf
fi
fi
}
wo_init() {
###
@ -631,12 +641,12 @@ wo_init() {
if [ -z "$wo_travis" ]; then
# import easyengine opensusebuildservice gpg key to avoid issues with packages update
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3050ac3cd2ae6f03 > /dev/null 2>&1
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xF1656F24C74CD1D8 > /dev/null 2>&1
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3050ac3cd2ae6f03 >/dev/null 2>&1
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xF1656F24C74CD1D8 >/dev/null 2>&1
# fix digitalocean mariadb repository issue
sed -i 's/sfo1.mirrors.digitalocean.com\/mariadb/mariadb.mirrors.ovh.net\/MariaDB/' /etc/apt/sources.list.d/*.list > /dev/null 2>&1
if [ -f /etc/apt/preferences.d/MariaDB.pref ]; then
sed -i 's/sfo1.mirrors.digitalocean.com/mariadb.mirrors.ovh.net/' /etc/apt/preferences.d/MariaDB.pref > /dev/null 2>&1
sed -i 's/sfo1.mirrors.digitalocean.com\/mariadb/mariadb.mirrors.ovh.net\/MariaDB/' /etc/apt/sources.list.d/*.list >/dev/null 2>&1
if [ -f /etc/apt/preferences.d/MariaDB.pref ]; then
sed -i 's/sfo1.mirrors.digitalocean.com/mariadb.mirrors.ovh.net/' /etc/apt/preferences.d/MariaDB.pref >/dev/null 2>&1
fi
if ! {
apt-get update --allow-releaseinfo-change -qq >/dev/null 2>&1
@ -696,16 +706,20 @@ else
# 1 - WO already installed
if [ -x /usr/local/bin/wo ]; then
_run wo_clean
# 2 - Migration from EEv3
elif [ -x /usr/local/bin/ee ]; then
if [ -z "$wo_force_install" ]; then
echo -e "Migrate from EasyEngine to WordOps (y/n): " && read -r WO_ANSWER
if [ "$WO_ANSWER" != "y" ] && [ "$WO_ANSWER" != "Y" ]; then
wo_lib_error "Not installing WordOps" 1
_run wo_woconf
# 2 - Migration from EEv3
else
if [ -x /usr/local/bin/ee ]; then
if [ -z "$wo_force_install" ]; then
echo -e "Migrate from EasyEngine to WordOps (y/n): " && read -r WO_ANSWER
if [ "$WO_ANSWER" != "y" ] && [ "$WO_ANSWER" != "Y" ]; then
wo_lib_error "Not installing WordOps" 1
fi
fi
_run wo_backup_ee "Backing-up EE install"
_run wo_remove_ee_cron "Removing EasyEngine cronjob"
fi
_run wo_backup_ee "Backing-up EE install"
_run wo_remove_ee_cron "Removing EasyEngine cronjob"
fi
_run wo_install_dep "Installing wo dependencies"
_run wo_timesync
@ -737,10 +751,10 @@ else
elif [ "$wo_upgrade" = "1" ]; then
wo_lib_echo "WordOps (wo) upgrade to $wo_version_new was succesfull!"
echo
wo_lib_echo "To upgrade WordOps web stacks use the command:"
wo_lib_echo "To upgrade WordOps web stacks, you can use the command:"
wo_lib_echo_info "wo stack upgrade"
echo
wo_lib_echo "To update all other packages use the command:"
wo_lib_echo "To update all other packages, you can use the command:"
wo_lib_echo_info "wo maintenance"
else
wo_lib_echo "WordOps (wo) installed successfully"

View File

@ -6,4 +6,6 @@ psutil>=5.6.3
sh>=1.12.14
SQLAlchemy>=1.3.8
requests>=2.22.0
distro>=1.4.0
distro>=1.4.0
argcomplete>=1.10.0
colorlog>=4.0.2

View File

@ -15,7 +15,7 @@ where=tests/
license-file = LICENSE
[flake8]
ignore = F405,W504,S322,S404,S603,s607,s602
ignore = F405,W504,S322,S404,S603,s607,s602,C901
exclude =
# No need to traverse our git directory
.git,

View File

@ -27,7 +27,7 @@
os.makedirs('/var/lib/wo/tmp/')
setup(name='wordops',
version='3.10.3',
version='3.11.0',
description='An essential toolset that eases server administration',
long_description=LONG,
long_description_content_type='text/markdown',
@ -40,11 +40,17 @@
"Natural Language :: English",
"Topic :: System :: Systems Administration",
],
keywords='',
keywords='nginx automation wordpress deployment CLI',
author='WordOps',
author_email='contact@wordops.io',
url='https://github.com/WordOps/WordOps',
license='MIT',
project_urls={
'Documentation': 'https://docs.wordops.net',
'Forum': 'https://community.wordops.net',
'Source': 'https://github.com/WordOps/WordOps',
'Tracker': 'https://github.com/WordOps/WordOps/issues',
},
packages=find_packages(exclude=['ez_setup', 'examples', 'tests',
'templates']),
include_package_data=True,
@ -64,6 +70,8 @@
'SQLAlchemy >= 1.3.8',
'requests >= 2.22.0',
'distro >= 1.4.0',
'argcomplete >= 1.10.0',
'colorlog >= 4.0.2',
],
extras_require={ # Optional
'testing': ['nose', 'coverage'],

View File

@ -2,11 +2,7 @@
from wo.cli.main import WOTestApp
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
class CliTestCaseStackInstall(test.WOTestCase):
def test_wo_cli_stack_install_nginx(self):
with WOTestApp(argv=['stack', 'install', '--nginx']) as app:

View File

@ -4,10 +4,6 @@
class CliTestCaseStackStop(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_stack_services_stop_nginx(self):
with WOTestApp(argv=['stack', 'stop', '--nginx']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseStackStart(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_stack_services_start_nginx(self):
with WOTestApp(argv=['stack', 'start', '--nginx']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseStackRestart(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_stack_services_restart_nginx(self):
with WOTestApp(argv=['stack', 'restart', '--nginx']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseStackStatus(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_stack_services_status_nginx(self):
with WOTestApp(argv=['stack', 'status', '--nginx']) as app:
app.run()

View File

@ -4,47 +4,53 @@
class CliTestCaseSiteCreate(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_site_create_html(self):
with WOTestApp(argv=['site', 'create', 'example1.com',
with WOTestApp(argv=['site', 'create', 'html.com',
'--html']) as app:
app.config.set('wo', '', True)
app.run()
def test_wo_cli_site_create_php(self):
with WOTestApp(argv=['site', 'create', 'example2.com',
with WOTestApp(argv=['site', 'create', 'php.com',
'--php']) as app:
app.run()
def test_wo_cli_site_create_mysql(self):
with WOTestApp(argv=['site', 'create', 'example3.com',
with WOTestApp(argv=['site', 'create', 'mysql.com',
'--mysql']) as app:
app.run()
def test_wo_cli_site_create_wp(self):
with WOTestApp(argv=['site', 'create', 'example4.com',
with WOTestApp(argv=['site', 'create', 'wp.com',
'--wp']) as app:
app.run()
def test_wo_cli_site_create_wpsubdir(self):
with WOTestApp(argv=['site', 'create', 'example5.com',
with WOTestApp(argv=['site', 'create', 'wpsubdir.com',
'--wpsubdir']) as app:
app.run()
def test_wo_cli_site_create_wpsubdomain(self):
with WOTestApp(argv=['site', 'create', 'example6.com',
with WOTestApp(argv=['site', 'create', 'wpsubdomain.com',
'--wpsubdomain']) as app:
app.run()
def test_wo_cli_site_create_wpfc(self):
with WOTestApp(argv=['site', 'create', 'example8.com',
with WOTestApp(argv=['site', 'create', 'wpfc.com',
'--wpfc']) as app:
app.run()
def test_wo_cli_site_create_wpsc(self):
with WOTestApp(argv=['site', 'create', 'example9.com',
with WOTestApp(argv=['site', 'create', 'wpsc.com',
'--wpsc']) as app:
app.run()
def test_wo_cli_site_create_wpce(self):
with WOTestApp(argv=['site', 'create', 'wpce.com',
'--wpce']) as app:
app.run()
def test_wo_cli_site_create_wprocket(self):
with WOTestApp(argv=['site', 'create', 'wprocket.com',
'--wprocket']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseSiteDisable(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_site_disable(self):
with WOTestApp(argv=['site', 'disable', 'example2.com']) as app:
with WOTestApp(argv=['site', 'disable', 'html.com']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseSiteEnable(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_site_enable(self):
with WOTestApp(argv=['site', 'enable', 'example2.com']) as app:
with WOTestApp(argv=['site', 'enable', 'html.com']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseSiteInfo(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_site_info(self):
with WOTestApp(argv=['site', 'info', 'example1.com']) as app:
with WOTestApp(argv=['site', 'info', 'html.com']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseSiteList(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_site_list_enable(self):
with WOTestApp(argv=['site', 'list', '--enabled']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseSiteShow(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_show_edit(self):
with WOTestApp(argv=['site', 'show', 'example1.com']) as app:
with WOTestApp(argv=['site', 'show', 'html.com']) as app:
app.run()

View File

@ -4,46 +4,42 @@
class CliTestCaseSiteUpdate(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_site_update_html(self):
with WOTestApp(argv=['site', 'update', 'example2.com',
with WOTestApp(argv=['site', 'update', 'php.com',
'--html']) as app:
app.run()
def test_wo_cli_site_update_php(self):
with WOTestApp(argv=['site', 'update', 'example1.com',
with WOTestApp(argv=['site', 'update', 'html.com',
'--php']) as app:
app.run()
def test_wo_cli_site_update_mysql(self):
with WOTestApp(argv=['site', 'update', 'example1.com',
with WOTestApp(argv=['site', 'update', 'mysql.com',
'--html']) as app:
app.run()
def test_wo_cli_site_update_wp(self):
with WOTestApp(argv=['site', 'update', 'example5.com',
with WOTestApp(argv=['site', 'update', 'mysql.com',
'--wp']) as app:
app.run()
def test_wo_cli_site_update_wpsubdir(self):
with WOTestApp(argv=['site', 'update', 'example4.com',
with WOTestApp(argv=['site', 'update', 'wp.com',
'--wpsubdir']) as app:
app.run()
def test_wo_cli_site_update_wpsubdomain(self):
with WOTestApp(argv=['site', 'update', 'example7.com',
with WOTestApp(argv=['site', 'update', 'wpsubdir.com',
'--wpsubdomain']) as app:
app.run()
def test_wo_cli_site_update_wpfc(self):
with WOTestApp(argv=['site', 'update', 'example9.com',
with WOTestApp(argv=['site', 'update', 'wpsc.com',
'--wpfc']) as app:
app.run()
def test_wo_cli_site_update_wpsc(self):
with WOTestApp(argv=['site', 'update', 'example6.com',
with WOTestApp(argv=['site', 'update', 'wpfc.com',
'--wpsc']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseClean(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_clean(self):
with WOTestApp(argv=['clean']) as app:
app.run()

View File

@ -1,66 +0,0 @@
from wo.utils import test
from wo.cli.main import WOTestApp
class CliTestCaseDebug(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_debug_stop(self):
with WOTestApp(argv=['debug', '--stop']) as app:
app.run()
def test_wo_cli_debug_start(self):
with WOTestApp(argv=['debug', '--start']) as app:
app.run()
def test_wo_cli_debug_php(self):
with WOTestApp(argv=['debug', '--php']) as app:
app.run()
def test_wo_cli_debug_nginx(self):
with WOTestApp(argv=['debug', '--nginx']) as app:
app.run()
def test_wo_cli_debug_rewrite(self):
with WOTestApp(argv=['debug', '--rewrite']) as app:
app.run()
def test_wo_cli_debug_fpm(self):
with WOTestApp(argv=['debug', '--fpm']) as app:
app.run()
def test_wo_cli_debug_mysql(self):
with WOTestApp(argv=['debug', '--mysql']) as app:
app.run()
def test_wo_cli_debug_import_slow_log_interval(self):
with WOTestApp(argv=['debug', '--mysql',
'--import-slow-log-interval']) as app:
app.run()
def test_wo_cli_debug_site_name_mysql(self):
with WOTestApp(argv=['debug', 'example3.com', '--mysql']) as app:
app.run()
def test_wo_cli_debug_site_name_wp(self):
with WOTestApp(argv=['debug', 'example4.com', '--wp']) as app:
app.run()
def test_wo_cli_debug_site_name_nginx(self):
with WOTestApp(argv=['debug', 'example4.com', '--nginx']) as app:
app.run()
def test_wo_cli_debug_site_name_start(self):
with WOTestApp(argv=['debug', 'example1.com', '--start']) as app:
app.run()
def test_wo_cli_debug_site_name_stop(self):
with WOTestApp(argv=['debug', 'example1.com', '--stop']) as app:
app.run()
def test_wo_cli_debug_site_name_rewrite(self):
with WOTestApp(argv=['debug', 'example1.com', '--rewrite']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseInfo(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_info_mysql(self):
with WOTestApp(argv=['info', '--mysql']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseSecure(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_secure_auth(self):
with WOTestApp(argv=['secure', '--auth', 'abc', 'superpass']) as app:
app.run()

View File

@ -4,26 +4,22 @@
class CliTestCaseSiteDelete(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_site_detele(self):
with WOTestApp(argv=['site', 'delete', 'example1.com',
'--no-prompt']) as app:
with WOTestApp(argv=['site', 'delete', 'html.com',
'--force']) as app:
app.run()
def test_wo_cli_site_detele_all(self):
with WOTestApp(argv=['site', 'delete', 'example2.com',
'--all', '--no-prompt']) as app:
with WOTestApp(argv=['site', 'delete', 'wp.com',
'--all', '--force']) as app:
app.run()
def test_wo_cli_site_detele_db(self):
with WOTestApp(argv=['site', 'delete', 'example3.com',
'--db', '--no-prompt']) as app:
with WOTestApp(argv=['site', 'delete', 'mysql.com',
'--db', '--force']) as app:
app.run()
def test_wo_cli_site_detele_files(self):
with WOTestApp(argv=['site', 'delete', 'example4.com',
'--files', '--no-prompt']) as app:
with WOTestApp(argv=['site', 'delete', 'php.com',
'--files', '--force']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseStackRemove(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_stack_remove_admin(self):
with WOTestApp(argv=['stack', 'remove', '--admin', '--force']) as app:
app.run()

View File

@ -4,10 +4,6 @@
class CliTestCaseStackPurge(test.WOTestCase):
def test_wo_cli(self):
with WOTestApp as app:
app.run()
def test_wo_cli_stack_purge_web(self):
with WOTestApp(
argv=['stack', 'purge', '--web', '--force']) as app:

View File

@ -16,7 +16,7 @@ export LC_ALL='C.UTF-8'
if [ -z "$1" ]; then
{
apt-get -qq purge mysql* graphviz* redis*
apt-get -qq purge mysql* graphviz* redis* php73-* php-*
apt-get install -qq git python3-setuptools python3-dev python3-apt ccze tree
sudo apt-get -qq autoremove --purge
} > /dev/null 2>&1
@ -30,7 +30,7 @@ exit_script() {
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' stack install '
echo -e "${CGREEN}#############################################${CEND}"
stack_list='nginx php php73 mysql redis fail2ban clamav proftpd netdata phpmyadmin composer dashboard extplorer adminer redis phpredisadmin mysqltuner utils ufw ngxblocker cheat nanorc'
stack_list='nginx php php73 php74 mysql redis fail2ban clamav proftpd netdata phpmyadmin composer dashboard extplorer adminer redis phpredisadmin mysqltuner utils ufw ngxblocker cheat nanorc'
for stack in $stack_list; do
echo -ne " Installing $stack [..]\r"
if {
@ -49,7 +49,7 @@ done
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' Simple site create '
echo -e "${CGREEN}#############################################${CEND}"
site_types='html php php73 mysql wp wpfc wpsc wpredis wpce wprocket wpsubdomain wpsubdir ngxblocker'
site_types='html php php73 php74 mysql wp wpfc wpsc wpredis wpce wprocket wpsubdomain wpsubdir ngxblocker'
for site in $site_types; do
echo -ne " Creating $site [..]\r"
if {
@ -64,10 +64,16 @@ for site in $site_types; do
fi
done
echo
echo -e "${CGREEN}#############################################${CEND}"
echo
wo site info wp.net
echo
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo site update --php73 '
echo -e "${CGREEN}#############################################${CEND}"
other_site_types='html mysql wp wpfc wpsc wpredis wpce wprocket wpsubdomain wpsubdir ngxblocker'
other_site_types='html mysql php php74 wp wpfc wpsc wpredis wpce wprocket wpsubdomain wpsubdir ngxblocker'
for site in $other_site_types; do
echo -ne " Updating site to $site php73 [..]\r"
if {
@ -82,7 +88,57 @@ for site in $other_site_types; do
fi
done
echo
echo -e "${CGREEN}#############################################${CEND}"
echo
wo site info wp.net
echo
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo site update --php74 '
echo -e "${CGREEN}#############################################${CEND}"
other_site_types='html mysql wp php php73 wpfc wpsc wpredis wpce wprocket wpsubdomain wpsubdir ngxblocker'
for site in $other_site_types; do
echo -ne " Updating site to $site php74 [..]\r"
if {
wo site update ${site}.net --php74
} >>/var/log/wo/test.log; then
echo -ne " Updating site to $site php74 [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
else
echo -e " Updating site to $site php74 [${CRED}FAIL${CEND}]"
echo -ne '\n'
exit_script
fi
done
echo
echo -e "${CGREEN}#############################################${CEND}"
echo
wo site info wp.net
echo
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo site update --php72 '
echo -e "${CGREEN}#############################################${CEND}"
other_site_types='html mysql php php73 php74 wp wpfc wpsc wpredis wpce wprocket wpsubdomain wpsubdir ngxblocker'
for site in $other_site_types; do
echo -ne " Updating site to $site php72 [..]\r"
if {
wo site update ${site}.net --php72
} >>/var/log/wo/test.log; then
echo -ne " Updating site to $site php72 [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
else
echo -e " Updating site to $site php72 [${CRED}FAIL${CEND}]"
echo -ne '\n'
exit_script
fi
done
echo
echo -e "${CGREEN}#############################################${CEND}"
echo
wo site info wp.net
echo
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo site update WP '
echo -e "${CGREEN}#############################################${CEND}"
@ -147,7 +203,7 @@ if [ -z "$1" ]; then
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo stack upgrade '
echo -e "${CGREEN}#############################################${CEND}"
stack_upgrade='nginx php php73 mysql redis netdata dashboard phpmyadmin composer ngxblocker'
stack_upgrade='nginx php php72 php73 php74 mysql redis netdata dashboard phpmyadmin composer ngxblocker mysqltuner'
for stack in $stack_upgrade; do
echo -ne " Upgrading $stack [..]\r"
if {
@ -232,7 +288,7 @@ echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo site info '
echo -e "${CGREEN}#############################################${CEND}"
wo site info wp.net
wo site info wpfc.net
echo
echo -e "${CGREEN}#############################################${CEND}"
@ -240,10 +296,29 @@ echo -e ' wo info '
echo -e "${CGREEN}#############################################${CEND}"
wo info
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo site delete '
echo -e "${CGREEN}#############################################${CEND}"
sites=$(wo site list 2>&1)
for site in $sites; do
echo -ne " deleting $site [..]\r"
if {
wo site delete $site --force
} >>/var/log/wo/test.log; then
echo -ne " deleting $site [${CGREEN}OK${CEND}]\\r"
echo -ne '\n'
else
echo -e " deleting $site [${CRED}FAIL${CEND}]"
echo -ne '\n'
exit_script
fi
done
echo -e "${CGREEN}#############################################${CEND}"
echo -e ' wo stack purge '
echo -e "${CGREEN}#############################################${CEND}"
stack_purge='nginx php php73 mysql redis fail2ban clamav proftpd netdata phpmyadmin composer dashboard extplorer adminer redis ufw ngxblocker cheat nanorc'
stack_purge='nginx php php73 php74 mysql redis fail2ban clamav proftpd netdata phpmyadmin composer dashboard extplorer adminer redis ufw ngxblocker cheat nanorc'
for stack in $stack_purge; do
echo -ne " purging $stack [..]\r"
if {

View File

@ -9,14 +9,6 @@
from wo.core import exc
# this has to happen after you import sys, but before you import anything
# from Cement "source: https://github.com/datafolklabs/cement/issues/290"
if '--debug' in sys.argv:
sys.argv.remove('--debug')
TOGGLE_DEBUG = True
else:
TOGGLE_DEBUG = False
# Application default. Should update config/wo.conf to reflect any
# changes, or additions here.
defaults = init_defaults('wo')
@ -65,7 +57,7 @@ class Meta:
# Internal templates (ship with application code)
template_module = 'wo.cli.templates'
extensions = ['mustache']
extensions = ['mustache', 'argcomplete', 'colorlog']
hooks = [
("post_render", encode_output)
@ -73,10 +65,9 @@ class Meta:
output_handler = 'mustache'
log_handler = 'colorlog'
arg_handler = WOArgHandler
debug = TOGGLE_DEBUG
exit_on_close = True
@ -125,14 +116,11 @@ def main():
print('FrameworkError > %s' % e)
app.exit_code = 1
finally:
# Print an exception (if it occurred) and --debug was passed
# Maybe we want to see a full-stack trace for the above
# exceptions, but only if --debug was passed?
if app.debug:
import sys
import traceback
exc_type, exc_value, exc_traceback = sys.exc_info()
if exc_traceback is not None:
traceback.print_exc()
traceback.print_exc()
if __name__ == '__main__':

View File

@ -32,6 +32,9 @@ class Meta:
(['--php73'],
dict(help='Get PHP 7.3 configuration information',
action='store_true')),
(['--php74'],
dict(help='Get PHP 7.4 configuration information',
action='store_true')),
(['--nginx'],
dict(help='Get Nginx configuration information',
action='store_true')),
@ -238,6 +241,93 @@ def info_php73(self):
debug_xdebug_profiler_enable_trigger=debug_xdebug)
self.app.render((data), 'info_php.mustache')
@expose(hide=True)
def info_php74(self):
"""Display PHP information"""
version = os.popen("/usr/bin/php7.4 -v 2>/dev/null | "
"head -n1 | cut -d' ' -f2 |"
" cut -d'+' -f1 | tr -d '\n'").read
config = configparser.ConfigParser()
config.read('/etc/php/7.4/fpm/php.ini')
expose_php = config['PHP']['expose_php']
memory_limit = config['PHP']['memory_limit']
post_max_size = config['PHP']['post_max_size']
upload_max_filesize = config['PHP']['upload_max_filesize']
max_execution_time = config['PHP']['max_execution_time']
if os.path.exists('/etc/php/7.4/fpm/pool.d/www.conf'):
config.read('/etc/php/7.4/fpm/pool.d/www.conf')
else:
Log.error(self, 'php-fpm pool config not found')
if config.has_section('www'):
wconfig = config['www']
elif config.has_section('www-php74'):
wconfig = config['www-php74']
else:
Log.error(self, 'Unable to parse configuration')
www_listen = wconfig['listen']
www_ping_path = wconfig['ping.path']
www_pm_status_path = wconfig['pm.status_path']
www_pm = wconfig['pm']
www_pm_max_requests = wconfig['pm.max_requests']
www_pm_max_children = wconfig['pm.max_children']
www_pm_start_servers = wconfig['pm.start_servers']
www_pm_min_spare_servers = wconfig['pm.min_spare_servers']
www_pm_max_spare_servers = wconfig['pm.max_spare_servers']
www_request_terminate_time = (wconfig
['request_terminate_timeout'])
try:
www_xdebug = (wconfig
['php_admin_flag[xdebug.profiler_enable'
'_trigger]'])
except Exception as e:
Log.debug(self, "{0}".format(e))
www_xdebug = 'off'
config.read('/etc/php/7.4/fpm/pool.d/debug.conf')
debug_listen = config['debug']['listen']
debug_ping_path = config['debug']['ping.path']
debug_pm_status_path = config['debug']['pm.status_path']
debug_pm = config['debug']['pm']
debug_pm_max_requests = config['debug']['pm.max_requests']
debug_pm_max_children = config['debug']['pm.max_children']
debug_pm_start_servers = config['debug']['pm.start_servers']
debug_pm_min_spare_servers = config['debug']['pm.min_spare_servers']
debug_pm_max_spare_servers = config['debug']['pm.max_spare_servers']
debug_request_terminate = (config['debug']
['request_terminate_timeout'])
try:
debug_xdebug = (config['debug']['php_admin_flag[xdebug.profiler_'
'enable_trigger]'])
except Exception as e:
Log.debug(self, "{0}".format(e))
debug_xdebug = 'off'
data = dict(version=version, expose_php=expose_php,
memory_limit=memory_limit, post_max_size=post_max_size,
upload_max_filesize=upload_max_filesize,
max_execution_time=max_execution_time,
www_listen=www_listen, www_ping_path=www_ping_path,
www_pm_status_path=www_pm_status_path, www_pm=www_pm,
www_pm_max_requests=www_pm_max_requests,
www_pm_max_children=www_pm_max_children,
www_pm_start_servers=www_pm_start_servers,
www_pm_min_spare_servers=www_pm_min_spare_servers,
www_pm_max_spare_servers=www_pm_max_spare_servers,
www_request_terminate_timeout=www_request_terminate_time,
www_xdebug_profiler_enable_trigger=www_xdebug,
debug_listen=debug_listen, debug_ping_path=debug_ping_path,
debug_pm_status_path=debug_pm_status_path,
debug_pm=debug_pm,
debug_pm_max_requests=debug_pm_max_requests,
debug_pm_max_children=debug_pm_max_children,
debug_pm_start_servers=debug_pm_start_servers,
debug_pm_min_spare_servers=debug_pm_min_spare_servers,
debug_pm_max_spare_servers=debug_pm_max_spare_servers,
debug_request_terminate_timeout=debug_request_terminate,
debug_xdebug_profiler_enable_trigger=debug_xdebug)
self.app.render((data), 'info_php.mustache')
@expose(hide=True)
def info_mysql(self):
"""Display MySQL information"""
@ -275,38 +365,48 @@ def info_mysql(self):
@expose(hide=True)
def default(self):
"""default function for info"""
if (not self.app.pargs.nginx and not self.app.pargs.php and
not self.app.pargs.mysql and not self.app.pargs.php73):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
pargs = self.app.pargs
if (not pargs.nginx and not pargs.php and
not pargs.mysql and not pargs.php73 and
not pargs.php74):
pargs.nginx = True
pargs.php = True
pargs.mysql = True
if WOAptGet.is_installed(self, 'php7.3-fpm'):
self.app.pargs.php73 = True
pargs.php73 = True
if WOAptGet.is_installed(self, 'php7.4-fpm'):
pargs.php74 = True
if self.app.pargs.nginx:
if pargs.nginx:
if ((not WOAptGet.is_installed(self, 'nginx-custom')) and
(not os.path.exists('/usr/bin/nginx'))):
Log.error(self, "Nginx is not installed")
Log.info(self, "Nginx is not installed")
else:
self.info_nginx()
if self.app.pargs.php:
if pargs.php:
if WOAptGet.is_installed(self, 'php7.2-fpm'):
self.info_php()
else:
Log.error(self, "PHP 7.2 is not installed")
Log.info(self, "PHP 7.2 is not installed")
if self.app.pargs.php73:
if pargs.php73:
if WOAptGet.is_installed(self, 'php7.3-fpm'):
self.info_php73()
else:
Log.error(self, "PHP 7.3 is not installed")
Log.info(self, "PHP 7.3 is not installed")
if self.app.pargs.mysql:
if pargs.php74:
if WOAptGet.is_installed(self, 'php7.4-fpm'):
self.info_php74()
else:
Log.info(self, "PHP 7.4 is not installed")
if pargs.mysql:
if WOShellExec.cmd_exec(self, "/usr/bin/mysqladmin ping"):
self.info_mysql()
else:
Log.error(self, "MySQL is not installed")
Log.info(self, "MySQL is not installed")
def load(app):

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,551 @@
import os
from cement.core.controller import CementBaseController, expose
from wo.cli.plugins.site_functions import *
from wo.cli.plugins.sitedb import (addNewSite, deleteSiteInfo,
updateSiteInfo)
from wo.core.acme import WOAcme
from wo.core.domainvalidate import WODomain
from wo.core.git import WOGit
from wo.core.logging import Log
from wo.core.nginxhashbucket import hashbucket
from wo.core.services import WOService
from wo.core.sslutils import SSL
from wo.core.variables import WOVar
class WOSiteCreateController(CementBaseController):
class Meta:
label = 'create'
stacked_on = 'site'
stacked_type = 'nested'
description = ('this commands set up configuration and installs '
'required files as options are provided')
arguments = [
(['site_name'],
dict(help='domain name for the site to be created.',
nargs='?')),
(['--html'],
dict(help="create html site", action='store_true')),
(['--php'],
dict(help="create php 7.2 site", action='store_true')),
(['--php72'],
dict(help="create php 7.2 site", action='store_true')),
(['--php73'],
dict(help="create php 7.3 site", action='store_true')),
(['--php74'],
dict(help="create php 7.4 site", action='store_true')),
(['--mysql'],
dict(help="create mysql site", action='store_true')),
(['--wp'],
dict(help="create WordPress single site",
action='store_true')),
(['--wpsubdir'],
dict(help="create WordPress multisite with subdirectory setup",
action='store_true')),
(['--wpsubdomain'],
dict(help="create WordPress multisite with subdomain setup",
action='store_true')),
(['--wpfc'],
dict(help="create WordPress single/multi site with "
"Nginx fastcgi_cache",
action='store_true')),
(['--wpsc'],
dict(help="create WordPress single/multi site with wpsc cache",
action='store_true')),
(['--wprocket'],
dict(help="create WordPress single/multi site with WP-Rocket",
action='store_true')),
(['--wpce'],
dict(help="create WordPress single/multi site with Cache-Enabler",
action='store_true')),
(['--wpredis'],
dict(help="create WordPress single/multi site "
"with redis cache",
action='store_true')),
(['-le', '--letsencrypt'],
dict(help="configure letsencrypt ssl for the site",
action='store' or 'store_const',
choices=('on', 'subdomain', 'wildcard'),
const='on', nargs='?')),
(['--force'],
dict(help="force Let's Encrypt certificate issuance",
action='store_true')),
(['--dns'],
dict(help="choose dns provider api for letsencrypt",
action='store' or 'store_const',
const='dns_cf', nargs='?')),
(['--dnsalias'],
dict(help="set domain used for acme dns alias validation",
action='store', nargs='?')),
(['--hsts'],
dict(help="enable HSTS for site secured with letsencrypt",
action='store_true')),
(['--ngxblocker'],
dict(help="enable HSTS for site secured with letsencrypt",
action='store_true')),
(['--user'],
dict(help="provide user for WordPress site")),
(['--email'],
dict(help="provide email address for WordPress site")),
(['--pass'],
dict(help="provide password for WordPress user",
dest='wppass')),
(['--proxy'],
dict(help="create proxy for site", nargs='+')),
(['--vhostonly'], dict(help="only create vhost and database "
"without installing WordPress",
action='store_true')),
]
@expose(hide=True)
def default(self):
pargs = self.app.pargs
# self.app.render((data), 'default.mustache')
# Check domain name validation
data = dict()
host, port = None, None
try:
stype, cache = detSitePar(vars(pargs))
except RuntimeError as e:
Log.debug(self, str(e))
Log.error(self, "Please provide valid options to creating site")
if stype is None and pargs.proxy:
stype, cache = 'proxy', ''
proxyinfo = pargs.proxy[0].strip()
if not proxyinfo:
Log.error(self, "Please provide proxy server host information")
proxyinfo = proxyinfo.split(':')
host = proxyinfo[0].strip()
port = '80' if len(proxyinfo) < 2 else proxyinfo[1].strip()
elif stype is None and not pargs.proxy:
stype, cache = 'html', 'basic'
elif stype and pargs.proxy:
Log.error(self, "proxy should not be used with other site types")
if not pargs.site_name:
try:
while not pargs.site_name:
# preprocessing before finalize site name
pargs.site_name = (input('Enter site name : ')
.strip())
except IOError as e:
Log.debug(self, str(e))
Log.error(self, "Unable to input site name, Please try again!")
pargs.site_name = pargs.site_name.strip()
wo_domain = WODomain.validate(self, pargs.site_name)
wo_www_domain = "www.{0}".format(wo_domain)
(wo_domain_type, wo_root_domain) = WODomain.getlevel(
self, wo_domain)
if not wo_domain.strip():
Log.error(self, "Invalid domain name, "
"Provide valid domain name")
wo_site_webroot = WOVar.wo_webroot + wo_domain
if check_domain_exists(self, wo_domain):
Log.error(self, "site {0} already exists".format(wo_domain))
elif os.path.isfile('/etc/nginx/sites-available/{0}'
.format(wo_domain)):
Log.error(self, "Nginx configuration /etc/nginx/sites-available/"
"{0} already exists".format(wo_domain))
if stype == 'proxy':
data = dict(
site_name=wo_domain, www_domain=wo_www_domain,
static=True, basic=False, wp=False,
wpfc=False, wpsc=False, wprocket=False, wpce=False,
multisite=False, wpsubdir=False, webroot=wo_site_webroot)
data['proxy'] = True
data['host'] = host
data['port'] = port
data['basic'] = True
if pargs.php72 or pargs.php73 or pargs.php74:
data = dict(
site_name=wo_domain, www_domain=wo_www_domain,
static=False, basic=False,
wp=False, wpfc=False, wpsc=False, wprocket=False,
wpce=False, multisite=False,
wpsubdir=False, webroot=wo_site_webroot)
data['basic'] = True
if stype in ['html', 'php']:
data = dict(
site_name=wo_domain, www_domain=wo_www_domain,
static=True, basic=False, wp=False,
wpfc=False, wpsc=False, wprocket=False, wpce=False,
multisite=False, wpsubdir=False, webroot=wo_site_webroot)
if stype == 'php':
data['static'] = False
data['basic'] = True
elif stype in ['mysql', 'wp', 'wpsubdir', 'wpsubdomain']:
data = dict(
site_name=wo_domain, www_domain=wo_www_domain,
static=False, basic=True, wp=False, wpfc=False,
wpsc=False, wpredis=False, wprocket=False, wpce=False,
multisite=False, wpsubdir=False, webroot=wo_site_webroot,
wo_db_name='', wo_db_user='', wo_db_pass='',
wo_db_host='')
if stype in ['wp', 'wpsubdir', 'wpsubdomain']:
data['wp'] = True
data['basic'] = False
data[cache] = True
data['wp-user'] = pargs.user
data['wp-email'] = pargs.email
data['wp-pass'] = pargs.wppass
if stype in ['wpsubdir', 'wpsubdomain']:
data['multisite'] = True
if stype == 'wpsubdir':
data['wpsubdir'] = True
else:
pass
if data and pargs.php73:
data['php73'] = True
data['php74'] = False
data['php72'] = False
data['wo_php'] = 'php73'
elif data and pargs.php74:
data['php72'] = False
data['php74'] = True
data['php73'] = False
data['wo_php'] = 'php74'
else:
data['php74'] = False
data['php72'] = True
data['php73'] = False
data['wo_php'] = 'php72'
if ((not pargs.wpfc) and (not pargs.wpsc) and
(not pargs.wprocket) and
(not pargs.wpce) and
(not pargs.wpredis)):
data['basic'] = True
if (cache == 'wpredis'):
cache = 'wpredis'
data['wpredis'] = True
data['basic'] = False
pargs.wpredis = True
# Check rerequired packages are installed or not
wo_auth = site_package_check(self, stype)
try:
pre_run_checks(self)
except SiteError as e:
Log.debug(self, str(e))
Log.error(self, "NGINX configuration check failed.")
try:
try:
# setup NGINX configuration, and webroot
setupdomain(self, data)
# Fix Nginx Hashbucket size error
hashbucket(self)
except SiteError as e:
# call cleanup actions on failure
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'])
Log.debug(self, str(e))
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
if 'proxy' in data.keys() and data['proxy']:
addNewSite(self, wo_domain, stype, cache, wo_site_webroot)
# Service Nginx Reload
if not WOService.reload_service(self, 'nginx'):
Log.info(self, Log.FAIL +
"There was a serious error encountered...")
Log.info(self, Log.FAIL + "Cleaning up afterwards...")
doCleanupAction(self, domain=wo_domain)
deleteSiteInfo(self, wo_domain)
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
if wo_auth and len(wo_auth):
for msg in wo_auth:
Log.info(self, Log.ENDC + msg, log=False)
Log.info(self, "Successfully created site"
" http://{0}".format(wo_domain))
return
if data['php73']:
php_version = "7.3"
elif data['php74']:
php_version = "7.4"
else:
php_version = "7.2"
addNewSite(self, wo_domain, stype, cache, wo_site_webroot,
php_version=php_version)
# Setup database for MySQL site
if 'wo_db_name' in data.keys() and not data['wp']:
try:
data = setupdatabase(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()
stype = 'mysql'
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")
# Setup WordPress if Wordpress site
if data['wp']:
vhostonly = bool(pargs.vhostonly)
try:
wo_wp_creds = setupwordpress(self, data, vhostonly)
# 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'):
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'])
if 'wo_db_name' in data.keys():
doCleanupAction(self, domain=wo_domain,
dbname=data['wo_db_name'],
dbuser=data['wo_db_user'],
dbhost=data['wo_mysql_grant_host'])
deleteSiteInfo(self, wo_domain)
Log.info(self, Log.FAIL + "service nginx reload failed."
" check issues with `nginx -t` command.")
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` "
"and please try again")
WOGit.add(self, ["/etc/nginx"],
msg="{0} created with {1} {2}"
.format(wo_www_domain, stype, cache))
# Setup Permissions for webroot
try:
setwebrootpermissions(self, data['webroot'])
except SiteError as e:
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'])
if 'wo_db_name' in data.keys():
print("Inside db cleanup")
doCleanupAction(self, domain=wo_domain,
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 wo_auth and len(wo_auth):
for msg in wo_auth:
Log.info(self, Log.ENDC + msg, log=False)
if data['wp'] and (not pargs.vhostonly):
Log.info(self, Log.ENDC + "WordPress admin user :"
" {0}".format(wo_wp_creds['wp_user']), log=False)
Log.info(self, Log.ENDC + "WordPress admin password : {0}"
.format(wo_wp_creds['wp_pass']), log=False)
display_cache_settings(self, data)
Log.info(self, "Successfully created site"
" http://{0}".format(wo_domain))
except SiteError:
Log.error(self, "Check the log for details: "
"`tail /var/log/wo/wordops.log` and please try again")
if pargs.letsencrypt:
acme_domains = []
data['letsencrypt'] = True
letsencrypt = True
Log.debug(self, "Going to issue Let's Encrypt certificate")
acmedata = dict(
acme_domains, dns=False, acme_dns='dns_cf',
dnsalias=False, acme_alias='', keylength='')
if self.app.config.has_section('letsencrypt'):
acmedata['keylength'] = self.app.config.get(
'letsencrypt', 'keylength')
else:
acmedata['keylength'] = 'ec-384'
if pargs.dns:
Log.debug(self, "DNS validation enabled")
acmedata['dns'] = True
if not pargs.dns == 'dns_cf':
Log.debug(self, "DNS API : {0}".format(pargs.dns))
acmedata['acme_dns'] = pargs.dns
if pargs.dnsalias:
Log.debug(self, "DNS Alias enabled")
acmedata['dnsalias'] = True
acmedata['acme_alias'] = pargs.dnsalias
# detect subdomain and set subdomain variable
if pargs.letsencrypt == "subdomain":
Log.warn(
self, 'Flag --letsencrypt=subdomain is '
'deprecated and not required anymore.')
acme_subdomain = True
acme_wildcard = False
elif pargs.letsencrypt == "wildcard":
acme_wildcard = True
acme_subdomain = False
acmedata['dns'] = True
else:
if ((wo_domain_type == 'subdomain')):
Log.debug(self, "Domain type = {0}"
.format(wo_domain_type))
acme_subdomain = True
else:
acme_subdomain = False
acme_wildcard = False
if acme_subdomain is True:
Log.info(self, "Certificate type : subdomain")
acme_domains = acme_domains + ['{0}'.format(wo_domain)]
elif acme_wildcard is True:
Log.info(self, "Certificate type : wildcard")
acme_domains = acme_domains + ['{0}'.format(wo_domain),
'*.{0}'.format(wo_domain)]
else:
Log.info(self, "Certificate type : domain")
acme_domains = acme_domains + ['{0}'.format(wo_domain),
'www.{0}'.format(wo_domain)]
if WOAcme.cert_check(self, wo_domain):
SSL.archivedcertificatehandle(self, wo_domain, acme_domains)
else:
if acme_subdomain is True:
# check if a wildcard cert for the root domain exist
Log.debug(self, "checkWildcardExist on *.{0}"
.format(wo_root_domain))
if SSL.checkwildcardexist(self, wo_root_domain):
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:
# check DNS records before issuing cert
if not acmedata['dns'] is True:
if not pargs.force:
if not WOAcme.check_dns(self, acme_domains):
Log.error(self,
"Aborting SSL "
"certificate issuance")
Log.debug(self, "Setup Cert with acme.sh for {0}"
.format(wo_domain))
if WOAcme.setupletsencrypt(
self, acme_domains, acmedata):
WOAcme.deploycert(self, wo_domain)
else:
if not acmedata['dns'] is True:
if not pargs.force:
if not WOAcme.check_dns(self, acme_domains):
Log.error(self,
"Aborting SSL certificate issuance")
if WOAcme.setupletsencrypt(
self, acme_domains, acmedata):
WOAcme.deploycert(self, wo_domain)
if pargs.hsts:
SSL.setuphsts(self, wo_domain)
SSL.httpsredirect(self, wo_domain, acme_domains, True)
SSL.siteurlhttps(self, wo_domain)
if not WOService.reload_service(self, 'nginx'):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
Log.info(self, "Congratulations! Successfully Configured "
"SSL on https://{0}".format(wo_domain))
# Add nginx conf folder into GIT
WOGit.add(self, ["{0}/conf/nginx".format(wo_site_webroot)],
msg="Adding letsencrypts config of site: {0}"
.format(wo_domain))
updateSiteInfo(self, wo_domain, ssl=letsencrypt)

View File

@ -38,7 +38,7 @@ def __str__(self):
def pre_run_checks(self):
# Check nginx configuration
Log.wait(self, "Running pre-update checks")
Log.wait(self, "Running pre-run checks")
try:
Log.debug(self, "checking NGINX configuration ...")
fnull = open('/dev/null', 'w')
@ -78,12 +78,8 @@ def setupdomain(self, data):
wo_site_nginx_conf = open('/etc/nginx/sites-available/{0}'
.format(wo_domain_name), encoding='utf-8',
mode='w')
if not data['php73']:
self.app.render((data), 'virtualconf.mustache',
out=wo_site_nginx_conf)
else:
self.app.render((data), 'virtualconf-php7.mustache',
out=wo_site_nginx_conf)
self.app.render((data), 'virtualconf.mustache',
out=wo_site_nginx_conf)
wo_site_nginx_conf.close()
except IOError as e:
Log.debug(self, str(e))
@ -148,7 +144,9 @@ def setupdatabase(self, data):
wo_random_pass = (''.join(random.sample(string.ascii_uppercase +
string.ascii_lowercase +
string.digits, 24)))
wo_replace_dot = wo_domain_name.replace('.', '')
wo_replace_dash = wo_domain_name.replace('-', '_')
wo_replace_dot = wo_replace_dash.replace('.', '_')
wo_replace_underscore = wo_replace_dot.replace('_', '')
if self.app.config.has_section('mysql'):
prompt_dbname = self.app.config.get('mysql', 'db-name')
prompt_dbuser = self.app.config.get('mysql', 'db-user')
@ -170,8 +168,7 @@ def setupdatabase(self, data):
raise SiteError("Unable to input database name")
if not wo_db_name:
wo_db_name = wo_replace_dot
wo_db_name = (wo_db_name[0:16] + generate_random())
wo_db_name = (wo_replace_dot[0:32] + '_' + generate_8_random())
if prompt_dbuser == 'True' or prompt_dbuser == 'true':
try:
@ -184,8 +181,7 @@ def setupdatabase(self, data):
raise SiteError("Unable to input database credentials")
if not wo_db_username:
wo_db_username = wo_replace_dot
wo_db_username = (wo_db_name[0:12] + generate_random())
wo_db_username = (wo_replace_underscore[0:12] + generate_random())
if not wo_db_password:
wo_db_password = wo_random_pass
@ -195,7 +191,7 @@ def setupdatabase(self, data):
try:
if WOMysql.check_db_exists(self, wo_db_name):
Log.debug(self, "Database already exists, Updating DB_NAME .. ")
wo_db_name = (wo_db_name[0:16] + generate_random())
wo_db_name = (wo_db_name[0:32] + '_' + generate_8_random())
wo_db_username = (wo_db_name[0:12] + generate_random())
except MySQLConnectionError:
raise SiteError("MySQL Connectivity problem occured")
@ -388,7 +384,7 @@ def setupwordpress(self, data, vhostonly=False):
['MEDIA_TRASH', 'true'],
['EMPTY_TRASH_DAYS', '15'],
['WP_AUTO_UPDATE_CORE', 'minor']]
Log.wait(self, "Configuring WordPress")
for wp_conf in wp_conf_variables:
wp_var = wp_conf[0]
wp_val = wp_conf[1]
@ -403,8 +399,10 @@ def setupwordpress(self, data, vhostonly=False):
wp_raw='--raw'
if var_raw is True else ''))
except CommandExecutionError as e:
Log.failed(self, "Configuring WordPress")
Log.debug(self, str(e))
Log.error(self, 'Unable to define wp-config.php variables')
Log.valide(self, "Configuring WordPress")
# WOFileUtils.mvfile(self, os.getcwd()+'/wp-config.php',
# os.path.abspath(os.path.join(os.getcwd(), os.pardir)))
@ -455,7 +453,7 @@ def setupwordpress(self, data, vhostonly=False):
raise SiteError("input WordPress user email failed")
Log.debug(self, "Setting up WordPress tables")
Log.wait(self, "Installing WordPress")
if not data['multisite']:
Log.debug(self, "Creating tables for WordPress Single site")
Log.debug(
@ -478,6 +476,7 @@ def setupwordpress(self, data, vhostonly=False):
log=False):
pass
else:
Log.failed(self, "Installing WordPress")
raise SiteError(
"setup WordPress tables failed for single site")
except CommandExecutionError:
@ -511,11 +510,12 @@ def setupwordpress(self, data, vhostonly=False):
log=False):
pass
else:
Log.failed(self, "Installing WordPress")
raise SiteError(
"setup WordPress tables failed for wp multi site")
except CommandExecutionError:
raise SiteError("setup WordPress tables failed for wp multi site")
Log.valide(self, "Installing WordPress")
Log.debug(self, "Updating WordPress permalink")
try:
WOShellExec.cmd_exec(self, " {0} --allow-root "
@ -774,8 +774,9 @@ def sitebackup(self, data):
WOFileUtils.copyfile(self, '/etc/nginx/sites-available/{0}'
.format(data['site_name']), backup_path)
if data['currsitetype'] in ['html', 'php', 'proxy', 'mysql']:
if data['php73'] is True and not data['wp']:
if data['currsitetype'] in ['html', 'php', 'php72', 'php74',
'php73', 'proxy', 'mysql']:
if not data['wp']:
Log.info(self, "Backing up Webroot \t\t", end='')
WOFileUtils.copyfiles(self, wo_site_webroot +
'/htdocs', backup_path + '/htdocs')
@ -832,8 +833,9 @@ def site_package_check(self, stype):
packages = []
stack = WOStackController()
stack.app = self.app
if stype in ['html', 'proxy', 'php', 'mysql', 'wp', 'wpsubdir',
'wpsubdomain', 'php73']:
pargs = self.app.pargs
if stype in ['html', 'proxy', 'php', 'php72', 'mysql', 'wp', 'wpsubdir',
'wpsubdomain', 'php73', 'php74']:
Log.debug(self, "Setting apt_packages variable for Nginx")
# Check if server has nginx-custom package
@ -846,7 +848,7 @@ def site_package_check(self, stype):
Log.info(self, "NGINX PLUS Detected ...")
apt = ["nginx-plus"] + WOVar.wo_nginx
# apt_packages = apt_packages + WOVar.wo_nginx
stack.post_pref(self, apt, packages)
post_pref(self, apt, packages)
elif WOAptGet.is_installed(self, 'nginx'):
Log.info(self, "WordOps detected a previously"
"installed Nginx package. "
@ -869,69 +871,68 @@ def site_package_check(self, stype):
wo_nginx.write('fastcgi_param \tSCRIPT_FILENAME '
'\t$request_filename;\n')
if self.app.pargs.php and self.app.pargs.php73:
if pargs.php and pargs.php73:
Log.error(
self, "Error: two different PHP versions cannot be "
"combined within the same WordOps site")
if not self.app.pargs.php73 and stype in ['php', 'mysql', 'wp', 'wpsubdir',
'wpsubdomain']:
Log.debug(self, "Setting apt_packages variable for PHP 7.2")
if not WOAptGet.is_installed(self, 'php7.2-fpm'):
if not WOAptGet.is_installed(self, 'php7.3-fpm'):
apt_packages = apt_packages + WOVar.wo_php + \
WOVar.wo_php_extra
else:
apt_packages = apt_packages + WOVar.wo_php
if pargs.php and pargs.php74:
Log.error(
self, "Error: two different PHP versions cannot be "
"combined within the same WordOps site")
if self.app.pargs.php73 and stype in ['mysql', 'wp',
if pargs.php73 and pargs.php74:
Log.error(
self, "Error: two different PHP versions cannot be "
"combined within the same WordOps site")
if ((not pargs.php73) and (not pargs.php74) and
stype in ['php', 'php72', 'mysql', 'wp', 'wpsubdir',
'wpsubdomain']):
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
if pargs.php73 and stype in ['php73', 'mysql', 'wp',
'wpsubdir', 'wpsubdomain']:
Log.debug(self, "Setting apt_packages variable for PHP 7.3")
if not WOAptGet.is_installed(self, 'php7.3-fpm'):
if not WOAptGet.is_installed(self, 'php7.2-fpm'):
apt_packages = apt_packages + WOVar.wo_php + \
WOVar.wo_php73 + WOVar.wo_php_extra
else:
apt_packages = apt_packages + WOVar.wo_php73
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
if pargs.php74 and stype in ['php74', 'mysql', 'wp',
'wpsubdir', 'wpsubdomain']:
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
if stype in ['mysql', 'wp', 'wpsubdir', 'wpsubdomain']:
Log.debug(self, "Setting apt_packages variable for MySQL")
if not WOShellExec.cmd_exec(self, "/usr/bin/mysqladmin ping"):
if not WOVar.wo_distro == 'raspbian':
if (not WOVar.wo_platform_codename == 'jessie'):
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb", "mariadb-backup"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysql.connector"]
else:
wo_mysql = ["mariadb-server", "percona-toolkit",
"python3-mysqldb"]
apt_packages = apt_packages + wo_mysql
apt_packages = apt_packages + WOVar.wo_mysql
if stype in ['wp', 'wpsubdir', 'wpsubdomain']:
Log.debug(self, "Setting packages variable for WP-CLI")
if not WOShellExec.cmd_exec(self, "command -v wp"):
if not WOAptGet.is_exec(self, "wp"):
packages = packages + [["https://github.com/wp-cli/wp-cli/"
"releases/download/v{0}/"
"wp-cli-{0}.phar"
.format(WOVar.wo_wp_cli),
"/usr/local/bin/wp", "WP-CLI"]]
if self.app.pargs.wpredis:
if pargs.wpredis:
Log.debug(self, "Setting apt_packages variable for redis")
if not WOAptGet.is_installed(self, 'redis-server'):
apt_packages = apt_packages + ["redis-server"]
apt_packages = apt_packages + WOVar.wo_redis
if self.app.pargs.php73:
Log.debug(self, "Setting apt_packages variable for PHP 7.3")
if not WOAptGet.is_installed(self, 'php7.3-fpm'):
if not WOAptGet.is_installed(self, 'php7.2-fpm'):
apt_packages = apt_packages + WOVar.wo_php + \
WOVar.wo_php73 + WOVar.wo_php_extra
else:
apt_packages = apt_packages + WOVar.wo_php73
if self.app.pargs.ngxblocker:
if pargs.ngxblocker:
if not os.path.isdir('/etc/nginx/bots.d'):
Log.debug(self, "Setting packages variable for ngxblocker")
packages = packages + \
@ -1093,7 +1094,8 @@ def detSitePar(opts):
cachelist = list()
for key, val in opts.items():
if val and key in ['html', 'php', 'mysql', 'wp',
'wpsubdir', 'wpsubdomain', 'php73']:
'wpsubdir', 'wpsubdomain', 'php72',
'php73', 'php74']:
typelist.append(key)
elif val and key in ['wpfc', 'wpsc', 'wpredis', 'wprocket', 'wpce']:
cachelist.append(key)
@ -1109,24 +1111,48 @@ def detSitePar(opts):
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php72', 'mysql', 'html') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php73', 'mysql', 'html') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php74', 'mysql', 'html') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php', 'mysql') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php72', 'mysql') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php73', 'mysql') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php74', 'mysql') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('html', 'mysql') for x in typelist]:
sitetype = 'mysql'
if not cachelist:
@ -1139,12 +1165,6 @@ def detSitePar(opts):
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('php73', 'html') for x in typelist]:
sitetype = 'php73'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wp', 'wpsubdir') for x in typelist]:
sitetype = 'wpsubdir'
if not cachelist:
@ -1157,33 +1177,75 @@ def detSitePar(opts):
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wp', 'php72') for x in typelist]:
sitetype = 'wp'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wp', 'php73') for x in typelist]:
sitetype = 'wp'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wp', 'php74') for x in typelist]:
sitetype = 'wp'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wpsubdir', 'php72') for x in typelist]:
sitetype = 'wpsubdir'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wpsubdir', 'php73') for x in typelist]:
sitetype = 'wpsubdir'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wpsubdir', 'php74') for x in typelist]:
sitetype = 'wpsubdir'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wpsubdomain', 'php72') for x in typelist]:
sitetype = 'wpsubdomain'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wpsubdomain', 'php73') for x in typelist]:
sitetype = 'wpsubdomain'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
elif False not in [x in ('wpsubdomain', 'php74') for x in typelist]:
sitetype = 'wpsubdomain'
if not cachelist:
cachetype = 'basic'
else:
cachetype = cachelist[0]
else:
raise RuntimeError("could not determine site and cache type")
else:
if not typelist and not cachelist:
sitetype = None
cachetype = None
elif (not typelist or "php72" in typelist) and cachelist:
sitetype = 'wp'
cachetype = cachelist[0]
elif (not typelist or "php73" in typelist) and cachelist:
sitetype = 'wp'
cachetype = cachelist[0]
elif (not typelist or "php74" in typelist) and cachelist:
sitetype = 'wp'
cachetype = cachelist[0]
elif typelist and (not cachelist):
sitetype = typelist[0]
cachetype = 'basic'
@ -1208,6 +1270,13 @@ def generate_random():
return wo_random10
def generate_8_random():
wo_random8 = (''.join(random.sample(string.ascii_uppercase +
string.ascii_lowercase +
string.digits, 8)))
return wo_random8
def deleteDB(self, dbname, dbuser, dbhost, exit=True):
try:
# Check if Database exists
@ -1382,170 +1451,6 @@ def renewLetsEncrypt(self, wo_domain_name):
# redirect= False to disable https redirection
def httpsRedirect(self, wo_domain_name, redirect=True, wildcard=False):
if redirect:
if os.path.isfile("/etc/nginx/conf.d/force-ssl-{0}.conf.disabled"
.format(wo_domain_name)):
WOFileUtils.mvfile(self,
"/etc/nginx/conf.d/force-ssl-{0}.conf.disabled"
.format(wo_domain_name),
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
else:
Log.wait(self, "Adding HTTPS redirection")
if wildcard:
try:
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
sslconf.write("server {\n"
"\tlisten 80;\n" +
"\tlisten [::]:80;\n" +
"\tserver_name *.{0} {0};\n"
.format(wo_domain_name) +
"\treturn 301 https://$host"
"$request_uri;\n}")
sslconf.close()
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
else:
try:
sslconf = open("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
sslconf.write("server {\n"
"\tlisten 80;\n" +
"\tlisten [::]:80;\n" +
"\tserver_name www.{0} {0};\n"
.format(wo_domain_name) +
"\treturn 301 https://$host"
"$request_uri;\n}")
sslconf.close()
except IOError as e:
Log.failed(self, "Adding HTTPS redirection")
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
else:
Log.valide(self, "Adding HTTPS redirection")
# Nginx Configation into GIT
WOGit.add(self,
["/etc/nginx"], msg="Adding /etc/nginx/conf.d/"
"force-ssl-{0}.conf".format(wo_domain_name))
else:
if os.path.isfile("/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name)):
WOFileUtils.mvfile(self, "/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
"/etc/nginx/conf.d/force-ssl-{0}.conf.disabled"
.format(wo_domain_name))
Log.info(self, "Disabled HTTPS Force Redirection for Site "
" http://{0}".format(wo_domain_name))
def archivedCertificateHandle(self, domain):
Log.warn(
self, "You already have an existing certificate "
"for the domain requested.\n"
"(ref: {0}/"
"{1}_ecc/{1}.conf)".format(WOVar.wo_ssl_archive, domain) +
"\nPlease select an option from below?"
"\n\t1: Reinstall existing certificate"
"\n\t2: Issue a new certificate to replace "
"the current one (limit ~5 per 7 days)"
"")
check_prompt = input(
"\nType the appropriate number [1-2] or any other key to cancel: ")
if not os.path.isfile("{0}/{1}/fullchain.pem"
.format(WOVar.wo_ssl_live, domain)):
Log.error(
self, "{0}/{1}/fullchain.pem file is missing."
.format(WOVar.wo_ssl_live, domain))
if check_prompt == "1":
Log.info(self, "Reinstalling SSL cert with acme.sh")
ssl = WOAcme.deploycert(self, domain)
if ssl:
try:
if not os.path.isfile("/var/www/{0}/conf/nginx/ssl.conf"
.format(domain)):
Log.info(
self, "Adding /var/www/{0}/conf/nginx/ssl.conf"
.format(domain))
sslconf = open("/var/www/{0}/conf/nginx/ssl.conf"
.format(domain),
encoding='utf-8', mode='w')
sslconf.write("listen 443 ssl http2;\n"
"listen [::]:443 ssl http2;\n"
"ssl_certificate "
"{0}/{1}/fullchain.pem;\n"
"ssl_certificate_key {0}/{1}/key.pem;\n"
"ssl_trusted_certificate {0}/{1}/ca.pem;\n"
"ssl_stapling_verify on;\n"
.format(WOVar.wo_ssl_live, domain))
sslconf.close()
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while generating "
"ssl.conf")
elif (check_prompt == "2"):
Log.info(self, "Issuing SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(self, "/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--renew -d {0} --ecc "
"--force"
.format(domain))
if ssl:
try:
WOShellExec.cmd_exec(self, "mkdir -p {0}/{1} && "
"/etc/letsencrypt/acme.sh "
"--config-home "
"'/etc/letsencrypt/config' "
"--install-cert -d {1} --ecc "
"--cert-file {0}/{1}/cert.pem "
"--key-file {0}/{1}/key.pem "
"--fullchain-file "
"{0}/{1}/fullchain.pem "
"ssl_trusted_certificate "
"{0}/{1}/ca.pem;\n"
"--reloadcmd "
"\"nginx -t && service nginx restart\" "
.format(WOVar.wo_ssl_live, domain))
except IOError as e:
Log.debug(self, str(e))
Log.debug(self, "Error occured while installing "
"the certificate")
else:
Log.error(self, "Operation cancelled by user.")
if os.path.isfile("{0}/conf/nginx/ssl.conf"
.format(domain)):
Log.info(self, "Existing ssl.conf . Backing it up ..")
WOFileUtils.mvfile(self, "/var/www/{0}/conf/nginx/ssl.conf"
.format(domain),
'/var/www/{0}/conf/nginx/ssl.conf.bak'
.format(domain))
return ssl
def setuprocketchat(self):
if ((not WOVar.wo_platform_codename == 'bionic') and
(not WOVar.wo_platform_codename == 'xenial')):
@ -1557,6 +1462,7 @@ def setuprocketchat(self):
WOAptGet.install(self, ["snapd"])
if WOShellExec.cmd_exec(self, "snap install rocketchat-server"):
return True
return False
def setupngxblocker(self, domain, block=True):

File diff suppressed because it is too large Load Diff

View File

@ -41,8 +41,12 @@ class Meta:
dict(help='Install Nginx stack', action='store_true')),
(['--php'],
dict(help='Install PHP 7.2 stack', action='store_true')),
(['--php72'],
dict(help='Install PHP 7.2 stack', action='store_true')),
(['--php73'],
dict(help='Install PHP 7.3 stack', action='store_true')),
(['--php74'],
dict(help='Install PHP 7.4 stack', action='store_true')),
(['--mysql'],
dict(help='Install MySQL stack', action='store_true')),
(['--mysqlclient'],
@ -105,40 +109,40 @@ def default(self):
def install(self, packages=[], apt_packages=[], disp_msg=True):
"""Start installation of packages"""
self.msg = []
empty_packages = []
wo_webroot = "/var/www/"
pargs = self.app.pargs
try:
# Default action for stack installation
if ((not pargs.web) and (not pargs.admin) and
(not pargs.nginx) and (not pargs.php) and
(not pargs.mysql) and (not pargs.wpcli) and
(not pargs.phpmyadmin) and (not pargs.composer) and
(not pargs.netdata) and (not pargs.dashboard) and
(not pargs.fail2ban) and (not pargs.security) and
(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.clamav) and
(not pargs.cheat) and (not pargs.nanorc) and
(not pargs.ufw) and (not pargs.ngxblocker) and
(not pargs.phpredisadmin) and (not pargs.sendmail) and
(not pargs.php73) and (not pargs.all)):
if not (pargs.web or pargs.admin or pargs.nginx or
pargs.php or pargs.php72 or pargs.php73 or pargs.php74 or
pargs.mysql or pargs.wpcli or pargs.phpmyadmin or
pargs.composer or pargs.netdata or pargs.composer or
pargs.dashboard or pargs.fail2ban or pargs.security or
pargs.mysqlclient or pargs.mysqltuner or
pargs.admin or pargs.adminer or
pargs.utils or pargs.redis or
pargs.proftpd or pargs.extplorer or
pargs.clamav or pargs.cheat or pargs.nanorc or
pargs.ufw or pargs.ngxblocker or
pargs.phpredisadmin or pargs.sendmail or pargs.all):
pargs.web = True
pargs.admin = True
pargs.fail2ban = True
if pargs.php:
pargs.php72 = True
if pargs.all:
pargs.web = True
pargs.admin = True
pargs.php73 = True
pargs.php74 = True
pargs.redis = True
pargs.proftpd = True
if pargs.web:
pargs.nginx = True
pargs.php = True
pargs.php72 = True
pargs.mysql = True
pargs.wpcli = True
pargs.sendmail = True
@ -163,23 +167,8 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
# Nginx
if pargs.nginx:
Log.debug(self, "Setting apt_packages variable for Nginx")
if not (WOAptGet.is_installed(self, 'nginx-custom')):
if not (WOAptGet.is_installed(self, 'nginx-plus') or
WOAptGet.is_installed(self, 'nginx')):
if not os.path.isfile('/usr/sbin/nginx'):
apt_packages = apt_packages + WOVar.wo_nginx
else:
if WOAptGet.is_installed(self, 'nginx-plus'):
Log.info(self, "NGINX PLUS Detected ...")
apt = ["nginx-plus"] + WOVar.wo_nginx
post_pref(self, apt, empty_packages)
elif WOAptGet.is_installed(self, 'nginx'):
Log.info(self, "WordOps detected an already "
"installed nginx package."
"It may or may not have "
"required modules.\n")
apt = ["nginx"] + WOVar.wo_nginx
post_pref(self, apt, empty_packages)
if not WOAptGet.is_exec(self, 'nginx'):
apt_packages = apt_packages + WOVar.wo_nginx
else:
Log.debug(self, "Nginx already installed")
@ -192,11 +181,13 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
Log.info(self, "Redis already installed")
# PHP 7.2
if pargs.php:
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_php +
WOVar.wo_php_extra)
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
else:
Log.debug(self, "PHP 7.2 already installed")
Log.info(self, "PHP 7.2 already installed")
@ -205,13 +196,26 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
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_php +
WOVar.wo_php73 +
WOVar.wo_php_extra)
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
else:
Log.debug(self, "PHP 7.3 already installed")
Log.info(self, "PHP 7.3 already installed")
# PHP 7.4
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
else:
Log.debug(self, "PHP 7.4 already installed")
Log.info(self, "PHP 7.4 already installed")
# MariaDB 10.3
if pargs.mysql:
pargs.mysqltuner = True
@ -235,8 +239,7 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
# WP-CLI
if pargs.wpcli:
Log.debug(self, "Setting packages variable for WP-CLI")
if ((not os.path.isfile("/usr/local/bin/wp")) and
(not os.path.isfile("/usr/bin/wp"))):
if not WOAptGet.is_exec(self, 'wp'):
packages = packages + [["https://github.com/wp-cli/wp-cli/"
"releases/download/v{0}/"
"wp-cli-{0}.phar"
@ -328,9 +331,9 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
# Composer
if pargs.composer:
if not WOShellExec.cmd_exec(self, 'php -v'):
if not WOAptGet.is_exec(self, 'php'):
pargs.php = True
if not os.path.isfile('/usr/local/bin/composer'):
if not WOAptGet.is_exec(self, 'composer'):
Log.debug(self, "Setting packages variable for Composer ")
packages = packages + [["https://getcomposer.org/"
"installer",
@ -344,7 +347,7 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
if pargs.adminer:
if not os.path.isfile("{0}22222/htdocs/db/"
"adminer/index.php"
.format(wo_webroot)):
.format(WOVar.wo_webroot)):
Log.debug(self, "Setting packages variable for Adminer ")
packages = packages + [[
"https://github.com/vrana/adminer/"
@ -434,6 +437,8 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
# ultimate ngx_blocker
if pargs.ngxblocker:
if not WOAptGet.is_exec(self, 'nginx'):
pargs.nginx = True
if not os.path.isdir('/etc/nginx/bots.d'):
Log.debug(self, "Setting packages variable for ngxblocker")
packages = packages + \
@ -468,6 +473,12 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
# UTILS
if pargs.utils:
if not WOShellExec.cmd_exec(self, 'mysqladmin ping'):
pargs.mysql = True
if not (WOAptGet.is_installed(self, 'php7.2-fpm') or
WOAptGet.is_installed(self, 'php7.3-fpm') or
WOAptGet.is_installed(self, 'php7.4-fpm')):
pargs.php = True
Log.debug(self, "Setting packages variable for utils")
packages = packages + [[
"https://raw.githubusercontent.com"
@ -524,9 +535,7 @@ def install(self, packages=[], apt_packages=[], disp_msg=True):
Log.wait(self, "Installing APT packages ")
WOAptGet.install(self, apt_packages)
Log.valide(self, "Installing APT packages ")
Log.wait(self, "Configuring APT packages ")
post_pref(self, apt_packages, [])
Log.valide(self, "Configuring APT packages ")
if (packages):
Log.debug(self, "Downloading following: {0}".format(packages))
WODownload.download(self, packages)
@ -563,13 +572,18 @@ def remove(self):
(not pargs.cheat) and (not pargs.nanorc) and
(not pargs.ufw) and (not pargs.ngxblocker) and
(not pargs.phpredisadmin) and (not pargs.sendmail) and
(not pargs.php73) and (not pargs.all)):
(not pargs.php73) and (not pargs.php74) and
(not pargs.php72) and (not pargs.all)):
self.app.args.print_help()
if pargs.php:
pargs.php72 = True
if pargs.all:
pargs.web = True
pargs.admin = True
pargs.php73 = True
pargs.php74 = True
pargs.fail2ban = True
pargs.proftpd = True
pargs.utils = True
@ -580,7 +594,7 @@ def remove(self):
if pargs.web:
pargs.nginx = True
pargs.php = True
pargs.php72 = True
pargs.mysql = True
pargs.wpcli = True
pargs.sendmail = True
@ -605,24 +619,40 @@ def remove(self):
apt_packages = apt_packages + WOVar.wo_nginx
# PHP 7.2
if pargs.php:
Log.debug(self, "Removing apt_packages variable of PHP")
if WOAptGet.is_installed(self, 'php7.2-fpm'):
if not WOAptGet.is_installed(self, 'php7.3-fpm'):
apt_packages = apt_packages + WOVar.wo_php + \
WOVar.wo_php_extra
else:
apt_packages = apt_packages + WOVar.wo_php
if pargs.php72:
Log.debug(self, "Setting apt_packages variable for PHP 7.2")
if (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
else:
Log.debug(self, "PHP 7.2 is not installed")
Log.info(self, "PHP 7.2 is not installed")
# PHP7.3
# PHP 7.3
if pargs.php73:
Log.debug(self, "Removing apt_packages variable of PHP 7.3")
Log.debug(self, "Setting apt_packages variable for PHP 7.3")
if WOAptGet.is_installed(self, 'php7.3-fpm'):
if not (WOAptGet.is_installed(self, 'php7.2-fpm')):
apt_packages = apt_packages + WOVar.wo_php73 + \
WOVar.wo_php_extra
else:
apt_packages = apt_packages + WOVar.wo_php73
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
else:
Log.debug(self, "PHP 7.3 is not installed")
Log.info(self, "PHP 7.3 is not installed")
# PHP 7.4
if pargs.php74:
Log.debug(self, "Setting apt_packages variable for PHP 7.4")
if 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
else:
Log.debug(self, "PHP 7.4 is not installed")
Log.info(self, "PHP 7.4 is not installed")
# REDIS
if pargs.redis:
@ -634,9 +664,7 @@ def remove(self):
if pargs.mysql:
if WOAptGet.is_installed(self, 'mariadb-server'):
Log.debug(self, "Removing apt_packages variable of MySQL")
apt_packages = apt_packages + ['mariadb-server',
'mysql-common',
'mariadb-client']
apt_packages = apt_packages + WOVar.wo_mysql
# mysqlclient
if pargs.mysqlclient:
@ -849,13 +877,18 @@ def purge(self):
(not pargs.cheat) and (not pargs.nanorc) and
(not pargs.ufw) and (not pargs.ngxblocker) and
(not pargs.phpredisadmin) and (not pargs.sendmail) and
(not pargs.php73) and (not pargs.all)):
(not pargs.php73) and (not pargs.php74) and
(not pargs.php72) and (not pargs.all)):
self.app.args.print_help()
if pargs.php:
pargs.php72 = True
if pargs.all:
pargs.web = True
pargs.admin = True
pargs.php73 = True
pargs.php74 = True
pargs.fail2ban = True
pargs.proftpd = True
pargs.utils = True
@ -864,7 +897,7 @@ def purge(self):
if pargs.web:
pargs.nginx = True
pargs.php = True
pargs.php72 = True
pargs.mysql = True
pargs.wpcli = True
pargs.sendmail = True
@ -875,6 +908,7 @@ def purge(self):
pargs.netdata = True
pargs.mysqltuner = True
pargs.cheat = True
packages = packages + ['/var/www/22222/htdocs']
if pargs.security:
pargs.fail2ban = True
@ -890,25 +924,41 @@ def purge(self):
else:
Log.info(self, "Nginx is not installed")
# PHP
if pargs.php:
Log.debug(self, "Add PHP to apt_packages list")
if WOAptGet.is_installed(self, 'php7.2-fpm'):
if not (WOAptGet.is_installed(self, 'php7.3-fpm')):
apt_packages = apt_packages + WOVar.wo_php + \
WOVar.wo_php_extra
else:
apt_packages = apt_packages + WOVar.wo_php
# PHP 7.2
if pargs.php72:
Log.debug(self, "Setting apt_packages variable for PHP 7.2")
if (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
else:
Log.debug(self, "PHP 7.2 is not installed")
Log.info(self, "PHP 7.2 is not installed")
# PHP 7.3
if pargs.php73:
Log.debug(self, "Removing apt_packages variable of PHP 7.3")
Log.debug(self, "Setting apt_packages variable for PHP 7.3")
if WOAptGet.is_installed(self, 'php7.3-fpm'):
if not (WOAptGet.is_installed(self, 'php7.2-fpm')):
apt_packages = apt_packages + WOVar.wo_php73 + \
WOVar.wo_php_extra
else:
apt_packages = apt_packages + WOVar.wo_php73
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
else:
Log.debug(self, "PHP 7.3 is not installed")
Log.info(self, "PHP 7.3 is not installed")
# PHP 7.4
if pargs.php74:
Log.debug(self, "Setting apt_packages variable for PHP 7.4")
if 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
else:
Log.debug(self, "PHP 7.4 is not installed")
Log.info(self, "PHP 7.4 is not installed")
# REDIS
if pargs.redis:

View File

@ -20,6 +20,7 @@
from wo.core.sslutils import SSL
from wo.core.template import WOTemplate
from wo.core.variables import WOVar
from wo.core.stackconf import WOConf
def pre_pref(self, apt_packages):
@ -112,8 +113,8 @@ def pre_pref(self, apt_packages):
WORepo.add_key(self, WOVar.wo_nginx_key)
# add php repository
if (set(WOVar.wo_php73).issubset(set(apt_packages)) or
set(WOVar.wo_php).issubset(set(apt_packages))):
if (('php7.3-fpm' in apt_packages) or
('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(
@ -182,13 +183,13 @@ def post_pref(self, apt_packages, packages, upgrade=False):
ngxcom = '/etc/nginx/common'
ngxroot = '/var/www/'
WOGit.add(self, ["/etc/nginx"], msg="Adding Nginx into Git")
data = dict(tls13=True)
data = dict(tls13=True, release=WOVar.wo_version)
WOTemplate.deploy(self,
'/etc/nginx/nginx.conf',
'nginx-core.mustache', data)
if not os.path.isfile('{0}/gzip.conf.disabled'.format(ngxcnf)):
data = dict()
data = dict(release=WOVar.wo_version)
WOTemplate.deploy(self, '{0}/gzip.conf'.format(ngxcnf),
'gzip.mustache', data)
@ -210,17 +211,19 @@ def post_pref(self, apt_packages, packages, upgrade=False):
'\t$request_filename;\n')
try:
data = dict(php="9000", debug="9001",
php7="9070", debug7="9170")
php7="9070", debug7="9170",
release=WOVar.wo_version)
WOTemplate.deploy(
self, '{0}/upstream.conf'.format(ngxcnf),
'upstream.mustache', data, overwrite=True)
data = dict(phpconf=(
bool(WOAptGet.is_installed(self, 'php7.2-fpm'))))
bool(WOAptGet.is_installed(self, 'php7.2-fpm'))),
release=WOVar.wo_version)
WOTemplate.deploy(
self, '{0}/stub_status.conf'.format(ngxcnf),
'stub_status.mustache', data)
data = dict()
data = dict(release=WOVar.wo_version)
WOTemplate.deploy(
self, '{0}/webp.conf'.format(ngxcnf),
'webp.mustache', data, overwrite=False)
@ -243,7 +246,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
os.makedirs('/etc/nginx/common')
try:
data = dict()
data = dict(release=WOVar.wo_version)
# Common Configuration
WOTemplate.deploy(self,
@ -255,89 +258,52 @@ def post_pref(self, apt_packages, packages, upgrade=False):
'{0}/wpsubdir.conf'
.format(ngxcom),
'wpsubdir.mustache', data)
data = dict(upstream="php72")
# PHP 7.2 conf
WOTemplate.deploy(self,
'{0}/php72.conf'
.format(ngxcom),
'php.mustache', data)
WOTemplate.deploy(self,
'{0}/redis-php72.conf'
.format(ngxcom),
'redis.mustache', data)
wo_php_version = ["php72", "php73", "php74"]
for wo_php in wo_php_version:
data = dict(upstream="{0}".format(wo_php),
release=WOVar.wo_version)
WOTemplate.deploy(self,
'{0}/{1}.conf'
.format(ngxcom, wo_php),
'php.mustache', data)
WOTemplate.deploy(self,
'{0}/wpcommon-php72.conf'
.format(ngxcom),
'wpcommon.mustache', data)
WOTemplate.deploy(
self, '{0}/redis-{1}.conf'.format(ngxcom, wo_php),
'redis.mustache', data)
WOTemplate.deploy(self,
'{0}/wpfc-php72.conf'
.format(ngxcom),
'wpfc.mustache', data)
WOTemplate.deploy(self,
'{0}/wpsc-php72.conf'
.format(ngxcom),
'wpsc.mustache', data)
WOTemplate.deploy(
self, '{0}/wpcommon-{1}.conf'.format(ngxcom, wo_php),
'wpcommon.mustache', data)
WOTemplate.deploy(self,
'{0}/wprocket-php72.conf'
.format(ngxcom),
'wprocket.mustache', data)
WOTemplate.deploy(
self, '{0}/wpfc-{1}.conf'.format(ngxcom, wo_php),
'wpfc.mustache', data)
WOTemplate.deploy(self,
'{0}/wpce-php72.conf'
.format(ngxcom),
'wpce.mustache', data)
# PHP 7.3 conf
data = dict(upstream="php73")
WOTemplate.deploy(
self, '{0}/wpsc-{1}.conf'.format(ngxcom, wo_php),
'wpsc.mustache', data)
WOTemplate.deploy(self,
'{0}/php73.conf'
.format(ngxcom),
'php.mustache', data)
WOTemplate.deploy(
self, '{0}/wprocket-{1}.conf'.format(ngxcom, wo_php),
'wprocket.mustache', data)
WOTemplate.deploy(self,
'{0}/redis-php73.conf'
.format(ngxcom),
'redis.mustache', data)
WOTemplate.deploy(
self, '{0}/wpce-{1}.conf'.format(ngxcom, wo_php),
'wpce.mustache', data)
WOTemplate.deploy(self,
'{0}/wpcommon-php73.conf'
.format(ngxcom),
'wpcommon.mustache', data)
WOTemplate.deploy(self,
'{0}/wpfc-php73.conf'
.format(ngxcom),
'wpfc.mustache', data)
WOTemplate.deploy(self,
'{0}/wpsc-php73.conf'
.format(ngxcom),
'wpsc.mustache', data)
WOTemplate.deploy(self,
'{0}/wprocket-php73.conf'
.format(ngxcom),
'wprocket.mustache', data)
WOTemplate.deploy(self,
'{0}/wpce-php73.conf'
.format(ngxcom),
'wpce.mustache', data)
except CommandExecutionError as e:
Log.debug(self, "{0}".format(e))
with open("/etc/nginx/common/release",
"w") as release_file:
"w", encoding='utf-8') as release_file:
release_file.write("v{0}"
.format(WOVar.wo_version))
release_file.close()
# Following files should not be overwrited
data = dict(webroot=ngxroot)
data = dict(webroot=ngxroot, release=WOVar.wo_version)
WOTemplate.deploy(self,
'{0}/acl.conf'
.format(ngxcom),
@ -383,7 +349,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
os.makedirs('/etc/nginx/sites-enabled')
# 22222 port settings
data = dict(webroot=ngxroot)
data = dict(webroot=ngxroot, release=WOVar.wo_version)
WOTemplate.deploy(
self,
'/etc/nginx/sites-available/22222',
@ -488,7 +454,7 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOVar.wo_fqdn)])
if not os.path.isfile("/opt/cf-update.sh"):
data = dict()
data = dict(release=WOVar.wo_version)
WOTemplate.deploy(self, '/opt/cf-update.sh',
'cf-update.mustache',
data, overwrite=False)
@ -528,10 +494,11 @@ def post_pref(self, apt_packages, packages, upgrade=False):
WOShellExec.cmd_exec(self, 'systemctl daemon-reload')
WOService.restart_service(self, 'nginx')
if set(WOVar.wo_php).issubset(set(apt_packages)):
if set(WOVar.wo_php72).issubset(set(apt_packages)):
WOGit.add(self, ["/etc/php"], msg="Adding PHP into Git")
Log.info(self, "Configuring php7.2-fpm")
ngxroot = '/var/www/'
# Create log directories
if not os.path.exists('/var/log/php/7.2/'):
Log.debug(self, 'Creating directory /var/log/php/7.2/')
@ -800,6 +767,153 @@ def post_pref(self, apt_packages, packages, upgrade=False):
else:
WOGit.add(self, ["/etc/php"], msg="Adding PHP into Git")
# PHP7.4 configuration
# php7.4 configuration
if set(WOVar.wo_php74).issubset(set(apt_packages)):
WOGit.add(self, ["/etc/php"], msg="Adding PHP into Git")
Log.info(self, "Configuring php7.4-fpm")
ngxroot = '/var/www/'
# Create log directories
if not os.path.exists('/var/log/php/7.4/'):
Log.debug(self, 'Creating directory /var/log/php/7.4/')
os.makedirs('/var/log/php/7.4/')
if not os.path.isfile('/etc/php/7.4/fpm/php.ini.orig'):
WOFileUtils.copyfile(self, '/etc/php/7.4/fpm/php.ini',
'/etc/php/7.4/fpm/php.ini.orig')
# Parse etc/php/7.4/fpm/php.ini
config = configparser.ConfigParser()
Log.debug(self, "configuring php file /etc/php/7.4/"
"fpm/php.ini")
config.read('/etc/php/7.4/fpm/php.ini.orig')
config['PHP']['expose_php'] = 'Off'
config['PHP']['post_max_size'] = '100M'
config['PHP']['upload_max_filesize'] = '100M'
config['PHP']['max_execution_time'] = '300'
config['PHP']['max_input_time'] = '300'
config['PHP']['max_input_vars'] = '20000'
config['Date']['date.timezone'] = WOVar.wo_timezone
config['opcache']['opcache.enable'] = '1'
config['opcache']['opcache.interned_strings_buffer'] = '8'
config['opcache']['opcache.max_accelerated_files'] = '10000'
config['opcache']['opcache.memory_consumption'] = '256'
config['opcache']['opcache.save_comments'] = '1'
config['opcache']['opcache.revalidate_freq'] = '5'
config['opcache']['opcache.consistency_checks'] = '0'
config['opcache']['opcache.validate_timestamps'] = '1'
with open('/etc/php/7.4/fpm/php.ini',
encoding='utf-8', mode='w') as configfile:
Log.debug(self, "Writting php configuration into "
"/etc/php/7.4/fpm/php.ini")
config.write(configfile)
# Render php-fpm pool template for php7.4
data = dict(pid="/run/php/php7.4-fpm.pid",
error_log="/var/log/php7.4-fpm.log",
include="/etc/php/7.4/fpm/pool.d/*.conf")
WOTemplate.deploy(
self, '/etc/php/7.4/fpm/php-fpm.conf',
'php-fpm.mustache', data)
data = dict(pool='www-php74', listen='php74-fpm.sock',
user='www-data',
group='www-data', listenuser='root',
listengroup='www-data', openbasedir=True)
WOTemplate.deploy(self, '/etc/php/7.4/fpm/pool.d/www.conf',
'php-pool.mustache', data)
data = dict(pool='www-two-php74', listen='php74-two-fpm.sock',
user='www-data',
group='www-data', listenuser='root',
listengroup='www-data', openbasedir=True)
WOTemplate.deploy(self, '/etc/php/7.4/fpm/pool.d/www-two.conf',
'php-pool.mustache', data)
# Generate /etc/php/7.4/fpm/pool.d/debug.conf
WOFileUtils.copyfile(self, "/etc/php/7.4/fpm/pool.d/www.conf",
"/etc/php/7.4/fpm/pool.d/debug.conf")
WOFileUtils.searchreplace(self, "/etc/php/7.4/fpm/pool.d/"
"debug.conf", "[www-php74]", "[debug]")
config = configparser.ConfigParser()
config.read('/etc/php/7.4/fpm/pool.d/debug.conf')
config['debug']['listen'] = '127.0.0.1:9174'
config['debug']['rlimit_core'] = 'unlimited'
config['debug']['slowlog'] = '/var/log/php/7.4/slow.log'
config['debug']['request_slowlog_timeout'] = '10s'
with open('/etc/php/7.4/fpm/pool.d/debug.conf',
encoding='utf-8', mode='w') as confifile:
Log.debug(self, "writting PHP 7.4 configuration into "
"/etc/php/7.4/fpm/pool.d/debug.conf")
config.write(confifile)
with open("/etc/php/7.4/fpm/pool.d/debug.conf",
encoding='utf-8', mode='a') as myfile:
myfile.write(
"php_admin_value[xdebug.profiler_output_dir] "
"= /tmp/ \nphp_admin_value[xdebug.profiler_"
"output_name] = cachegrind.out.%p-%H-%R "
"\nphp_admin_flag[xdebug.profiler_enable"
"_trigger] = on \nphp_admin_flag[xdebug."
"profiler_enable] = off\n")
# Disable xdebug
if not WOShellExec.cmd_exec(
self, "grep -q \';zend_extension\'"
" /etc/php/7.4/mods-available/xdebug.ini"):
WOFileUtils.searchreplace(
self, "/etc/php/7.4/mods-available/"
"xdebug.ini",
"zend_extension", ";zend_extension")
# PHP and Debug pull configuration
if not os.path.exists('{0}22222/htdocs/fpm/status/'
.format(ngxroot)):
Log.debug(self, 'Creating directory '
'{0}22222/htdocs/fpm/status/ '
.format(ngxroot))
os.makedirs('{0}22222/htdocs/fpm/status/'
.format(ngxroot))
open('{0}22222/htdocs/fpm/status/debug74'
.format(ngxroot),
encoding='utf-8', mode='a').close()
open('{0}22222/htdocs/fpm/status/php74'
.format(ngxroot),
encoding='utf-8', mode='a').close()
# Write info.php
if not os.path.exists('{0}22222/htdocs/php/'
.format(ngxroot)):
Log.debug(self, 'Creating directory '
'{0}22222/htdocs/php/ '
.format(ngxroot))
os.makedirs('{0}22222/htdocs/php'
.format(ngxroot))
WOFileUtils.textwrite(
self, "{0}22222/htdocs/php/info.php"
.format(ngxroot), "<?php\nphpinfo();\n?>")
WOFileUtils.chown(self, "{0}22222/htdocs"
.format(ngxroot),
'www-data',
'www-data', recursive=True)
# check service restart or rollback configuration
if not WOService.restart_service(self, 'php7.4-fpm'):
WOGit.rollback(self, ["/etc/php"], msg="Rollback PHP")
else:
WOGit.add(self, ["/etc/php"], msg="Adding PHP into Git")
if os.path.exists('/etc/nginx/conf.d/upstream.conf'):
if not WOFileUtils.grepcheck(
self, '/etc/nginx/conf.d/upstream.conf', 'php74'):
data = dict(php="9000", debug="9001",
php7="9070", debug7="9170",
release=WOVar.wo_version)
WOTemplate.deploy(
self, '/etc/nginx/conf.d/upstream.conf',
'upstream.mustache', data, True)
WOConf.nginxcommon(self)
# create mysql config if it doesn't exist
if "mariadb-server" in apt_packages:
WOGit.add(self, ["/etc/mysql"], msg="Adding MySQL into Git")
@ -812,6 +926,23 @@ def post_pref(self, apt_packages, packages, upgrade=False):
config_file.write(config)
config_file.close()
else:
if "PASSWORD" not in WOShellExec.cmd_exec_stdout(
self, 'mysql -e "use mysql; show grants;"'):
try:
if not os.path.exists('/etc/mysql/conf.d/my.cnf'):
Log.error(self, 'my.cnf not found')
config = configparser.ConfigParser()
config.read('/etc/mysql/conf.d/my.cnf')
chars = config['client']['password']
WOShellExec.cmd_exec(
self, "mysql -e \"use mysql; "
"GRANT ALL PRIVILEGES on "
"*.* TO 'root'@'127.0.0.1' IDENTIFIED by "
"'{0}' WITH GRANT OPTION\"".format(chars))
WOShellExec.cmd_exec(
self, 'mysql -e "flush privileges;"')
except CommandExecutionError:
Log.error(self, "Unable to set MySQL password")
Log.info(self, "Tuning MariaDB configuration")
if not os.path.isfile("/etc/mysql/my.cnf.default-pkg"):
WOFileUtils.copyfile(self, "/etc/mysql/my.cnf",
@ -867,11 +998,12 @@ def post_pref(self, apt_packages, packages, upgrade=False):
# create fail2ban configuration files
if set(WOVar.wo_fail2ban).issubset(set(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()
data = dict(release=WOVar.wo_version)
WOTemplate.deploy(
self,
'/etc/fail2ban/jail.d/custom.conf',
@ -1463,7 +1595,7 @@ def pre_stack(self):
if wo_check is False:
# wo sysctl tweaks
# check system type
wo_arch = bool(os.uname()[4] == 'x86_x64')
wo_arch = bool((os.uname()[4]) == 'x86_64')
if os.path.isfile('/proc/1/environ'):
# detect lxc containers
wo_lxc = WOFileUtils.grepcheck(

View File

@ -4,6 +4,7 @@
from wo.core.logging import Log
from wo.core.services import WOService
from wo.core.variables import WOVar
from wo.core.fileutils import WOFileUtils
class WOStackStatusController(CementBaseController):
@ -20,17 +21,21 @@ def start(self):
wo_system = "/lib/systemd/system/"
pargs = self.app.pargs
if not (pargs.nginx or pargs.php or
pargs.php72 or
pargs.php73 or
pargs.php74 or
pargs.mysql or
pargs.redis or
pargs.fail2ban or
pargs.proftpd or
pargs.netdata):
pargs.netdata or
pargs.ufw):
pargs.nginx = True
pargs.php = True
pargs.mysql = True
pargs.fail2ban = True
pargs.netdata = True
pargs.ufw = True
if pargs.nginx:
if os.path.exists('{0}'.format(wo_system) + 'nginx.service'):
@ -47,6 +52,16 @@ def start(self):
services = services + ['php7.3-fpm']
else:
Log.info(self, "PHP7.3-FPM is not installed")
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.php72:
if os.path.exists('{0}'.format(wo_system) + 'php7.2-fpm.service'):
services = services + ['php7.2-fpm']
else:
Log.info(self, "PHP7.2-FPM is not installed")
if pargs.php73:
if os.path.exists('{0}'.format(wo_system) + 'php7.3-fpm.service'):
@ -54,6 +69,12 @@ def start(self):
else:
Log.info(self, "PHP7.3-FPM is not installed")
if pargs.php74:
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.mysql:
if ((WOVar.wo_mysql_host == "localhost") or
(WOVar.wo_mysql_host == "127.0.0.1")):
@ -103,7 +124,8 @@ def stop(self):
wo_system = "/lib/systemd/system/"
pargs = self.app.pargs
if not (pargs.nginx or pargs.php or
pargs.php73 or
pargs.php72 or pargs.php73 or
pargs.php74 or
pargs.mysql or
pargs.fail2ban or
pargs.netdata or
@ -128,6 +150,16 @@ def stop(self):
services = services + ['php7.3-fpm']
else:
Log.info(self, "PHP7.3-FPM is not installed")
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.php72:
if os.path.exists('{0}'.format(wo_system) + 'php7.2-fpm.service'):
services = services + ['php7.2-fpm']
else:
Log.info(self, "PHP7.2-FPM is not installed")
if pargs.php73:
if os.path.exists('{0}'.format(wo_system) + 'php7.3-fpm.service'):
@ -135,6 +167,12 @@ def stop(self):
else:
Log.info(self, "PHP7.3-FPM is not installed")
if pargs.php74:
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.mysql:
if ((WOVar.wo_mysql_host == "localhost") or
(WOVar.wo_mysql_host == "127.0.0.1")):
@ -184,7 +222,8 @@ def restart(self):
wo_system = "/lib/systemd/system/"
pargs = self.app.pargs
if not (pargs.nginx or pargs.php or
pargs.php73 or
pargs.php72 or pargs.php73 or
pargs.php74 or
pargs.mysql or
pargs.netdata or
pargs.proftpd or
@ -210,6 +249,16 @@ def restart(self):
services = services + ['php7.3-fpm']
else:
Log.info(self, "PHP7.3-FPM is not installed")
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.php72:
if os.path.exists('{0}'.format(wo_system) + 'php7.2-fpm.service'):
services = services + ['php7.2-fpm']
else:
Log.info(self, "PHP7.2-FPM is not installed")
if pargs.php73:
if os.path.exists('{0}'.format(wo_system) + 'php7.3-fpm.service'):
@ -217,6 +266,12 @@ def restart(self):
else:
Log.info(self, "PHP7.3-FPM is not installed")
if pargs.php74:
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.mysql:
if ((WOVar.wo_mysql_host == "localhost") or
(WOVar.wo_mysql_host == "127.0.0.1")):
@ -266,7 +321,9 @@ def status(self):
wo_system = "/lib/systemd/system/"
pargs = self.app.pargs
if not (pargs.nginx or pargs.php or
pargs.php72 or
pargs.php73 or
pargs.php74 or
pargs.mysql or
pargs.netdata or
pargs.proftpd or
@ -277,6 +334,7 @@ def status(self):
pargs.mysql = True
pargs.fail2ban = True
pargs.netdata = True
pargs.ufw = True
if pargs.nginx:
if os.path.exists('{0}'.format(wo_system) + 'nginx.service'):
@ -293,6 +351,16 @@ def status(self):
services = services + ['php7.3-fpm']
else:
Log.info(self, "PHP7.3-FPM is not installed")
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.php72:
if os.path.exists('{0}'.format(wo_system) + 'php7.2-fpm.service'):
services = services + ['php7.2-fpm']
else:
Log.info(self, "PHP7.2-FPM is not installed")
if pargs.php73:
if os.path.exists('{0}'.format(wo_system) + 'php7.3-fpm.service'):
@ -300,6 +368,12 @@ def status(self):
else:
Log.info(self, "PHP7.3-FPM is not installed")
if pargs.php74:
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.mysql:
if ((WOVar.wo_mysql_host == "localhost") or
(WOVar.wo_mysql_host == "127.0.0.1")):
@ -338,6 +412,17 @@ def status(self):
else:
Log.info(self, "Netdata is not installed")
# UFW
if pargs.ufw:
if os.path.exists('/usr/sbin/ufw'):
if WOFileUtils.grepcheck(
self, '/etc/ufw/ufw.conf', 'ENABLED=yes'):
Log.info(self, "UFW Firewall is enabled")
else:
Log.info(self, "UFW Firewall is disabled")
else:
Log.info(self, "UFW is not installed")
for service in services:
if WOService.get_service_status(self, service):
Log.info(self, "{0:10}: {1}".format(service, "Running"))
@ -349,7 +434,8 @@ def reload(self):
wo_system = "/lib/systemd/system/"
pargs = self.app.pargs
if not (pargs.nginx or pargs.php or
pargs.php73 or
pargs.php72 or pargs.php73 or
pargs.php74 or
pargs.mysql or
pargs.netdata or
pargs.proftpd or
@ -375,6 +461,16 @@ def reload(self):
services = services + ['php7.3-fpm']
else:
Log.info(self, "PHP7.3-FPM is not installed")
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.php72:
if os.path.exists('{0}'.format(wo_system) + 'php7.2-fpm.service'):
services = services + ['php7.2-fpm']
else:
Log.info(self, "PHP7.2-FPM is not installed")
if pargs.php73:
if os.path.exists('{0}'.format(wo_system) + 'php7.3-fpm.service'):
@ -382,6 +478,12 @@ def reload(self):
else:
Log.info(self, "PHP7.3-FPM is not installed")
if pargs.php74:
if os.path.exists('{0}'.format(wo_system) + 'php7.4-fpm.service'):
services = services + ['php7.4-fpm']
else:
Log.info(self, "PHP7.4-FPM is not installed")
if pargs.mysql:
if ((WOVar.wo_mysql_host == "localhost") or
(WOVar.wo_mysql_host == "127.0.0.1")):

View File

@ -30,8 +30,12 @@ class Meta:
dict(help='Upgrade Nginx stack', action='store_true')),
(['--php'],
dict(help='Upgrade PHP 7.2 stack', action='store_true')),
(['--php72'],
dict(help='Upgrade PHP 7.2 stack', action='store_true')),
(['--php73'],
dict(help='Upgrade PHP 7.3 stack', action='store_true')),
(['--php74'],
dict(help='Upgrade PHP 7.4 stack', action='store_true')),
(['--mysql'],
dict(help='Upgrade MySQL stack', action='store_true')),
(['--wpcli'],
@ -44,8 +48,12 @@ class Meta:
dict(help='Upgrade WordOps Dashboard', action='store_true')),
(['--composer'],
dict(help='Upgrade Composer', action='store_true')),
(['--mysqltuner'],
dict(help='Upgrade Composer', action='store_true')),
(['--phpmyadmin'],
dict(help='Upgrade phpMyAdmin', action='store_true')),
(['--adminer'],
dict(help='Upgrade Adminer', action='store_true')),
(['--ngxblocker'],
dict(help='Upgrade phpMyAdmin', action='store_true')),
(['--no-prompt'],
@ -63,27 +71,33 @@ def default(self, disp_msg=False):
packages = []
self.msg = []
pargs = self.app.pargs
if ((not pargs.web) and (not pargs.nginx) and
(not pargs.php) and (not pargs.php73) 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.dashboard) and
(not pargs.phpmyadmin) and (not pargs.adminer) and
(not pargs.dashboard) and (not pargs.mysqltuner) and
(not pargs.redis)):
pargs.web = True
pargs.admin = True
if pargs.php:
pargs.php72 = True
if pargs.all:
pargs.web = True
pargs.admin = True
pargs.redis = True
pargs.php73 = True
pargs.ngxblocker = True
if pargs.web:
pargs.nginx = True
pargs.php = True
pargs.php72 = True
pargs.php73 = True
pargs.php74 = True
pargs.mysql = True
pargs.wpcli = True
@ -93,6 +107,8 @@ def default(self, disp_msg=False):
pargs.dashboard = True
pargs.phpmyadmin = True
pargs.wpcli = True
pargs.adminer = True
pargs.mysqltuner = True
# nginx
if pargs.nginx:
@ -106,34 +122,32 @@ def default(self, disp_msg=False):
Log.info(self, "Nginx Stable is not already installed")
# php 7.2
if pargs.php:
if pargs.php72:
if WOAptGet.is_installed(self, 'php7.2-fpm'):
apt_packages = apt_packages + WOVar.wo_php + \
apt_packages = apt_packages + WOVar.wo_php72 + \
WOVar.wo_php_extra
else:
Log.info(self, "PHP 7.2 is not installed")
# php 7.3
if pargs.php73:
if WOAptGet.is_installed(self, 'php7.3-fpm'):
apt_packages = apt_packages + WOVar.wo_php73 + \
WOVar.wo_php_extra
else:
Log.info(self, "PHP 7.3 is not installed")
# php 7.4
if pargs.php74:
if WOAptGet.is_installed(self, 'php7.4-fpm'):
apt_packages = apt_packages + WOVar.wo_php74 + \
WOVar.wo_php_extra
# mysql
if pargs.mysql:
if WOShellExec.cmd_exec(self, 'mysqladmin ping'):
apt_packages = apt_packages + ['mariadb-server']
else:
Log.info(self, "MariaDB is not installed")
# redis
if pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
apt_packages = apt_packages + ['redis-server']
else:
Log.info(self, "Redis is not installed")
# wp-cli
if pargs.wpcli:
@ -188,6 +202,32 @@ def default(self, disp_msg=False):
else:
Log.info(self, "phpMyAdmin isn't installed")
# adminer
if pargs.adminer:
if os.path.isfile("{0}22222/htdocs/db/"
"adminer/index.php"
.format(WOVar.wo_webroot)):
Log.debug(self, "Setting packages variable for Adminer ")
packages = packages + [[
"https://github.com/vrana/adminer/"
"releases/download/v{0}"
"/adminer-{0}.php"
.format(WOVar.wo_adminer),
"{0}22222/"
"htdocs/db/adminer/index.php"
.format(WOVar.wo_webroot),
"Adminer"],
["https://raw.githubusercontent.com"
"/vrana/adminer/master/designs/"
"pepa-linha/adminer.css",
"{0}22222/"
"htdocs/db/adminer/adminer.css"
.format(WOVar.wo_webroot),
"Adminer theme"]]
else:
Log.debug(self, "Adminer isn't installed")
Log.info(self, "Adminer isn't installed")
# composer
if pargs.composer:
if os.path.isfile('/usr/local/bin/composer'):
@ -198,6 +238,18 @@ def default(self, disp_msg=False):
else:
Log.info(self, "Composer isn't installed")
# mysqltuner
if pargs.mysqltuner:
if WOAptGet.is_exec(self, 'mysqltuner'):
Log.debug(self, "Setting packages variable "
"for MySQLTuner ")
packages = packages + [["https://raw."
"githubusercontent.com/"
"major/MySQLTuner-perl"
"/master/mysqltuner.pl",
"/usr/bin/mysqltuner",
"MySQLTuner"]]
# ngxblocker
if pargs.ngxblocker:
if os.path.exists('/usr/local/sbin/install-ngxblocker'):
@ -217,6 +269,8 @@ def default(self, disp_msg=False):
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)):
pass
@ -243,6 +297,9 @@ def default(self, disp_msg=False):
if "php7.3-fpm" in apt_packages:
WOAptGet.remove(self, ['php7.3-fpm'],
auto=False, purge=True)
if "php7.4-fpm" in apt_packages:
WOAptGet.remove(self, ['php7.4-fpm'],
auto=False, purge=True)
# check if nginx upgrade is blocked
if os.path.isfile(
'/etc/apt/preferences.d/nginx-block'):
@ -257,16 +314,16 @@ def default(self, disp_msg=False):
# Post Actions after package updates
if (packages):
if pargs.wpcli:
if WOAptGet.is_selected(self, 'WP-CLI', packages):
WOFileUtils.rm(self, '/usr/local/bin/wp')
if pargs.netdata:
if WOAptGet.is_selected(self, 'Netdata', packages):
WOFileUtils.rm(self, '/var/lib/wo/tmp/kickstart.sh')
if pargs.ngxblocker:
if WOAptGet.is_selected(self, 'ngxblocker', packages):
WOFileUtils.rm(self, '/usr/local/sbin/update-ngxblocker')
if pargs.dashboard:
if WOAptGet.is_selected(self, 'WordOps Dashboard', packages):
if os.path.isfile('/var/www/22222/htdocs/index.php'):
WOFileUtils.rm(self, '/var/www/22222/htdocs/index.php')
if os.path.isfile('/var/www/22222/htdocs/index.html'):
@ -276,18 +333,22 @@ def default(self, disp_msg=False):
Log.debug(self, "Downloading following: {0}".format(packages))
WODownload.download(self, packages)
if pargs.wpcli:
if WOAptGet.is_selected(self, 'WP-CLI', packages):
WOFileUtils.chmod(self, "/usr/local/bin/wp", 0o775)
if pargs.ngxblocker:
if WOAptGet.is_selected(self, 'ngxblocker', packages):
WOFileUtils.chmod(
self, '/usr/local/sbin/update-ngxblocker', 0o700)
self, '/usr/local/sbin/update-ngxblocker', 0o775)
WOShellExec.cmd_exec(
self, '/usr/local/sbin/update-ngxblocker -nq'
)
self, '/usr/local/sbin/update-ngxblocker -nq')
if WOAptGet.is_selected(self, 'MySQLTuner', packages):
WOFileUtils.chmod(self, "/usr/bin/mysqltuner", 0o775)
if os.path.exists('/usr/local/bin/mysqltuner'):
WOFileUtils.rm(self, '/usr/local/bin/mysqltuner')
# Netdata
if pargs.netdata:
if WOAptGet.is_selected(self, 'Netdata', packages):
Log.wait(self, "Upgrading Netdata")
# detect static binaries install
if os.path.isdir('/opt/netdata'):
@ -313,7 +374,7 @@ def default(self, disp_msg=False):
self, "bash /var/lib/wo/tmp/kickstart.sh")
Log.valide(self, "Upgrading Netdata")
if pargs.dashboard:
if WOAptGet.is_selected(self, 'WordOps Dashboard', packages):
post_pref(
self, [], [["https://github.com/WordOps"
"/wordops-dashboard/"
@ -323,7 +384,7 @@ def default(self, disp_msg=False):
"/var/lib/wo/tmp/wo-dashboard.tar.gz",
"WordOps Dashboard"]])
if pargs.composer:
if WOAptGet.is_selected(self, 'Composer', packages):
Log.wait(self, "Upgrading Composer")
if WOShellExec.cmd_exec(
self, '/usr/bin/php -v'):
@ -336,7 +397,7 @@ def default(self, disp_msg=False):
WOFileUtils.chmod(self, "/usr/local/bin/composer", 0o775)
Log.valide(self, "Upgrading Composer ")
if pargs.phpmyadmin:
if WOAptGet.is_selected(self, 'PHPMyAdmin', packages):
Log.wait(self, "Upgrading phpMyAdmin")
WOExtract.extract(self, '/var/lib/wo/tmp/pma.tar.gz',
'/var/lib/wo/tmp/')
@ -359,5 +420,10 @@ def default(self, disp_msg=False):
'www-data',
'www-data', recursive=True)
Log.valide(self, "Upgrading phpMyAdmin")
if os.path.exists('{0}22222/htdocs'.format(WOVar.wo_webroot)):
WOFileUtils.chown(self, "{0}22222/htdocs"
.format(WOVar.wo_webroot),
'www-data',
'www-data', recursive=True)
Log.info(self, "Successfully updated packages")

View File

@ -1,4 +1,5 @@
import glob
import os
from cement.core.controller import CementBaseController, expose
@ -39,6 +40,13 @@ def sync(self):
# Read config files
configfiles = glob.glob(wo_site_webroot + '/*-config.php')
if (os.path.exists(
'{0}/ee-config.php'.format(wo_site_webroot)) and
os.path.exists(
'{0}/wo-config.php'.format(wo_site_webroot))):
configfiles = glob.glob(
wo_site_webroot + 'wo-config.php')
# search for wp-config.php inside htdocs/
if not configfiles:
Log.debug(self, "Config files not found in {0}/ "

View File

@ -1,4 +1,4 @@
# WordOps admin NGINX CONFIGURATION - WO v3.9.7
# WordOps admin NGINX CONFIGURATION - WordOps {{release}}
server {

View File

@ -6,19 +6,21 @@ enabled = true
[nginx-http-auth]
enabled = true
logpath = /var/log/nginx/*error*.log
[nginx-botsearch]
enabled = true
logpath = /var/log/nginx/*access*.log
[wo-wordpress]
enabled = true
filter = wo-wordpress
action = iptables-multiport[name="wo-wordpress", port="http,https"]
logpath = /var/log/nginx/*access.log
logpath = /var/log/nginx/*access*.log
maxretry = 5
[nginx-forbidden]
enabled = true
filter = nginx-forbidden
action = iptables-multiport[name="wo-wordpress", port="http,https"]
action = iptables-multiport[name="nginx-forbidden", port="http,https"]
logpath = /var/log/nginx/*error*.log

View File

@ -6,6 +6,7 @@
gzip_disable "msie6";
gzip_vary on;
gzip_static on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;

View File

@ -1,4 +1,4 @@
# NGINX CONFIGURATION FOR COMMON LOCATION - WO v3.9.7
# NGINX CONFIGURATION FOR COMMON LOCATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# Basic locations files
location = /favicon.ico {
@ -41,7 +41,7 @@ location ~* "/(^$|readme|license|example|README|LEGALNOTICE|INSTALLATION|CHANGE
deny all;
}
# Deny backup extensions & log files and return 403 forbidden
location ~* "\.(old|orig|original|php#|php~|php_bak|save|swo|aspx?|tpl|sh|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$" {
location ~* "\.(old|orig|original|php#|php~|php_bak|save|swo|aspx?|tpl|sh|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf|gz|zip|bz2|7z|pem|asc|conf|dump)$" {
deny all;
}
location ~* "/(=|\$&|_mm|(wp-)?config\.|cgi-|etc/passwd|muieblack)" {

View File

@ -1,4 +1,4 @@
# NGINX CONFIGURATION FOR FASTCGI_CACHE EXCEPTION - WO v3.9.8
# NGINX CONFIGURATION FOR FASTCGI_CACHE EXCEPTION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# do not cache xhtml request

View File

@ -16,7 +16,7 @@ events {
http {
##
# WordOps Settings
# WordOps Settings - WordOps {{release}}
##
keepalive_timeout 8;
@ -51,17 +51,18 @@ http {
# SSL Settings
##
# Enable 0-RTT support for TLS 1.3
proxy_set_header Early-Data $ssl_early_data;
ssl_early_data on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_prefer_server_ciphers on;
ssl_early_data on;
{{#tls13}}ssl_ciphers 'TLS13+AESGCM+AES256:TLS13+AESGCM+AES128:TLS13+CHACHA20:EECDH+AESGCM:EECDH+CHACHA20';
ssl_protocols TLSv1.2 TLSv1.3;{{/tls13}}
ssl_ciphers 'TLS13+AESGCM+AES256:TLS13+AESGCM+AES128:TLS13+CHACHA20:EECDH+AESGCM:EECDH+CHACHA20';
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:P-521:P-384:P-256;
{{^tls13}}# Previous TLS v1.2 configuration
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM:EECDH+AES;{{/tls13}}
# Common security headers
more_set_headers "X-Frame-Options : SAMEORIGIN";

View File

@ -1,4 +1,4 @@
# PHP NGINX CONFIGURATION - WO v3.9.7
# PHP NGINX CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
location / {
try_files $uri $uri/ /index.php$is_args$args;

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
# WordOps script to download public suffix list from Github
# check if curl is available
if ! { command -v curl; }; then
apt-get update && apt-get install curl -qq > /dev/null 2>&1
fi
# download the list
rm -f /var/lib/wo/public_suffix_list.dat
curl -sL -m 30 --retry 3 -k https://raw.githubusercontent.com/publicsuffix/list/master/public_suffix_list.dat | sed '/^\/\//d' | sed '/^$/d' | sed 's/^\s+//g' > /var/lib/wo/public_suffix_list.dat

View File

@ -1,4 +1,4 @@
# Redis NGINX CONFIGURATION - WO v3.9.7
# Redis NGINX CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# $skip_cache variable set in /etc/nginx/conf.d/map-wp.conf

View File

@ -2,13 +2,17 @@ Information about {{domain}}:
Nginx configuration {{type}} {{enable}}
{{#php_version}}PHP Version {{php_version}}{{/php_version}}
{{#ssl}}SSL {{ssl}}{{/ssl}}
{{#sslprovider}}SSL PROVIDER {{sslprovider}}{{/sslprovider}}
{{#sslexpiry}}SSL EXPIRY DATE {{sslexpiry}}{{/sslexpiry}}
{{#ssl}}SSL {{ssl}}{{/ssl}}{{#sslprovider}}
SSL PROVIDER {{sslprovider}}{{/sslprovider}}{{#sslexpiry}}
SSL EXPIRY DATE {{sslexpiry}}{{/sslexpiry}}
access_log {{accesslog}}
error_log {{errorlog}}
{{#webroot}}Webroot {{webroot}}{{/webroot}}
{{#dbname}}DB_NAME {{dbname}}{{/dbname}}
{{#dbname}}
DB_NAME {{dbname}}{{/dbname}}
{{#dbname}}DB_USER {{dbuser}}{{/dbname}}
{{#dbname}}DB_PASS {{dbpass}}{{/dbname}}
{{#tablepref}}table_prefix {{tableprefix}}{{/tablepref}}

View File

@ -1,4 +1,4 @@
# NGINX Tweaks - WO v3.9.8
# NGINX Tweaks - WordOps {{release}}
directio 4m;
directio_alignment 512;
http2_max_field_size 16k;

View File

@ -1,4 +1,4 @@
# NGINX UPSTREAM CONFIGURATION - WO v3.9.8
# NGINX UPSTREAM CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
#-------------------------------
# PHP 5.6
@ -41,8 +41,8 @@ upstream php72 {
# PHP 7.2 debug
upstream debug72 {
# Debug Pool
server 127.0.0.1:9172;
# Debug Pool
server 127.0.0.1:9172;
}
#-------------------------------
@ -61,10 +61,30 @@ upstream php73 {
# PHP 7.3 debug
upstream debug73 {
# Debug Pool
# Debug Pool
server 127.0.0.1:9173;
}
#-------------------------------
# PHP 7.4
#-------------------------------
# PHP 7.4 upstream with load-balancing on two unix sockets
upstream php74 {
least_conn;
server unix:/var/run/php/php74-fpm.sock;
server unix:/var/run/php/php74-two-fpm.sock;
keepalive 5;
}
# PHP 7.4 debug
upstream debug74 {
# Debug Pool
server 127.0.0.1:9174;
}
#-------------------------------
# Netdata
#-------------------------------

View File

@ -1,58 +0,0 @@
server {
{{#multisite}}
# Uncomment the following line for domain mapping
# listen 80 default_server;
{{/multisite}}
server_name {{site_name}} {{#multisite}}*{{/multisite}}{{^multisite}}www{{/multisite}}.{{site_name}};
{{#multisite}}
# Uncomment the following line for domain mapping
#server_name_in_redirect off;
{{/multisite}}
access_log /var/log/nginx/{{site_name}}.access.log {{^wpredis}}{{^static}}rt_cache{{/static}}{{/wpredis}}{{#wpredis}}rt_cache_redis{{/wpredis}};
error_log /var/log/nginx/{{site_name}}.error.log;
{{#proxy}}
add_header X-Proxy-Cache $upstream_cache_status;
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;
}
# Security settings for better privacy
# Deny hidden files
location ~ /\.(?!well-known\/) {
deny all;
}
# letsencrypt validation
location /.well-known/acme-challenge/ {
alias /var/www/html/.well-known/acme-challenge/;
allow all;
}
{{/proxy}}
{{^proxy}}
root {{webroot}}/htdocs;
index {{^static}}index.php{{/static}} index.html index.htm;
{{#static}}
location / {
try_files $uri $uri/ =404;
}
{{/static}}
{{^static}}include {{#basic}}common/php73.conf;{{/basic}}{{#wpfc}}common/wpfc-php73.conf;{{/wpfc}} {{#wpsc}}common/wpsc-php73.conf;{{/wpsc}}{{#wpredis}}common/redis-php73.conf;{{/wpredis}}{{#wprocket}}common/wprocket-php73.conf;{{/wprocket}}{{#wpce}}common/wpce-php73.conf;{{/wpce}}
{{#wpsubdir}}include common/wpsubdir.conf;{{/wpsubdir}}{{/static}}
{{#wp}}include common/wpcommon-php73.conf;{{/wp}}
include common/locations-wo.conf;{{/proxy}}
include {{webroot}}/conf/nginx/*.conf;
}

View File

@ -49,9 +49,9 @@ server {
}
{{/static}}
{{^static}}include {{#basic}}common/php72.conf;{{/basic}}{{#wpfc}}common/wpfc-php72.conf;{{/wpfc}}{{#wpsc}}common/wpsc-php72.conf;{{/wpsc}}{{#wpredis}}common/redis-php72.conf;{{/wpredis}}{{#wprocket}}common/wprocket-php72.conf;{{/wprocket}}{{#wpce}}common/wpce-php72.conf;{{/wpce}}
{{^static}}include {{#basic}}common/{{wo_php}}.conf;{{/basic}}{{#wpfc}}common/wpfc-{{wo_php}}.conf;{{/wpfc}}{{#wpsc}}common/wpsc-{{wo_php}}.conf;{{/wpsc}}{{#wpredis}}common/redis-{{wo_php}}.conf;{{/wpredis}}{{#wprocket}}common/wprocket-{{wo_php}}.conf;{{/wprocket}}{{#wpce}}common/wpce-{{wo_php}}.conf;{{/wpce}}
{{#wpsubdir}}include common/wpsubdir.conf;{{/wpsubdir}}{{/static}}
{{#wp}}include common/wpcommon-php72.conf;{{/wp}}
{{#wp}}include common/wpcommon-{{wo_php}}.conf;{{/wp}}
include common/locations-wo.conf;{{/proxy}}
include {{webroot}}/conf/nginx/*.conf;

View File

@ -1,7 +1,39 @@
# WEBP NGINX CONFIGURATION - WO v3.9.7
# WEBP NGINX CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
map $http_accept $webp_suffix_valid {
default 1;
"~*webp" 0;
}
map $realip_remote_addr $webp_suffix_cf {
default 0;
103.21.244.0/22 1;
103.22.200.0/22 1;
103.31.4.0/22 1;
104.16.0.0/12 1;
108.162.192.0/18 1;
131.0.72.0/22 1;
141.101.64.0/18 1;
162.158.0.0/15 1;
172.64.0.0/13 1;
173.245.48.0/20 1;
188.114.96.0/20 1;
190.93.240.0/20 1;
197.234.240.0/22 1;
198.41.128.0/17 1;
199.27.128.0/21 1;
2400:cb00::/32 1;
2405:8100::/32 1;
2405:b500::/32 1;
2606:4700::/32 1;
2803:f800::/32 1;
2a06:98c0::/29 1;
2c0f:f248::/32 1;
}
map $webp_suffix_cf$webp_suffix_valid $webp_suffix {
default "";
00 ".webp";
}

View File

@ -26,15 +26,16 @@ fi
if [ -n "$CURRENT_RELEASE" ] && [ -n "$LATEST_RELEASE" ]; then
if [ "$CURRENT_RELEASE" != "$LATEST_RELEASE" ]; then
# display message with motd-news on Ubuntu
echo '*** A new WordOps release is available ***' > "$NEWS" 2> "$ERR"
echo '*** A new WordOps release is available ***' >"$NEWS" 2>"$ERR"
echo
# At most, 10 lines of text, remove control characters, print at most 80 characters per line
safe_print "$NEWS"
# Try to update the cache
safe_print "$NEWS" 2> /dev/null > $CACHE || true
safe_print "$NEWS" 2>/dev/null >$CACHE || true
else
# clean news
echo '' > "$NEWS" 2> "$ERR"
safe_print "$NEWS" 2> /dev/null > $CACHE || true
echo '' >"$NEWS" 2>"$ERR"
safe_print "$NEWS" 2>/dev/null >$CACHE || true
fi
fi

View File

@ -1,4 +1,4 @@
# WPCE NGINX CONFIGURATION - WO v3.9.8
# WPCE NGINX CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# $cache_uri variable set in /etc/nginx/conf.d/map-wp.conf
# Use cached or actual file if they exists, Otherwise pass request to WordPress
@ -10,7 +10,7 @@ location ~ \.php$ {
include fastcgi_params;
fastcgi_pass {{upstream}};
}
location ~ /wp-content/cache/cache-enabler/.*html$ {
location ~ /wp-content/cache/cache-enabler/*\.html$ {
etag on;
add_header Vary "Accept-Encoding, Cookie";
access_log off;

View File

@ -1,4 +1,4 @@
# WordPress COMMON SETTINGS - WO v3.9.7
# WordPress COMMON SETTINGS - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# Limit access to avoid brute force attack
location = /wp-login.php {
@ -12,7 +12,7 @@ location = /wp-cron.php {
include fastcgi_params;
fastcgi_pass {{upstream}};
}
# Prevent Dos attacks with xmlrpc.php
# Prevent DoS attacks with xmlrpc.php
location = /xmlrpc.php {
limit_req zone=two burst=1 nodelay;
include fastcgi_params;
@ -41,7 +41,7 @@ location /wp-content/uploads {
location ~ \.(png|jpe?g)$ {
add_header Vary "Accept-Encoding";
more_set_headers 'Access-Control-Allow-Origin : *';
add_header Cache-Control "public, no-transform";
more_set_headers "Cache-Control : public, no-transform";
access_log off;
log_not_found off;
expires max;
@ -57,7 +57,7 @@ location /wp-content/plugins/ewww-image-optimizer/images {
location ~ \.(png|jpe?g)$ {
add_header Vary "Accept-Encoding";
more_set_headers 'Access-Control-Allow-Origin : *';
add_header Cache-Control "public, no-transform";
more_set_headers "Cache-Control : public, no-transform";
access_log off;
log_not_found off;
expires max;

View File

@ -1,4 +1,4 @@
# WPFC NGINX CONFIGURATION - WO v3.9.7
# WPFC NGINX CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# $skip_cache variable set in /etc/nginx/conf.d/map-wp.conf

View File

@ -1,4 +1,4 @@
# WPROCKET NGINX CONFIGURATION - WO v3.9.8
# WPROCKET NGINX CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# $cache_uri variable set in /etc/nginx/conf.d/map-wp.conf
# Use cached or actual file if they exists, Otherwise pass request to WordPress
@ -10,8 +10,9 @@ location ~ \.php$ {
include fastcgi_params;
fastcgi_pass {{upstream}};
}
location ~ /wp-content/cache/wp-rocket/.*html$ {
location ~ /wp-content/cache/wp-rocket/*\.html$ {
etag on;
gzip_static on;
add_header Vary "Accept-Encoding, Cookie";
access_log off;
log_not_found off;

View File

@ -1,4 +1,4 @@
# WPSC NGINX CONFIGURATION - WO v3.9.7
# WPSC NGINX CONFIGURATION - WordOps {{release}}
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# $cache_uri variable set in /etc/nginx/conf.d/map-wp.conf

View File

@ -16,8 +16,41 @@ class WOAcme:
wo_acme_exec = ("/etc/letsencrypt/acme.sh --config-home "
"'/etc/letsencrypt/config'")
def check_acme(self):
"""
Check if acme.sh is properly installed,
and install it if required
"""
if not os.path.exists('/etc/letsencrypt/acme.sh'):
if os.path.exists('/opt/acme.sh'):
WOFileUtils.rm(self, '/opt/acme.sh')
WOGit.clone(
self, 'https://github.com/Neilpang/acme.sh.git',
'/opt/acme.sh', branch='master')
WOFileUtils.mkdir(self, '/etc/letsencrypt/config')
WOFileUtils.mkdir(self, '/etc/letsencrypt/renewal')
WOFileUtils.mkdir(self, '/etc/letsencrypt/live')
try:
WOFileUtils.chdir(self, '/opt/acme.sh')
WOShellExec.cmd_exec(
self, './acme.sh --install --home /etc/letsencrypt'
'--config-home /etc/letsencrypt/config'
'--cert-home /etc/letsencrypt/renewal'
)
WOShellExec.cmd_exec(
self, "{0} --upgrade --auto-upgrade"
.format(WOAcme.wo_acme_exec)
)
except CommandExecutionError as e:
Log.debug(self, str(e))
Log.error(self, "acme.sh installation failed")
if not os.path.exists('/etc/letsencrypt/acme.sh'):
Log.error(self, 'acme.sh ')
def export_cert(self):
"""Export acme.sh csv certificate list"""
# check acme.sh is installed
WOAcme.check_acme(self)
if not WOShellExec.cmd_exec(
self, "{0} ".format(WOAcme.wo_acme_exec) +
"--list --listraw > /var/lib/wo/cert.csv"):
@ -26,6 +59,9 @@ def export_cert(self):
def setupletsencrypt(self, acme_domains, acmedata):
"""Issue SSL certificates with acme.sh"""
# check acme.sh is installed
WOAcme.check_acme(self)
# define variables
all_domains = '\' -d \''.join(acme_domains)
wo_acme_dns = acmedata['acme_dns']
keylenght = acmedata['keylength']
@ -74,6 +110,8 @@ def setupletsencrypt(self, acme_domains, acmedata):
def deploycert(self, wo_domain_name):
"""Deploy Let's Encrypt certificates with acme.sh"""
# check acme.sh is installed
WOAcme.check_acme(self)
if not os.path.isfile('/etc/letsencrypt/renewal/{0}_ecc/fullchain.cer'
.format(wo_domain_name)):
Log.error(self, 'Certificate not found. Deployment canceled')
@ -135,6 +173,8 @@ def deploycert(self, wo_domain_name):
def renew(self, domain):
"""Renew letsencrypt certificate with acme.sh"""
# check acme.sh is installed
WOAcme.check_acme(self)
try:
WOShellExec.cmd_exec(
self, "{0} ".format(WOAcme.wo_acme_exec) +
@ -158,7 +198,10 @@ def check_dns(self, acme_domains):
response = requests.get(url, headers=headers).json()
domain_ip = response["Answer"][0]['data']
except requests.RequestException:
Log.error(self, 'Resolving domain IP failed')
Log.error(
self, 'Resolving domain IP failed.\n'
'The domain {0} do not exist or a DNS record is missing'
.format(domain))
if(not domain_ip == server_ip):
Log.warn(
self, "{0}".format(domain) +
@ -202,6 +245,8 @@ def removeconf(self, domain):
.format(WOVar.wo_ssl_live, domain),
'/etc/letsencrypt/shared/{0}.conf'.format(domain)]
wo_domain = domain
# check acme.sh is installed
WOAcme.check_acme(self)
if WOAcme.cert_check(self, wo_domain):
Log.info(self, "Removing Acme configuration")
Log.debug(self, "Removing Acme configuration")

View File

@ -1,6 +1,7 @@
"""WordOps package installation using apt-get module."""
import subprocess
import sys
import os
from sh import ErrorReturnCode, apt_get
@ -222,6 +223,29 @@ def is_installed(self, package_name):
# apt_cache.close()
return False
def is_exec(self, package_name):
"""
Check if package is available by looking
for an executable or a systemd service related
to this package
"""
exec_path = ["/bin", "/usr/bin", "/usr/local/bin",
"/usr/sbin", "/usr/local/sbin"]
for path in exec_path:
if os.path.exists('{0}/{1}'.format(path, package_name)):
return True
return False
def is_selected(self, package_name, packages_list):
"""
Check if package is selected for install/removal/purge
in packages_list
"""
for package in packages_list:
if package_name == package[2]:
return True
return False
def download_only(self, package_name, repo_url=None, repo_key=None):
"""
Similar to `apt-get install --download-only PACKAGE_NAME`

View File

@ -252,10 +252,7 @@ def isexist(self, path):
Check if file exist on given path
"""
try:
if os.path.exists(path):
return (True)
else:
return (False)
return bool(os.path.exists(path))
except OSError as e:
Log.debug(self, "{0}".format(e.strerror))
Log.error(self, "Unable to check path {0}".format(path))
@ -369,3 +366,22 @@ def textappend(self, path, content):
except IOError as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to append content in {0}".format(path))
def enabledisable(self, path, enable=True):
"""Switch conf from .conf.disabled to .conf or vice-versa"""
if enable:
Log.debug(self, "Check if disabled file exist")
if os.path.exists('{0}.disabled'.format(path)):
Log.debug(self, "Moving .disabled file")
shutil.move('{0}.disabled'.format(path), path)
return True
else:
return False
else:
Log.debug(self, "Check if .conf file exist")
if os.path.exists(path):
Log.debug(self, "Moving .conf file")
shutil.move(path, '{0}.disabled'.format(path))
return True
else:
return False

View File

@ -18,25 +18,24 @@ def add(self, paths, msg="Intializating"):
"""
for path in paths:
global git
git = git.bake("--git-dir={0}/.git".format(path),
"--work-tree={0}".format(path))
wogit = git.bake("-C", "{0}".format(path))
if os.path.isdir(path):
if not os.path.isdir(path + "/.git"):
try:
Log.debug(self, "WOGit: git init at {0}"
.format(path))
git.init(path)
wogit.init(path)
except ErrorReturnCode as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to git init at {0}"
.format(path))
status = git.status("-s")
status = wogit.status("-s")
if len(status.splitlines()) > 0:
try:
Log.debug(self, "WOGit: git commit at {0}"
.format(path))
git.add("--all")
git.commit("-am {0}".format(msg))
wogit.add("--all")
wogit.commit("-am {0}".format(msg))
except ErrorReturnCode as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to git commit at {0} "
@ -49,9 +48,8 @@ def checkfilestatus(self, repo, filepath):
Checks status of file, If its tracked or untracked.
"""
global git
git = git.bake("--git-dir={0}/.git".format(repo),
"--work-tree={0}".format(repo))
status = git.status("-s", "{0}".format(filepath))
wogit = git.bake("-C", "{0}".format(repo))
status = wogit.status("-s", "{0}".format(filepath))
if len(status.splitlines()) > 0:
return True
else:
@ -64,8 +62,7 @@ def rollback(self, paths, msg="Rolling-Back"):
"""
for path in paths:
global git
git = git.bake("--git-dir={0}/.git".format(path),
"--work-tree={0}".format(path))
wogit = git.bake("-C", "{0}".format(path))
if os.path.isdir(path):
if not os.path.isdir(path + "/.git"):
Log.error(
@ -75,8 +72,8 @@ def rollback(self, paths, msg="Rolling-Back"):
Log.debug(
self, "WOGit: git stash --include-untracked at {0}"
.format(path))
git.stash("push", "--include-untracked", "-m {0}"
.format(msg))
wogit.stash("push", "--include-untracked", "-m {0}"
.format(msg))
except ErrorReturnCode as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to git reset at {0} "

19
wo/core/nginx.py Normal file
View File

@ -0,0 +1,19 @@
"""WordOps Nginx Manager"""
import subprocess
from wo.core.logging import Log
def check_config(self):
"""Check Nginx configuration and return boolean"""
Log.debug(self, "Testing Nginx configuration ")
# Check Nginx configuration before executing command
sub = subprocess.Popen('nginx -t', stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
output, error_output = sub.communicate()
if 'emerg' in str(error_output):
Log.debug(self, "Nginx configuration check failed")
return False
else:
Log.debug(self, "Nginx configuration check was successful")
return True

View File

@ -20,15 +20,17 @@ def start_service(self, service_name):
# Check Nginx configuration before executing command
sub = subprocess.Popen('nginx -t', stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
output, error_output = sub.communicate()
if 'emerg' not in str(error_output):
output = sub.communicate()
if 'emerg' not in str(output):
Log.valide(self, "Testing Nginx configuration ")
Log.wait(self, "Starting Nginx ")
Log.wait(self, "Starting Nginx")
service_cmd = ('service {0} start'.format(service_name))
retcode = subprocess.getstatusoutput(service_cmd)
if retcode[0] == 0:
Log.valide(self, "Starting Nginx ")
return True
else:
Log.failed(self, "Starting Nginx")
else:
Log.failed(self, "Testing Nginx configuration ")
return False
@ -129,15 +131,15 @@ def reload_service(self, service_name):
output, error_output = sub.communicate()
if 'emerg' not in str(error_output):
Log.valide(self, "Testing Nginx configuration ")
Log.wait(self, "Reloading Nginx ")
Log.wait(self, "Reloading Nginx")
service_cmd = ('service {0} reload'.format(service_name))
retcode = subprocess.getstatusoutput(service_cmd)
if retcode[0] == 0:
Log.valide(self, "Reloading Nginx ")
Log.valide(self, "Reloading Nginx")
return True
else:
Log.failed(self, "Testing Nginx configuration ")
return False
else:
Log.failed(self, "Testing Nginx configuration ")
return False
else:
service_cmd = ('service {0} reload'.format(service_name))
Log.wait(self, "Reloading {0:10}".format(
@ -160,10 +162,11 @@ def reload_service(self, service_name):
def get_service_status(self, service_name):
try:
is_exist = subprocess.getstatusoutput('which {0}'
is_exist = subprocess.getstatusoutput('command -v {0}'
.format(service_name))
if is_exist[0] == 0 or service_name in ['php7.2-fpm',
'php7.3-fpm']:
'php7.3-fpm',
'php7.4-fpm']:
retcode = subprocess.getstatusoutput('service {0} status'
.format(service_name))
if retcode[0] == 0:

View File

@ -37,27 +37,6 @@ def cmd_exec(self, command, errormsg='', log=True):
Log.debug(self, str(e))
raise CommandExecutionError
def cmd_exist(self, command):
"""Check if a command exist with command -v"""
try:
Log.debug(self, "Testing command: {0}".format(command))
testing_command = ("command -v {0}".format(command))
with subprocess.Popen([testing_command], stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True) as proc:
(cmd_stdout_bytes, cmd_stderr_bytes) = proc.communicate()
(cmd_stdout, cmd_stderr) = (
cmd_stdout_bytes.decode('utf-8', "replace"),
cmd_stderr_bytes.decode('utf-8', "replace"))
Log.debug(self, "Command Output: {0}, \nCommand Error: {1}"
.format(cmd_stdout, cmd_stderr))
return bool(proc.returncode == 0)
except OSError as e:
Log.debug(self, str(e))
raise CommandExecutionError
except Exception as e:
Log.debug(self, str(e))
raise CommandExecutionError
def invoke_editor(self, filepath, errormsg=''):
"""
Open files using sensible editor

View File

@ -6,26 +6,39 @@
from wo.core.logging import Log
from wo.core.shellexec import WOShellExec
from wo.core.variables import WOVar
from wo.core.acme import WOAcme
class SSL:
def getexpirationdays(self, domain, returnonerror=False):
# check if exist
if not os.path.isfile('/etc/letsencrypt/live/{0}/cert.pem'
if not os.path.exists('/etc/letsencrypt/live/{0}/cert.pem'
.format(domain)):
Log.error(self, 'File Not Found: '
'/etc/letsencrypt/live/{0}/cert.pem'
.format(domain), False)
if returnonerror:
return -1
Log.error(self, "Check the WordOps log for more details "
"`tail /var/log/wo/wordops.log` and please try again...")
Log.debug(self, "cert not found for {0}".format(domain))
split_domain = domain.split('.')
root_domain = ('.').join(split_domain[1:])
Log.debug(self, "trying with {0}".format(root_domain))
if os.path.exists('/etc/letsencrypt/live/{0}/cert.pem'
.format(root_domain)):
domain = root_domain
else:
Log.error(self, 'File Not Found: '
'/etc/letsencrypt/live/{0}/cert.pem'
.format(domain), False)
Log.error(
self, "Check the WordOps log for more details "
"`tail /var/log/wo/wordops.log` "
"and please try again...")
Log.debug(
self,
"Getting expiration of /etc/letsencrypt/live/{0}/cert.pem"
.format(domain))
current_date = WOShellExec.cmd_exec_stdout(self, "date -d \"now\" +%s")
expiration_date = WOShellExec.cmd_exec_stdout(
self, "date -d \""
"$(openssl x509 -in /etc/letsencrypt/live/"
self, "date -d \"$(openssl x509 -in /etc/letsencrypt/live/"
"{0}/cert.pem -text -noout | grep \"Not After\" "
"| cut -c 25-)\" +%s"
.format(domain))
@ -39,23 +52,27 @@ def getexpirationdays(self, domain, returnonerror=False):
def getexpirationdate(self, domain):
# check if exist
if os.path.islink('/var/www/{0}/conf/nginx/ssl.conf'):
split_domain = domain.split('.')
domain = ('.').join(split_domain[1:])
if not os.path.isfile('/etc/letsencrypt/live/{0}/cert.pem'
.format(domain)):
Log.error(self, 'File Not Found: /etc/letsencrypt/'
'live/{0}/cert.pem'
.format(domain), False)
Log.error(self, "Check the WordOps log for more details "
"`tail /var/log/wo/wordops.log` and please try again...")
if os.path.exists('/var/www/{0}/conf/nginx/ssl.conf'):
split_domain = domain.split('.')
check_domain = ('.').join(split_domain[1:])
else:
Log.error(
self, 'File Not Found: /etc/letsencrypt/'
'live/{0}/cert.pem'
.format(domain), False)
Log.error(
self, "Check the WordOps log for more details "
"`tail /var/log/wo/wordops.log` and please try again...")
else:
check_domain = domain
expiration_date = WOShellExec.cmd_exec_stdout(
return WOShellExec.cmd_exec_stdout(
self, "date -d \"$(/usr/bin/openssl x509 -in "
"/etc/letsencrypt/live/{0}/cert.pem -text -noout | grep "
"\"Not After\" | cut -c 25-)\" "
.format(domain))
return expiration_date
.format(check_domain))
def siteurlhttps(self, domain):
wo_site_webroot = ('/var/www/{0}'.format(domain))
@ -93,8 +110,8 @@ def siteurlhttps(self, domain):
Log.valide(self, "Updating site url with https")
# check if a wildcard exist to secure a new subdomain
def checkwildcardexist(self, wo_domain_name):
"""Check if a wildcard certificate exist for a domain"""
wo_acme_exec = ("/etc/letsencrypt/acme.sh --config-home "
"'/etc/letsencrypt/config'")
@ -110,31 +127,44 @@ def checkwildcardexist(self, wo_domain_name):
reader = csv.reader(certfile, 'acmeconf')
wo_wildcard_domain = ("*.{0}".format(wo_domain_name))
for row in reader:
if wo_wildcard_domain in row[2]:
if not row[2] == "":
iswildcard = True
break
else:
iswildcard = False
if wo_wildcard_domain == row[2]:
if not row[3] == "":
return True
certfile.close()
return False
return iswildcard
def setuphsts(self, wo_domain_name, enable=True):
"""Enable or disable htsts for a site"""
if enable:
if WOFileUtils.enabledisable(
self, '/var/www/{0}/conf/nginx/hsts.conf'
):
return 0
else:
Log.info(
self, "Adding /var/www/{0}/conf/nginx/hsts.conf"
.format(wo_domain_name))
def setuphsts(self, wo_domain_name):
Log.info(
self, "Adding /var/www/{0}/conf/nginx/hsts.conf"
.format(wo_domain_name))
hstsconf = open("/var/www/{0}/conf/nginx/hsts.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
hstsconf.write("more_set_headers "
"\"Strict-Transport-Security: "
"max-age=31536000; "
"includeSubDomains; "
"preload\";")
hstsconf.close()
return 0
hstsconf = open("/var/www/{0}/conf/nginx/hsts.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
hstsconf.write("more_set_headers "
"\"Strict-Transport-Security: "
"max-age=31536000; "
"includeSubDomains; "
"preload\";")
hstsconf.close()
return 0
else:
if WOFileUtils.enabledisable(
self, '/var/www/{0}/conf/nginx/hsts.conf',
enable=False
):
Log.info(self, "HSTS disabled")
return 0
else:
Log.info(self, "HSTS is not enabled")
return 0
def selfsignedcert(self, proftpd=False, backend=False):
"""issue a self-signed certificate"""
@ -197,3 +227,100 @@ def selfsignedcert(self, proftpd=False, backend=False):
"/etc/proftpd/ssl/proftpd.crt")
# remove self-signed tmp directory
WOFileUtils.rm(self, selfs_tmp)
def httpsredirect(self, wo_domain_name, acme_domains, redirect=True):
"""Create Nginx redirection from http to https"""
wo_acme_domains = ' '.join(acme_domains)
if redirect:
Log.wait(self, "Adding HTTPS redirection")
if WOFileUtils.enabledisable(
self, '/etc/nginx/conf.d/force-ssl-{0}.conf'
.format(wo_domain_name), enable=True):
Log.valide(self, "Adding HTTPS redirection")
return 0
else:
try:
sslconf = open(
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name),
encoding='utf-8', mode='w')
sslconf.write(
"server {\n"
"\tlisten 80;\n" +
"\tlisten [::]:80;\n" +
"\tserver_name {0};\n"
.format(wo_acme_domains) +
"\treturn 301 https://$host"
"$request_uri;\n}")
sslconf.close()
except IOError as e:
Log.debug(self, str(e))
Log.debug(
self, "Error occured while generating "
"/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name))
return 1
Log.valide(self, "Adding HTTPS redirection")
return 0
else:
if WOFileUtils.enabledisable(
self, "/etc/nginx/conf.d/force-ssl-{0}.conf"
.format(wo_domain_name), enable=False):
Log.info(
self, "Disabled HTTPS Force Redirection for site "
"{0}".format(wo_domain_name))
else:
Log.info(
self, "HTTPS redirection already disabled for site"
"{0}".format(wo_domain_name)
)
return 0
def archivedcertificatehandle(self, domain, acme_domains):
Log.warn(
self, "You already have an existing certificate "
"for the domain requested.\n"
"(ref: {0}/"
"{1}_ecc/{1}.conf)".format(WOVar.wo_ssl_archive, domain) +
"\nPlease select an option from below?"
"\n\t1: Reinstall existing certificate"
"\n\t2: Issue a new certificate to replace "
"the current one (limit ~5 per 7 days)"
"")
check_prompt = input(
"\nType the appropriate number [1-2] or any other key to cancel: ")
if not os.path.isfile("{0}/{1}/fullchain.pem"
.format(WOVar.wo_ssl_live, domain)):
Log.debug(
self, "{0}/{1}/fullchain.pem file is missing."
.format(WOVar.wo_ssl_live, domain))
check_prompt = "2"
if check_prompt == "1":
Log.info(self, "Reinstalling SSL cert with acme.sh")
ssl = WOAcme.deploycert(self, domain)
if ssl:
SSL.httpsredirect(self, domain, acme_domains)
elif (check_prompt == "2"):
Log.info(self, "Issuing new SSL cert with acme.sh")
ssl = WOShellExec.cmd_exec(
self, "/etc/letsencrypt/acme.sh "
"--config-home '/etc/letsencrypt/config' "
"--renew -d {0} --ecc --force"
.format(domain))
if ssl:
WOAcme.deploycert(self, domain)
else:
Log.error(self, "Operation cancelled by user.")
if os.path.isfile("{0}/conf/nginx/ssl.conf"
.format(domain)):
Log.info(self, "Existing ssl.conf . Backing it up ..")
WOFileUtils.mvfile(self, "/var/www/{0}/conf/nginx/ssl.conf"
.format(domain),
'/var/www/{0}/conf/nginx/ssl.conf.bak'
.format(domain))
return ssl

50
wo/core/stackconf.py Normal file
View File

@ -0,0 +1,50 @@
import os
from wo.core.logging import Log
from wo.core.template import WOTemplate
from wo.core.variables import WOVar
class WOConf():
"""wo stack configuration utilities"""
def __init__():
pass
def nginxcommon(self):
"""nginx common configuration deployment"""
wo_php_version = ["php72", "php73", "php74"]
ngxcom = '/etc/nginx/common'
for wo_php in wo_php_version:
if not os.path.exists(ngxcom):
os.mkdir(ngxcom)
Log.debug(self, 'deploying templates for {0}'.format(wo_php))
data = dict(upstream="{0}".format(wo_php),
release=WOVar.wo_version)
WOTemplate.deploy(self,
'{0}/{1}.conf'
.format(ngxcom, wo_php),
'php.mustache', data)
WOTemplate.deploy(
self, '{0}/redis-{1}.conf'.format(ngxcom, wo_php),
'redis.mustache', data)
WOTemplate.deploy(
self, '{0}/wpcommon-{1}.conf'.format(ngxcom, wo_php),
'wpcommon.mustache', data)
WOTemplate.deploy(
self, '{0}/wpfc-{1}.conf'.format(ngxcom, wo_php),
'wpfc.mustache', data)
WOTemplate.deploy(
self, '{0}/wpsc-{1}.conf'.format(ngxcom, wo_php),
'wpsc.mustache', data)
WOTemplate.deploy(
self, '{0}/wprocket-{1}.conf'.format(ngxcom, wo_php),
'wprocket.mustache', data)
WOTemplate.deploy(
self, '{0}/wpce-{1}.conf'.format(ngxcom, wo_php),
'wpce.mustache', data)

View File

@ -14,11 +14,11 @@ class WOVar():
"""Intialization of core variables"""
# WordOps version
wo_version = "3.10.3"
wo_version = "3.11.0"
# WordOps packages versions
wo_wp_cli = "2.3.0"
wo_adminer = "4.7.3"
wo_phpmyadmin = "4.9.1"
wo_wp_cli = "2.4.0"
wo_adminer = "4.7.5"
wo_phpmyadmin = "4.9.2"
wo_extplorer = "2.1.13"
wo_dashboard = "1.2"
@ -133,16 +133,23 @@ class WOVar():
wo_nginx = ["nginx-custom", "nginx-wo"]
wo_nginx_key = '188C9FB063F0247A'
wo_php = ["php7.2-fpm", "php7.2-curl", "php7.2-gd", "php7.2-imap",
"php7.2-readline", "php7.2-common", "php7.2-recode",
"php7.2-cli", "php7.2-mbstring", "php7.2-intl",
"php7.2-bcmath", "php7.2-mysql", "php7.2-opcache",
"php7.2-zip", "php7.2-xml", "php7.2-soap"]
wo_php73 = ["php7.3-fpm", "php7.3-curl", "php7.3-gd", "php7.3-imap",
"php7.3-readline", "php7.3-common", "php7.3-recode",
"php7.3-cli", "php7.3-mbstring", "php7.3-intl",
"php7.3-bcmath", "php7.3-mysql", "php7.3-opcache",
"php7.3-zip", "php7.3-xml", "php7.3-soap"]
wo_module = ["fpm", "curl", "gd", "imap",
"readline", "common",
"cli", "mbstring", "intl",
"bcmath", "mysql", "opcache",
"zip", "xml", "soap"]
wo_php72 = []
for module in wo_module:
wo_php72 = wo_php72 + ["php7.2-{0}".format(module),
"php7.2-recode"]
wo_php73 = []
for module in wo_module:
wo_php73 = wo_php73 + ["php7.3-{0}".format(module),
"php7.3-recode"]
wo_php74 = []
for module in wo_module:
wo_php74 = wo_php74 + ["php7.4-{0}".format(module)]
wo_php_extra = ["php-memcached", "php-imagick",
"graphviz", "php-xdebug", "php-msgpack", "php-redis"]

17
wo/core/wpcli.py Normal file
View File

@ -0,0 +1,17 @@
"""WordPress utilities for WordOps"""
from wo.core.logging import Log
from wo.core.shellexec import WOShellExec
from wo.core.variables import WOVar
class WOWp:
"""WordPress utilities for WordOps"""
def wpcli(self, command):
"""WP-CLI wrapper"""
try:
WOShellExec.cmd_exec(
self, '{0} --allow-root '.format(WOVar.wo_wpcli_path) +
'{0}'.format(command))
except Exception:
Log.error(self, "WP-CLI command failed")