Refactored

This commit is contained in:
jeroenops
2018-11-13 21:55:59 +01:00
commit b36df4384a
129 changed files with 14400 additions and 0 deletions

66
.gitignore vendored Normal file
View File

@@ -0,0 +1,66 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
.idea/
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Vim .swp file
*.swp
# Folder created for Nose testing
bin/
coverage_report/
include/
local/
man/

100
.travis.yml Normal file
View File

@@ -0,0 +1,100 @@
language: bash
before_install:
- rm -rf ~/.gnupg
before_script:
- sudo rm -rf /etc/mysql/
- sudo bash -c 'echo example.com > /etc/hostname'
- sudo service hostname restart
- sudo apt-get -qq purge mysql* graphviz*
- sudo apt-get -qq autoremove
- sudo apt-get update
script:
- lsb_release -a
- unset LANG
- sudo bash -c 'echo -e "[user]\n\tname = abc\n\temail = root@localhost.com" > /home/travis/.gitconfig'
- sudo echo "Travis Banch = $TRAVIS_BRANCH"
- sudo apt-get install -y --force-yes git python3-setuptools python3-dev python3-apt
- sudo bash install $TRAVIS_BRANCH
- sudo wo --help
- sudo wo stack install || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo stack install --web || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo stack install --admin || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create html.net --html || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create php.com --php || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create mysql.com --mysql || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site1.com --wp || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site2.net --wp --wpsc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site4.com --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site4.net --wp --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site4.org --wpfc --wp || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site5.com --wpsubdir || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site6.com --wpsubdir --wpsc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site8.com --wpsubdir --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site8.net --wpfc --wpsubdir || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site9.com --wpsubdomain || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site10.org --wpsubdomain --wpsc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site12.org --wpsubdomain --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site12.in --wpfc --wpsubdomain || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed2.com --wpsc --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed4.com --wpfc --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed5.com --wpsubdir --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed6.com --wpsubdir --wpsc --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed8.com --wpsubdir --wpfc --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed9.com --wpsubdomain --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed10.org --wpsubdomain --wpsc --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site.hhvm.pagespeed12.in --wpfc --wpsubdomain --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site1.localtest.me --php --mysql || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site2.localtest.me --mysql --html || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site3.localtest.me --php --html || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site4.localtest.me --wp --wpsubdomain || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create site5.localtest.me --wp --wpsubdir --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site6.localtest.me --wpredis || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site7.localtest.me --wpsubdomain --wpredis || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site create site8.localtest.me --wpsubdir --wpredis || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo debug --all || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo debug --all=off || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo debug site12.net || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo debug site12.net --all=off || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create 1.com --html || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create 2.com --php || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create 3.com --mysql || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update 1.com --wp || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update 2.com --wpsubdir || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update 3.com --wpsubdomain || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update site1.com --wp --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update site1.com --wp --wpsc || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site update site1.com --wpredis || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update site5.com --wpsubdir --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update site5.com --wpsubdir --wpsc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update site9.com --wpsubdomain --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update site9.com --wpsubdomain --wpsc || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site update site.hhvm.pagespeed12.in --hhvm=off || sudo tail -n50 /var/log/wo/wordops.log
- yes | sudo wo site update site9.com --hhvm || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site info site.hhvm.pagespeed12.in || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site info site9.com || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create www.site-1.com --wp || sudo tail -n50 /var/log/wo/wordops.log|| sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site create www.subsite.site-1.com --wpfc || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site update www.subsite.site-1.com --wp || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site delete www.subsite.site-1.com --all --no-prompt || sudo tail -n50 /var/log/wo/wordops.log
- sudo wo site delete site12.in --all --no-prompt || sudo tail -n50 /var/log/wo/wordops.log
- sudo ls /var/www/
- sudo wp --allow-root --info
- sudo bash -c 'cat /var/log/wo/wordops.log'

8
CHANGELOG.txt Normal file
View File

@@ -0,0 +1,8 @@
v3.9.0 - November 11, 2018
[+] Rebranded the fork to WordOps
[+] Codebase cleanup
[+] Included support for newer OS releases
[+] Reworked the HTTPS configuration
[-] Dropped mail services
[-] Dropped w3tc support

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 WordOps
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

93
README.md Normal file
View File

@@ -0,0 +1,93 @@
# [WordOps](https://wordops.org/)
WordOps (wo) is the essential toolset that eases WordPress site and server administration.
**WordOps currently supports:**
- Ubuntu 14.04, 16.04 & 18.04
- Debian 7, 8 & 9
**Port requirements:**
| Name | Port Number | Inbound | Outbound |
|:-----:|:-----------:|:-------:|:---------:|
|SSH |22 | ✓ |✓ |
|HTTP |80 | ✓ |✓ |
|HTTPS/SSL |443 | ✓ |✓ |
|WO Admin |22222 | ✓ | |
|GPG Key Server |11371 | |✓ |
## Quick start
```bash
wget -qO wo wordops.se/tup && sudo bash wo # Install WordOps
sudo wo site create example.com --wp # Install required packages & setup WordPress on example.com
```
## Must read!
WordOps made some fundamental changes:
* We've deprecated the mail stack. Less is more. As an alternative, take a look at [iRedMail](https://www.iredmail.org/) or [Caesonia](https://github.com/vedetta-com/caesonia). And an alternative for Roundcube is [Rainloop](https://www.rainloop.net/).
* Support for w3tc is dropped as a security precaution.
* We are currently migrating the PHP 5.x series to PHP 7.1 and PHP 7.2. We'll offer an easy to use migration script once we are confident enough to unleash this daemon.
## Update WordOps
#### With one simple command
```
wo update
```
## More site creation commands
### Standard WordPress sites
```bash
wo site create example.com --wp # install wordpress without any page caching
wo site create example.com --wpsc # install wordpress with wp-super-cache plugin
wo site create example.com --wpfc # install wordpress + nginx fastcgi_cache
wo site create example.com --wpredis # install wordpress + nginx redis_cache
```
### WordPress multsite with subdirectory
```bash
wo site create example.com --wpsubdir # install wpmu-subdirectory without any page caching
wo site create example.com --wpsubdir --wpsc # install wpmu-subdirectory with wp-super-cache plugin
wo site create example.com --wpsubdir --wpfc # install wpmu-subdirectory + nginx fastcgi_cache
wo site create example.com --wpsubdir --wpredis # install wpmu-subdirectory + nginx redis_cache
```
### WordPress multsite with subdomain
```bash
wo site create example.com --wpsubdomain # install wpmu-subdomain without any page caching
wo site create example.com --wpsubdomain --wpsc # install wpmu-subdomain with wp-super-cache plugin
wo site create example.com --wpsubdomain --wpfc # install wpmu-subdomain + nginx fastcgi_cache
wo site create example.com --wpsubdomain --wpredis # install wpmu-subdomain + nginx redis_cache
```
### Non-WordPress sites
```bash
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 --mysql # create example.com with php & mysql support
```
### HHVM enabled sites
```bash
wo site create example.com --wp --hhvm # create example.com WordPress site with HHVM support
wo site create example.com --php --hhvm # create example.com php site with HHVM support
```
## Cheatsheet - site creation
| | single site | multisite w/ subdir | multisite w/ subdom |
|--------------------|---------------|-----------------------|--------------------------|
| **NO Cache** | --wp | --wpsubdir | --wpsubdomain |
| **WP Super Cache** | --wpsc | --wpsubdir --wpsc | --wpsubdomain --wpsc |
| **Nginx cache** | --wpfc | --wpsubdir --wpfc | --wpsubdomain --wpfc |
| **Redis cache** | --wpredis | --wpsubdir --wpredis | --wpsubdomain --wpredis |
## License
[MIT](http://opensource.org/licenses/MIT)

View File

@@ -0,0 +1,378 @@
_wo_complete()
{
local cur prev BASE_LEVEL
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
mprev=${COMP_WORDS[COMP_CWORD-2]}
# SETUP THE BASE LEVEL (everything after "wo")
if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=( $(compgen \
-W "stack site debug clean secure import-slow-log log update sync info --version --help --quiet" \
-- $cur) )
# SETUP THE SECOND LEVEL (EVERYTHING AFTER "wo second")
elif [ $COMP_CWORD -eq 2 ]; then
case "$prev" in
# HANDLE EVERYTHING AFTER THE SECOND LEVEL NAMESPACE
"clean")
COMPREPLY=( $(compgen \
-W "--memcache --opcache --fastcgi --redis --all" \
-- $cur) )
;;
# IF YOU HAD ANOTHER CONTROLLER, YOU'D HANDLE THAT HERE
"debug")
COMPREPLY=( $(compgen \
-W "$(command find /etc/nginx/sites-enabled/ -type l -printf "%P " 2> /dev/null) --nginx --php --php7 --fpm --fpm7 --mysql -i --interactive --all --import-slow-log --import-slow-log-interval= --nginx=off --php=off --php7=off --fpm=off --fpm7=off --mysql=off --all=off " \
-- $cur) )
;;
"stack")
COMPREPLY=( $(compgen \
-W "upgrade install purge reload remove restart start status stop migrate" \
-- $cur) )
;;
"site")
COMPREPLY=( $(compgen \
-W "cd create delete disable edit enable info list log show update" \
-- $cur) )
;;
"secure")
COMPREPLY=( $(compgen \
-W "--auth --port --ip" \
-- $cur) )
;;
"info")
COMPREPLY=( $(compgen \
-W "--mysql --php --php7 --nginx" \
-- $cur) )
;;
"log")
COMPREPLY=( $(compgen \
-W "show reset gzip mail" \
-- $cur) )
;;
# EVERYTHING ELSE
*)
;;
esac
# SETUP THE THIRD LEVEL (EVERYTHING AFTER "wo second third")
elif [ $COMP_CWORD -eq 3 ]; then
case "$prev" in
# HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE
"install" | "purge" | "remove" )
COMPREPLY=( $(compgen \
-W "--web --admin --nginx --php --php7 --mysql --wpcli --phpmyadmin --adminer --utils --all --hhvm --redis --phpredisadmin" \
-- $cur) )
;;
"upgrade" )
COMPREPLY=( $(compgen \
-W "--web --nginx --php --php7 --mysql --all --hhvm --php56 --no-prompt --wpcli" \
-- $cur) )
;;
"start" | "stop" | "reload" | "restart" | "status")
COMPREPLY=( $(compgen \
-W "--nginx --php --php7 --mysql --memcache --redis" \
-- $cur) )
;;
"migrate")
COMPREPLY=( $(compgen \
-W "--mariadb" \
-- $cur) )
;;
"list")
COMPREPLY=( $(compgen \
-W "--enabled --disabled" \
-- $cur) )
;;
"edit" | "enable" | "info" | "log" | "show" | "cd" | "delete")
if [ ${COMP_WORDS[1]} == "log" ]; then
COMPREPLY=( $(compgen \
-W "$(find /etc/nginx/sites-available/ -type f -printf "%P " 2> /dev/null) --nginx --php --fpm --mysql --access" \
-- $cur) )
else
COMPREPLY=( $(compgen \
-W "$(find /etc/nginx/sites-available/ -type f -printf "%P " 2> /dev/null)" \
-- $cur) )
fi
;;
"update")
COMPREPLY=( $(compgen \
-W "$(find /etc/nginx/sites-available/ -type f -printf "%P " 2> /dev/null) --all" \
-- $cur) )
;;
"gzip")
COMPREPLY=( $(compgen \
-W "$(find /etc/nginx/sites-available/ -type f -printf "%P " 2> /dev/null) --nginx --php --fpm --mysql --access" \
-- $cur) )
;;
"reset")
COMPREPLY=( $(compgen \
-W "$(find /etc/nginx/sites-available/ -type f -printf "%P " 2> /dev/null) --nginx --php --fpm --mysql --wp --access --slow-log-db" \
-- $cur) )
;;
"disable")
COMPREPLY=( $(compgen \
-W "$(command find /etc/nginx/sites-enabled/ -type l -printf "%P " 2> /dev/null)" \
-- $cur) )
;;
*)
;;
esac
if [ ${COMP_WORDS[1]} == "debug" ] && ([ "$prev" != "--start" ] && [ "$prev" != "--nginx" ] && [ "$prev" != "--php" ] && [ "$prev" != "--php7" ] && [ "$prev" != "--fpm" ] && [ "$prev" != "--fpm7" ] && [ "$prev" != "--mysql" ] && [ "$prev" != "-i" ] && [ "$prev" != "--interactive" ] && [ "$prev" != "--import-slow-log" ] && [ "$prev" != "--stop" ]); then
retlist="--all --wp --rewrite -i --all=off --wp=off --rewrite=off"
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
fi
#if [ ${COMP_WORDS[1]} == "log" ] && ([ "$prev" != "--access" ] || [ "$prev" != "--nginx" ] || [ "$prev" != "--php" ] || [ "$prev" != "--fpm" ] || [ "$prev" != "--mysql" ] || [ "$prev" != "-i" ] || ["$prev" != "--interactive" ] || ["$prev" != "--stop" ]); then
# retlist="--all --wp --rewrite -i --all=off --wp=off --rewrite=off"
# ret="${retlist[@]/$prev}"
# COMPREPLY=( $(compgen \
# -W "$(echo $ret)" \
# -- $cur) )
#fi
elif [ $COMP_CWORD -eq 4 ]; then
case "$mprev" in
# HANDLE EVERYTHING AFTER THE THIRD LEVEL NAMESPACE
"create")
COMPREPLY=( $(compgen \
-W "--user --pass --email --html --php --php7 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --hhvm --proxy= --wpredis --letsencrypt -le" \
-- $cur) )
;;
"update")
COMPREPLY=( $(compgen \
-W "--password --php --php7 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --hhvm --hhvm=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew" \
-- $cur) )
;;
"delete")
COMPREPLY=( $(compgen \
-W "--db --files --all --no-prompt --force -f" \
-- $cur) )
;;
"show")
COMPREPLY=( $(compgen \
-W "--wp --nginx --php --fpm --mysql --access" \
-- $cur) )
;;
"gzip")
COMPREPLY=( $(compgen \
-W "--wp --nginx --php --fpm --mysql --access" \
-- $cur) )
;;
"mail")
COMPREPLY=( $(compgen \
-W "--wp --nginx --php --fpm --mysql --access --to=" \
-- $cur) )
;;
"reset")
COMPREPLY=( $(compgen \
-W "--wp --nginx --php --fpm --mysql --wp --access --slow-log-db" \
-- $cur) )
;;
edit)
COMPREPLY=( $(compgen \
-- $cur) )
;;
*)
;;
esac
fi
case "$prev" in
"--wp")
if [ ${COMP_WORDS[1]} != "debug" ]; then
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--wp --wpsc --wpfc --hhvm --user --email --pass --wpredis --letsencrypt --php7"
elif [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--wp --wpfc --wpsc --php7 --php7=off --hhvm --hhvm=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
else
retlist="--wp --wp=off --rewrite --rewrite=off -i --interactive"
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--wpsubdir" | "--wpsubdomain")
if [ ${COMP_WORDS[1]} != "debug" ]; then
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--wpsc --wpfc --hhvm --user --email --pass --wpredis --letsencrypt --php7"
elif [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--wpfc --wpsc --php7 --php7=off --hhvm --hhvm=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
else
retlist="--wp=off --rewrite --rewrite=off -i --interactive"
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--hhvm" | "--wpredis" | "--wpfc" | "--wpsc" | "--wpsubdir" | "--wpsubdomain" | "--user" | "--pass" | "--email" | "--wp")
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--user --pass --email --wp --wpsubdir --wpsubdomain --wpfc --wpsc --hhvm --experimenal --wpredis --php7 --letsencrypt "
else
retlist=""
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--hhvm" | "--wpredis" | "--wpfc")
if [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--password --php --php7 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --hhvm --hhvm=off --experimenal --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--web" | "--admin" | "--nginx" | "--php" | "--php7" | "--mysql" | "--wpcli" | "--phpmyadmin" | "--adminer" | "--utils" | "--memcache" | "--redis | --phpredisadmin")
if [[ ${COMP_WORDS[2]} == "install" || ${COMP_WORDS[2]} == "purge" || ${COMP_WORDS[2]} == "remove" ]]; then
retlist="--web --admin --nginx --php --php7 --mysql--wpcli --phpmyadmin --adminer --utils --memcache --redis --phpredisadmin"
elif [[ ${COMP_WORDS[2]} == "start" || ${COMP_WORDS[2]} == "reload" || ${COMP_WORDS[2]} == "restart" || ${COMP_WORDS[2]} == "stop" ]]; then
retlist="--nginx --php --php7 --mysql --memcache --redis"
elif [[ ${COMP_WORDS[1]} == "debug" ]]; then
retlist="--start --nginx --php --php7 --fpm --fpm7 --mysql -i --interactive -stop --import-slow-log --import-slow-log-interval= -"
if [[ $prev == '--mysql' ]]; then
retlist="--start --nginx --php --php7 --fpm --fpm7 --mysql -i --interactive --stop --import-slow-log"
fi
elif [[ ${COMP_WORDS[1]} == "log" ]]; then
if [ ${COMP_WORDS[2]} == "show" ]; then
retlist="--access --nginx --php --mysql --fpm --wp"
elif [ ${COMP_WORDS[2]} == "reset" ]; then
retlist="--access --nginx --php --mysql --fpm --wp --slow-log-db"
elif [ ${COMP_WORDS[2]} == "mail" ]; then
retlist="--access --nginx --php --mysql --fpm --wp --to="
fi
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--db" | "--files" | "--force")
retlist="--db --files --all --force"
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--all")
if [ ${COMP_WORDS[1]} == "clean" ]; then
retlist="--memcache --opcache --fastcgi --redis"
elif [ ${COMP_WORDS[2]} == "delete" ]; then
retlist="--db --files --force"
elif [ ${COMP_WORDS[2]} == "update" ]; then
retlist="--password --php --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --hhvm --hhvm=off --wpredis --letsencrypt --letsencrypt=off --letsencrypt=renew"
else
retlist=""
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--memcache" | "--opcache" | "--fastcgi" | "--all" | "--redis")
retlist="--memcache --opcache --fastcgi --redis --all"
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--auth" | "--port" | "--ip")
retlist="--auth --port --ip"
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
"--access" | "--fpm" | "--wp" | "--slow-log-db")
if [[ ${COMP_WORDS[1]} == "log" ]]; then
if [ ${COMP_WORDS[2]} == "show" ]; then
retlist="--access --nginx --php --mysql --fpm --wp"
elif [ ${COMP_WORDS[2]} == "reset" ]; then
retlist="--access --nginx --php --mysql --fpm --wp --slow-log-db"
elif [ ${COMP_WORDS[2]} == "mail" ]; then
retlist="--access --nginx --php --mysql --fpm --wp --to="
fi
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
*)
;;
esac
case "$mprev" in
"--user" | "--email" | "--pass")
if [ ${COMP_WORDS[2]} == "create" ]; then
retlist="--user --pass --email --html --php --php7 --mysql --wp --wpsubdir --wpsubdomain --wpfc --wpsc --hhvm --wpredis --letsencrypt"
fi
ret="${retlist[@]/$prev}"
COMPREPLY=( $(compgen \
-W "$(echo $ret)" \
-- $cur) )
;;
esac
return 0
} &&
complete -F _wo_complete wo

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[clean]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[debug]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[import_slow_log]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

View File

@@ -0,0 +1,11 @@
### Example Plugin Configuration for WordOps
[info]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true
### Additional plugin configuration settings
foo = bar

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[log]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[secure]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[site]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[stack]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

View File

@@ -0,0 +1,8 @@
### Example Plugin Configuration for WordOps
[update]
### If enabled, load a plugin named `example` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

82
config/wo.conf Normal file
View File

@@ -0,0 +1,82 @@
# WordOps Configuration
#
# All commented values are the application default
#
[wo]
### Toggle application level debug (does not toggle framework debugging)
# debug = false
### Where external (third-party) plugins are loaded from
# plugin_dir = /var/lib/wo/plugins/
### Where all plugin configurations are loaded from
# plugin_config_dir = /etc/wo/plugins.d/
### Where external templates are loaded from
# template_dir = /var/lib/wo/templates/
[log.logging]
### Where the log file lives (no log file by default)
file = /var/log/wo/wordops.log
### The level for which to log. One of: info, warn, error, fatal, debug
level = debug
### Whether or not to log to console
to_console = false
### Whether or not to rotate the log file when it reaches `max_bytes`
rotate = true
### Max size in bytes that a log file can grow until it is rotated.
max_bytes = 512000
### The maximun number of log files to maintain when rotating
max_files = 7
[stack]
### IP address that will be used in Nginx configurations while installing
ip-address = 127.0.0.1
[mysql]
### MySQL database grant host name
grant-host = localhost
### Ask for MySQL db name while site creation
db-name = False
### Ask for MySQL user name while site creation
db-user = False
[wordpress]
### Ask for WordPress prefix while site creation
prefix = False
### User name for WordPress sites
user =
### Password for WordPress sites
password =
### EMail for WordPress sites
email =
[update]
### If enabled, load a plugin named `update` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true
[sync]
### If enabled, load a plugin named `update` either from the Python module
### `wo.cli.plugins.example` or from the file path
### `/var/lib/wo/plugins/example.py`
enable_plugin = true

318
docs/wo.8 Normal file
View File

@@ -0,0 +1,318 @@
.TH wo 8 "WordOps (wo) version: 3.3.8" "Sep 10,2015" "WordOps"
.SH NAME
.B WordOps (wo)
\- Manage Nginx Based Websites.
.SH SYNOPSIS
wo [ --version | --help | info | stack | site | debug | update | clean | import_slow_log | log | secure | sync]
.TP
wo stack [ install | remove | purge | migrate | upgrade] [ --web | --mail | --all | --nginx | --php | --php7 | --mysql | --admin | --postfix | --mailscanner | --adminer | --redis | --hhvm | --phpmyadmin | --phpredisadmin | --wpcli | --utils ]
.TP
wo stack [ status | start | stop | reload | restart ] [--all | --nginx | --php | --php7 |--mysql | --devcot | --web | --postfix | --memcache | --redis]
.TP
wo site [ list | info | show | enable | disable | edit | cd | show ] [ example.com ]
.TP
wo site create example.com [ --html | --php | --php7 | --mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --w3tc | --wpfc | --wpredis | --hhvm | --letsencrypt/-le]]
.TP
wo site update example.com [ --php | --php7 |--mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --w3tc | --wpfc | --wpredis | --hhvm ] [--password] [--letsencrypt=on/off/renew]]
.TP
wo site delete example.com [--db | --files | --all | --no-prompt | --force/-f ]
.TP
wo debug [ -i | --all=on/off |--nginx=on/off | --rewrite=on/off | --php=on/off | --fpm=on/off | --mysql=on/off ]
.TP
wo debug example.com [ -i | --all=on/off | --nginx=on/off | --rewrite=on/off | --wp=on/off ]
.TP
wo secure [ --auth | --port | --ip ]
.SH DESCRIPTION
WordOps aka wo is the opensource project developed with the purpose to automate web-server configuration.
.br
WordOps is the collection of python script that provides automation for the web-server
.br
installation, site creation, services debugging & monitoring.
.SH OPTIONS
.TP
.B --version
.br
Display WordOps (wo) version information.
.TP
.B info
.br
wo info - Display Nginx, PHP, MySQL and wo common location information
.br
wo site info - Diplay given website details like enable, disable. weboot and log files.
.TP
.B --help
.br
Display WordOps (wo) help.
.TP
.B stack
.TP
.B install [ --all | --web | --mail | --nginx | --php | --php7 |--mysql | --redis | --postfix | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils ]
.br
Install Nginx PHP5 MySQL Postfix stack Packages if not used with
.br
any options.Installs specific package if used with option.
.TP
.B remove [ --all | --web | --mail | --nginx | --php | --php7 |--mysql | --redis | --postfix | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils ]
.br
Remove Nginx PHP5 MySQL Postfix stack Packages if not used with
.br
any options. Remove specific package if used with option.
.TP
.B purge [ --all | --web | --mail | --nginx | --php | --php7 |--mysql | --redis | --postfix | --adminer | --phpmyadmin | --phpredismyadmin | --wpcli | --utils ]
.br
Purge Nginx PHP5 MySQL Postfix stack Packages if not used with any
.br
options.Purge specific package if used with option.
.TP
.B status
.br
Display status of NGINX, PHP5-FPM, MySQL, Postfix, Redis-Server services.
.TP
.B start
.br
Start services NGINX, PHP5-FPM, MySQL, Postfix, Redis-Server.
.TP
.B stop
.br
Stop services NGINX, PHP5-FPM, MySQL, Postfix, Redis-Server.
.TP
.B reload
.br
Reload services NGINX, PHP5-FPM, MySQL, Postfix, Redis-Server.
.TP
.B restart
.br
Restart services NGINX, PHP5-FPM, MySQL, Postfix, Redis-Server.
.TP
.B site
.br
.TP
.B cd [ example.com ]
.br
Change directory to webroot of specified site in subshell.
.TP
.B log [ example.com ]
.br
monitor access and error logs for site specified.
.TP
.B list [ --enabled | --disabled ]
.br
Lists all available sites from /etc/nginx/sites-enabled/
.br
by default & enable argument. Display sites list from
.br
/etc/nginx/sites-available/ if used with available option.
.TP
.B info [ example.com ]
.br
prints information about site such as access log, error log
.br
location and type of site.
.TP
.B show [ example.com ]
.br
Display NGINX configuration of site.
.TP
.B enable [ example.com ]
.br
Enable site by creating softlink with site file in
.br
/etc/nginx/sites-available to /etc/nginx/sites-enabled/.
.TP
.B disable [ example.com ]
.br
Disable site by Destroying softlink with site file in
.br
/etc/nginx/sites-available to /etc/nginx/sites-enabled/.
.TP
.B edit [ example.com ]
.br
Edit NGINX configuration of site.
.TP
.B create [ example.com ] [ --html | --php | --php7 |--mysql] [[--wp | --wpsubdir | --wpsubdomain ] [--wpsc | --w3tc | --wpfc | --wpredis | --hhvm ]]
.br
Create new site according to given options. If no options provided
.br
create static site with html only.
.TP
.B update [ example.com ] [ --html | --php | --php7 |--mysql] [[--wp | --wpsubdir | --wpsubdomain ] [ --wpsc | --w3tc | --wpfc | --wpredis | --hhvm ] [--password]]
.br
Update site configuration according to specified options.
.TP
.B delete [ example.com ] [--no-prompt ] [--force/-f] [ --db | --files | --all ]
.br
Delete site i.e webroot, database, ad configuration permanently.
.TP
.B debug [ -i | --nginx=on/off | --php=on/off | --php7=on/off | --mysql=on/off | --rewrite=on/off | --fpm=on/off | --fpm7=on/off ]
.br
Starts server level debugging. If this is used without arguments it will start debugging
.br
all services.Else it will debug only service provided with argument.This will Stop
.br
Debugging if used with --all=off argument.
.TP
.B debug example.com [ -i | --nginx=on/off | --rewrite=on/off | --wp=on/off | --all=on/off ]
.br
Starts site level debugging. If this is used without arguments it will start debugging all
.br
services.Else it will debug only service provided with argument.This will Stop Debugging
.br
if used with --all=off argument.
.TP
.B secure [ --auth | --port | --ip ]
.br
Update security settings.
.TP
.B clean [ --fastcgi | --opcache | --memcache | --redis | --all ]
.br
Clean NGINX fastCGI cache, Opcache, Memcache, Redis cache.
.br
Clean NGINX fastCGI cache if no option specified.
.SH ARGUMENTS
.TP
.B -i
.br
setup intractive mode while used with debug.
.TP
.B --nginx=on/off
.br
used with wo debug command. used to start or stop nginx debugging.
.TP
.B --php=on/off
.br
used with wo debug command. used to start or stop php debugging.
.TP
.B --php7=on/off
.br
used with wo debug command. used to start or stop php7 debugging.
.TP
.B --mysql=on/off
.br
used with wo debug command. used to start or stop mysql debugging.
.TP
.B --rewrite=on/off
.br
used with wo debug command. used to start or stop nginx rewrite rules debugging.
.TP
.B --fpm=on/off
.br
used with wo debug command. used to start or stop fpm debugging.
.TP
.B --wp=on/off
.br
used with wo debug command. used to start or stop wordpress site debugging.
.TP
.B --all=on/off
.br
used with wo debug command. used to stop debugging.
.TP
.B --all=off
.br
used with wo debug command. used to stop debugging.
.TP
.B --html
.br
Create a HTML website.
.TP
.B --php
.br
Create a PHP website.
.TP
.B --mysql
.br
Create a PHP+MySQL website.
.TP
.B --wp
.br
Create a WordPress Website.
.TP
.B --wpsubdir
.br
Create a Wordpress Multisite with Sub Directories Setup.
.TP
.B --wpsubdomain
.br
Create a Wordpress Multisite with Sub Domains Setup.
.br
.TP
.B --db
.br
Delete website database.
.br
.TP
.B --files
.br
Delete website webroot.
.br
.TP
.B --no-prompt
.br
Does not prompt for confirmation when delete command used.
.br
.TP
.B --force/-f
.br
Delete website webroot and database forcefully.Remove nginx configuration for site.
.br
.TP
.B --auth
.br
used with wo secure command. Update credential of HTTP authentication
.TP
.B --port
.br
used with wo secure command. Change WordOps admin port 22222.
.TP
.B --ip
.br
used with wo secure command. Update whitelist IP address
.SH WORDPRESS CACHING OPTIONS
.TP
.B --wpsc
.br
Install and activate Nginx-helper and WP Super Cache plugin.
.TP
.B --wpfc
.br
Install and activate Nginx-helper and W3 Total Cache plugin with
.br
Nginx FastCGI cache.
.TP
.B --wpredis
.br
Install, activate, configure Nginx-helper and Redis Object Cache Plugin, Configure NGINX for Redis Page Caching.
.TP
.B --hhvm
.br
Install, activate Nginx-helper and configure NGINX for HHVM.
.SH FILES
.br
/etc/wo/wo.conf
.SH BUGS
Report bugs at <http://github.com/WordOps/WordOps/issues/>
.SH AUTHOR
.br
.B rtCamp Team
.I \<admin@rtcamp.com\>
.br
.B Mitesh Shah
.I \<Mitesh.Shah@rtcamp.com\>
.br
.B Manish
.I \<Manish.Songirkar@rtcamp.com\>
.br
.B Gaurav
.I \<Gaurav.Astikar@rtcamp.com\>
.br
.B Harshad
.I \<harshad.yeola@rtcamp.com>
.br
.B Prabuddha
.I \<prabuddha.chakraborty@rtcamp.com\>
.br
.B Shital
.I \<shital.patil@rtcamp.com\>
.br
.B Rajdeep Sharma
.I \<rajdeep.sharma@rtcamp.com\>
.br

744
install Normal file
View File

@@ -0,0 +1,744 @@
#!/bin/bash
# WordOps update script.
# This script is designed to install latest WordOps or
# to update current WordOps from the v3 branch of EasyEngine.
# Define echo function
# Blue color
function wo_lib_echo()
{
echo $(tput setaf 4)$@$(tput sgr0)
}
# White color
function wo_lib_echo_info()
{
echo $(tput setaf 7)$@$(tput sgr0)
}
# Red color
function wo_lib_echo_fail()
{
echo $(tput setaf 1)$@$(tput sgr0)
}
# Checking permissions
if [[ $EUID -ne 0 ]]; then
wo_lib_echo_fail "Sudo privilege required..."
wo_lib_echo_fail "Uses: wget -qO wo wordops.se/tup && sudo bash wo"
exit 100
fi
# Capture errors
function wo_lib_error()
{
echo "[ `date` ] $(tput setaf 1)$@$(tput sgr0)"
exit $2
}
# Execute: apt-get update
wo_lib_echo "Executing apt-get update, please wait..."
apt-get update &>> /dev/null
# Checking lsb_release package
if [ ! -x /usr/bin/lsb_release ]; then
wo_lib_echo "Installing lsb-release, please wait..."
apt-get -y install lsb-release &>> /dev/null
fi
# Define variables for later use
wo_branch=$1
readonly wo_version_old="2.2.3"
readonly wo_version_new="3.8.1"
readonly wo_log_dir=/var/log/wo/
readonly wo_install_log=/var/log/wo/install.log
readonly wo_linux_distro=$(lsb_release -i | awk '{print $3}')
readonly wo_distro_version=$(lsb_release -sc)
# Checking linux distro
if [ "$wo_linux_distro" != "Ubuntu" ] && [ "$wo_linux_distro" != "Debian" ]; then
wo_lib_echo_fail "WordOps (wo) only supports Ubuntu and Debian at the moment."
wo_lib_echo_fail "If you are feeling adventurous, you are free to fork WordOps to support"
wo_lib_echo_fail "other Linux distributions and perhaps even Unix deratives."
wo_lib_echo_fail "WordOps (wo) only supports Ubuntu 14.04/16.04/18.04, Debian 8.x and Debian 9.x"
exit 100
fi
# WordOps (wo) only supports Ubuntu/Debian versions that are eligible for support
lsb_release -d | egrep -e "14.04|16.04|18.04|jessie|stretch" &>> /dev/null
if [ "$?" -ne "0" ]; then
wo_lib_echo_fail "WordOps (wo) only supports Ubuntu 14.04/16.04/18.04, Debian 8.x and Debian 9.x"
exit 100
fi
# To prevent errors or unexpected behaviour, create
# the log directory and properly set the ACL.
if [ ! -d $wo_log_dir ]; then
wo_lib_echo "Creating WordOps log directory, just a second..."
mkdir -p $wo_log_dir || wo_lib_error "Whoops - seems we are unable to create the log directory $wo_log_dir, exit status " $?
# Touch/create two empty log files within the wo_log_dir
touch /var/log/wo/{wordops.log,install.log}
# Set the ACL to only allow access by the root user and block others
chmod -R 700 /var/log/wo || wo_lib_error "Whoops, there was an error setting the permissions on the WordOps log folder, exit status " $?
fi
# Install a few dependencies (python v3, git, tar and python-software-properties),
# plus generate the locale afterwards.
function wo_install_dep()
{
if [ "$wo_linux_distro" == "Ubuntu" ]; then
apt-get -y install build-essential curl gzip python3 python3-apt python3-setuptools python3-dev sqlite3 git tar software-properties-common || wo_lib_error "There was an error during dependency installation, exit status " 1
elif [ "$wo_linux_distro" == "Debian" ]; then
apt-get -y install build-essential curl gzip dirmngr python3 python3-apt python3-setuptools python3-dev sqlite3 git tar python-software-properties || wo_lib_error "There was an error during dependency installation, exit status " 1
fi
# Generate the locale, output to the blackhole rather than STDOUT
locale-gen en &>> /dev/null
}
# Create the WordOps database and intialize it
function wo_sync_db()
{
if [ ! -f /var/lib/wo/dbase.db ]; then
mkdir -p /var/lib/wo
echo "CREATE TABLE sites (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sitename UNIQUE,
site_type CHAR,
cache_type CHAR,
site_path CHAR,
created_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
is_enabled INT,
is_ssl INT,
storage_fs CHAR,
storage_db CHAR,
db_name VARCHAR,
db_user VARCHAR,
db_password VARCHAR,
db_host VARCHAR,
is_hhvm INT INT DEFAULT '0',
php_version VARCHAR
);" | sqlite3 /var/lib/wo/dbase.db
# Check site is enable/live or disable
for site in $(ls /etc/nginx/sites-available/ | grep -v default);
do
if [ -f /etc/nginx/sites-enabled/$site ]; then
wo_site_status='1'
else
wo_site_status='0'
fi
# Acquire information about the current nginx configuration
wo_site_current_type=$(head -n1 /etc/nginx/sites-available/$site | grep "NGINX CONFIGURATION" | rev | cut -d' ' -f3,4,5,6,7 | rev | cut -d ' ' -f2,3,4,5)
# Sniff out the vhost type and cache configuration
if [ "$wo_site_current_type" = "HTML" ]; then
wo_site_current="html"
wo_site_current_cache="basic"
elif [ "$wo_site_current_type" = "PHP" ]; then
wo_site_current="php"
wo_site_current_cache="basic"
elif [ "$wo_site_current_type" = "MYSQL" ]; then
wo_site_current="mysql"
wo_site_current_cache="basic"
# Caching types on a single WordPress installation
elif [ "$wo_site_current_type" = "WPSINGLE BASIC" ]; then
wo_site_current="wp"
wo_site_current_cache="basic"
elif [ "$wo_site_current_type" = "WPSINGLE WP SUPER CACHE" ]; then
wo_site_current="wp"
wo_site_current_cache="wpsc"
elif [ "$wo_site_current_type" = "WPSINGLE FAST CGI" ] || [ "$wo_site_current_type" = "WPSINGLE FASTCGI" ]; then
wo_site_current="wp"
wo_site_current_cache="wpfc"
# Caching types on a single, subdirectory WordPress installation
elif [ "$wo_site_current_type" = "WPSUBDIR BASIC" ]; then
wo_site_current="wpsubdir"
wo_site_current_cache="basic"
elif [ "$wo_site_current_type" = "WPSUBDIR WP SUPER CACHE" ]; then
wo_site_current="wpsubdir"
wo_site_current_cache="wpsc"
elif [ "$wo_site_current_type" = "WPSUBDIR FAST CGI" ] || [ "$wo_site_current_type" = "WPSUBDIR FASTCGI" ]; then
wo_site_current="wpsubdir"
wo_site_current_cache="wpfc"
# Caching types on a single, subdomain WordPress installation
elif [ "$wo_site_current_type" = "WPSUBDOMAIN BASIC" ]; then
wo_site_current="wpsubdomain"
wo_site_current_cache="basic"
elif [ "$wo_site_current_type" = "WPSUBDOMAIN WP SUPER CACHE" ]; then
wo_site_current="wpsubdomain"
wo_site_current_cache="wpsc"
elif [ "$wo_site_current_type" = "WPSUBDOMAIN FAST CGI" ] || [ "$wo_site_current_type" = "WPSUBDOMAIN FASTCGI" ]; then
wo_site_current="wpsubdomain"
wo_site_current_cache="wpfc"
fi
wo_webroot="/var/www/$site"
# Import the configuration into the WordOps SQLite database
echo "INSERT INTO sites (sitename, site_type, cache_type, site_path, is_enabled, is_ssl, storage_fs, storage_db)
VALUES (\"$site\", \"$wo_site_current\", \"$wo_site_current_cache\", \"$wo_webroot\", \"$wo_site_status\", 0, 'ext4', 'mysql');" | sqlite3 /var/lib/wo/dbase.db
done
else
wo_php_version=$(php -v | head -n1 | cut -d' ' -f2 |cut -c1-3)
wo_lib_echo "Updating WordOps Database"
echo "ALTER TABLE sites ADD COLUMN db_name varchar;" | sqlite3 /var/lib/wo/dbase.db
echo "ALTER TABLE sites ADD COLUMN db_user varchar; " | sqlite3 /var/lib/wo/dbase.db
echo "ALTER TABLE sites ADD COLUMN db_password varchar;" | sqlite3 /var/lib/wo/dbase.db
echo "ALTER TABLE sites ADD COLUMN db_host varchar;" | sqlite3 /var/lib/wo/dbase.db
echo "ALTER TABLE sites ADD COLUMN is_hhvm INT DEFAULT '0';" | sqlite3 /var/lib/wo/dbase.db
echo "ALTER TABLE sites ADD COLUMN php_version varchar DEFAULT \"$wo_php_version\";" | sqlite3 /var/lib/wo/dbase.db
fi
}
# Once again, set the proper ACL on the WordOps configuration directory
function secure_wo_db()
{
# The owner is root
chown -R root:root /var/lib/wo/
# Only allow access by root, block others
chmod -R 600 /var/lib/wo/
}
# Update the WP-CLI version
function wo_update_wp_cli()
{
wo_lib_echo "Updating WP-CLI version to resolve compatibility issue."
PHP_PATH=$(which php)
WP_CLI_PATH=$(which wp)
if [ "${WP_CLI_PATH}" != "" ]; then
# Obtain the current WP-CLI version
WP_CLI_VERSION=$(${PHP_PATH} ${WP_CLI_PATH} --allow-root cli version | awk '{ print $2 }')
dpkg --compare-versions ${WP_CLI_VERSION} lt 1.4.1
# Update WP-CLI to the most recent version
if [ "$?" == "0" ]; then
wget -qO ${WP_CLI_PATH} https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x ${WP_CLI_PATH}
fi
fi
}
# Now, finally, let's install WordOps
function wo_install()
{
# Remove old versions of EasyEngine/WordOps
rm -rf /tmp/easyengine &>> /dev/null
rm -rf /tmp/wordops &>> /dev/null
# Clone the latest version directly from GitHub
wo_lib_echo "Downloading WordOps straight from GitHub - fresh and brewed with love. Hold your horses..."
if [ "$wo_branch" = "" ]; then
wo_branch=master
fi
git clone -b $wo_branch https://github.com/WordOps/WordOps.git /tmp/wordops --quiet > /dev/null \
|| wo_lib_error "An error was encountered during the download, exit status" $?
cd /tmp/wordops
wo_lib_echo "The moment you've all been waiting for, time to install WordOps!"
python3 setup.py install || wo_lib_error "An error was encountered during the installation, exit status " $?
}
# Update the WordOps installation,
# remove old versions
function wo_update()
{
wo_lib_echo "Importing the EasyEngine configuration and magically importing it to WordOps."
wo_lib_echo "No worries, we'll make sure the configuration is duly backupped..."
wo_grant_host=$(grep grant-host /etc/easyengine/ee.conf | awk '{ print $3 }' | head -1 )
wo_db_name=$(grep db-name /etc/easyengine/ee.conf | awk '{ print $3 }')
wo_db_user=$(grep db-name /etc/easyengine/ee.conf | awk '{ print $3 }')
wo_wp_prefix=$(grep prefix /etc/easyengine/ee.conf | awk '{ print $3 }')
wo_wp_user=$(grep 'user ' /etc/easyengine/ee.conf | grep -v db-user |awk '{ print $3 }')
wo_wp_pass=$(grep password /etc/easyengine/ee.conf | awk '{ print $3 }')
wo_wp_email=$(grep email /etc/easyengine/ee.conf | awk '{ print $3 }')
wo_ip_addr=$(grep ip-address /etc/easyengine/ee.conf |awk -F'=' '{ print $2 }')
sed -i "s/ip-address.*/ip-address = ${wo_ip_addr}/" /etc/wo/wo.conf && \
sed -i "s/grant-host.*/grant-host = ${wo_grant_host}/" /etc/ee/wo.conf && \
sed -i "s/db-name.*/db-name = ${db-name}/" /etc/ee/wo.conf && \
sed -i "s/db-user.*/db-user = ${wo_db_user}/" /etc/wo/wo.conf && \
sed -i "s/prefix.*/prefix = ${wo_wp_prefix}/" /etc/wo/wo.conf && \
sed -i "s/^user.*/user = ${wo_wp_user}/" /etc/wo/wo.conf && \
sed -i "s/password.*/password = ${wo_wp_password}/" /etc/wo/wo.conf && \
sed -i "s/email.*/email = ${wo_wp_email}/" /etc/wo/wo.conf || wo_lib_error "An error was encountered during the configuration update, exit status " $?
wo_lib_echo "Removing EasyEngine 2.x"
rm -rf /etc/bash_completion.d/ee /etc/easyengine/ /usr/share/easyengine/ /usr/local/lib/easyengine /usr/local/sbin/easyengine /usr/local/sbin/ee /var/log/easyengine
# Softlink to fix command not found error
ln -s /usr/local/bin/wo /usr/local/sbin/wo || wo_lib_error "Unable to softlink the WordOps binary, exit status " $?
}
function wo_upgrade_php(){
# Change the PHP repository for PHP 7.x support
if [ "$wo_distro_version" == "trusty" ]; then
if [ -f /etc/apt/sources.list.d/ondrej-php5-5_6-trusty.list ]; then
# add-apt-repository -y --remove 'ppa:ondrej/php5-5.6'
add-apt-repository -y 'ppa:ondrej/php'
wo_lib_echo "Updating the PHP repository for some neat PHP 7 support"
apt-get update &>> /dev/null
apt-get -y install php5.6-fpm php5.6-curl php5.6-gd php5.6-imap php5.6-mcrypt php5.6-readline php5.6-mysql php5.6-cli php5.6-common php5.6-curl php5.6-mbstring php5.6-bcmath php5.6-recode php5.6-mysql php5.6-opcache php-memcached php-imagick memcached php-pear php-xdebug php-msgpack php5.6-zip php5.6-xml php5.6-soap php-memcache || wo_lib_error "Unable to install PHP 5.6 packages, exit status " 1
if [ -e /etc/php5/fpm/pool.d/www.conf -a -e /etc/php5/fpm/pool.d/debug.conf -a -e /etc/php5/fpm/php.ini -a -e /etc/php5/fpm/php-fpm.conf ]; then
cp -f /etc/php5/fpm/pool.d/www.conf /etc/php/5.6/fpm/pool.d/www.conf &>> /dev/null
cp -f /etc/php5/fpm/pool.d/debug.conf /etc/php/5.6/fpm/pool.d/debug.conf &>> /dev/null
cp -f /etc/php5/fpm/php.ini /etc/php/5.6/fpm/php.ini &>> /dev/null
cp -f /etc/php5/fpm/php-fpm.conf /etc/php/5.6/fpm/php-fpm.conf &>> /dev/null
else
echo "Some expected files are missing." || wo_lib_error "Unable to configure PHP 5.6 packages, exit status " 1
fi
sed -i "s/pid.*/pid = \/run\/php\/php5.6-fpm.pid/" /etc/php/5.6/fpm/php-fpm.conf && \
sed -i "s/error_log.*/error_log = \/var\/log\/php\/5.6\/fpm.log/" /etc/php/5.6/fpm/php-fpm.conf && \
sed -i "s/log_level.*/log_level = notice/" /etc/php/5.6/fpm/php-fpm.conf && \
sed -i "s/include.*/include = \/etc\/php\/5.6\/fpm\/pool.d\/*.conf/" /etc/php/5.6/fpm/php-fpm.conf && \
sed -i "s/slowlog =.*/slowlog = \/var\/log\/php\/5.6\/slow.log/" /etc/php/5.6/fpm/pool.d/debug.conf || wo_lib_error "An error was encountered during the configuration update, exit status " $?
mkdir -p /var/log/php/5.6/
touch /var/log/php/5.6/slow.log /var/log/php/5.6/fpm.log
service php5-fpm stop &>> /dev/null
service php5.6-fpm restart &>> /dev/null
rm -f /etc/apt/sources.list.d/ondrej-php5-5_6-trusty.list &>> /dev/null
apt-get remove -y php5-fpm php5-curl php5-gd php5-imap php5-mcrypt php5-common php5-readline php5-mysql php5-cli php5-memcache php5-imagick memcached graphviz php-pear
# Fix for PHP 5.6 + 7.0 missed packages
elif [ -f /etc/php/mods-available/readline.ini ]; then
mkdir -p /tmp/php-conf/5.6
mkdir -p /tmp/php-conf/7.0
cp -f /etc/php/5.6/fpm/pool.d/www.conf /tmp/php-conf/5.6 &>> /dev/null
cp -f /etc/php/5.6/fpm/pool.d/debug.conf /tmp/php-conf/5.6 &>> /dev/null
cp -f /etc/php/5.6/fpm/php.ini /tmp/php-conf/5.6 &>> /dev/null
cp -f /etc/php/5.6/fpm/php-fpm.conf /tmp/php-conf/5.6 &>> /dev/null
cp -f /etc/php/7.0/fpm/pool.d/www.conf /tmp/php-conf/7.0 &>> /dev/null
cp -f /etc/php/7.0/fpm/pool.d/debug.conf /tmp/php-conf/7.0 &>> /dev/null
cp -f /etc/php/7.0/fpm/php.ini /tmp/php-conf/7.0 &>> /dev/null
cp -f /etc/php/7.0/fpm/php-fpm.conf /tmp/php-conf/7.0 &>> /dev/null
apt-get -y install php5.6-fpm php5.6-curl php5.6-gd php5.6-imap php5.6-mcrypt php5.6-readline php5.6-mysql php5.6-cli php5.6-common php5.6-curl php5.6-mbstring php5.6-bcmath php5.6-recode php5.6-mysql php5.6-opcache php-memcached php-imagick memcached php-pear php-xdebug php-msgpack php5.6-zip php5.6-xml php-memcache || wo_lib_error "Unable to install PHP 5.6 packages, exit status " 1
dpkg-query -W -f='${Status} ${Version}\n' php7.0-fpm 2>/dev/null | grep installed
if [ "$?" -eq "0" ]; then
apt-get -y install php7.0-fpm php7.0-curl php7.0-gd php7.0-imap php7.0-mcrypt php7.0-readline php7.0-common php7.0-recode php7.0-mysql php7.0-cli php7.0-curl php7.0-mbstring php7.0-bcmath php7.0-mysql php7.0-opcache php7.0-zip php7.0-xml php-memcached php-imagick php-memcache memcached php-pear php-xdebug php-msgpack php7.0-soap || wo_lib_error "Unable to install PHP 7.0 packages, exit status " 1
mv -f /tmp/php-conf/7.0/www.conf /etc/php/7.0/fpm/pool.d/www.conf &>> /dev/null
mv -f /tmp/php-conf/7.0/debug.conf /etc/php/7.0/fpm/pool.d/debug.conf &>> /dev/null
mv -f /tmp/php-conf/7.0/php.ini /etc/php/7.0/fpm/php.ini &>> /dev/null
mv -f /tmp/php-conf/7.0/php-fpm.conf /etc/php/7.0/fpm/php-fpm.conf &>> /dev/null
service php7.0-fpm restart &>> /dev/null
fi
mv -f /tmp/php-conf/5.6/www.conf /etc/php/5.6/fpm/pool.d/www.conf &>> /dev/null
mv -f /tmp/php-conf/5.6/debug.conf /etc/php/5.6/fpm/pool.d/debug.conf &>> /dev/null
mv -f /tmp/php-conf/5.6/php.ini /etc/php/5.6/fpm/php.ini &>> /dev/null
mv -f /tmp/php-conf/5.6/php-fpm.conf /etc/php/5.6/fpm/php-fpm.conf &>> /dev/null
service php5.6-fpm restart &>> /dev/null
rm -rf /tmp/php-conf
fi
fi
}
function wo_update_latest()
{
if [ -f /etc/nginx/fastcgi_params ]
then
cat /etc/nginx/fastcgi_params| grep -q 'HTTP_PROXY'
if [[ $? -ne 0 ]]; then
echo "fastcgi_param HTTP_PROXY \"\";" >> /etc/nginx/fastcgi_params
echo "fastcgi_param HTTP_PROXY \"\";" >> /etc/nginx/fastcgi.conf
service nginx restart &>> /dev/null
fi
fi
if [ -f /etc/ImageMagick/policy.xml ]
then
if [ ! -f /etc/ImageMagick/patch.txt ]
then
echo -e "\t<policy domain="coder" rights="none" pattern="EPHEMERAL" />\n\t<policy domain="coder" rights="none" pattern="URL" />\n\t<policy domain="coder" rights="none" pattern="HTTPS" />\n\t<policy domain="coder" rights="none" pattern="MVG" />\n\t<policy domain="coder" rights="none" pattern="MSL" />" >> /etc/ImageMagick/patch.txt
sed -i '/<policymap>/r /etc/ImageMagick/patch.txt' /etc/ImageMagick/policy.xml
fi
fi
#Move ~/.my.cnf to /etc/mysql/conf.d/my.cnf
if [ ! -f /etc/mysql/conf.d/my.cnf ]
then
#create conf.d folder if not exist
if [ ! -d /etc/mysql/conf.d ]; then
mkdir -p /etc/mysql/conf.d
chmod 755 /etc/mysql/conf.d
fi
if [ -d /etc/mysql/conf.d ]
then
if [ -f ~/.my.cnf ]
then
cp ~/.my.cnf /etc/mysql/conf.d/my.cnf &>> /dev/null
chmod 600 /etc/mysql/conf.d/my.cnf
else
if [ -f /root/.my.cnf ]
then
cp /root/.my.cnf /etc/mysql/conf.d/my.cnf &>> /dev/null
chmod 600 /etc/mysql/conf.d/my.cnf
else
wo_lib_echo_fail ".my.cnf cannot be located in your current user or root folder..."
fi
fi
fi
fi
if [ -f /etc/nginx/nginx.conf ]; then
wo_lib_echo "Updating Nginx configuration, please wait..."
# From version 3.1.10 we are using Suse builder for repository
if [ "$wo_distro_version" == "precise" ]; then
wo_lib_echo_fail ".my.cnf cannot be located in your current user or root folder..."
elif [ "$wo_distro_version" == "trusty" ]; then
grep -Hr 'http://download.opensuse.org/repositories/home:/rtCamp:/EasyEngine/xUbuntu_14.04/ /' /etc/apt/sources.list.d/ &>> /dev/null
if [[ $? -ne 0 ]]; then
if [ -f /etc/apt/sources.list.d/rtcamp-nginx-trusty.list ]; then
rm -rf /etc/apt/sources.list.d/rtcamp-nginx-trusty.list
fi
echo -e "\ndeb http://download.opensuse.org/repositories/home:/rtCamp:/EasyEngine/xUbuntu_14.04/ /" >> /etc/apt/sources.list.d/wo-repo.list
gpg --keyserver "hkp://pgp.mit.edu" --recv-keys '3050AC3CD2AE6F03'
gpg -a --export --armor '3050AC3CD2AE6F03' | apt-key add -
if [ -f /etc/nginx/conf.d/ee-nginx.conf ]; then
mv /etc/nginx/conf.d/ee-nginx.conf /etc/nginx/conf.d/ee-nginx.conf.old &>> /dev/null
fi
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old &>> /dev/null
apt-get update
service nginx stop &>> /dev/null
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install nginx-custom nginx-ee
service nginx restart &>> /dev/null
fi
dpkg --get-selections | grep -v deinstall | grep nginx-common
if [ $? -eq 0 ]; then
apt-get update
dpkg --get-selections | grep -v deinstall | grep nginx-mainline
if [ $? -eq 0 ]; then
apt-get remove -y nginx-mainline
fi
service nginx stop &>> /dev/null
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y --allow-unauthenticated install nginx-ee nginx-custom
service nginx restart &>> /dev/null
fi
elif [ "$wo_distro_version" == "wheezy" ]; then
grep -Hr 'http://download.opensuse.org/repositories/home:/rtCamp:/EasyEngine/Debian_7.0/ /' /etc/apt/sources.list.d/ &>> /dev/null
#grep -Hr "deb http://packages.dotdeb.org wheezy all" /etc/apt/sources.list.d/wo-repo.list &>> /dev/null
if [[ $? -ne 0 ]]; then
# if [ -f /etc/apt/sources.list.d/dotdeb-wheezy.list ]; then
# rm -rf /etc/apt/sources.list.d/dotdeb-wheezy.list
# else
# sed -i "/deb http:\/\/packages.dotdeb.org wheezy all/d" /etc/apt/sources.list.d/wo-repo.list &>> /dev/null
# fi
echo -e "deb http://download.opensuse.org/repositories/home:/rtCamp:/EasyEngine/Debian_7.0/ /" >> /etc/apt/sources.list.d/wo-repo.list
gpg --keyserver "hkp://pgp.mit.edu" --recv-keys '3050AC3CD2AE6F03'
gpg -a --export --armor '3050AC3CD2AE6F03' | apt-key add -
if [ -f /etc/nginx/conf.d/wo-nginx.conf ]; then
mv /etc/nginx/conf.d/wo-nginx.conf /etc/nginx/conf.d/wo-nginx.conf.old &>> /dev/null
fi
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old &>> /dev/null
mv /etc/nginx/fastcgi_params /etc/nginx/fastcgi_params.old &>> /dev/null
apt-get update
service nginx stop &>> /dev/null
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install nginx-custom
service nginx restart &>> /dev/null
fi
dpkg --get-selections | grep -v deinstall | grep nginx-common
if [ $? -eq 0 ]; then
apt-get update
service nginx stop &>> /dev/null
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install nginx-ee nginx-custom
service nginx restart &>> /dev/null
fi
elif [ "$wo_distro_version" == "jessie" ]; then
grep -Hr 'http://download.opensuse.org/repositories/home:/rtCamp:/EasyEngine/Debian_8.0/ /' /etc/apt/sources.list.d/ &>> /dev/null
#grep -Hr "deb http://packages.dotdeb.org jessie all" /etc/apt/sources.list.d/wo-repo.list &>> /dev/null
if [[ $? -ne 0 ]]; then
#sed -i "/deb http:\/\/packages.dotdeb.org jessie all/d" /etc/apt/sources.list.d/wo-repo.list &>> /dev/null
echo -e "deb http://download.opensuse.org/repositories/home:/rtCamp:/EasyEngine/Debian_8.0/ /" >> /etc/apt/sources.list.d/wo-repo.list
gpg --keyserver "hkp://pgp.mit.edu" --recv-keys '3050AC3CD2AE6F03'
gpg -a --export --armor '3050AC3CD2AE6F03' | apt-key add -
if [ -f /etc/nginx/conf.d/ee-nginx.conf ]; then
mv /etc/nginx/conf.d/ee-nginx.conf /etc/nginx/conf.d/ee-nginx.conf.old &>> /dev/null
fi
mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old &>> /dev/null
mv /etc/nginx/fastcgi_params /etc/nginx/fastcgi_params.old &>> /dev/null
apt-get update
service nginx stop &>> /dev/null
apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y install nginx-custom
service nginx restart &>> /dev/null
fi
dpkg --get-selections | grep -v deinstall | grep nginx-common
if [ $? -eq 0 ]; then
apt-get update
dpkg --get-selections | grep -v deinstall | grep nginx-mainline
if [ $? -eq 0 ]; then
apt-get remove -y nginx-mainline
fi
service nginx stop &>> /dev/null
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confmiss" -o Dpkg::Options::="--force-confold" -y --allow-unauthenticated install nginx-ee nginx-custom
service nginx restart &>> /dev/null
fi
fi
fi
if [ -f /etc/nginx/nginx.conf ]; then
sed -i "s/.*X-Powered-By.*/\tadd_header X-Powered-By \"WordOps $wo_version_new\";/" /etc/nginx/nginx.conf &>> /dev/null
fi
if [ -f /etc/nginx/conf.d/wo-plus.conf ]; then
sed -i "s/.*X-Powered-By.*/\tadd_header X-Powered-By \"WordOps $wo_version_new\";/" /etc/nginx/conf.d/wo-plus.conf &>> /dev/null
fi
# Disable Xdebug on old systems if and only if wo debug is off
if [ -f /etc/php5/mods-available/xdebug.ini ]; then
wo_debug_value=$(grep -Hr 9001 /etc/nginx/conf.d/upstream.conf | wc -l )
if [ $wo_debug_value -eq 1 ]; then
grep -Hr ";zend_extension" /etc/php5/mods-available/xdebug.ini &>> /dev/null
if [ $? -ne 0 ]; then
sed -i "s/zend_extension/;zend_extension/" /etc/php5/mods-available/xdebug.ini
fi
fi
fi
# Fix HHVM autostart on reboot
dpkg --get-selections | grep -v deinstall | grep hhvm &>> /dev/null
if [ $? -eq 0 ]; then
update-rc.d hhvm defaults &>> /dev/null
fi
# Fix WordPress example.html issue
# Ref: http://wptavern.com/xss-vulnerability-in-jetpack-and-the-twenty-fifteen-default-theme-affects-millions-of-wordpress-users
dpkg --get-selections | grep -v deinstall | grep nginx &>> /dev/null
if [ $? -eq 0 ]; then
cp /usr/lib/wo/templates/locations.mustache /etc/nginx/common/locations.conf &>> /dev/null
fi
# Fix HHVM upstream issue that was preventing from using EasyEngine for site operations
if [ -f /etc/nginx/conf.d/upstream.conf ]; then
grep -Hr hhvm /etc/nginx/conf.d/upstream.conf &>> /dev/null
if [ $? -ne 0 ]; then
echo -e "upstream hhvm {\n# HHVM Pool\nserver 127.0.0.1:8000;\nserver 127.0.0.1:9000 backup;\n}\n" >> /etc/nginx/conf.d/upstream.conf
fi
fi
# Fix HHVM server IP
if [ -f /etc/hhvm/server.ini ]; then
grep -Hr "hhvm.server.ip" /etc/hhvm/server.ini &>> /dev/null
if [ $? -ne 0 ]; then
echo -e "hhvm.server.ip = 127.0.0.1\n" >> /etc/hhvm/server.ini
fi
fi
# Rename Redis Header
if [ -f /etc/nginx/common/redis-hhvm.conf ]; then
sed -i "s/X-Cache /X-SRCache-Fetch-Status /g" /etc/nginx/common/redis-hhvm.conf &>> /dev/null
sed -i "s/X-Cache-2 /X-SRCache-Store-Status /g" /etc/nginx/common/redis-hhvm.conf &>> /dev/null
fi
if [ -f /etc/nginx/common/redis.conf ]; then
sed -i "s/X-Cache /X-SRCache-Fetch-Status /g" /etc/nginx/common/redis.conf &>> /dev/null
sed -i "s/X-Cache-2 /X-SRCache-Store-Status /g" /etc/nginx/common/redis.conf &>> /dev/null
fi
if [ -f /etc/nginx/common/redis-hhvm.conf ]; then
# Update Timeout redis-hhvm.conf
grep -0 'redis2_query expire $key 6h' /etc/nginx/common/redis-hhvm.conf &>> /dev/null
if [ $? -eq 0 ]; then
sed -i 's/redis2_query expire $key 6h/redis2_query expire $key 14400/g' /etc/nginx/common/redis-hhvm.conf &>> /dev/null
fi
#Fix for 3.3.4 redis-hhvm issue
grep -0 'HTTP_ACCEPT_ENCODING' /etc/nginx/common/redis-hhvm.conf &>> /dev/null
if [ $? -ne 0 ]; then
sed -i 's/fastcgi_params;/fastcgi_params;\n fastcgi_param HTTP_ACCEPT_ENCODING "";/g' /etc/nginx/common/redis-hhvm.conf &>> /dev/null
fi
fi
#Fix Security Issue. commit #c64f28e
if [ -f /etc/nginx/common/locations.conf ]; then
grep -0 '$request_uri ~\* \"^.+(readme|license|example)\\.(txt|html)$\"' /etc/nginx/common/locations.conf &>> /dev/null
if [ $? -eq 0 ]; then
sed -i 's/$request_uri ~\* \"^.+(readme|license|example)\\.(txt|html)$\"/$uri ~\* \"^.+(readme|license|example)\\.(txt|html)$\"/g' /etc/nginx/common/locations.conf &>> /dev/null
fi
fi
#Fix Redis-server security issue
#http://redis.io/topics/security
if [ -f /etc/redis/redis.conf ]; then
grep -0 -v "#" /etc/redis/redis.conf | grep 'bind' &>> /dev/null
if [ $? -ne 0 ]; then
sed -i '$ a bind 127.0.0.1' /etc/redis/redis.conf &>> /dev/null
service redis-server restart &>> /dev/null
fi
fi
#Fix For --letsencrypt
if [ -f /etc/nginx/common/locations.conf ]; then
grep -0 'location ~ \/\\.well-known' /etc/nginx/common/locations.conf &>> /dev/null
if [ $? -ne 0 ]; then
sed -i 's/# Deny hidden files/# Deny hidden files\nlocation ~ \/\\.well-known {\n allow all;\n}\n /g' /etc/nginx/common/locations.conf &>> /dev/null
fi
fi
# Fix for 3.3.2 renamed nginx.conf
nginx -V 2>&1 &>>/dev/null
if [[ $? -eq 0 ]]; then
nginx -t 2>&1 | grep 'open() "/etc/nginx/nginx.conf" failed' &>>/dev/null
if [[ $? -eq 0 ]]; then
if [ -f /etc/nginx/nginx.conf.old ]; then
if [ ! -f /etc/nginx/nginx.conf ]; then
cp /etc/nginx/nginx.conf.old /etc/nginx/nginx.conf
fi
fi
fi
# Fix for 3.3.2 renamed fastcgi_param
nginx -t 2>&1 | grep 'open() "/etc/nginx/fastcgi_params" failed' &>>/dev/null
if [[ $? -eq 0 ]]; then
if [ -f /etc/nginx/fastcgi_params.old ]; then
if [ ! -f /etc/nginx/fastcgi_params ]; then
cp /etc/nginx/fastcgi_params.old /etc/nginx/fastcgi_params
fi
fi
fi
fi
#Fix For ssl_ciphers
if [ -f /etc/nginx/nginx.conf ]; then
sed -i 's/HIGH:!aNULL:!MD5:!kEDH;/ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;/' /etc/nginx/nginx.conf
fi
#Fix for SSL cert --all
crontab -l | grep -q '\-\-min_expiry_limit'
if [[ $? -eq 0 ]]; then
crontab -l > /var/spool/cron/cron-backup.txt #backup cron before editing
crontab -l | sed '/--min_expiry_limit/d' | crontab -
/bin/bash -c "crontab -l 2> /dev/null | { cat; echo -e \"\n0 0 * * 0 wo site update --le=renew --all 2> /dev/null # Renew all letsencrypt SSL cert. Set by EasyEngine\"; } | crontab -"
fi
}
# Do git intialisation
function wo_git_init()
{
# Nginx under git version control
if [ -d /etc/nginx ];then
cd /etc/nginx
if [ ! -d /etc/nginx/.git ]; then
git init &>> /dev/null
fi
git add -A .
git commit -am "Updated Nginx" > /dev/null
fi
# EasyEngine under git version control
cd /etc/wo
if [ ! -d /etc/wo/.git ]; then
git init > /dev/null
fi
git add -A .
git commit -am "Installed/Updated to WordOps" &>> /dev/null
#PHP under git version control
if [ -d /etc/php ];then
cd /etc/php
if [ ! -d /etc/php/.git ]; then
git init &>> /dev/null
fi
git add -A .
git commit -am "Updated PHP" > /dev/null
fi
}
# Update WordOps
if [ -f /usr/local/sbin/easyengine ]; then
# Check old EasyEngine version
ee version | grep ${wo_version_old} &>> /dev/null
if [[ $? -ne 0 ]]; then
wo_lib_echo "WordOps/EasyEngine $wo_version_old not found on your system" | tee -ai $wo_install_log
wo_lib_echo "Updating your EasyEngine to $wo_version_old for compability" | tee -ai $wo_install_log
wget -q https://raw.githubusercontent.com/EasyEngine/easyengine/old-stable/bin/update && bash update
if [[ $? -ne 0 ]]; then
wo_lib_echo_fail "Unable to update EasyEngine to $wo_version_old, exit status = " $?
exit 100
fi
fi
read -p "Update WordOps to $wo_version_new (y/n): " wo_ans
if [ "$wo_ans" = "y" ] || [ "$wo_ans" = "Y" ]; then
wo_install_dep | tee -ai $wo_install_log
wo_sync_db 2&>>1 $WO_INSTALL_LOG
secure_wo_db | tee -ai $WO_INSTALL_LOG
wo_upgrade_php | tee -ai $wo_install_log
wo_install | tee -ai $wo_install_log
wo_update | tee -ai $wo_install_log
wo_update_latest | tee -ai $wo_install_log
wo_git_init | tee -ai $wo_install_log
else
wo_lib_error "Not updating WordOps to $wo_version_new, exit status = " 1
fi
elif [ ! -f /usr/local/bin/wo ]; then
wo_lib_echo "Installing depedencies" | tee -ai $wo_install_log
wo_install_dep | tee -ai $wo_install_log
wo_lib_echo "Installing WordOps $wo_branch" | tee -ai $wo_install_log
wo_install | tee -ai $wo_install_log
wo_lib_echo "Running post-install steps" | tee -ai $wo_install_log
secure_wo_db | tee -ai $WO_INSTALL_LOG
wo_git_init | tee -ai $wo_install_log
else
wo -v 2>&1 | grep $wo_version_new &>> /dev/null
if [[ $? -ne 0 ]];then
read -p "Update WordOps to $wo_version_new (y/n): " wo_ans
if [ "$wo_ans" = "y" ] || [ "$wo_ans" = "Y" ]; then
wo_install_dep | tee -ai $wo_install_log
wo_sync_db 2&>>1 $WO_INSTALL_LOG
secure_wo_db | tee -ai $WO_INSTALL_LOG
wo_upgrade_php | tee -ai $wo_install_log
wo_install | tee -ai $wo_install_log
wo_update_latest | tee -ai $wo_install_log
wo_git_init | tee -ai $wo_install_log
service nginx reload &>> /dev/null
if [ "$wo_distro_version" == "trusty" ]; then
service php5.6-fpm restart &>> /dev/null
else
service php5-fpm restart &>> /dev/null
fi
wo_update_wp_cli | tee -ai $wo_install_log
else
wo_lib_error "Not updating WordOps to $wo_version_new, exit status = " 1
fi
else
wo_lib_error "You already have WordOps $wo_version_new, exit status = " 1
fi
fi
wo sync | tee -ai $WO_INSTALL_LOG
echo
wo_lib_echo "For WordOps (wo) auto completion, run the following command"
echo
wo_lib_echo_info "source /etc/bash_completion.d/wo_auto.rc"
echo
wo_lib_echo "Yay! WordOps (wo) installed/updated successfully"
wo_lib_echo "WordOps (wo) help: https://wordops.org/docs"

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
cement>=2.4.0

9
setup.cfg Normal file
View File

@@ -0,0 +1,9 @@
[nosetests]
verbosity=3
debug=0
detailed-errors=1
with-coverage=1
cover-package=wo
cover-erase=1
cover-html=1
cover-html-dir=coverage_report/

103
setup.py Normal file
View File

@@ -0,0 +1,103 @@
from setuptools import setup, find_packages
import sys
import os
import glob
import configparser
import re
import shutil
conf = []
templates = []
long_description = '''WordOps is the commandline tool to manage your
Websites based on WordPress and Nginx with easy to use
commands'''
for name in glob.glob('config/plugins.d/*.conf'):
conf.insert(1, name)
for name in glob.glob('wo/cli/templates/*.mustache'):
templates.insert(1, name)
if not os.path.exists('/var/log/wo/'):
os.makedirs('/var/log/wo/')
if not os.path.exists('/var/lib/wo/'):
os.makedirs('/var/lib/wo/')
# WordOps git configuration management
config = configparser.ConfigParser()
config.read(os.path.expanduser("~")+'/.gitconfig')
try:
wo_user = config['user']['name']
wo_email = config['user']['email']
except Exception as e:
print("WordOps (wo) required your name & email address to track"
" changes you made under the Git version control")
print("WordOps (wo) will be able to send you daily reports & alerts in "
"upcoming version")
print("WordOps (wo) will NEVER share your information with other parties")
wo_user = input("Enter your name: ")
while wo_user is "":
print("Unfortunately, this can't be left blank")
wo_user = input("Enter your name: ")
wo_email = input("Enter your email: ")
while not re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$",
wo_email):
print("Whoops, seems like you made a typo - the e-mailaddress is invalid...")
wo_email = input("Enter your email: ")
os.system("git config --global user.name {0}".format(wo_user))
os.system("git config --global user.email {0}".format(wo_email))
if not os.path.isfile('/root/.gitconfig'):
shutil.copy2(os.path.expanduser("~")+'/.gitconfig', '/root/.gitconfig')
setup(name='wo',
version='3.8.1',
description=long_description,
long_description=long_description,
classifiers=[],
keywords='',
author='WordOps',
author_email='core@wordops.org',
url='https://wordops.io',
license='MIT',
packages=find_packages(exclude=['ez_setup', 'examples', 'tests',
'templates']),
include_package_data=True,
zip_safe=False,
test_suite='nose.collector',
install_requires=[
# Required to build documentation
# "Sphinx >= 1.0",
# Required for testing
# "nose",
# "coverage",
# Required to function
'cement == 2.4',
'pystache',
'python-apt',
'pynginxconfig',
'PyMySQL == 0.8.0',
'psutil == 3.1.1',
'sh',
'SQLAlchemy',
],
data_files=[('/etc/wo', ['config/wo.conf']),
('/etc/wo/plugins.d', conf),
('/usr/lib/wo/templates', templates),
('/etc/bash_completion.d/',
['config/bash_completion.d/wo_auto.rc']),
('/usr/share/man/man8/', ['docs/wo.8'])],
setup_requires=[],
entry_points="""
[console_scripts]
wo = wo.cli.main:main
""",
namespace_packages=[],
)

0
tests/__init__.py Normal file
View File

View File

@@ -0,0 +1,64 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_web(self):
self.app = get_test_app(argv=['stack', 'install', '--web'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_admin(self):
self.app = get_test_app(argv=['stack', 'install', '--admin'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_nginx(self):
self.app = get_test_app(argv=['stack', 'install', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_php(self):
self.app = get_test_app(argv=['stack', 'install', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_mysql(self):
self.app = get_test_app(argv=['stack', 'install', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_wpcli(self):
self.app = get_test_app(argv=['stack', 'install', '--wpcli'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_phpmyadmin(self):
self.app = get_test_app(argv=['stack', 'install', '--phpmyadmin'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_adminer(self):
self.app = get_test_app(argv=['stack', 'install', '--adminer'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_utils(self):
self.app = get_test_app(argv=['stack', 'install', '--utils'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,40 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_start_nginx(self):
self.app = get_test_app(argv=['stack', 'start', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_start_php5_fpm(self):
self.app = get_test_app(argv=['stack', 'start', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_start_mysql(self):
self.app = get_test_app(argv=['stack', 'start', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_start_memcached(self):
self.app = get_test_app(argv=['stack', 'start', '--memcache'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_start_all(self):
self.app = get_test_app(argv=['stack', 'start'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,40 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_status_nginx(self):
self.app = get_test_app(argv=['stack', 'status', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_status_php5_fpm(self):
self.app = get_test_app(argv=['stack', 'status', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_status_mysql(self):
self.app = get_test_app(argv=['stack', 'status', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_status_memcached(self):
self.app = get_test_app(argv=['stack', 'status', '--memcache'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_status_all(self):
self.app = get_test_app(argv=['stack', 'status'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,40 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_stop_nginx(self):
self.app = get_test_app(argv=['stack', 'stop', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_stop_php5_fpm(self):
self.app = get_test_app(argv=['stack', 'stop', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_stop_mysql(self):
self.app = get_test_app(argv=['stack', 'stop', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_stop_memcached(self):
self.app = get_test_app(argv=['stack', 'stop', '--memcache'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_stop_all(self):
self.app = get_test_app(argv=['stack', 'stop'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,40 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_restart_nginx(self):
self.app = get_test_app(argv=['stack', 'restart', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_restart_php5_fpm(self):
self.app = get_test_app(argv=['stack', 'restart', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_restart_mysql(self):
self.app = get_test_app(argv=['stack', 'restart', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_restart_memcached(self):
self.app = get_test_app(argv=['stack', 'restart', '--memcache'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_services_restart_all(self):
self.app = get_test_app(argv=['stack', 'restart'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,66 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_html(self):
self.app = get_test_app(argv=['site', 'create', 'example1.com',
'--html'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_php(self):
self.app = get_test_app(argv=['site', 'create', 'example2.com',
'--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_mysql(self):
self.app = get_test_app(argv=['site', 'create', 'example3.com',
'--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_wp(self):
self.app = get_test_app(argv=['site', 'create', 'example4.com',
'--wp'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_wpsubdir(self):
self.app = get_test_app(argv=['site', 'create', 'example5.com',
'--wpsubdir'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_wpsubdomain(self):
self.app = get_test_app(argv=['site', 'create', 'example6.com',
'--wpsubdomain'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_wpfc(self):
self.app = get_test_app(argv=['site', 'create', 'example8.com',
'--wpfc'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_create_wpsc(self):
self.app = get_test_app(argv=['site', 'create', 'example9.com',
'--wpsc'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,16 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_info(self):
self.app = get_test_app(argv=['site', 'info', 'example1.com'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,22 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_list_enable(self):
self.app = get_test_app(argv=['site', 'list', '--enabled'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_list_disable(self):
self.app = get_test_app(argv=['site', 'list', '--disabled'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,16 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_show_edit(self):
self.app = get_test_app(argv=['site', 'show', 'example1.com'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,66 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_html(self):
self.app = get_test_app(argv=['site', 'update', 'example2.com',
'--html'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_php(self):
self.app = get_test_app(argv=['site', 'update', 'example1.com',
'--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_mysql(self):
self.app = get_test_app(argv=['site', 'update', 'example1.com',
'--html'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_wp(self):
self.app = get_test_app(argv=['site', 'update', 'example5.com',
'--wp'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_wpsubdir(self):
self.app = get_test_app(argv=['site', 'update', 'example4.com',
'--wpsubdir'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_wpsubdomain(self):
self.app = get_test_app(argv=['site', 'update', 'example7.com',
'--wpsubdomain'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_wpfc(self):
self.app = get_test_app(argv=['site', 'update', 'example9.com',
'--wpfc'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_update_wpsc(self):
self.app = get_test_app(argv=['site', 'update', 'example6.com',
'--wpsc'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,16 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_enable(self):
self.app = get_test_app(argv=['site', 'enable', 'example2.com'])
self.app.setup()
self.app.run()
self.app.close()

0
tests/cli/__init__.py Normal file
View File

View File

@@ -0,0 +1,16 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_disable(self):
self.app = get_test_app(argv=['site', 'disable', 'example2.com'])
self.app.setup()
self.app.run()
self.app.close()

View File

View File

View File

@@ -0,0 +1,8 @@
"""Tests for Example Plugin."""
from wo.utils import test
class ExamplePluginTestCase(test.WOTestCase):
def test_load_example_plugin(self):
self.app.setup()
self.app.plugin.load_plugin('example')

40
tests/cli/test_clean.py Normal file
View File

@@ -0,0 +1,40 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseClean(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_clean(self):
self.app = get_test_app(argv=['clean'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_clean_fastcgi(self):
self.app = get_test_app(argv=['clean', '--fastcgi'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_clean_all(self):
self.app = get_test_app(argv=['clean', '--all'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_clean_memcache(self):
self.app = get_test_app(argv=['clean', '--memcache'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_clean_opcache(self):
self.app = get_test_app(argv=['clean', '--opcache'])
self.app.setup()
self.app.run()
self.app.close()

95
tests/cli/test_debug.py Normal file
View File

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

28
tests/cli/test_info.py Normal file
View File

@@ -0,0 +1,28 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseInfo(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_info_mysql(self):
self.app = get_test_app(argv=['info', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_info_php(self):
self.app = get_test_app(argv=['info', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_info_nginx(self):
self.app = get_test_app(argv=['info', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()

28
tests/cli/test_secure.py Normal file
View File

@@ -0,0 +1,28 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSecure(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_secure_auth(self):
self.app = get_test_app(argv=['secure', '--auth'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_secure_port(self):
self.app = get_test_app(argv=['secure', '--port'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_secure_ip(self):
self.app = get_test_app(argv=['secure', '--ip'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,38 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseSite(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_detele(self):
self.app = get_test_app(argv=['site', 'delete', 'example1.com',
'--no-prompt'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_detele_all(self):
self.app = get_test_app(argv=['site', 'delete', 'example2.com',
'--all', '--no-prompt'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_detele_db(self):
self.app = get_test_app(argv=['site', 'delete', 'example3.com',
'--db', '--no-prompt'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_site_detele_files(self):
self.app = get_test_app(argv=['site', 'delete', 'example4.com',
'--files', '--no-prompt'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,64 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_web(self):
self.app = get_test_app(argv=['stack', 'purge', '--web'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_admin(self):
self.app = get_test_app(argv=['stack', 'purge', '--admin'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_nginx(self):
self.app = get_test_app(argv=['stack', 'purge', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_php(self):
self.app = get_test_app(argv=['stack', 'purge', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_mysql(self):
self.app = get_test_app(argv=['stack', 'purge', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_wpcli(self):
self.app = get_test_app(argv=['stack', 'purge', '--wpcli'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_phpmyadmin(self):
self.app = get_test_app(argv=['stack', 'purge', '--phpmyadmin'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_adminer(self):
self.app = get_test_app(argv=['stack', 'purge', '--adminer'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_purge_utils(self):
self.app = get_test_app(argv=['stack', 'purge', '--utils'])
self.app.setup()
self.app.run()
self.app.close()

View File

@@ -0,0 +1,64 @@
from wo.utils import test
from wo.cli.main import get_test_app
class CliTestCaseStack(test.WOTestCase):
def test_wo_cli(self):
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_remove_web(self):
self.app = get_test_app(argv=['stack', 'remove', '--web'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_admin(self):
self.app = get_test_app(argv=['stack', 'remove', '--admin'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_nginx(self):
self.app = get_test_app(argv=['stack', 'remove', '--nginx'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_php(self):
self.app = get_test_app(argv=['stack', 'remove', '--php'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_mysql(self):
self.app = get_test_app(argv=['stack', 'remove', '--mysql'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_wpcli(self):
self.app = get_test_app(argv=['stack', 'remove', '--wpcli'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_phpmyadmin(self):
self.app = get_test_app(argv=['stack', 'remove', '--phpmyadmin'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_adminer(self):
self.app = get_test_app(argv=['stack', 'remove', '--adminer'])
self.app.setup()
self.app.run()
self.app.close()
def test_wo_cli_stack_install_utils(self):
self.app = get_test_app(argv=['stack', 'remove', '--utils'])
self.app.setup()
self.app.run()
self.app.close()

0
tests/core/__init__.py Normal file
View File

1
wo/__init__.py Normal file
View File

@@ -0,0 +1 @@
__import__('pkg_resources').declare_namespace(__name__)

0
wo/cli/__init__.py Normal file
View File

11
wo/cli/bootstrap.py Normal file
View File

@@ -0,0 +1,11 @@
"""WordOps bootstrapping."""
# All built-in application controllers should be imported, and registered
# in this file in the same way as WOBaseController.
from cement.core import handler
from wo.cli.controllers.base import WOBaseController
def load(app):
handler.register(WOBaseController)

View File

View File

@@ -0,0 +1,25 @@
"""WordOps base controller."""
from cement.core.controller import CementBaseController, expose
from wo.core.variables import WOVariables
VERSION = WOVariables.wo_version
BANNER = """
WordOps v%s
Copyright (c) 2018 WordOps.
""" % VERSION
class WOBaseController(CementBaseController):
class Meta:
label = 'base'
description = ("WordOps is the commandline tool to manage your"
" websites based on WordPress and Nginx with easy to"
" use commands")
arguments = [
(['-v', '--version'], dict(action='version', version=BANNER)),
]
@expose(hide=True)
def default(self):
self.app.args.print_help()

0
wo/cli/ext/__init__.py Normal file
View File

View File

@@ -0,0 +1,20 @@
# Based on https://github.com/datafolklabs/cement/issues/295
# To avoid encoding releated error,we defined our custom output handler
# I hope we will remove this when we upgarde to Cement 2.6 (Not released yet)
import os
from cement.utils import fs
from cement.ext.ext_mustache import MustacheOutputHandler
class WOOutputHandler(MustacheOutputHandler):
class Meta:
label = 'wo_output_handler'
def _load_template_from_file(self, path):
for templ_dir in self.app._meta.template_dirs:
full_path = fs.abspath(os.path.join(templ_dir, path))
if os.path.exists(full_path):
self.app.log.debug('loading template file %s' % full_path)
return open(full_path, encoding='utf-8', mode='r').read()
else:
continue

135
wo/cli/main.py Normal file
View File

@@ -0,0 +1,135 @@
"""WordOps main application entry point."""
import sys
import os
# 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
from cement.core import foundation
from cement.utils.misc import init_defaults
from cement.core.exc import FrameworkError, CaughtSignal
from cement.ext.ext_argparse import ArgParseArgumentHandler
from wo.core import exc
from wo.cli.ext.wo_outputhandler import WOOutputHandler
# Application default. Should update config/wo.conf to reflect any
# changes, or additions here.
defaults = init_defaults('wo')
# All internal/external plugin configurations are loaded from here
defaults['wo']['plugin_config_dir'] = '/etc/wo/plugins.d'
# External plugins (generally, do not ship with application code)
defaults['wo']['plugin_dir'] = '/var/lib/wo/plugins'
# External templates (generally, do not ship with application code)
defaults['wo']['template_dir'] = '/var/lib/wo/templates'
class WOArgHandler(ArgParseArgumentHandler):
class Meta:
label = 'wo_args_handler'
def error(self, message):
super(WOArgHandler, self).error("unknown args")
class WOApp(foundation.CementApp):
class Meta:
label = 'wo'
config_defaults = defaults
# All built-in application bootstrapping (always run)
bootstrap = 'wo.cli.bootstrap'
# Optional plugin bootstrapping (only run if plugin is enabled)
plugin_bootstrap = 'wo.cli.plugins'
# Internal templates (ship with application code)
template_module = 'wo.cli.templates'
# Internal plugins (ship with application code)
plugin_bootstrap = 'wo.cli.plugins'
extensions = ['mustache']
# default output handler
output_handler = WOOutputHandler
arg_handler = WOArgHandler
debug = TOGGLE_DEBUG
class WOTestApp(WOApp):
"""A test app that is better suited for testing."""
class Meta:
argv = []
config_files = []
# Define the applicaiton object outside of main, as some libraries might wish
# to import it as a global (rather than passing it into another class/func)
app = WOApp()
def main():
try:
global sys
# Default our exit status to 0 (non-error)
code = 0
# if not root...kick out
if not os.geteuid() == 0:
print("\nNon-privileged users cant use WordOps. Switch to root or invoke sudo.\n")
app.close(1)
# Setup the application
app.setup()
# Dump all arguments into wo log
app.log.debug(sys.argv)
# Run the application
app.run()
except exc.WOError as e:
# Catch our application errors and exit 1 (error)
code = 1
print(e)
except FrameworkError as e:
# Catch framework errors and exit 1 (error)
code = 1
print(e)
except CaughtSignal as e:
# Default Cement signals are SIGINT and SIGTERM, exit 0 (non-error)
code = 0
print(e)
except Exception as e:
code = 1
print(e)
finally:
# Print an exception (if it occurred) and --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()
# # Close the application
app.close(code)
def get_test_app(**kw):
app = WOApp(**kw)
return app
if __name__ == '__main__':
main()

View File

104
wo/cli/plugins/clean.py Normal file
View File

@@ -0,0 +1,104 @@
"""Clean Plugin for WordOps."""
from wo.core.shellexec import WOShellExec
from wo.core.aptget import WOAptGet
from wo.core.services import WOService
from wo.core.logging import Log
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
import os
import urllib.request
def wo_clean_hook(app):
pass
class WOCleanController(CementBaseController):
class Meta:
label = 'clean'
stacked_on = 'base'
stacked_type = 'nested'
description = ('Clean NGINX FastCGI cache, Opcache, Memcache, Redis Cache')
arguments = [
(['--all'],
dict(help='Clean all cache', action='store_true')),
(['--fastcgi'],
dict(help='Clean FastCGI cache', action='store_true')),
(['--memcache'],
dict(help='Clean MemCache', action='store_true')),
(['--opcache'],
dict(help='Clean OpCache', action='store_true')),
(['--redis'],
dict(help='Clean Redis Cache', action='store_true')),
]
usage = "wo clean [options]"
@expose(hide=True)
def default(self):
if (not (self.app.pargs.all or self.app.pargs.fastcgi or
self.app.pargs.memcache or self.app.pargs.opcache or
self.app.pargs.redis)):
self.clean_fastcgi()
if self.app.pargs.all:
self.clean_memcache()
self.clean_fastcgi()
self.clean_opcache()
self.clean_redis()
if self.app.pargs.fastcgi:
self.clean_fastcgi()
if self.app.pargs.memcache:
self.clean_memcache()
if self.app.pargs.opcache:
self.clean_opcache()
if self.app.pargs.redis:
self.clean_redis()
@expose(hide=True)
def clean_redis(self):
"""This function clears Redis cache"""
if(WOAptGet.is_installed(self, "redis-server")):
Log.info(self, "Cleaning Redis cache")
WOShellExec.cmd_exec(self, "redis-cli flushall")
else:
Log.info(self, "Redis is not installed")
@expose(hide=True)
def clean_memcache(self):
try:
if(WOAptGet.is_installed(self, "memcached")):
WOService.restart_service(self, "memcached")
Log.info(self, "Cleaning MemCache")
else:
Log.info(self, "Memcache not installed")
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to restart Memcached", False)
@expose(hide=True)
def clean_fastcgi(self):
if(os.path.isdir("/var/run/nginx-cache")):
Log.info(self, "Cleaning NGINX FastCGI cache")
WOShellExec.cmd_exec(self, "rm -rf /var/run/nginx-cache/*")
else:
Log.error(self, "Unable to clean FastCGI cache", False)
@expose(hide=True)
def clean_opcache(self):
try:
Log.info(self, "Cleaning opcache")
wp = urllib.request.urlopen(" https://127.0.0.1:22222/cache"
"/opcache/opgui.php?page=reset").read()
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.debug(self, "Unable hit url, "
" https://127.0.0.1:22222/cache/opcache/opgui.php?page=reset,"
" please check you have admin tools installed")
Log.debug(self, "please check you have admin tools installed,"
" or install them with `wo stack install --admin`")
Log.error(self, "Unable to clean opcache", False)
def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(WOCleanController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', wo_clean_hook)

856
wo/cli/plugins/debug.py Normal file
View File

@@ -0,0 +1,856 @@
"""Debug Plugin for WordOps"""
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.aptget import WOAptGet
from wo.core.shellexec import *
from wo.core.mysql import WOMysql
from wo.core.services import WOService
from wo.core.logging import Log
from wo.cli.plugins.site_functions import logwatch
from wo.core.variables import WOVariables
from wo.core.fileutils import WOFileUtils
from pynginxconfig import NginxConfig
import os
import configparser
import glob
import signal
import subprocess
def wo_debug_hook(app):
pass
class WODebugController(CementBaseController):
class Meta:
label = 'debug'
description = 'Used for server level debugging'
stacked_on = 'base'
stacked_type = 'nested'
arguments = [
(['--stop'],
dict(help='Stop debug', action='store_true')),
(['--start'],
dict(help='Start debug', action='store_true')),
(['--import-slow-log'],
dict(help='Import MySQL slow log to Anemometer database',
action='store_true')),
(['--nginx'],
dict(help='start/stop debugging nginx server '
'configuration for site',
action='store' or 'store_const',
choices=('on', 'off'), const='on', nargs='?')),
(['--php'],
dict(help='start/stop debugging server PHP configuration',
action='store' or 'store_const',
choices=('on', 'off'), const='on', nargs='?')),
(['--fpm'],
dict(help='start/stop debugging fastcgi configuration',
action='store' or 'store_const',
choices=('on', 'off'), const='on', nargs='?')),
(['--php7'],
dict(help='start/stop debugging server PHP 7 configuration',
action='store' or 'store_const',
choices=('on', 'off'), const='on', nargs='?')),
(['--fpm7'],
dict(help='start/stop debugging fastcgi 7.0 configuration',
action='store' or 'store_const',
choices=('on', 'off'), const='on', nargs='?')),
(['--mysql'],
dict(help='start/stop debugging MySQL server',
action='store' or 'store_const',
choices=('on', 'off'), const='on', nargs='?')),
(['--wp'],
dict(help='start/stop wordpress debugging for site',
action='store' or 'store_const', choices=('on', 'off'),
const='on', nargs='?')),
(['--rewrite'],
dict(help='start/stop debugging nginx rewrite rules for site',
action='store' or 'store_const', choices=('on', 'off'),
const='on', nargs='?')),
(['--all'],
dict(help='start/stop debugging all server parameters',
action='store' or 'store_const', choices=('on', 'off'),
const='on', nargs='?')),
(['-i', '--interactive'],
dict(help='Interactive debug', action='store_true')),
(['--import-slow-log-interval'],
dict(help='Import MySQL slow log to Anemometer',
action='store', dest='interval')),
(['site_name'],
dict(help='Website Name', nargs='?', default=None))
]
usage = "wo debug [<site_name>] [options] "
@expose(hide=True)
def debug_nginx(self):
"""Start/Stop Nginx debug"""
# start global debug
if (self.app.pargs.nginx == 'on' and not self.app.pargs.site_name):
try:
debug_address = (self.app.config.get('stack', 'ip-address')
.split())
except Exception as e:
debug_address = ['0.0.0.0/0']
# Check if IP address is 127.0.0.1 then enable debug globally
if debug_address == ['127.0.0.1'] or debug_address == []:
debug_address = ['0.0.0.0/0']
for ip_addr in debug_address:
if not ("debug_connection "+ip_addr in open('/etc/nginx/'
'nginx.conf', encoding='utf-8').read()):
Log.info(self, "Setting up Nginx debug connection"
" for "+ip_addr)
WOShellExec.cmd_exec(self, "sed -i \"/events {{/a\\ \\ \\ "
"\\ $(echo debug_connection "
"{ip}\;)\" /etc/nginx/"
"nginx.conf".format(ip=ip_addr))
self.trigger_nginx = True
if not self.trigger_nginx:
Log.info(self, "Nginx debug connection already enabled")
self.msg = self.msg + ["/var/log/nginx/*.error.log"]
# stop global debug
elif (self.app.pargs.nginx == 'off' and not self.app.pargs.site_name):
if "debug_connection " in open('/etc/nginx/nginx.conf',
encoding='utf-8').read():
Log.info(self, "Disabling Nginx debug connections")
WOShellExec.cmd_exec(self, "sed -i \"/debug_connection.*/d\""
" /etc/nginx/nginx.conf")
self.trigger_nginx = True
else:
Log.info(self, "Nginx debug connection already disabled")
# start site specific debug
elif (self.app.pargs.nginx == 'on' and self.app.pargs.site_name):
config_path = ("/etc/nginx/sites-available/{0}"
.format(self.app.pargs.site_name))
if os.path.isfile(config_path):
if not WOShellExec.cmd_exec(self, "grep \"error.log debug\" "
"{0}".format(config_path)):
Log.info(self, "Starting NGINX debug connection for "
"{0}".format(self.app.pargs.site_name))
WOShellExec.cmd_exec(self, "sed -i \"s/error.log;/"
"error.log "
"debug;/\" {0}".format(config_path))
self.trigger_nginx = True
else:
Log.info(self, "Nginx debug for site already enabled")
self.msg = self.msg + ['{0}{1}/logs/error.log'
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
else:
Log.info(self, "{0} domain not valid"
.format(self.app.pargs.site_name))
# stop site specific debug
elif (self.app.pargs.nginx == 'off' and self.app.pargs.site_name):
config_path = ("/etc/nginx/sites-available/{0}"
.format(self.app.pargs.site_name))
if os.path.isfile(config_path):
if WOShellExec.cmd_exec(self, "grep \"error.log debug\" {0}"
.format(config_path)):
Log.info(self, "Stoping NGINX debug connection for {0}"
.format(self.app.pargs.site_name))
WOShellExec.cmd_exec(self, "sed -i \"s/error.log debug;/"
"error.log;/\" {0}"
.format(config_path))
self.trigger_nginx = True
else:
Log.info(self, "Nginx debug for site already disabled")
else:
Log.info(self, "{0} domain not valid"
.format(self.app.pargs.site_name))
@expose(hide=True)
def debug_php(self):
"""Start/Stop PHP debug"""
# PHP global debug start
if (self.app.pargs.php == 'on' and not self.app.pargs.site_name):
if not (WOShellExec.cmd_exec(self, "sed -n \"/upstream php"
"{/,/}/p \" /etc/nginx/"
"conf.d/upstream.conf "
"| grep 9001")):
Log.info(self, "Enabling PHP debug")
# Change upstream.conf
nc = NginxConfig()
nc.loadf('/etc/nginx/conf.d/upstream.conf')
nc.set([('upstream','php',), 'server'], '127.0.0.1:9001')
if os.path.isfile("/etc/nginx/common/wpfc-hhvm.conf"):
nc.set([('upstream','hhvm',), 'server'], '127.0.0.1:9001')
nc.savef('/etc/nginx/conf.d/upstream.conf')
# Enable xdebug
WOFileUtils.searchreplace(self, "/etc/{0}/mods-available/".format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5") +
"xdebug.ini",
";zend_extension",
"zend_extension")
# Fix slow log is not enabled default in PHP5.6
config = configparser.ConfigParser()
config.read('/etc/{0}/fpm/pool.d/debug.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
config['debug']['slowlog'] = '/var/log/{0}/slow.log'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5")
config['debug']['request_slowlog_timeout'] = '10s'
with open('/etc/{0}/fpm/pool.d/debug.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"),
encoding='utf-8', mode='w') as confifile:
Log.debug(self, "Writting debug.conf configuration into "
"/etc/{0}/fpm/pool.d/debug.conf".format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
config.write(confifile)
self.trigger_php = True
self.trigger_nginx = True
else:
Log.info(self, "PHP debug is already enabled")
self.msg = self.msg + ['/var/log/{0}/slow.log'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5")]
# PHP global debug stop
elif (self.app.pargs.php == 'off' and not self.app.pargs.site_name):
if WOShellExec.cmd_exec(self, " sed -n \"/upstream php {/,/}/p\" "
"/etc/nginx/conf.d/upstream.conf "
"| grep 9001"):
Log.info(self, "Disabling PHP debug")
# Change upstream.conf
nc = NginxConfig()
nc.loadf('/etc/nginx/conf.d/upstream.conf')
nc.set([('upstream','php',), 'server'], '127.0.0.1:9000')
if os.path.isfile("/etc/nginx/common/wpfc-hhvm.conf"):
nc.set([('upstream','hhvm',), 'server'], '127.0.0.1:8000')
nc.savef('/etc/nginx/conf.d/upstream.conf')
# Disable xdebug
WOFileUtils.searchreplace(self, "/etc/{0}/mods-available/".format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5") +
"xdebug.ini",
"zend_extension",
";zend_extension")
self.trigger_php = True
self.trigger_nginx = True
else:
Log.info(self, "PHP debug is already disabled")
@expose(hide=True)
def debug_fpm(self):
"""Start/Stop PHP5-FPM debug"""
# PHP5-FPM start global debug
if (self.app.pargs.fpm == 'on' and not self.app.pargs.site_name):
if not WOShellExec.cmd_exec(self, "grep \"log_level = debug\" "
"/etc/{0}/fpm/php-fpm.conf".format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5")):
Log.info(self, "Setting up PHP5-FPM log_level = debug")
config = configparser.ConfigParser()
config.read('/etc/{0}/fpm/php-fpm.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
config.remove_option('global', 'include')
config['global']['log_level'] = 'debug'
config['global']['include'] = '/etc/{0}/fpm/pool.d/*.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5")
with open('/etc/{0}/fpm/php-fpm.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"),
encoding='utf-8', mode='w') as configfile:
Log.debug(self, "Writting php5-FPM configuration into "
"/etc/{0}/fpm/php-fpm.conf".format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
config.write(configfile)
self.trigger_php = True
else:
Log.info(self, "PHP5-FPM log_level = debug already setup")
self.msg = self.msg + ['/var/log/{0}/fpm.log'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5")]
# PHP5-FPM stop global debug
elif (self.app.pargs.fpm == 'off' and not self.app.pargs.site_name):
if WOShellExec.cmd_exec(self, "grep \"log_level = debug\" "
"/etc/{0}/fpm/php-fpm.conf".format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5")):
Log.info(self, "Disabling PHP5-FPM log_level = debug")
config = configparser.ConfigParser()
config.read('/etc/{0}/fpm/php-fpm.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
config.remove_option('global', 'include')
config['global']['log_level'] = 'notice'
config['global']['include'] = '/etc/{0}/fpm/pool.d/*.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5")
with open('/etc/{0}/fpm/php-fpm.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"),
encoding='utf-8', mode='w') as configfile:
Log.debug(self, "writting php5 configuration into "
"/etc/{0}/fpm/php-fpm.conf".format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
config.write(configfile)
self.trigger_php = True
else:
Log.info(self, "PHP5-FPM log_level = debug already disabled")
@expose(hide=True)
def debug_php7(self):
"""Start/Stop PHP debug"""
# PHP global debug start
if (self.app.pargs.php7 == 'on' and not self.app.pargs.site_name):
if (WOVariables.wo_platform_codename == 'wheezy' or WOVariables.wo_platform_codename == 'precise'):
Log.error(self,"PHP 7.0 not supported.")
if not (WOShellExec.cmd_exec(self, "sed -n \"/upstream php7"
"{/,/}/p \" /etc/nginx/"
"conf.d/upstream.conf "
"| grep 9170")):
Log.info(self, "Enabling PHP 7.0 debug")
# Change upstream.conf
nc = NginxConfig()
nc.loadf('/etc/nginx/conf.d/upstream.conf')
nc.set([('upstream','php7',), 'server'], '127.0.0.1:9170')
if os.path.isfile("/etc/nginx/common/wpfc-hhvm.conf"):
nc.set([('upstream','hhvm',), 'server'], '127.0.0.1:9170')
nc.savef('/etc/nginx/conf.d/upstream.conf')
# Enable xdebug
WOFileUtils.searchreplace(self, "/etc/php/7.0/mods-available/"
"xdebug.ini",
";zend_extension",
"zend_extension")
# Fix slow log is not enabled default in PHP5.6
config = configparser.ConfigParser()
config.read('/etc/php/7.0/fpm/pool.d/debug.conf')
config['debug']['slowlog'] = '/var/log/php/7.0/slow.log'
config['debug']['request_slowlog_timeout'] = '10s'
with open('/etc/php/7.0/fpm/pool.d/debug.conf',
encoding='utf-8', mode='w') as confifile:
Log.debug(self, "Writting debug.conf configuration into "
"/etc/php/7.0/fpm/pool.d/debug.conf")
config.write(confifile)
self.trigger_php = True
self.trigger_nginx = True
else:
Log.info(self, "PHP debug is already enabled")
self.msg = self.msg + ['/var/log/php/7.0/slow.log']
# PHP global debug stop
elif (self.app.pargs.php7 == 'off' and not self.app.pargs.site_name):
if WOShellExec.cmd_exec(self, " sed -n \"/upstream php7 {/,/}/p\" "
"/etc/nginx/conf.d/upstream.conf "
"| grep 9170"):
Log.info(self, "Disabling PHP 7.0 debug")
# Change upstream.conf
nc = NginxConfig()
nc.loadf('/etc/nginx/conf.d/upstream.conf')
nc.set([('upstream','php7',), 'server'], '127.0.0.1:9070')
if os.path.isfile("/etc/nginx/common/wpfc-hhvm.conf"):
nc.set([('upstream','hhvm',), 'server'], '127.0.0.1:8000')
nc.savef('/etc/nginx/conf.d/upstream.conf')
# Disable xdebug
WOFileUtils.searchreplace(self, "/etc/php/7.0/mods-available/"
"xdebug.ini",
"zend_extension",
";zend_extension")
self.trigger_php = True
self.trigger_nginx = True
else:
Log.info(self, "PHP 7.0 debug is already disabled")
@expose(hide=True)
def debug_fpm7(self):
"""Start/Stop PHP5-FPM debug"""
# PHP5-FPM start global debug
if (self.app.pargs.fpm7 == 'on' and not self.app.pargs.site_name):
if not WOShellExec.cmd_exec(self, "grep \"log_level = debug\" "
"/etc/php/7.0/fpm/php-fpm.conf"):
Log.info(self, "Setting up PHP7.0-FPM log_level = debug")
config = configparser.ConfigParser()
config.read('/etc/php/7.0/fpm/php-fpm.conf')
config.remove_option('global', 'include')
config['global']['log_level'] = 'debug'
config['global']['include'] = '/etc/php/7.0/fpm/pool.d/*.conf'
with open('/etc/php/7.0/fpm/php-fpm.conf',
encoding='utf-8', mode='w') as configfile:
Log.debug(self, "Writting php7.0-FPM configuration into "
"/etc/php/7.0/fpm/php-fpm.conf")
config.write(configfile)
self.trigger_php = True
else:
Log.info(self, "PHP7.0-FPM log_level = debug already setup")
self.msg = self.msg + ['/var/log/php/7.0/fpm.log']
# PHP5-FPM stop global debug
elif (self.app.pargs.fpm7 == 'off' and not self.app.pargs.site_name):
if WOShellExec.cmd_exec(self, "grep \"log_level = debug\" "
"/etc/php/7.0/fpm/php-fpm.conf"):
Log.info(self, "Disabling PHP7.0-FPM log_level = debug")
config = configparser.ConfigParser()
config.read('/etc/php/7.0/fpm/php-fpm.conf')
config.remove_option('global', 'include')
config['global']['log_level'] = 'notice'
config['global']['include'] = '/etc/php/7.0/fpm/pool.d/*.conf'
with open('/etc/php/7.0/fpm/php-fpm.conf',
encoding='utf-8', mode='w') as configfile:
Log.debug(self, "writting php7.0 configuration into "
"/etc/php/7.0/fpm/php-fpm.conf")
config.write(configfile)
self.trigger_php = True
else:
Log.info(self, "PHP7.0-FPM log_level = debug already disabled")
@expose(hide=True)
def debug_mysql(self):
"""Start/Stop MySQL debug"""
# MySQL start global debug
if (self.app.pargs.mysql == 'on' and not self.app.pargs.site_name):
if not WOShellExec.cmd_exec(self, "mysql -e \"show variables like"
" \'slow_query_log\';\" | "
"grep ON"):
Log.info(self, "Setting up MySQL slow log")
WOMysql.execute(self, "set global slow_query_log = "
"\'ON\';")
WOMysql.execute(self, "set global slow_query_log_file = "
"\'/var/log/mysql/mysql-slow.log\';")
WOMysql.execute(self, "set global long_query_time = 2;")
WOMysql.execute(self, "set global log_queries_not_using"
"_indexes = \'ON\';")
else:
Log.info(self, "MySQL slow log is already enabled")
self.msg = self.msg + ['/var/log/mysql/mysql-slow.log']
# MySQL stop global debug
elif (self.app.pargs.mysql == 'off' and not self.app.pargs.site_name):
if WOShellExec.cmd_exec(self, "mysql -e \"show variables like \'"
"slow_query_log\';\" | grep ON"):
Log.info(self, "Disabling MySQL slow log")
WOMysql.execute(self, "set global slow_query_log = \'OFF\';")
WOMysql.execute(self, "set global slow_query_log_file = \'"
"/var/log/mysql/mysql-slow.log\';")
WOMysql.execute(self, "set global long_query_time = 10;")
WOMysql.execute(self, "set global log_queries_not_using_index"
"es = \'OFF\';")
WOShellExec.cmd_exec(self, "crontab -l | sed \'/#WordOps "
"start/,/#WordOps end/d\' | crontab -")
else:
Log.info(self, "MySQL slow log already disabled")
@expose(hide=True)
def debug_wp(self):
"""Start/Stop WordPress debug"""
if (self.app.pargs.wp == 'on' and self.app.pargs.site_name):
wp_config = ("{0}/{1}/wp-config.php"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name))
webroot = "{0}{1}".format(WOVariables.wo_webroot,
self.app.pargs.site_name)
# Check wp-config.php file into htdocs folder
if not os.path.isfile(wp_config):
wp_config = ("{0}/{1}/htdocs/wp-config.php"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name))
if os.path.isfile(wp_config):
if not WOShellExec.cmd_exec(self, "grep \"\'WP_DEBUG\'\" {0} |"
" grep true".format(wp_config)):
Log.info(self, "Starting WordPress debug")
open("{0}/htdocs/wp-content/debug.log".format(webroot),
encoding='utf-8', mode='a').close()
WOShellExec.cmd_exec(self, "chown {1}: {0}/htdocs/wp-"
"content/debug.log"
"".format(webroot,
WOVariables.wo_php_user))
WOShellExec.cmd_exec(self, "sed -i \"s/define(\'WP_DEBUG\'"
".*/define(\'WP_DEBUG\', true);\\n"
"define(\'WP_DEBUG_DISPLAY\', false);"
"\\ndefine(\'WP_DEBUG_LOG\', true);"
"\\ndefine(\'SAVEQUERIES\', true);/\""
" {0}".format(wp_config))
WOShellExec.cmd_exec(self, "cd {0}/htdocs/ && wp"
" plugin --allow-root install "
"developer query-monitor"
.format(webroot))
WOShellExec.cmd_exec(self, "chown -R {1}: {0}/htdocs/"
"wp-content/plugins"
.format(webroot,
WOVariables.wo_php_user))
self.msg = self.msg + ['{0}{1}/htdocs/wp-content'
'/debug.log'
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
else:
Log.info(self, "Unable to find wp-config.php for site: {0}"
.format(self.app.pargs.site_name))
elif (self.app.pargs.wp == 'off' and self.app.pargs.site_name):
wp_config = ("{0}{1}/wp-config.php"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name))
webroot = "{0}{1}".format(WOVariables.wo_webroot,
self.app.pargs.site_name)
# Check wp-config.php file into htdocs folder
if not os.path.isfile(wp_config):
wp_config = ("{0}/{1}/htdocs/wp-config.php"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name))
if os.path.isfile(wp_config):
if WOShellExec.cmd_exec(self, "grep \"\'WP_DEBUG\'\" {0} | "
"grep true".format(wp_config)):
Log.info(self, "Disabling WordPress debug")
WOShellExec.cmd_exec(self, "sed -i \"s/define(\'WP_DEBUG\'"
", true);/define(\'WP_DEBUG\', "
"false);/\" {0}".format(wp_config))
WOShellExec.cmd_exec(self, "sed -i \"/define(\'"
"WP_DEBUG_DISPLAY\', false);/d\" {0}"
.format(wp_config))
WOShellExec.cmd_exec(self, "sed -i \"/define(\'"
"WP_DEBUG_LOG\', true);/d\" {0}"
.format(wp_config))
WOShellExec.cmd_exec(self, "sed -i \"/define(\'"
"SAVEQUERIES\', "
"true);/d\" {0}".format(wp_config))
else:
Log.info(self, "WordPress debug all already disabled")
else:
Log.error(self, "Missing argument site name")
@expose(hide=True)
def debug_rewrite(self):
"""Start/Stop Nginx rewrite rules debug"""
# Start Nginx rewrite debug globally
if (self.app.pargs.rewrite == 'on' and not self.app.pargs.site_name):
if not WOShellExec.cmd_exec(self, "grep \"rewrite_log on;\" "
"/etc/nginx/nginx.conf"):
Log.info(self, "Setting up Nginx rewrite logs")
WOShellExec.cmd_exec(self, "sed -i \'/http {/a \\\\t"
"rewrite_log on;\' /etc/nginx/nginx.conf")
self.trigger_nginx = True
else:
Log.info(self, "Nginx rewrite logs already enabled")
if '/var/log/nginx/*.error.log' not in self.msg:
self.msg = self.msg + ['/var/log/nginx/*.error.log']
# Stop Nginx rewrite debug globally
elif (self.app.pargs.rewrite == 'off'
and not self.app.pargs.site_name):
if WOShellExec.cmd_exec(self, "grep \"rewrite_log on;\" "
"/etc/nginx/nginx.conf"):
Log.info(self, "Disabling Nginx rewrite logs")
WOShellExec.cmd_exec(self, "sed -i \"/rewrite_log.*/d\""
" /etc/nginx/nginx.conf")
self.trigger_nginx = True
else:
Log.info(self, "Nginx rewrite logs already disabled")
# Start Nginx rewrite for site
elif (self.app.pargs.rewrite == 'on' and self.app.pargs.site_name):
config_path = ("/etc/nginx/sites-available/{0}"
.format(self.app.pargs.site_name))
if not WOShellExec.cmd_exec(self, "grep \"rewrite_log on;\" {0}"
.format(config_path)):
Log.info(self, "Setting up Nginx rewrite logs for {0}"
.format(self.app.pargs.site_name))
WOShellExec.cmd_exec(self, "sed -i \"/access_log/i \\\\\\t"
"rewrite_log on;\" {0}"
.format(config_path))
self.trigger_nginx = True
else:
Log.info(self, "Nginx rewrite logs for {0} already setup"
.format(self.app.pargs.site_name))
if ('{0}{1}/logs/error.log'.format(WOVariables.wo_webroot,
self.app.pargs.site_name)
not in self.msg):
self.msg = self.msg + ['{0}{1}/logs/error.log'
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
# Stop Nginx rewrite for site
elif (self.app.pargs.rewrite == 'off' and self.app.pargs.site_name):
config_path = ("/etc/nginx/sites-available/{0}"
.format(self.app.pargs.site_name))
if WOShellExec.cmd_exec(self, "grep \"rewrite_log on;\" {0}"
.format(config_path)):
Log.info(self, "Disabling Nginx rewrite logs for {0}"
.format(self.app.pargs.site_name))
WOShellExec.cmd_exec(self, "sed -i \"/rewrite_log.*/d\" {0}"
.format(config_path))
self.trigger_nginx = True
else:
Log.info(self, "Nginx rewrite logs for {0} already "
" disabled".format(self.app.pargs.site_name))
@expose(hide=True)
def signal_handler(self, signal, frame):
"""Handle Ctrl+c hevent for -i option of debug"""
self.start = False
if self.app.pargs.nginx:
self.app.pargs.nginx = 'off'
self.debug_nginx()
if self.app.pargs.php:
self.app.pargs.php = 'off'
self.debug_php()
if self.app.pargs.php7:
self.app.pargs.php7 = 'off'
self.debug_php7()
if self.app.pargs.fpm:
self.app.pargs.fpm = 'off'
self.debug_fpm()
if self.app.pargs.fpm7:
self.app.pargs.fpm7 = 'off'
self.debug_fpm7()
if self.app.pargs.mysql:
# MySQL debug will not work for remote MySQL
if WOVariables.wo_mysql_host is "localhost":
self.app.pargs.mysql = 'off'
self.debug_mysql()
else:
Log.warn(self, "Remote MySQL found, WordOps does not support "
"debugging remote servers")
if self.app.pargs.wp:
self.app.pargs.wp = 'off'
self.debug_wp()
if self.app.pargs.rewrite:
self.app.pargs.rewrite = 'off'
self.debug_rewrite()
# Reload Nginx
if self.trigger_nginx:
WOService.reload_service(self, 'nginx')
# Reload PHP
if self.trigger_php:
if WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic':
if WOAptGet.is_installed(self,'php5.6-fpm'):
WOService.reload_service(self, 'php5.6-fpm')
if WOAptGet.is_installed(self,'php7.0-fpm'):
WOService.reload_service(self, 'php7.0-fpm')
else:
WOService.reload_service(self, 'php5-fpm')
self.app.close(0)
@expose(hide=True)
def default(self):
"""Default function of debug"""
# self.start = True
self.interactive = False
self.msg = []
self.trigger_nginx = False
self.trigger_php = False
if ((not self.app.pargs.nginx) and (not self.app.pargs.php) and (not self.app.pargs.php7)
and (not self.app.pargs.fpm) and (not self.app.pargs.fpm7) and (not self.app.pargs.mysql)
and (not self.app.pargs.wp) and (not self.app.pargs.rewrite)
and (not self.app.pargs.all)
and (not self.app.pargs.site_name)
and (not self.app.pargs.import_slow_log)
and (not self.app.pargs.interval)):
if self.app.pargs.stop or self.app.pargs.start:
print("--start/stop option is deprecated since ee v3.0.5")
self.app.args.print_help()
else:
self.app.args.print_help()
if self.app.pargs.import_slow_log:
self.import_slow_log()
if self.app.pargs.interval:
try:
cron_time = int(self.app.pargs.interval)
except Exception as e:
cron_time = 5
try:
if not WOShellExec.cmd_exec(self, "crontab -l | grep "
"'wo debug --import-slow-log'"):
if not cron_time == 0:
Log.info(self, "setting up crontab entry,"
" please wait...")
WOShellExec.cmd_exec(self, "/bin/bash -c \"crontab -l "
"2> /dev/null | {{ cat; echo -e"
" \\\"#WordOps start MySQL "
"slow log \\n*/{0} * * * * "
"/usr/local/bin/wo debug"
" --import-slow-log\\n"
"#WordOps end MySQL slow log"
"\\\"; }} | crontab -\""
.format(cron_time))
else:
if not cron_time == 0:
Log.info(self, "updating crontab entry,"
" please wait...")
if not WOShellExec.cmd_exec(self, "/bin/bash -c "
"\"crontab "
"-l | sed '/WordOps "
"start MySQL slow "
"log/!b;n;c\*\/{0} "
"\* \* \* "
"\* \/usr"
"\/local\/bin\/wo debug "
"--import\-slow\-log' "
"| crontab -\""
.format(cron_time)):
Log.error(self, "failed to update crontab entry")
else:
Log.info(self, "removing crontab entry,"
" please wait...")
if not WOShellExec.cmd_exec(self, "/bin/bash -c "
"\"crontab "
"-l | sed '/WordOps "
"start MySQL slow "
"log/,+2d'"
"| crontab -\""
.format(cron_time)):
Log.error(self, "failed to remove crontab entry")
except CommandExecutionError as e:
Log.debug(self, str(e))
if self.app.pargs.all == 'on':
if self.app.pargs.site_name:
self.app.pargs.wp = 'on'
self.app.pargs.nginx = 'on'
self.app.pargs.php = 'on'
self.app.pargs.fpm = 'on'
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') and WOAptGet.is_installed(self,'php7.0-fpm'):
self.app.pargs.php7 = 'on'
self.app.pargs.fpm7 = 'on'
self.app.pargs.mysql = 'on'
self.app.pargs.rewrite = 'on'
if self.app.pargs.all == 'off':
if self.app.pargs.site_name:
self.app.pargs.wp = 'off'
self.app.pargs.nginx = 'off'
self.app.pargs.php = 'off'
self.app.pargs.fpm = 'off'
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') and WOAptGet.is_installed(self,'php7.0-fpm'):
self.app.pargs.php7 = 'off'
self.app.pargs.fpm7 = 'off'
self.app.pargs.mysql = 'off'
self.app.pargs.rewrite = 'off'
if ((not self.app.pargs.nginx) and (not self.app.pargs.php) and (not self.app.pargs.php7)
and (not self.app.pargs.fpm) and (not self.app.pargs.fpm7) and (not self.app.pargs.mysql)
and (not self.app.pargs.wp) and (not self.app.pargs.rewrite)
and self.app.pargs.site_name):
self.app.args.print_help()
# self.app.pargs.nginx = 'on'
# self.app.pargs.wp = 'on'
# self.app.pargs.rewrite = 'on'
if self.app.pargs.nginx:
self.debug_nginx()
if self.app.pargs.php:
self.debug_php()
if self.app.pargs.fpm:
self.debug_fpm()
if self.app.pargs.php7:
self.debug_php7()
if self.app.pargs.fpm7:
self.debug_fpm7()
if self.app.pargs.mysql:
# MySQL debug will not work for remote MySQL
if WOVariables.wo_mysql_host is "localhost":
self.debug_mysql()
else:
Log.warn(self, "Remote MySQL found, WordOps does not support "
"debugging remote servers")
if self.app.pargs.wp:
self.debug_wp()
if self.app.pargs.rewrite:
self.debug_rewrite()
if self.app.pargs.interactive:
self.interactive = True
# Reload Nginx
if self.trigger_nginx:
WOService.reload_service(self, 'nginx')
# Reload PHP
if self.trigger_php:
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic'):
if WOAptGet.is_installed(self,'php5.6-fpm'):
WOService.restart_service(self, 'php5.6-fpm')
if WOAptGet.is_installed(self,'php7.0-fpm'):
WOService.restart_service(self, 'php7.0-fpm')
else:
WOService.restart_service(self, 'php5-fpm')
if WOVariables.wo_platform_codename == 'jessie':
WOService.restart_service(self, 'php7.0-fpm')
if len(self.msg) > 0:
if not self.app.pargs.interactive:
disp_msg = ' '.join(self.msg)
Log.info(self, "Use following command to check debug logs:\n"
+ Log.ENDC + "tail -f {0}".format(disp_msg))
else:
signal.signal(signal.SIGINT, self.signal_handler)
watch_list = []
for w_list in self.msg:
watch_list = watch_list + glob.glob(w_list)
logwatch(self, watch_list)
@expose(hide=True)
def import_slow_log(self):
"""Default function for import slow log"""
if os.path.isdir("{0}22222/htdocs/db/anemometer"
.format(WOVariables.wo_webroot)):
if os.path.isfile("/var/log/mysql/mysql-slow.log"):
# Get Anemometer user name and password
Log.info(self, "Importing MySQL slow log to Anemometer")
host = os.popen("grep -e \"\'host\'\" {0}22222/htdocs/"
.format(WOVariables.wo_webroot)
+ "db/anemometer/conf/config.inc.php "
"| head -1 | cut -d\\\' -f4 | "
"tr -d '\n'").read()
user = os.popen("grep -e \"\'user\'\" {0}22222/htdocs/"
.format(WOVariables.wo_webroot)
+ "db/anemometer/conf/config.inc.php "
"| head -1 | cut -d\\\' -f4 | "
"tr -d '\n'").read()
password = os.popen("grep -e \"\'password\'\" {0}22222/"
.format(WOVariables.wo_webroot)
+ "htdocs/db/anemometer/conf"
"/config.inc.php "
"| head -1 | cut -d\\\' -f4 | "
"tr -d '\n'").read()
# Import slow log Anemometer using pt-query-digest
try:
WOShellExec.cmd_exec(self, "pt-query-digest --user={0} "
"--password={1} "
"--review D=slow_query_log,"
"t=global_query_review "
"--history D=slow_query_log,t="
"global_query_review_history "
"--no-report --limit=0% "
"--filter=\" \\$event->{{Bytes}} = "
"length(\\$event->{{arg}}) "
"and \\$event->{{hostname}}=\\\""
"{2}\\\"\" "
"/var/log/mysql/mysql-slow.log"
.format(user, password, host))
except CommandExecutionError as e:
Log.debug(self, str(e))
Log.error(self, "MySQL slow log import failed.")
else:
Log.error(self, "MySQL slow log file not found,"
" so not imported slow logs")
else:
Log.error(self, "Anemometer is not installed." +
Log.ENDC + "\n Install Anemometer with:"
+ Log.BOLD + "\n `wo stack install --utils`"
+ Log.ENDC)
def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(WODebugController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', wo_debug_hook)

View File

@@ -0,0 +1,34 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.shellexec import WOShellExec
from wo.core.logging import Log
from wo.core.variables import WOVariables
import os
def wo_import_slow_log_hook(app):
pass
class WOImportslowlogController(CementBaseController):
class Meta:
label = 'import_slow_log'
stacked_on = 'base'
stacked_type = 'nested'
description = 'Import MySQL slow log to Anemometer database'
usage = "wo import-slow-log"
@expose(hide=True)
def default(self):
Log.info(self, "This command is deprecated."
" You can use this command instead, " +
Log.ENDC + Log.BOLD + "\n`wo debug --import-slow-log`" +
Log.ENDC)
def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(WOImportslowlogController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', wo_import_slow_log_hook)

289
wo/cli/plugins/info.py Normal file
View File

@@ -0,0 +1,289 @@
"""WOInfo Plugin for WordOps"""
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.variables import WOVariables
from pynginxconfig import NginxConfig
from wo.core.aptget import WOAptGet
from wo.core.shellexec import WOShellExec
from wo.core.logging import Log
import os
import configparser
def wo_info_hook(app):
pass
class WOInfoController(CementBaseController):
class Meta:
label = 'info'
stacked_on = 'base'
stacked_type = 'nested'
description = ('Display configuration information related to Nginx,'
' PHP and MySQL')
arguments = [
(['--mysql'],
dict(help='Get MySQL configuration information',
action='store_true')),
(['--php'],
dict(help='Get PHP configuration information',
action='store_true')),
(['--php7'],
dict(help='Get PHP 7.0 configuration information',
action='store_true')),
(['--nginx'],
dict(help='Get Nginx configuration information',
action='store_true')),
]
usage = "wo info [options]"
@expose(hide=True)
def info_nginx(self):
"""Display Nginx information"""
version = os.popen("nginx -v 2>&1 | cut -d':' -f2 | cut -d' ' -f2 | "
"cut -d'/' -f2 | tr -d '\n'").read()
allow = os.popen("grep ^allow /etc/nginx/common/acl.conf | "
"cut -d' ' -f2 | cut -d';' -f1 | tr '\n' ' '").read()
nc = NginxConfig()
nc.loadf('/etc/nginx/nginx.conf')
user = nc.get('user')[1]
worker_processes = nc.get('worker_processes')[1]
worker_connections = nc.get([('events',), 'worker_connections'])[1]
keepalive_timeout = nc.get([('http',), 'keepalive_timeout'])[1]
fastcgi_read_timeout = nc.get([('http',),
'fastcgi_read_timeout'])[1]
client_max_body_size = nc.get([('http',),
'client_max_body_size'])[1]
data = dict(version=version, allow=allow, user=user,
worker_processes=worker_processes,
keepalive_timeout=keepalive_timeout,
worker_connections=worker_connections,
fastcgi_read_timeout=fastcgi_read_timeout,
client_max_body_size=client_max_body_size)
self.app.render((data), 'info_nginx.mustache')
@expose(hide=True)
def info_php(self):
"""Display PHP information"""
version = os.popen("{0} -v 2>/dev/null | head -n1 | cut -d' ' -f2 |".format("php5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php") +
" cut -d'+' -f1 | tr -d '\n'").read
config = configparser.ConfigParser()
config.read('/etc/{0}/fpm/php.ini'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
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']
config.read('/etc/{0}/fpm/pool.d/www.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
www_listen = config['www']['listen']
www_ping_path = config['www']['ping.path']
www_pm_status_path = config['www']['pm.status_path']
www_pm = config['www']['pm']
www_pm_max_requests = config['www']['pm.max_requests']
www_pm_max_children = config['www']['pm.max_children']
www_pm_start_servers = config['www']['pm.start_servers']
www_pm_min_spare_servers = config['www']['pm.min_spare_servers']
www_pm_max_spare_servers = config['www']['pm.max_spare_servers']
www_request_terminate_time = (config['www']
['request_terminate_timeout'])
try:
www_xdebug = (config['www']['php_admin_flag[xdebug.profiler_enable'
'_trigger]'])
except Exception as e:
www_xdebug = 'off'
config.read('/etc/{0}/fpm/pool.d/debug.conf'.format("php/5.6" if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic') else "php5"))
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:
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_php7(self):
"""Display PHP information"""
version = os.popen("php7.0 -v 2>/dev/null | head -n1 | cut -d' ' -f2 |"
" cut -d'+' -f1 | tr -d '\n'").read
config = configparser.ConfigParser()
config.read('/etc/php/7.0/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']
config.read('/etc/php/7.0/fpm/pool.d/www.conf')
www_listen = config['www']['listen']
www_ping_path = config['www']['ping.path']
www_pm_status_path = config['www']['pm.status_path']
www_pm = config['www']['pm']
www_pm_max_requests = config['www']['pm.max_requests']
www_pm_max_children = config['www']['pm.max_children']
www_pm_start_servers = config['www']['pm.start_servers']
www_pm_min_spare_servers = config['www']['pm.min_spare_servers']
www_pm_max_spare_servers = config['www']['pm.max_spare_servers']
www_request_terminate_time = (config['www']
['request_terminate_timeout'])
try:
www_xdebug = (config['www']['php_admin_flag[xdebug.profiler_enable'
'_trigger]'])
except Exception as e:
www_xdebug = 'off'
config.read('/etc/php/7.0/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:
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"""
version = os.popen("mysql -V | awk '{print($5)}' | cut -d ',' "
"-f1 | tr -d '\n'").read()
host = "localhost"
port = os.popen("mysql -e \"show variables\" | grep ^port | awk "
"'{print($2)}' | tr -d '\n'").read()
wait_timeout = os.popen("mysql -e \"show variables\" | grep "
"^wait_timeout | awk '{print($2)}' | "
"tr -d '\n'").read()
interactive_timeout = os.popen("mysql -e \"show variables\" | grep "
"^interactive_timeout | awk "
"'{print($2)}' | tr -d '\n'").read()
max_used_connections = os.popen("mysql -e \"show global status\" | "
"grep Max_used_connections | awk "
"'{print($2)}' | tr -d '\n'").read()
datadir = os.popen("mysql -e \"show variables\" | grep datadir | awk"
" '{print($2)}' | tr -d '\n'").read()
socket = os.popen("mysql -e \"show variables\" | grep \"^socket\" | "
"awk '{print($2)}' | tr -d '\n'").read()
data = dict(version=version, host=host, port=port,
wait_timeout=wait_timeout,
interactive_timeout=interactive_timeout,
max_used_connections=max_used_connections,
datadir=datadir, socket=socket)
self.app.render((data), 'info_mysql.mustache')
@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.php7):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
if WOAptGet.is_installed(self, 'php7.0-fpm'):
self.app.pargs.php = True
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom') or WOAptGet.is_installed(self, 'nginx-common'):
self.info_nginx()
else:
Log.error(self, "Nginx is not installed")
if self.app.pargs.php:
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if WOAptGet.is_installed(self, 'php5-fpm'):
self.info_php()
else:
Log.error(self, "PHP5 is not installed")
else:
if WOAptGet.is_installed(self, 'php5.6-fpm'):
self.info_php()
else:
Log.error(self, "PHP5.6 is not installed")
if self.app.pargs.php7:
if WOAptGet.is_installed(self, 'php7.0-fpm'):
self.info_php7()
else:
Log.error(self, "PHP 7.0 is not installed")
if self.app.pargs.mysql:
if WOShellExec.cmd_exec(self, "mysqladmin ping"):
self.info_mysql()
else:
Log.error(self, "MySQL is not installed")
def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(WOInfoController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', wo_info_hook)

577
wo/cli/plugins/log.py Normal file
View File

@@ -0,0 +1,577 @@
"""Logfile Plugin for WordOps"""
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.logging import Log
from wo.cli.plugins.site_functions import logwatch
from wo.core.variables import WOVariables
from wo.core.fileutils import WOFileUtils
from wo.core.shellexec import WOShellExec
from wo.core.sendmail import WOSendMail
from wo.core.mysql import WOMysql
import os
import glob
import gzip
def wo_log_hook(app):
pass
class WOLogController(CementBaseController):
class Meta:
label = 'log'
description = 'Perform operations on Nginx, PHP and MySQL log files'
stacked_on = 'base'
stacked_type = 'nested'
usage = "wo log [<site_name>] [options]"
@expose(hide=True)
def default(self):
self.app.args.print_help()
class WOLogShowController(CementBaseController):
class Meta:
label = 'show'
description = 'Show Nginx, PHP, MySQL log file'
stacked_on = 'log'
stacked_type = 'nested'
arguments = [
(['--all'],
dict(help='Show All logs file', action='store_true')),
(['--nginx'],
dict(help='Show Nginx Error logs file', action='store_true')),
(['--php'],
dict(help='Show PHP Error logs file', action='store_true')),
(['--fpm'],
dict(help='Show PHP5-fpm slow logs file',
action='store_true')),
(['--mysql'],
dict(help='Show MySQL logs file', action='store_true')),
(['--wp'],
dict(help='Show Site specific WordPress logs file',
action='store_true')),
(['--access'],
dict(help='Show Nginx access log file',
action='store_true')),
(['site_name'],
dict(help='Website Name', nargs='?', default=None))
]
usage = "wo log show [<site_name>] [options]"
@expose(hide=True)
def default(self):
"""Default function of log show"""
self.msg = []
if self.app.pargs.php:
self.app.pargs.nginx = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (not self.app.pargs.site_name)):
self.app.pargs.nginx = True
self.app.pargs.fpm = True
self.app.pargs.mysql = True
self.app.pargs.access = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (self.app.pargs.site_name)):
self.app.pargs.nginx = True
self.app.pargs.wp = True
self.app.pargs.access = True
self.app.pargs.mysql = True
if self.app.pargs.nginx and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*error.log"]
if self.app.pargs.access and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*access.log"]
if self.app.pargs.fpm:
open('/var/log/php5/slow.log', 'a').close()
open('/var/log/php5/fpm.log', 'a').close()
self.msg = self.msg + ['/var/log/php5/slow.log',
'/var/log/php5/fpm.log']
if self.app.pargs.mysql:
# MySQL debug will not work for remote MySQL
if WOVariables.wo_mysql_host is "localhost":
if os.path.isfile('/var/log/mysql/mysql-slow.log'):
self.msg = self.msg + ['/var/log/mysql/mysql-slow.log']
else:
Log.info(self, "MySQL slow-log not found, skipped")
else:
Log.warn(self, "Remote MySQL found, WordOps does not support"
"remote MySQL servers or log files")
if self.app.pargs.site_name:
webroot = "{0}{1}".format(WOVariables.wo_webroot,
self.app.pargs.site_name)
if not os.path.isdir(webroot):
Log.error(self, "Site not present, quitting")
if self.app.pargs.access:
self.msg = self.msg + ["{0}/{1}/logs/access.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.nginx:
self.msg = self.msg + ["{0}/{1}/logs/error.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.wp:
if os.path.isdir('{0}/htdocs/wp-content'.format(webroot)):
if not os.path.isfile('{0}/logs/debug.log'
.format(webroot)):
if not os.path.isfile('{0}/htdocs/wp-content/debug.log'
.format(webroot)):
open("{0}/htdocs/wp-content/debug.log"
.format(webroot),
encoding='utf-8', mode='a').close()
WOShellExec.cmd_exec(self, "chown {1}: {0}/htdocs/"
"wp-content/debug.log"
"".format(webroot,
WOVariables
.wo_php_user)
)
# create symbolic link for debug log
WOFileUtils.create_symlink(self, ["{0}/htdocs/wp-content/"
"debug.log"
.format(webroot),
'{0}/logs/debug.log'
.format(webroot)])
self.msg = self.msg + ["{0}/{1}/logs/debug.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
else:
Log.info(self, "Site is not WordPress site, skipping "
"WordPress logs")
watch_list = []
for w_list in self.msg:
watch_list = watch_list + glob.glob(w_list)
logwatch(self, watch_list)
class WOLogResetController(CementBaseController):
class Meta:
label = 'reset'
description = 'Reset Nginx, PHP, MySQL log file'
stacked_on = 'log'
stacked_type = 'nested'
arguments = [
(['--all'],
dict(help='Reset All logs file', action='store_true')),
(['--nginx'],
dict(help='Reset Nginx Error logs file', action='store_true')),
(['--php'],
dict(help='Reset PHP Error logs file', action='store_true')),
(['--fpm'],
dict(help='Reset PHP5-fpm slow logs file',
action='store_true')),
(['--mysql'],
dict(help='Reset MySQL logs file', action='store_true')),
(['--wp'],
dict(help='Reset Site specific WordPress logs file',
action='store_true')),
(['--access'],
dict(help='Reset Nginx access log file',
action='store_true')),
(['--slow-log-db'],
dict(help='Drop all rows from slowlog table in database',
action='store_true')),
(['site_name'],
dict(help='Website Name', nargs='?', default=None))
]
usage = "wo log reset [<site_name>] [options]"
@expose(hide=True)
def default(self):
"""Default function of log reset"""
self.msg = []
if self.app.pargs.php:
self.app.pargs.nginx = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (not self.app.pargs.site_name)
and (not self.app.pargs.slow_log_db)):
self.app.pargs.nginx = True
self.app.pargs.fpm = True
self.app.pargs.mysql = True
self.app.pargs.access = True
self.app.pargs.slow_log_db = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (self.app.pargs.site_name)
and (not self.app.pargs.slow-log-db)):
self.app.pargs.nginx = True
self.app.pargs.wp = True
self.app.pargs.access = True
self.app.pargs.mysql = True
if self.app.pargs.slow_log_db:
if os.path.isdir("/var/www/22222/htdocs/db/anemometer"):
Log.info(self, "Resetting MySQL slow_query_log database table")
WOMysql.execute(self, "TRUNCATE TABLE "
"slow_query_log.global_query_review_history")
WOMysql.execute(self, "TRUNCATE TABLE "
"slow_query_log.global_query_review")
if self.app.pargs.nginx and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*error.log"]
if self.app.pargs.access and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*access.log"]
if self.app.pargs.fpm:
open('/var/log/php5/slow.log', 'a').close()
open('/var/log/php5/fpm.log', 'a').close()
self.msg = self.msg + ['/var/log/php5/slow.log',
'/var/log/php5/fpm.log']
if self.app.pargs.mysql:
# MySQL debug will not work for remote MySQL
if WOVariables.wo_mysql_host is "localhost":
if os.path.isfile('/var/log/mysql/mysql-slow.log'):
self.msg = self.msg + ['/var/log/mysql/mysql-slow.log']
else:
Log.info(self, "MySQL slow-log not found, skipped")
else:
Log.warn(self, "Remote MySQL found, WordOps does not support"
"remote MySQL servers or log files")
if self.app.pargs.site_name:
webroot = "{0}{1}".format(WOVariables.wo_webroot,
self.app.pargs.site_name)
if not os.path.isdir(webroot):
Log.error(self, "Site not present, quitting")
if self.app.pargs.access:
self.msg = self.msg + ["{0}/{1}/logs/access.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.nginx:
self.msg = self.msg + ["{0}/{1}/logs/error.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.wp:
if os.path.isdir('{0}/htdocs/wp-content'.format(webroot)):
if not os.path.isfile('{0}/logs/debug.log'
.format(webroot)):
if not os.path.isfile('{0}/htdocs/wp-content/debug.log'
.format(webroot)):
open("{0}/htdocs/wp-content/debug.log"
.format(webroot),
encoding='utf-8', mode='a').close()
WOShellExec.cmd_exec(self, "chown {1}: {0}/htdocs/"
"wp-content/debug.log"
"".format(webroot,
WOVariables
.wo_php_user)
)
# create symbolic link for debug log
WOFileUtils.create_symlink(self, ["{0}/htdocs/wp-content/"
"debug.log"
.format(webroot),
'{0}/logs/debug.log'
.format(webroot)])
self.msg = self.msg + ["{0}/{1}/logs/debug.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
else:
Log.info(self, "Site is not WordPress site, skipping "
"WordPress logs")
reset_list = []
for r_list in self.msg:
reset_list = reset_list + glob.glob(r_list)
# Clearing content of file
for r_list in reset_list:
Log.info(self, "Resetting file {file}".format(file=r_list))
open(r_list, 'w').close()
class WOLogGzipController(CementBaseController):
class Meta:
label = 'gzip'
description = 'GZip Nginx, PHP, MySQL log file'
stacked_on = 'log'
stacked_type = 'nested'
arguments = [
(['--all'],
dict(help='GZip All logs file', action='store_true')),
(['--nginx'],
dict(help='GZip Nginx Error logs file', action='store_true')),
(['--php'],
dict(help='GZip PHP Error logs file', action='store_true')),
(['--fpm'],
dict(help='GZip PHP5-fpm slow logs file',
action='store_true')),
(['--mysql'],
dict(help='GZip MySQL logs file', action='store_true')),
(['--wp'],
dict(help='GZip Site specific WordPress logs file',
action='store_true')),
(['--access'],
dict(help='GZip Nginx access log file',
action='store_true')),
(['site_name'],
dict(help='Website Name', nargs='?', default=None))
]
usage = "wo log gzip [<site_name>] [options]"
@expose(hide=True)
def default(self):
"""Default function of log GZip"""
self.msg = []
if self.app.pargs.php:
self.app.pargs.nginx = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (not self.app.pargs.site_name)):
self.app.pargs.nginx = True
self.app.pargs.fpm = True
self.app.pargs.mysql = True
self.app.pargs.access = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (self.app.pargs.site_name)):
self.app.pargs.nginx = True
self.app.pargs.wp = True
self.app.pargs.access = True
self.app.pargs.mysql = True
if self.app.pargs.nginx and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*error.log"]
if self.app.pargs.access and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*access.log"]
if self.app.pargs.fpm:
open('/var/log/php5/slow.log', 'a').close()
open('/var/log/php5/fpm.log', 'a').close()
self.msg = self.msg + ['/var/log/php5/slow.log',
'/var/log/php5/fpm.log']
if self.app.pargs.mysql:
# MySQL debug will not work for remote MySQL
if WOVariables.wo_mysql_host is "localhost":
if os.path.isfile('/var/log/mysql/mysql-slow.log'):
self.msg = self.msg + ['/var/log/mysql/mysql-slow.log']
else:
Log.info(self, "MySQL slow-log not found, skipped")
else:
Log.warn(self, "Remote MySQL found, WordOps does not support"
"remote MySQL servers or log files")
if self.app.pargs.site_name:
webroot = "{0}{1}".format(WOVariables.wo_webroot,
self.app.pargs.site_name)
if not os.path.isdir(webroot):
Log.error(self, "Site not present, quitting")
if self.app.pargs.access:
self.msg = self.msg + ["{0}/{1}/logs/access.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.nginx:
self.msg = self.msg + ["{0}/{1}/logs/error.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.wp:
if os.path.isdir('{0}/htdocs/wp-content'.format(webroot)):
if not os.path.isfile('{0}/logs/debug.log'
.format(webroot)):
if not os.path.isfile('{0}/htdocs/wp-content/debug.log'
.format(webroot)):
open("{0}/htdocs/wp-content/debug.log"
.format(webroot),
encoding='utf-8', mode='a').close()
WOShellExec.cmd_exec(self, "chown {1}: {0}/htdocs/"
"wp-content/debug.log"
"".format(webroot,
WOVariables
.wo_php_user)
)
# create symbolic link for debug log
WOFileUtils.create_symlink(self, ["{0}/htdocs/wp-content/"
"debug.log"
.format(webroot),
'{0}/logs/debug.log'
.format(webroot)])
self.msg = self.msg + ["{0}/{1}/logs/debug.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
else:
Log.info(self, "Site is not WordPress site, skipping "
"WordPress logs")
gzip_list = []
for g_list in self.msg:
gzip_list = gzip_list + glob.glob(g_list)
# Gzip content of file
for g_list in gzip_list:
Log.info(self, "Gzipping file {file}".format(file=g_list))
in_file = g_list
in_data = open(in_file, "rb").read()
out_gz = g_list + ".gz"
gzf = gzip.open(out_gz, "wb")
gzf.write(in_data)
gzf.close()
class WOLogMailController(CementBaseController):
class Meta:
label = 'mail'
description = 'Mail Nginx, PHP, MySQL log file'
stacked_on = 'log'
stacked_type = 'nested'
arguments = [
(['--all'],
dict(help='Mail All logs file', action='store_true')),
(['--nginx'],
dict(help='Mail Nginx Error logs file', action='store_true')),
(['--php'],
dict(help='Mail PHP Error logs file', action='store_true')),
(['--fpm'],
dict(help='Mail PHP5-fpm slow logs file',
action='store_true')),
(['--mysql'],
dict(help='Mail MySQL logs file', action='store_true')),
(['--wp'],
dict(help='Mail Site specific WordPress logs file',
action='store_true')),
(['--access'],
dict(help='Mail Nginx access log file',
action='store_true')),
(['site_name'],
dict(help='Website Name', nargs='?', default=None)),
(['--to'],
dict(help='Email addresses to send log files', action='append',
dest='to', nargs=1, required=True)),
]
usage = "wo log mail [<site_name>] [options]"
@expose(hide=True)
def default(self):
"""Default function of log Mail"""
self.msg = []
if self.app.pargs.php:
self.app.pargs.nginx = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (not self.app.pargs.site_name)):
self.app.pargs.nginx = True
self.app.pargs.fpm = True
self.app.pargs.mysql = True
self.app.pargs.access = True
if ((not self.app.pargs.nginx) and (not self.app.pargs.fpm)
and (not self.app.pargs.mysql) and (not self.app.pargs.access)
and (not self.app.pargs.wp) and (self.app.pargs.site_name)):
self.app.pargs.nginx = True
self.app.pargs.wp = True
self.app.pargs.access = True
self.app.pargs.mysql = True
if self.app.pargs.nginx and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*error.log"]
if self.app.pargs.access and (not self.app.pargs.site_name):
self.msg = self.msg + ["/var/log/nginx/*access.log"]
if self.app.pargs.fpm:
open('/var/log/php5/slow.log', 'a').close()
open('/var/log/php5/fpm.log', 'a').close()
self.msg = self.msg + ['/var/log/php5/slow.log',
'/var/log/php5/fpm.log']
if self.app.pargs.mysql:
# MySQL debug will not work for remote MySQL
if WOVariables.wo_mysql_host is "localhost":
if os.path.isfile('/var/log/mysql/mysql-slow.log'):
self.msg = self.msg + ['/var/log/mysql/mysql-slow.log']
else:
Log.info(self, "MySQL slow-log not found, skipped")
else:
Log.warn(self, "Remote MySQL found, WordOps does not support"
"remote MySQL servers or log files")
if self.app.pargs.site_name:
webroot = "{0}{1}".format(WOVariables.wo_webroot,
self.app.pargs.site_name)
if not os.path.isdir(webroot):
Log.error(self, "Site not present, quitting")
if self.app.pargs.access:
self.msg = self.msg + ["{0}/{1}/logs/access.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.nginx:
self.msg = self.msg + ["{0}/{1}/logs/error.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
if self.app.pargs.wp:
if os.path.isdir('{0}/htdocs/wp-content'.format(webroot)):
if not os.path.isfile('{0}/logs/debug.log'
.format(webroot)):
if not os.path.isfile('{0}/htdocs/wp-content/debug.log'
.format(webroot)):
open("{0}/htdocs/wp-content/debug.log"
.format(webroot),
encoding='utf-8', mode='a').close()
WOShellExec.cmd_exec(self, "chown {1}: {0}/htdocs/"
"wp-content/debug.log"
"".format(webroot,
WOVariables
.wo_php_user)
)
# create symbolic link for debug log
WOFileUtils.create_symlink(self, ["{0}/htdocs/wp-content/"
"debug.log"
.format(webroot),
'{0}/logs/debug.log'
.format(webroot)])
self.msg = self.msg + ["{0}/{1}/logs/debug.log"
.format(WOVariables.wo_webroot,
self.app.pargs.site_name)]
else:
Log.info(self, "Site is not WordPress site, skipping "
"WordPress logs")
mail_list = []
for m_list in self.msg:
mail_list = mail_list + glob.glob(m_list)
for tomail in self.app.pargs.to:
Log.info(self, "Sending mail to {0}".format(tomail[0]))
WOSendMail("wordops", tomail[0], "{0} Log Files"
.format(WOVariables.wo_fqdn),
"Hi,\n The requested logfiles are attached."
"\n\nBest regards,\nYour WordOps worker",
files=mail_list, port=25, isTls=False)
def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(WOLogController)
handler.register(WOLogShowController)
handler.register(WOLogResetController)
handler.register(WOLogGzipController)
handler.register(WOLogMailController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', wo_log_hook)

57
wo/cli/plugins/models.py Normal file
View File

@@ -0,0 +1,57 @@
from sqlalchemy import Column, DateTime, String, Integer, Boolean, func
from wo.core.database import Base
class SiteDB(Base):
"""
Database model for site table
"""
__tablename__ = 'sites'
__table_args__ = {'extend_existing': True}
id = Column(Integer, primary_key=True)
sitename = Column(String, unique=True)
site_type = Column(String)
cache_type = Column(String)
site_path = Column(String)
# Use default=func.now() to set the default created time
# of a site to be the current time when a
# Site record was created
created_on = Column(DateTime, default=func.now())
is_enabled = Column(Boolean, unique=False, default=True, nullable=False)
is_ssl = Column(Boolean, unique=False, default=False)
storage_fs = Column(String)
storage_db = Column(String)
db_name = Column(String)
db_user = Column(String)
db_password = Column(String)
db_host = Column(String)
is_hhvm = Column(Boolean, unique=False, default=False)
php_version = Column(String)
def __init__(self, sitename=None, site_type=None, cache_type=None,
site_path=None, site_enabled=None,
is_ssl=None, storage_fs=None, storage_db=None, db_name=None,
db_user=None, db_password=None, db_host='localhost',
hhvm=None, php_version=None):
self.sitename = sitename
self.site_type = site_type
self.cache_type = cache_type
self.site_path = site_path
self.is_enabled = site_enabled
self.is_ssl = is_ssl
self.storage_fs = storage_fs
self.storage_db = storage_db
self.db_name = db_name
self.db_user = db_user
self.db_password = db_password
self.db_host = db_host
self.is_hhvm = hhvm
self.php_version = php_version
# def __repr__(self):
# return '<Site %r>' % (self.site_type)
#
# def getType(self):
# return '%r>' % (self.site_type)

141
wo/cli/plugins/secure.py Normal file
View File

@@ -0,0 +1,141 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.aptget import WOAptGet
from wo.core.shellexec import WOShellExec
from wo.core.variables import WOVariables
from wo.core.logging import Log
from wo.core.git import WOGit
from wo.core.services import WOService
import string
import random
import sys
import hashlib
import getpass
def wo_secure_hook(app):
pass
class WOSecureController(CementBaseController):
class Meta:
label = 'secure'
stacked_on = 'base'
stacked_type = 'nested'
description = ('Secure command secure auth, ip and port')
arguments = [
(['--auth'],
dict(help='secure auth', action='store_true')),
(['--port'],
dict(help='secure port', action='store_true')),
(['--ip'],
dict(help='secure ip', action='store_true')),
(['user_input'],
dict(help='user input', nargs='?', default=None)),
(['user_pass'],
dict(help='user pass', nargs='?', default=None))]
usage = "wo secure [options]"
@expose(hide=True)
def default(self):
if self.app.pargs.auth:
self.secure_auth()
if self.app.pargs.port:
self.secure_port()
if self.app.pargs.ip:
self.secure_ip()
@expose(hide=True)
def secure_auth(self):
"""This function secures authentication"""
passwd = ''.join([random.choice
(string.ascii_letters + string.digits)
for n in range(6)])
if not self.app.pargs.user_input:
username = input("Provide HTTP authentication user "
"name [{0}] :".format(WOVariables.wo_user))
self.app.pargs.user_input = username
if username == "":
self.app.pargs.user_input = WOVariables.wo_user
if not self.app.pargs.user_pass:
password = getpass.getpass("Provide HTTP authentication "
"password [{0}] :".format(passwd))
self.app.pargs.user_pass = password
if password == "":
self.app.pargs.user_pass = passwd
Log.debug(self, "printf username:"
"$(openssl passwd -crypt "
"password 2> /dev/null)\n\""
"> /etc/nginx/htpasswd-wo 2>/dev/null")
WOShellExec.cmd_exec(self, "printf \"{username}:"
"$(openssl passwd -crypt "
"{password} 2> /dev/null)\n\""
"> /etc/nginx/htpasswd-wo 2>/dev/null"
.format(username=self.app.pargs.user_input,
password=self.app.pargs.user_pass),
log=False)
WOGit.add(self, ["/etc/nginx"],
msg="Adding changed secure auth into Git")
@expose(hide=True)
def secure_port(self):
"""This function Secures port"""
if self.app.pargs.user_input:
while not self.app.pargs.user_input.isdigit():
Log.info(self, "Please enter a valid port number ")
self.app.pargs.user_input = input("WordOps "
"admin port [22222]:")
if not self.app.pargs.user_input:
port = input("WordOps admin port [22222]:")
if port == "":
self.app.pargs.user_input = 22222
while not port.isdigit() and port != "":
Log.info(self, "Please Enter valid port number :")
port = input("WordOps admin port [22222]:")
self.app.pargs.user_input = port
if WOVariables.wo_platform_distro == 'ubuntu':
WOShellExec.cmd_exec(self, "sed -i \"s/listen.*/listen "
"{port} default_server ssl http2;/\" "
"/etc/nginx/sites-available/22222"
.format(port=self.app.pargs.user_input))
if WOVariables.wo_platform_distro == 'debian':
WOShellExec.cmd_exec(self, "sed -i \"s/listen.*/listen "
"{port} default_server ssl http2;/\" "
"/etc/nginx/sites-available/22222"
.format(port=self.app.pargs.user_input))
WOGit.add(self, ["/etc/nginx"],
msg="Adding changed secure port into Git")
if not WOService.reload_service(self, 'nginx'):
Log.error(self, "service nginx reload failed. "
"check issues with `nginx -t` command")
Log.info(self, "Successfully port changed {port}"
.format(port=self.app.pargs.user_input))
@expose(hide=True)
def secure_ip(self):
"""IP whitelisting"""
newlist = []
if not self.app.pargs.user_input:
ip = input("Enter the comma separated IP addresses "
"to white list [127.0.0.1]:")
self.app.pargs.user_input = ip
try:
user_ip = self.app.pargs.user_input.split(',')
except Exception as e:
user_ip = ['127.0.0.1']
for ip_addr in user_ip:
if not ("exist_ip_address "+ip_addr in open('/etc/nginx/common/'
'acl.conf').read()):
WOShellExec.cmd_exec(self, "sed -i "
"\"/deny/i allow {whitelist_address}\;\""
" /etc/nginx/common/acl.conf"
.format(whitelist_address=ip_addr))
WOGit.add(self, ["/etc/nginx"],
msg="Adding changed secure ip into Git")
Log.info(self, "Successfully added IP address in acl.conf file")
def load(app):
handler.register(WOSecureController)
hook.register('post_argument_parsing', wo_secure_hook)

1735
wo/cli/plugins/site.py Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

126
wo/cli/plugins/sitedb.py Normal file
View File

@@ -0,0 +1,126 @@
from sqlalchemy import Column, DateTime, String, Integer, Boolean
from sqlalchemy import ForeignKey, func
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
from wo.core.logging import Log
from wo.core.database import db_session
from wo.cli.plugins.models import SiteDB
import sys
import glob
def addNewSite(self, site, stype, cache, path,
enabled=True, ssl=False, fs='ext4', db='mysql',
db_name=None, db_user=None, db_password=None,
db_host='localhost', hhvm=0, php_version='5.5'):
"""
Add New Site record information into the wo database.
"""
try:
newRec = SiteDB(site, stype, cache, path, enabled, ssl, fs, db,
db_name, db_user, db_password, db_host, hhvm,
php_version)
db_session.add(newRec)
db_session.commit()
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to add site to database")
def getSiteInfo(self, site):
"""
Retrieves site record from ee databse
"""
try:
q = SiteDB.query.filter(SiteDB.sitename == site).first()
return q
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to query database for site info")
def updateSiteInfo(self, site, stype='', cache='', webroot='',
enabled=True, ssl=False, fs='', db='', db_name=None,
db_user=None, db_password=None, db_host=None, hhvm=None,
php_version=''):
"""updates site record in database"""
try:
q = SiteDB.query.filter(SiteDB.sitename == site).first()
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to query database for site info")
if not q:
Log.error(self, "{0} does not exist in database".format(site))
# Check if new record matches old if not then only update database
if stype and q.site_type != stype:
q.site_type = stype
if cache and q.cache_type != cache:
q.cache_type = cache
if q.is_enabled != enabled:
q.is_enabled = enabled
if q.is_ssl != ssl:
q.is_ssl = ssl
if db_name and q.db_name != db_name:
q.db_name = db_name
if db_user and q.db_user != db_user:
q.db_user = db_user
if db_user and q.db_password != db_password:
q.db_password = db_password
if db_host and q.db_host != db_host:
q.db_host = db_host
if webroot and q.site_path != webroot:
q.site_path = webroot
if (hhvm is not None) and (q.is_hhvm is not hhvm):
q.is_hhvm = hhvm
if php_version and q.php_version != php_version:
q.php_version = php_version
try:
q.created_on = func.now()
db_session.commit()
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to update site info in application database.")
def deleteSiteInfo(self, site):
"""Delete site record in database"""
try:
q = SiteDB.query.filter(SiteDB.sitename == site).first()
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to query database")
if not q:
Log.error(self, "{0} does not exist in database".format(site))
try:
db_session.delete(q)
db_session.commit()
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to delete site from application database.")
def getAllsites(self):
"""
1. returns all records from ee database
"""
try:
q = SiteDB.query.all()
return q
except Exception as e:
Log.debug(self, "{0}".format(e))
Log.error(self, "Unable to query database")

2047
wo/cli/plugins/stack.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,115 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.mysql import WOMysql
from wo.core.logging import Log
from wo.core.variables import WOVariables
from wo.core.aptget import WOAptGet
from wo.core.shellexec import WOShellExec
from wo.core.apt_repo import WORepo
from wo.core.services import WOService
import configparser
import os
class WOStackMigrateController(CementBaseController):
class Meta:
label = 'migrate'
stacked_on = 'stack'
stacked_type = 'nested'
description = ('Migrate stack safely')
arguments = [
(['--mariadb'],
dict(help="Migrate database to MariaDB",
action='store_true')),
]
@expose(hide=True)
def migrate_mariadb(self):
# Backup all database
WOMysql.backupAll(self)
# Add MariaDB repo
Log.info(self, "Adding repository for MariaDB, please wait...")
mysql_pref = ("Package: *\nPin: origin sfo1.mirrors.digitalocean.com"
"\nPin-Priority: 1000\n")
with open('/etc/apt/preferences.d/'
'MariaDB.pref', 'w') as mysql_pref_file:
mysql_pref_file.write(mysql_pref)
WORepo.add(self, repo_url=WOVariables.wo_mysql_repo)
Log.debug(self, 'Adding key for {0}'
.format(WOVariables.wo_mysql_repo))
WORepo.add_key(self, '0xcbcb082a1bb943db',
keyserver="keyserver.ubuntu.com")
config = configparser.ConfigParser()
if os.path.exists('/etc/mysql/conf.d/my.cnf'):
config.read('/etc/mysql/conf.d/my.cnf')
else:
config.read(os.path.expanduser("~")+'/.my.cnf')
try:
chars = config['client']['password']
except Exception as e:
Log.error(self, "Error: process exited with error %s"
% e)
Log.debug(self, "Pre-seeding MariaDB")
Log.debug(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password "
"password \" | "
"debconf-set-selections")
WOShellExec.cmd_exec(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password "
"password {chars}\" | "
"debconf-set-selections"
.format(chars=chars),
log=False)
Log.debug(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password_again "
"password \" | "
"debconf-set-selections")
WOShellExec.cmd_exec(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password_again "
"password {chars}\" | "
"debconf-set-selections"
.format(chars=chars),
log=False)
# Install MariaDB
apt_packages = WOVariables.wo_mysql
# If PHP is installed then install php5-mysql
if WOAptGet.is_installed(self, "php5-fpm"):
apt_packages = apt_packages + ["php5-mysql"]
Log.info(self, "Updating apt-cache, hang on...")
WOAptGet.update(self)
Log.info(self, "Installing MariaDB, hang on...")
WOAptGet.remove(self, ["mysql-common", "libmysqlclient18"])
WOAptGet.auto_remove(self)
WOAptGet.install(self, apt_packages)
@expose(hide=True)
def default(self):
if ((not self.app.pargs.mariadb)):
self.app.args.print_help()
if self.app.pargs.mariadb:
if WOVariables.wo_mysql_host is not "localhost":
Log.error(self, "Remote MySQL server in use, skipping local install")
if WOShellExec.cmd_exec(self, "mysqladmin ping") and (not
WOAptGet.is_installed(self, 'mariadb-server')):
Log.info(self, "If your database size is big, "
"migration may take some time.")
Log.info(self, "During migration non nginx-cached parts of "
"your site may remain down")
start_migrate = input("Type \"mariadb\" to continue:")
if start_migrate != "mariadb":
Log.error(self, "Not starting migration")
self.migrate_mariadb()
else:
Log.error(self, "Your current MySQL is not alive or "
"you allready installed MariaDB")

View File

@@ -0,0 +1,403 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.services import WOService
from wo.core.logging import Log
from wo.core.variables import WOVariables
from wo.core.aptget import WOAptGet
class WOStackStatusController(CementBaseController):
class Meta:
label = 'stack_services'
stacked_on = 'stack'
stacked_type = 'embedded'
description = 'Check the stack status'
arguments = [
(['--memcache'],
dict(help='start/stop/restart memcache', action='store_true')),
]
@expose(help="Start stack services")
def start(self):
"""Start services"""
services = []
if not (self.app.pargs.nginx or self.app.pargs.php or self.app.pargs.php7
or self.app.pargs.mysql or self.app.pargs.hhvm or self.app.pargs.memcache
or self.app.pargs.redis):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom') or WOAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
if self.app.pargs.php:
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if WOAptGet.is_installed(self, 'php5-fpm'):
services = services + ['php5-fpm']
else:
Log.info(self, "PHP5-FPM is not installed")
else:
if WOAptGet.is_installed(self, 'php5.6-fpm'):
services = services + ['php5.6-fpm']
else:
Log.info(self, "PHP5.6-FPM is not installed")
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
if self.app.pargs.php7:
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic'):
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
else:
Log.info(self, "Your platform does not support PHP 7")
if self.app.pargs.mysql:
if ((WOVariables.wo_mysql_host is "localhost") or
(WOVariables.wo_mysql_host is "127.0.0.1")):
if (WOAptGet.is_installed(self, 'mysql-server') or
WOAptGet.is_installed(self, 'percona-server-server-5.6') or
WOAptGet.is_installed(self, 'mariadb-server')):
services = services + ['mysql']
else:
Log.info(self, "MySQL is not installed")
else:
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.hhvm:
if WOAptGet.is_installed(self, 'hhvm'):
services = services + ['hhvm']
else:
Log.info(self, "HHVM is not installed")
if self.app.pargs.memcache:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcache is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
else:
Log.info(self, "Redis server is not installed")
for service in services:
Log.debug(self, "Starting service: {0}".format(service))
WOService.start_service(self, service)
@expose(help="Stop stack services")
def stop(self):
"""Stop services"""
services = []
if not (self.app.pargs.nginx or self.app.pargs.php or self.app.pargs.php7
or self.app.pargs.mysql or self.app.pargs.hhvm or self.app.pargs.memcache
or self.app.pargs.redis):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom') or WOAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
if self.app.pargs.php:
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if WOAptGet.is_installed(self, 'php5-fpm'):
services = services + ['php5-fpm']
else:
Log.info(self, "PHP5-FPM is not installed")
else:
if WOAptGet.is_installed(self, 'php5.6-fpm'):
services = services + ['php5.6-fpm']
else:
Log.info(self, "PHP5.6-FPM is not installed")
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
if self.app.pargs.php7:
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic'):
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
else:
Log.info(self, "Your platform does not support PHP 7")
if self.app.pargs.mysql:
if ((WOVariables.wo_mysql_host is "localhost") or
(WOVariables.wo_mysql_host is "127.0.0.1")):
if (WOAptGet.is_installed(self, 'mysql-server') or
WOAptGet.is_installed(self, 'percona-server-server-5.6') or
WOAptGet.is_installed(self, 'mariadb-server')):
services = services + ['mysql']
else:
Log.info(self, "MySQL is not installed")
else:
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.hhvm:
if WOAptGet.is_installed(self, 'hhvm'):
services = services + ['hhvm']
else:
Log.info(self, "HHVM is not installed")
if self.app.pargs.memcache:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcache is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
else:
Log.info(self, "Redis server is not installed")
for service in services:
Log.debug(self, "Stopping service: {0}".format(service))
WOService.stop_service(self, service)
@expose(help="Restart stack services")
def restart(self):
"""Restart services"""
services = []
if not (self.app.pargs.nginx or self.app.pargs.php or self.app.pargs.php7
or self.app.pargs.mysql or self.app.pargs.hhvm or self.app.pargs.memcache
or self.app.pargs.redis):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom') or WOAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
if self.app.pargs.php:
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if WOAptGet.is_installed(self, 'php5-fpm'):
services = services + ['php5-fpm']
else:
Log.info(self, "PHP5-FPM is not installed")
else:
if WOAptGet.is_installed(self, 'php5.6-fpm'):
services = services + ['php5.6-fpm']
else:
Log.info(self, "PHP5.6-FPM is not installed")
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
if self.app.pargs.php7:
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic'):
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
else:
Log.info(self, "Your platform does not support PHP 7")
if self.app.pargs.mysql:
if ((WOVariables.wo_mysql_host is "localhost") or
(WOVariables.wo_mysql_host is "127.0.0.1")):
if (WOAptGet.is_installed(self, 'mysql-server') or
WOAptGet.is_installed(self, 'percona-server-server-5.6') or
WOAptGet.is_installed(self, 'mariadb-server')):
services = services + ['mysql']
else:
Log.info(self, "MySQL is not installed")
else:
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.hhvm:
if WOAptGet.is_installed(self, 'hhvm'):
services = services + ['hhvm']
else:
Log.info(self, "HHVM is not installed")
if self.app.pargs.memcache:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcache is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
else:
Log.info(self, "Redis server is not installed")
for service in services:
Log.debug(self, "Restarting service: {0}".format(service))
WOService.restart_service(self, service)
@expose(help="Get stack status")
def status(self):
"""Status of services"""
services = []
if not (self.app.pargs.nginx or self.app.pargs.php or self.app.pargs.php7
or self.app.pargs.mysql or self.app.pargs.hhvm or self.app.pargs.memcache
or self.app.pargs.redis):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
self.app.pargs.hhvm = True
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom') or WOAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
if self.app.pargs.php:
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if WOAptGet.is_installed(self, 'php5-fpm'):
services = services + ['php5-fpm']
else:
Log.info(self, "PHP5-FPM is not installed")
else:
if WOAptGet.is_installed(self, 'php5.6-fpm'):
services = services + ['php5.6-fpm']
else:
Log.info(self, "PHP5.6-FPM is not installed")
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
if self.app.pargs.php7:
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic'):
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
else:
Log.info(self, "Your platform does not support PHP 7")
if self.app.pargs.mysql:
if ((WOVariables.wo_mysql_host is "localhost") or
(WOVariables.wo_mysql_host is "127.0.0.1")):
if (WOAptGet.is_installed(self, 'mysql-server') or
WOAptGet.is_installed(self, 'percona-server-server-5.6') or
WOAptGet.is_installed(self, 'mariadb-server')):
services = services + ['mysql']
else:
Log.info(self, "MySQL is not installed")
else:
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.hhvm:
if WOAptGet.is_installed(self, 'hhvm'):
services = services + ['hhvm']
else:
Log.info(self, "HHVM is not installed")
if self.app.pargs.memcache:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcache is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
else:
Log.info(self, "Redis server is not installed")
for service in services:
if WOService.get_service_status(self, service):
Log.info(self, "{0:10}: {1}".format(service, "Running"))
@expose(help="Reload stack services")
def reload(self):
"""Reload service"""
services = []
if not (self.app.pargs.nginx or self.app.pargs.php or self.app.pargs.php7
or self.app.pargs.mysql or self.app.pargs.hhvm or self.app.pargs.memcache
or self.app.pargs.redis):
self.app.pargs.nginx = True
self.app.pargs.php = True
self.app.pargs.mysql = True
if self.app.pargs.nginx:
if WOAptGet.is_installed(self, 'nginx-custom') or WOAptGet.is_installed(self,'nginx-mainline'):
services = services + ['nginx']
else:
Log.info(self, "Nginx is not installed")
if self.app.pargs.php:
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if WOAptGet.is_installed(self, 'php5-fpm'):
services = services + ['php5-fpm']
else:
Log.info(self, "PHP5-FPM is not installed")
else:
if WOAptGet.is_installed(self, 'php5.6-fpm'):
services = services + ['php5.6-fpm']
else:
Log.info(self, "PHP5.6-FPM is not installed")
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
if self.app.pargs.php7:
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic'):
if WOAptGet.is_installed(self, 'php7.0-fpm'):
services = services + ['php7.0-fpm']
else:
Log.info(self, "PHP7.0-FPM is not installed")
else:
Log.info(self, "Your platform does not support PHP 7")
if self.app.pargs.mysql:
if ((WOVariables.wo_mysql_host is "localhost") or
(WOVariables.wo_mysql_host is "127.0.0.1")):
if (WOAptGet.is_installed(self, 'mysql-server') or
WOAptGet.is_installed(self, 'percona-server-server-5.6') or
WOAptGet.is_installed(self, 'mariadb-server')):
services = services + ['mysql']
else:
Log.info(self, "MySQL is not installed")
else:
Log.warn(self, "Remote MySQL found, "
"Unable to check MySQL service status")
if self.app.pargs.hhvm:
Log.info(self, "HHVM does not support to reload")
if self.app.pargs.memcache:
if WOAptGet.is_installed(self, 'memcached'):
services = services + ['memcached']
else:
Log.info(self, "Memcache is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
services = services + ['redis-server']
else:
Log.info(self, "Redis server is not installed")
for service in services:
Log.debug(self, "Reloading service: {0}".format(service))
WOService.reload_service(self, service)

View File

@@ -0,0 +1,233 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.logging import Log
from wo.core.variables import WOVariables
from wo.core.aptget import WOAptGet
from wo.core.apt_repo import WORepo
from wo.core.services import WOService
from wo.core.fileutils import WOFileUtils
from wo.core.shellexec import WOShellExec
from wo.core.git import WOGit
from wo.core.download import WODownload
import configparser
import os
class WOStackUpgradeController(CementBaseController):
class Meta:
label = 'upgrade'
stacked_on = 'stack'
stacked_type = 'nested'
description = ('Upgrade stack safely')
arguments = [
(['--all'],
dict(help='Upgrade all stack', action='store_true')),
(['--web'],
dict(help='Upgrade web stack', action='store_true')),
(['--admin'],
dict(help='Upgrade admin tools stack', action='store_true')),
(['--nginx'],
dict(help='Upgrade Nginx stack', action='store_true')),
(['--nginxmainline'],
dict(help='Upgrade Nginx Mainline stack', action='store_true')),
(['--php'],
dict(help='Upgrade PHP stack', action='store_true')),
(['--mysql'],
dict(help='Upgrade MySQL stack', action='store_true')),
(['--hhvm'],
dict(help='Upgrade HHVM stack', action='store_true')),
(['--wpcli'],
dict(help='Upgrade WPCLI', action='store_true')),
(['--redis'],
dict(help='Upgrade Redis', action='store_true')),
(['--php56'],
dict(help="Upgrade to PHP5.6 from PHP5.5",
action='store_true')),
(['--no-prompt'],
dict(help="Upgrade Packages without any prompt",
action='store_true')),
]
@expose(hide=True)
def upgrade_php56(self):
if WOVariables.wo_platform_distro == "ubuntu":
if os.path.isfile("/etc/apt/sources.list.d/ondrej-php5-5_6-{0}."
"list".format(WOVariables.wo_platform_codename)):
Log.error(self, "Unable to find PHP 5.5")
else:
if not(os.path.isfile(WOVariables.wo_repo_file_path) and
WOFileUtils.grep(self, WOVariables.wo_repo_file_path,
"php55")):
Log.error(self, "Unable to find PHP 5.5")
Log.info(self, "During PHP update process non nginx-cached"
" parts of your site may remain down.")
# Check prompt
if (not self.app.pargs.no_prompt):
start_upgrade = input("Do you want to continue:[y/N]")
if start_upgrade != "Y" and start_upgrade != "y":
Log.error(self, "Not starting PHP package update")
if WOVariables.wo_platform_distro == "ubuntu":
WORepo.remove(self, ppa="ppa:ondrej/php5")
WORepo.add(self, ppa=WOVariables.wo_php_repo)
else:
WOAptGet.remove(self, ["php5-xdebug"])
WOFileUtils.searchreplace(self, WOVariables.wo_repo_file_path,
"php55", "php56")
Log.info(self, "Updating apt-cache, please wait...")
WOAptGet.update(self)
Log.info(self, "Installing packages, please wait ...")
if (WOVariables.wo_platform_codename == 'trusty' or WOVariables.wo_platform_codename == 'xenial' or WOVariables.wo_platform_codename == 'bionic'):
WOAptGet.install(self, WOVariables.wo_php5_6 + WOVariables.wo_php_extra)
else:
WOAptGet.install(self, WOVariables.wo_php)
if WOVariables.wo_platform_distro == "debian":
WOShellExec.cmd_exec(self, "pecl install xdebug")
with open("/etc/php5/mods-available/xdebug.ini",
encoding='utf-8', mode='a') as myfile:
myfile.write(";zend_extension=/usr/lib/php5/20131226/"
"xdebug.so\n")
WOFileUtils.create_symlink(self, ["/etc/php5/mods-available/"
"xdebug.ini", "/etc/php5/fpm/conf.d"
"/20-xedbug.ini"])
Log.info(self, "Successfully upgraded from PHP 5.5 to PHP 5.6")
@expose(hide=True)
def default(self):
# All package update
if ((not self.app.pargs.php56)):
apt_packages = []
packages = []
if ((not self.app.pargs.web) and (not self.app.pargs.nginx) and
(not self.app.pargs.php) and (not self.app.pargs.mysql) and
(not self.app.pargs.hhvm) and (not self.app.pargs.all) and
(not self.app.pargs.wpcli) and (not self.app.pargs.redis) and
(not self.app.pargs.nginxmainline)):
self.app.pargs.web = True
if self.app.pargs.all:
self.app.pargs.web = True
if self.app.pargs.web:
if WOAptGet.is_installed(self, 'nginx-custom'):
self.app.pargs.nginx = True
else:
Log.info(self, "Nginx is not already installed")
self.app.pargs.php = True
self.app.pargs.mysql = True
self.app.pargs.wpcli = True
if self.app.pargs.nginx :
if WOAptGet.is_installed(self, 'nginx-custom'):
apt_packages = apt_packages + WOVariables.wo_nginx
else:
Log.info(self, "Nginx Stable is not already installed")
if self.app.pargs.php:
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if WOAptGet.is_installed(self, 'php5-fpm'):
apt_packages = apt_packages + WOVariables.wo_php
else:
Log.info(self, "PHP is not installed")
if WOAptGet.is_installed(self, 'php7.0-fpm'):
apt_packages = apt_packages + WOVariables.wo_php7_0
else:
if WOAptGet.is_installed(self, 'php5.6-fpm'):
apt_packages = apt_packages + WOVariables.wo_php5_6 + WOVariables.wo_php_extra
else:
Log.info(self, "PHP 5.6 is not installed")
if WOAptGet.is_installed(self, 'php7.0-fpm'):
apt_packages = apt_packages + WOVariables.wo_php7_0 + WOVariables.wo_php_extra
else:
Log.info(self, "PHP 7.0 is not installed")
if self.app.pargs.hhvm:
if WOAptGet.is_installed(self, 'hhvm'):
apt_packages = apt_packages + WOVariables.wo_hhvm
else:
Log.info(self, "HHVM is not installed")
if self.app.pargs.mysql:
if WOAptGet.is_installed(self, 'mariadb-server'):
apt_packages = apt_packages + WOVariables.wo_mysql
else:
Log.info(self, "MariaDB is not installed")
if self.app.pargs.redis:
if WOAptGet.is_installed(self, 'redis-server'):
apt_packages = apt_packages + WOVariables.wo_redis
else:
Log.info(self, "Redis is not installed")
if self.app.pargs.wpcli:
if os.path.isfile('/usr/bin/wp'):
packages = packages + [["https://github.com/wp-cli/wp-cli/"
"releases/download/v{0}/"
"wp-cli-{0}.phar"
"".format(WOVariables.wo_wp_cli),
"/usr/bin/wp",
"WP-CLI"]]
else:
Log.info(self, "WPCLI is not installed with WordOps")
if len(packages) or len(apt_packages):
Log.info(self, "During package update process non nginx-cached"
" parts of your site may remain down")
# Check prompt
if (not self.app.pargs.no_prompt):
start_upgrade = input("Do you want to continue:[y/N]")
if start_upgrade != "Y" and start_upgrade != "y":
Log.error(self, "Not starting package update")
Log.info(self, "Updating packages, please wait...")
if len(apt_packages):
# apt-get update
WOAptGet.update(self)
# Update packages
WOAptGet.install(self, apt_packages)
# Post Actions after package updates
if (set(WOVariables.wo_nginx).issubset(set(apt_packages))):
WOService.restart_service(self, 'nginx')
if (WOVariables.wo_platform_distro == 'debian' or WOVariables.wo_platform_codename == 'precise'):
if set(WOVariables.wo_php).issubset(set(apt_packages)):
WOService.restart_service(self, 'php5-fpm')
else:
if set(WOVariables.wo_php5_6).issubset(set(apt_packages)):
WOService.restart_service(self, 'php5.6-fpm')
if set(WOVariables.wo_php7_0).issubset(set(apt_packages)):
WOService.restart_service(self, 'php7.0-fpm')
if set(WOVariables.wo_hhvm).issubset(set(apt_packages)):
WOService.restart_service(self, 'hhvm')
if set(WOVariables.wo_mysql).issubset(set(apt_packages)):
WOService.restart_service(self, 'mysql')
if set(WOVariables.wo_redis).issubset(set(apt_packages)):
WOService.restart_service(self, 'redis-server')
if len(packages):
if self.app.pargs.wpcli:
WOFileUtils.remove(self,['/usr/bin/wp'])
Log.debug(self, "Downloading following: {0}".format(packages))
WODownload.download(self, packages)
if self.app.pargs.wpcli:
WOFileUtils.chmod(self, "/usr/bin/wp", 0o775)
Log.info(self, "Successfully updated packages")
# PHP 5.6 to 5.6
elif (self.app.pargs.php56):
self.upgrade_php56()
else:
self.app.args.print_help()

94
wo/cli/plugins/sync.py Normal file
View File

@@ -0,0 +1,94 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.fileutils import WOFileUtils
from wo.cli.plugins.sitedb import *
from wo.core.mysql import *
from wo.core.logging import Log
def wo_sync_hook(app):
pass
class WOSyncController(CementBaseController):
class Meta:
label = 'sync'
stacked_on = 'base'
stacked_type = 'nested'
description = 'synchronize the WordOps database'
@expose(hide=True)
def default(self):
self.sync()
@expose(hide=True)
def sync(self):
"""
1. reads database information from wp/wo-config.php
2. updates records into wo database accordingly.
"""
Log.info(self, "Synchronizing wo database, please wait...")
sites = getAllsites(self)
if not sites:
pass
for site in sites:
if site.site_type in ['mysql', 'wp', 'wpsubdir', 'wpsubdomain']:
wo_site_webroot = site.site_path
# Read config files
configfiles = glob.glob(wo_site_webroot + '/*-config.php')
#search for wp-config.php inside htdocs/
if not configfiles:
Log.debug(self, "Config files not found in {0}/ "
.format(wo_site_webroot))
if site.site_type != 'mysql':
Log.debug(self, "Searching wp-config.php in {0}/htdocs/ "
.format(wo_site_webroot))
configfiles = glob.glob(wo_site_webroot + '/htdocs/wp-config.php')
if configfiles:
if WOFileUtils.isexist(self, configfiles[0]):
wo_db_name = (WOFileUtils.grep(self, configfiles[0],
'DB_NAME').split(',')[1]
.split(')')[0].strip().replace('\'', ''))
wo_db_user = (WOFileUtils.grep(self, configfiles[0],
'DB_USER').split(',')[1]
.split(')')[0].strip().replace('\'', ''))
wo_db_pass = (WOFileUtils.grep(self, configfiles[0],
'DB_PASSWORD').split(',')[1]
.split(')')[0].strip().replace('\'', ''))
wo_db_host = (WOFileUtils.grep(self, configfiles[0],
'DB_HOST').split(',')[1]
.split(')')[0].strip().replace('\'', ''))
# Check if database really exist
try:
if not WOMysql.check_db_exists(self, wo_db_name):
# Mark it as deleted if not exist
wo_db_name = 'deleted'
wo_db_user = 'deleted'
wo_db_pass = 'deleted'
except StatementExcecutionError as e:
Log.debug(self, str(e))
except Exception as e:
Log.debug(self, str(e))
if site.db_name != wo_db_name:
# update records if any mismatch found
Log.debug(self, "Updating wo db record for {0}"
.format(site.sitename))
updateSiteInfo(self, site.sitename,
db_name=wo_db_name,
db_user=wo_db_user,
db_password=wo_db_pass,
db_host=wo_db_host)
else:
Log.debug(self, "Config files not found for {0} "
.format(site.sitename))
def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(WOSyncController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', wo_sync_hook)

44
wo/cli/plugins/update.py Normal file
View File

@@ -0,0 +1,44 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from wo.core.download import WODownload
from wo.core.logging import Log
import time
import os
def wo_update_hook(app):
pass
class WOUpdateController(CementBaseController):
class Meta:
label = 'wo_update'
stacked_on = 'base'
aliases = ['update']
aliases_only = True
stacked_type = 'nested'
description = ('update WordOps to latest version')
usage = "wo update"
@expose(hide=True)
def default(self):
filename = "woupdate" + time.strftime("%Y%m%d-%H%M%S")
WODownload.download(self, [["https://wrdps.nl/woup",
"/tmp/{0}".format(filename),
"update script"]])
try:
Log.info(self, "updating WordOps, please wait...")
os.system("bash /tmp/{0}".format(filename))
except OSError as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
except Exception as e:
Log.debug(self, str(e))
Log.error(self, "WordOps update failed !")
def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(WOUpdateController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', wo_update_hook)

View File

@@ -0,0 +1,27 @@
use strict;
# You can modify this file to re-enable SPAM checking through spamassassin
# and to re-enable antivirus checking.
#
# Default antivirus checking mode
# Please note, that anti-virus checking is DISABLED by
# default.
# If You wish to enable it, please uncomment the following lines:
@bypass_virus_checks_maps = (
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
#
# Default SPAM checking mode
# Please note, that anti-spam checking is DISABLED by
# default.
# If You wish to enable it, please uncomment the following lines:
@bypass_spam_checks_maps = (
\%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
1; # ensure a defined return

View File

@@ -0,0 +1,44 @@
# WordOps admin NGINX CONFIGURATION
server {
listen 22222 default_server ssl http2;
access_log /var/log/nginx/22222.access.log rt_cache;
error_log /var/log/nginx/22222.error.log;
ssl_certificate {{webroot}}22222/cert/22222.crt;
ssl_certificate_key {{webroot}}22222/cert/22222.key;
# Force HTTP to HTTPS
error_page 497 =200 https://$host:22222$request_uri;
root {{webroot}}22222/htdocs;
index index.php index.htm index.html;
# Turn on directory listing
autoindex on;
# HTTP Authentication on port 22222
include common/acl.conf;
location / {
try_files $uri $uri/ /index.php?$args;
}
# Display menu at location /fpm/status/
location = /fpm/status/ {}
location ~ /fpm/status/(.*) {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_NAME /status;
fastcgi_pass $1;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass php;
}
}

View File

View File

@@ -0,0 +1,8 @@
# WordOps (wo) protect locations using
# HTTP authentication || IP address
satisfy any;
auth_basic "Restricted Area";
auth_basic_user_file htpasswd-wo;
# Allowed IP Address List
allow 127.0.0.1;
deny all;

View File

@@ -0,0 +1,255 @@
<?php
$conf['datasources']['localhost'] = array(
'host' => '{{host}}',
'port' => '{{port}}',
'db' => 'slow_query_log',
'user' => '{{user}}',
'password' => '{{password}}',
'tables' => array(
'global_query_review' => 'fact',
'global_query_review_history' => 'dimension'
),
'source_type' => 'slow_query_log'
);
$conf['default_report_action'] = 'report';
$conf['reviewers'] = array( 'dba1','dba2');
$conf['review_types'] = array( 'good', 'bad', 'ticket-created', 'needs-fix', 'fixed', 'needs-analysis', 'review-again');
$conf['history_defaults'] = array(
'output' => 'table',
'fact-group' => 'date',
'fact-order' => 'date DESC',
'fact-limit' => '90',
'dimension-ts_min_start' => date("Y-m-d H:i:s", strtotime( '-90 day')),
'dimension-ts_min_end' => date("Y-m-d H:i:s"),
'table_fields' => array('date', 'index_ratio','query_time_avg','rows_sent_avg','ts_cnt','Query_time_sum','Lock_time_sum','Rows_sent_sum','Rows_examined_sum','Tmp_table_sum','Filesort_sum','Full_scan_sum')
);
$conf['report_defaults'] = array(
'fact-group' => 'checksum',
'fact-order' => 'Query_time_sum DESC',
'fact-limit' => '20',
'dimension-ts_min_start' => date("Y-m-d H:i:s", strtotime( '-1 day')),
'dimension-ts_min_end' => date("Y-m-d H:i:s"),
'table_fields' => array('checksum','snippet', 'index_ratio','query_time_avg','rows_sent_avg','ts_cnt','Query_time_sum','Lock_time_sum','Rows_sent_sum','Rows_examined_sum','Tmp_table_sum','Filesort_sum','Full_scan_sum'),
'dimension-pivot-hostname_max' => null
);
$conf['graph_defaults'] = array(
'fact-group' => 'minute_ts',
'fact-order' => 'minute_ts',
'fact-limit' => '',
'dimension-ts_min_start' => date("Y-m-d H:i:s", strtotime( '-7 day')),
'dimension-ts_min_end' => date("Y-m-d H:i:s"),
'table_fields' => array('minute_ts'),
'plot_field' => 'Query_time_sum',
);
$conf['report_defaults']['performance_schema'] = array(
'fact-order' => 'SUM_TIMER_WAIT DESC',
'fact-limit' => '20',
'fact-group' => 'DIGEST',
'table_fields' => array( 'DIGEST', 'snippet', 'index_ratio', 'COUNT_STAR', 'SUM_TIMER_WAIT', 'SUM_LOCK_TIME','SUM_ROWS_AFFECTED','SUM_ROWS_SENT','SUM_ROWS_EXAMINED','SUM_CREATED_TMP_TABLES','SUM_SORT_SCAN','SUM_NO_INDEX_USED' )
);
$conf['history_defaults']['performance_schema'] = array(
'fact-order' => 'SUM_TIMER_WAIT DESC',
'fact-limit' => '20',
'fact-group' => 'DIGEST',
'table_fields' => array( 'DIGEST', 'index_ratio', 'COUNT_STAR', 'SUM_LOCK_TIME','SUM_ROWS_AFFECTED','SUM_ROWS_SENT','SUM_ROWS_EXAMINED','SUM_CREATED_TMP_TABLES','SUM_SORT_SCAN','SUM_NO_INDEX_USED' )
);
$conf['report_defaults']['performance_schema_history'] = array(
'fact-group' => 'DIGEST',
'fact-order' => 'SUM_TIMER_WAIT DESC',
'fact-limit' => '20',
'dimension-FIRST_SEEN_start' => date("Y-m-d H:i:s", strtotime( '-1 day')),
'dimension-FIRST_SEEN_end' => date("Y-m-d H:i:s"),
'table_fields' => array( 'DIGEST', 'snippet', 'index_ratio', 'COUNT_STAR', 'SUM_LOCK_TIME','SUM_ROWS_AFFECTED','SUM_ROWS_SENT','SUM_ROWS_EXAMINED','SUM_CREATED_TMP_TABLES','SUM_SORT_SCAN','SUM_NO_INDEX_USED' )
);
$conf['graph_defaults']['performance_schema_history'] = array(
'fact-group' => 'minute_ts',
'fact-order' => 'minute_ts',
'fact-limit' => '',
'dimension-FIRST_SEEN_start' => date("Y-m-d H:i:s", strtotime( '-7 day')),
'dimension-FIRST_SEEN_end' => date("Y-m-d H:i:s"),
'table_fields' => array('minute_ts'),
'plot_field' => 'SUM_TIMER_WAIT',
'dimension-pivot-hostname_max' => null
);
$conf['history_defaults']['performance_schema_history'] = array(
'output' => 'table',
'fact-group' => 'date',
'fact-order' => 'date DESC',
'fact-limit' => '90',
'dimension-FIRST_SEEN_start' => date("Y-m-d H:i:s", strtotime( '-90 day')),
'dimension-FIRST_SEEN_end' => date("Y-m-d H:i:s"),
'table_fields' => array( 'date', 'snippet', 'index_ratio', 'COUNT_STAR', 'SUM_LOCK_TIME','SUM_ROWS_AFFECTED','SUM_ROWS_SENT','SUM_ROWS_EXAMINED','SUM_CREATED_TMP_TABLES','SUM_SORT_SCAN','SUM_NO_INDEX_USED' )
);
$conf['plugins'] = array(
'visual_explain' => '/usr/bin/pt-visual-explain',
'query_advisor' => '/usr/bin/pt-query-advisor',
'show_create' => true,
'show_status' => true,
'explain' => function ($sample) {
$conn = array();
if (!array_key_exists('hostname_max',$sample) or strlen($sample['hostname_max']) < 5)
{
return;
}
$pos = strpos($sample['hostname_max'], ':');
if ($pos === false)
{
$conn['port'] = 3306;
$conn['host'] = $sample['hostname_max'];
}
else
{
$parts = preg_split("/:/", $sample['hostname_max']);
$conn['host'] = $parts[0];
$conn['port'] = $parts[1];
}
$conn['db'] = 'mysql';
if ($sample['db_max'] != '')
{
$conn['db'] = $sample['db_max'];
}
$conn['user'] = '{{user}}';
$conn['password'] = '{{password}}';
return $conn;
},
);
$conf['reports']['slow_query_log'] = array(
'join' => array (
'dimension' => 'USING (`checksum`)'
),
'fields' => array(
'fact' => array(
'group' => 'group',
'order' => 'order',
'having' => 'having',
'limit' => 'limit',
'first_seen'=> 'clear|reldate|ge|where',
'where' => 'raw_where',
'sample' => 'clear|like|where',
'checksum' => 'clear|where',
'reviewed_status' => 'clear|where',
),
'dimension' => array(
'extra_fields' => 'where',
'hostname_max' => 'clear|where',
'ts_min' => 'date_range|reldate|clear|where',
'pivot-hostname_max' => 'clear|pivot|select',
'pivot-checksum' => 'clear|pivot|select',
),
),
'custom_fields' => array(
'checksum' => 'checksum',
'date' => 'DATE(ts_min)',
'hour' => 'substring(ts_min,1,13)',
'hour_ts' => 'round(unix_timestamp(substring(ts_min,1,13)))',
'minute_ts' => 'round(unix_timestamp(substring(ts_min,1,16)))',
'minute' => 'substring(ts_min,1,16)',
'snippet' => 'LEFT(dimension.sample,20)',
'index_ratio' =>'ROUND(SUM(Rows_examined_sum)/SUM(rows_sent_sum),2)',
'query_time_avg' => 'SUM(Query_time_sum) / SUM(ts_cnt)',
'rows_sent_avg' => 'ROUND(SUM(Rows_sent_sum)/SUM(ts_cnt),0)',
),
'callbacks' => array(
'table' => array(
'date' => function ($x) { $type=''; if ( date('N',strtotime($x)) >= 6) { $type = 'weekend'; } return array($x,$type); },
'checksum' => function ($x) { return array(dec2hex($x), ''); }
)
)
);
$conf['reports']['performance_schema'] = array(
'fields' => array(
'fact' => array(
'order' => 'order',
'having' => 'having',
'limit' => 'limit',
'first_seen' => 'date_range|reldate|clear|where',
'where' => 'raw_where',
'DIGEST' => 'clear|where',
'DIGEST_TEXT' => 'clear|like|where',
'group' => 'group',
),
),
'custom_fields' => array(
'snippet' => 'LEFT(fact.DIGEST_TEXT,20)',
'index_ratio' =>'ROUND(SUM_ROWS_EXAMINED/SUM_ROWS_SENT,2)',
'rows_sent_avg' => 'ROUND(SUM_ROWS_SENT/COUNT_STAR,0)',
),
'special_field_names' => array(
'time' => 'FIRST_SEEN',
'checksum' => 'DIGEST',
'sample' => 'DIGEST_TEXT',
'fingerprint' => 'DIGEST_TEXT',
),
);
$conf['reports']['performance_schema_history'] = array(
'join' => array (
'dimension' => 'USING (`DIGEST`)'
),
'fields' => array(
'fact' => array(
'group' => 'group',
'order' => 'order',
'having' => 'having',
'limit' => 'limit',
'first_seen'=> 'clear|reldate|ge|where',
'where' => 'raw_where',
'DIGEST_TEXT' => 'clear|like|where',
'DIGEST' => 'clear|where',
'reviewed_status' => 'clear|where',
),
'dimension' => array(
'extra_fields' => 'where',
'hostname' => 'clear|where',
'FIRST_SEEN' => 'date_range|reldate|clear|where',
'pivot-hostname' => 'clear|pivot|select',
),
),
'custom_fields' => array(
'date' => 'DATE(fact.FIRST_SEEN)',
'snippet' => 'LEFT(fact.DIGEST_TEXT,20)',
'index_ratio' =>'ROUND(SUM_ROWS_EXAMINED/SUM_ROWS_SENT,2)',
'rows_sent_avg' => 'ROUND(SUM_ROWS_SENT/COUNT_STAR,0)',
'hour' => 'substring(dimension.FIRST_SEEN,1,13)',
'hour_ts' => 'round(unix_timestamp(substring(dimension.FIRST_SEEN,1,13)))',
'minute_ts' => 'round(unix_timestamp(substring(dimension.FIRST_SEEN,1,16)))',
'minute' => 'substring(dimension.FIRST_SEEN,1,16)',
),
'special_field_names' => array(
'time' => 'FIRST_SEEN',
'checksum' => 'DIGEST',
'hostname' => 'hostname',
'sample' => 'DIGEST_TEXT'
),
);
?>

View File

@@ -0,0 +1,2 @@
# Block IP Address
# deny 1.1.1.1;

View File

@@ -0,0 +1,10 @@
# FastCGI cache settings
fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:50m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header updating http_500 http_503;
fastcgi_cache_valid 200 301 302 404 1h;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SERVER_NAME $http_host;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_keep_conn on;

View File

@@ -0,0 +1,10 @@
MySQL ({{version}}) on {{host}}:
port {{port}}
wait_timeout {{wait_timeout}}
interactive_timeout {{interactive_timeout}}
max_used_connections {{max_used_connections}}
datadir {{datadir}}
socket {{socket}}
my.cnf [PATH] /etc/mysql/conf.d/my.cnf

View File

@@ -0,0 +1,10 @@
NGINX ({{version}}):
user {{user}}
worker_processes {{worker_processes}}
worker_connections {{worker_connections}}
keepalive_timeout {{keepalive_timeout}}
fastcgi_read_timeout {{fastcgi_read_timeout}}
client_max_body_size {{client_max_body_size}}
allow {{allow}}

View File

@@ -0,0 +1,35 @@
PHP ({{version}}):
user {{user}}
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}}
Information about www.conf
ping.path {{www_ping_path}}
pm.status_path {{www_pm_status_path}}
process_manager {{www_pm}}
pm.max_requests {{www_pm_max_requests}}
pm.max_children {{www_pm_max_children}}
pm.start_servers {{www_pm_start_servers}}
pm.min_spare_servers {{www_pm_min_spare_servers}}
pm.max_spare_servers {{www_pm_max_spare_servers}}
request_terminate_timeout {{www_request_terminate_timeout}}
xdebug.profiler_enable_trigger {{www_xdebug_profiler_enable_trigger}}
listen {{www_listen}}
Information about debug.conf
ping.path {{debug_ping_path}}
pm.status_path {{debug_pm_status_path}}
process_manager {{debug_pm}}
pm.max_requests {{debug_pm_max_requests}}
pm.max_children {{debug_pm_max_children}}
pm.start_servers {{debug_pm_start_servers}}
pm.min_spare_servers {{debug_pm_min_spare_servers}}
pm.max_spare_servers {{debug_pm_max_spare_servers}}
request_terminate_timeout {{debug_request_terminate_timeout}}
xdebug.profiler_enable_trigger {{debug_xdebug_profiler_enable_trigger}}
listen {{debug_listen}}

View File

@@ -0,0 +1,68 @@
# NGINX CONFIGURATION FOR COMMON LOCATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# Basic locations files
location = /favicon.ico {
access_log off;
log_not_found off;
expires max;
}
location = /robots.txt {
# Some WordPress plugin gererate robots.txt file
# Refer #340 issue
try_files $uri $uri/ /index.php?$args;
access_log off;
log_not_found off;
}
# Cache static files
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf)$ {
add_header "Access-Control-Allow-Origin" "*";
access_log off;
log_not_found off;
expires max;
}
# Security settings for better privacy
# Deny hidden files
location ~ /\.well-known {
allow all;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny backup extensions & log files
location ~* ^.+\.(bak|log|old|orig|original|php#|php~|php_bak|save|swo|swp|sql)$ {
deny all;
access_log off;
log_not_found off;
}
# Return 403 forbidden for readme.(txt|html) or license.(txt|html) or example.(txt|html)
if ($uri ~* "^.+(readme|license|example)\.(txt|html)$") {
return 403;
}
# Status pages
location = /nginx_status {
stub_status on;
access_log off;
include common/acl.conf;
}
location ~ ^/(status|ping)$ {
include fastcgi_params;
fastcgi_pass php7;
include common/acl.conf;
}
# WordOps (wo) utilities
# phpMyAdmin settings
location = /pma {
return 301 https://$host:22222/db/pma;
}
location = /phpMyAdmin {
return 301 https://$host:22222/db/pma;
}
location = /phpmyadmin {
return 301 https://$host:22222/db/pma;
}
# Adminer settings
location = /adminer {
return 301 https://$host:22222/db/adminer;
}

View File

@@ -0,0 +1,68 @@
# NGINX CONFIGURATION FOR COMMON LOCATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# Basic locations files
location = /favicon.ico {
access_log off;
log_not_found off;
expires max;
}
location = /robots.txt {
# Some WordPress plugin gererate robots.txt file
# Refer #340 issue
try_files $uri $uri/ /index.php?$args;
access_log off;
log_not_found off;
}
# Cache static files
location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf)$ {
add_header "Access-Control-Allow-Origin" "*";
access_log off;
log_not_found off;
expires max;
}
# Security settings for better privacy
# Deny hidden files
location ~ /\.well-known {
allow all;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny backup extensions & log files
location ~* ^.+\.(bak|log|old|orig|original|php#|php~|php_bak|save|swo|swp|sql)$ {
deny all;
access_log off;
log_not_found off;
}
# Return 403 forbidden for readme.(txt|html) or license.(txt|html) or example.(txt|html)
if ($uri ~* "^.+(readme|license|example)\.(txt|html)$") {
return 403;
}
# Status pages
location = /nginx_status {
stub_status on;
access_log off;
include common/acl.conf;
}
location ~ ^/(status|ping)$ {
include fastcgi_params;
fastcgi_pass php;
include common/acl.conf;
}
# WordOps (wo) utilities
# phpMyAdmin settings
location = /pma {
return 301 https://$host:22222/db/pma;
}
location = /phpMyAdmin {
return 301 https://$host:22222/db/pma;
}
location = /phpmyadmin {
return 301 https://$host:22222/db/pma;
}
# Adminer settings
location = /adminer {
return 301 https://$host:22222/db/adminer;
}

View File

@@ -0,0 +1,60 @@
##
# WordOps Settings
##
server_tokens off;
reset_timedout_connection on;
add_header X-Powered-By "WordOps {{version}}";
# Limit Request
limit_req_status 403;
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
# Proxy Settings
# set_real_ip_from proxy-server-ip;
# real_ip_header X-Forwarded-For;
fastcgi_read_timeout 300;
client_max_body_size 100m;
# SSL Settings
ssl_protocols TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
{{#Ubuntu}}
ssl_prefer_server_ciphers on;
{{/Ubuntu}}
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
# Log format Settings
log_format rt_cache '$remote_addr $upstream_response_time $upstream_cache_status [$time_local] '
'$http_host "$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
# GZip settings
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
# Compress all output labeled with one of the following MIME-types.
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component
text/xml
text/javascript;
# text/html is always compressed by HttpGzipModule

View File

@@ -0,0 +1,5 @@
[global]
pid = {{pid}}
error_log = {{error_log}}
log_level = notice
include = {{include}}

View File

@@ -0,0 +1,10 @@
# PHP NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass hhvm;
}

View File

@@ -0,0 +1,10 @@
# PHP NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass php;
}

View File

@@ -0,0 +1,10 @@
# PHP NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass php7;
}

View File

@@ -0,0 +1,58 @@
# Redis NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
set $skip_cache 0;
# POST requests and URL with a query string should always go to php
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache URL containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|wp-.*\.php|index.php|/feed/|.*sitemap.*\.xml)") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenter or customer with items in cart
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|[a-z0-9]+_items_in_cart") {
set $skip_cache 1;
}
# Use cached or actual file if they exists, Otherwise pass request to WordPress
location / {
try_files $uri $uri/ /index.php?$args;
}
location /redis-fetch {
internal ;
set $redis_key $args;
redis_pass redis;
}
location /redis-store {
internal ;
set_unescape_uri $key $arg_key ;
redis2_query set $key $echo_request_body;
redis2_query expire $key 14400;
redis2_pass redis;
}
location ~ \.php$ {
set $key "nginx-cache:$scheme$request_method$host$request_uri";
try_files $uri =404;
srcache_fetch_skip $skip_cache;
srcache_store_skip $skip_cache;
srcache_response_cache_control off;
set_escape_uri $escaped_key $key;
srcache_fetch GET /redis-fetch $key;
srcache_store PUT /redis-store key=$escaped_key;
more_set_headers 'X-SRCache-Fetch-Status $srcache_fetch_status';
more_set_headers 'X-SRCache-Store-Status $srcache_store_status';
include fastcgi_params;
fastcgi_param HTTP_ACCEPT_ENCODING "";
fastcgi_pass hhvm;
}

View File

@@ -0,0 +1,56 @@
# Redis NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
set $skip_cache 0;
# POST requests and URL with a query string should always go to php
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache URL containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|wp-.*\.php|index.php|/feed/|.*sitemap.*\.xml)") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenter or customer with items in cart
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|[a-z0-9]+_items_in_cart") {
set $skip_cache 1;
}
# Use cached or actual file if they exists, Otherwise pass request to WordPress
location / {
try_files $uri $uri/ /index.php?$args;
}
location /redis-fetch {
internal ;
set $redis_key $args;
redis_pass redis;
}
location /redis-store {
internal ;
set_unescape_uri $key $arg_key ;
redis2_query set $key $echo_request_body;
redis2_query expire $key 14400;
redis2_pass redis;
}
location ~ \.php$ {
set $key "nginx-cache:$scheme$request_method$host$request_uri";
try_files $uri =404;
srcache_fetch_skip $skip_cache;
srcache_store_skip $skip_cache;
srcache_response_cache_control off;
set_escape_uri $escaped_key $key;
srcache_fetch GET /redis-fetch $key;
srcache_store PUT /redis-store key=$escaped_key;
more_set_headers 'X-SRCache-Fetch-Status $srcache_fetch_status';
more_set_headers 'X-SRCache-Store-Status $srcache_store_status';
include fastcgi_params;
fastcgi_pass php7;
}

View File

@@ -0,0 +1,57 @@
# Redis NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
set $skip_cache 0;
# POST requests and URL with a query string should always go to php
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache URL containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|wp-.*\.php|index.php|/feed/|.*sitemap.*\.xml)") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenter or customer with items in cart
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|[a-z0-9]+_items_in_cart") {
set $skip_cache 1;
}
# Use cached or actual file if they exists, Otherwise pass request to WordPress
location / {
try_files $uri $uri/ /index.php?$args;
}
location /redis-fetch {
internal ;
set $redis_key $args;
redis_pass redis;
}
location /redis-store {
internal ;
set_unescape_uri $key $arg_key ;
redis2_query set $key $echo_request_body;
redis2_query expire $key 14400;
redis2_pass redis;
}
location ~ \.php$ {
set $key "nginx-cache:$scheme$request_method$host$request_uri";
try_files $uri =404;
srcache_fetch_skip $skip_cache;
srcache_store_skip $skip_cache;
srcache_response_cache_control off;
set_escape_uri $escaped_key $key;
srcache_fetch GET /redis-fetch $key;
srcache_store PUT /redis-store key=$escaped_key;
more_set_headers 'X-SRCache-Fetch-Status $srcache_fetch_status';
more_set_headers 'X-SRCache-Store-Status $srcache_store_status';
include fastcgi_params;
fastcgi_pass php;
}

View File

@@ -0,0 +1,15 @@
Information about {{domain}}:
Nginx configuration {{type}} {{enable}}
{{#php_version}}PHP Version {{php_version}}{{/php_version}}
{{#hhvm}}HHVM {{hhvm}}{{/hhvm}}
{{#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_USER {{dbuser}}{{/dbname}}
{{#dbname}}DB_PASS {{dbpass}}{{/dbname}}
{{#tablepref}}table_prefix {{tableprefix}}{{/tablepref}}

View File

@@ -0,0 +1,26 @@
# Common upstream settings
upstream php {
# server unix:/run/php5-fpm.sock;
server 127.0.0.1:{{php}};
}
upstream debug {
# Debug Pool
server 127.0.0.1:{{debug}};
}
{{#php7conf}}
upstream php7 {
server 127.0.0.1:{{php7}};
}
upstream debug7 {
# Debug Pool
server 127.0.0.1:{{debug7}};
}
{{/php7conf}}
{{#hhvmconf}}
upstream hhvm {
# HHVM Pool
server 127.0.0.1:{{hhvm}};
server 127.0.0.1:{{php}} backup;
}
{{/hhvmconf}}

View File

@@ -0,0 +1,47 @@
server {
{{#multisite}}
# Uncomment the following line for domain mapping
# listen 80 default_server;
{{/multisite}}
server_name {{^vma}}{{^rc}}{{site_name}}{{/rc}}{{/vma}} {{#vma}}vma.*{{/vma}} {{#rc}}webmail.*{{/rc}} {{^vma}}{{^rc}}{{#multisite}}*{{/multisite}}{{^multisite}}www{{/multisite}}.{{site_name}}{{/rc}}{{/vma}};
{{#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;
}
{{/proxy}}
{{^proxy}}
{{^vma}}{{^rc}}root {{webroot}}/htdocs;{{/rc}}{{/vma}}
{{^proxy}}index {{^static}}index.php{{/static}} index.html index.htm;{{/proxy}}
{{#static}}
location / {
try_files $uri $uri/ =404;
}
{{/static}}
{{^static}}include {{^hhvm}}{{#basic}}common/php7.conf;{{/basic}}{{#wpfc}}common/wpfc-php7.conf;{{/wpfc}} {{#wpsc}}common/wpsc-php7.conf;{{/wpsc}}{{#wpredis}}common/redis-php7.conf;{{/wpredis}} {{/hhvm}}{{#hhvm}}{{#basic}}common/php-hhvm.conf;{{/basic}}{{#wpfc}}common/wpfc-hhvm.conf;{{/wpfc}} {{#wpsc}}common/wpsc-hhvm.conf;{{/wpsc}}{{#wpredis}}common/redis-hhvm.conf;{{/wpredis}} {{/hhvm}}
{{#wpsubdir}}include common/wpsubdir.conf;{{/wpsubdir}}{{/static}}
{{#wp}}include common/wpcommon-php7.conf;{{/wp}}
{{^proxy}}include common/locations-php7.conf;{{/proxy}}
{{^vma}}{{^rc}}include {{webroot}}/conf/nginx/*.conf;{{/rc}}{{/vma}}
{{/proxy}}
}

View File

@@ -0,0 +1,46 @@
server {
{{#multisite}}
# Uncomment the following line for domain mapping
# listen 80 default_server;
{{/multisite}}
server_name {{^vma}}{{^rc}}{{site_name}}{{/rc}}{{/vma}} {{#vma}}vma.*{{/vma}} {{#rc}}webmail.*{{/rc}} {{^vma}}{{^rc}}{{#multisite}}*{{/multisite}}{{^multisite}}www{{/multisite}}.{{site_name}}{{/rc}}{{/vma}};
{{#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;
}
{{/proxy}}
{{^proxy}}
{{^vma}}{{^rc}}root {{webroot}}/htdocs;{{/rc}}{{/vma}}
{{^proxy}}index {{^static}}index.php{{/static}} index.html index.htm;{{/proxy}}
{{#static}}
location / {
try_files $uri $uri/ =404;
}
{{/static}}
{{^static}}include {{^hhvm}}{{#basic}}common/php.conf;{{/basic}}{{#wpfc}}common/wpfc.conf;{{/wpfc}} {{#wpsc}}common/wpsc.conf;{{/wpsc}}{{#wpredis}}common/redis.conf;{{/wpredis}} {{/hhvm}}{{#hhvm}}{{#basic}}common/php-hhvm.conf;{{/basic}}{{#wpfc}}common/wpfc-hhvm.conf;{{/wpfc}} {{#wpsc}}common/wpsc-hhvm.conf;{{/wpsc}}{{#wpredis}}common/redis-hhvm.conf;{{/wpredis}} {{/hhvm}} {{#wpsubdir}}include common/wpsubdir.conf;{{/wpsubdir}}{{/static}}
{{#wp}}include common/wpcommon.conf;{{/wp}}
{{^proxy}}include common/locations.conf;{{/proxy}}
{{^vma}}{{^rc}}include {{webroot}}/conf/nginx/*.conf;{{/rc}}{{/vma}}
{{/proxy}}
}

View File

@@ -0,0 +1,83 @@
##
# WordOps Settings
##
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
server_tokens off;
reset_timedout_connection on;
add_header X-Powered-By "WordOps {{ version }}";
# Limit Request
limit_req_status 403;
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
# Proxy Settings
# set_real_ip_from proxy-server-ip;
# real_ip_header X-Forwarded-For;
fastcgi_read_timeout 300;
client_max_body_size 100m;
##
# SSL Settings
##
ssl_session_cache shared:SSL:5m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_protocols TLSv1.1 TLSv1.2;
##
# Basic Settings
##
server_names_hash_bucket_size 16384;
# server_name_in_redirect off;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Log format Settings
log_format rt_cache '$remote_addr $upstream_response_time $upstream_cache_status [$time_local] '
'$http_host "$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$request_body"';
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component
text/xml
text/javascript;

View File

@@ -0,0 +1,21 @@
# WordPress COMMON SETTINGS
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# Limit access to avoid brute force attack
location = /wp-login.php {
limit_req zone=one burst=1 nodelay;
include fastcgi_params;
fastcgi_pass php7;
}
# Disable wp-config.txt
location = /wp-config.txt {
deny all;
access_log off;
log_not_found off;
}
# Disallow php in upload folder
location /wp-content/uploads/ {
location ~ \.php$ {
#Prevent Direct Access Of PHP Files From Web Browsers
deny all;
}
}

View File

@@ -0,0 +1,21 @@
# WordPress COMMON SETTINGS
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
# Limit access to avoid brute force attack
location = /wp-login.php {
limit_req zone=one burst=1 nodelay;
include fastcgi_params;
fastcgi_pass php;
}
# Disable wp-config.txt
location = /wp-config.txt {
deny all;
access_log off;
log_not_found off;
}
# Disallow php in upload folder
location /wp-content/uploads/ {
location ~ \.php$ {
#Prevent Direct Access Of PHP Files From Web Browsers
deny all;
}
}

View File

@@ -0,0 +1,37 @@
# WPFC NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
set $skip_cache 0;
# POST requests and URL with a query string should always go to php
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache URL containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|wp-.*\.php|index.php|/feed/|.*sitemap.*\.xml)") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenter or customer with items in cart
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|[a-z0-9]+_items_in_cart") {
set $skip_cache 1;
}
# Use cached or actual file if they exists, Otherwise pass request to WordPress
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ ^/wp-content/cache/minify/(.+\.(css|js))$ {
try_files $uri /wp-content/plugins/w3-total-cache/pub/minify.php?file=$1;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass hhvm;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache WORDPRESS;
}
location ~ /purge(/.*) {
fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
access_log off;
}

View File

@@ -0,0 +1,37 @@
# WPFC NGINX CONFIGURATION
# DO NOT MODIFY, ALL CHANGES WILL BE LOST AFTER AN WordOps (wo) UPDATE
set $skip_cache 0;
# POST requests and URL with a query string should always go to php
if ($request_method = POST) {
set $skip_cache 1;
}
if ($query_string != "") {
set $skip_cache 1;
}
# Don't cache URL containing the following segments
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|wp-.*\.php|index.php|/feed/|.*sitemap.*\.xml)") {
set $skip_cache 1;
}
# Don't use the cache for logged in users or recent commenter or customer with items in cart
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|[a-z0-9]+_items_in_cart") {
set $skip_cache 1;
}
# Use cached or actual file if they exists, Otherwise pass request to WordPress
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ ^/wp-content/cache/minify/(.+\.(css|js))$ {
try_files $uri /wp-content/plugins/w3-total-cache/pub/minify.php?file=$1;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass php7;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache WORDPRESS;
}
location ~ /purge(/.*) {
fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
access_log off;
}

Some files were not shown because too many files have changed in this diff Show More