diff --git a/config/plugins.d/info.conf b/config/plugins.d/info.conf new file mode 100644 index 00000000..59f51a03 --- /dev/null +++ b/config/plugins.d/info.conf @@ -0,0 +1,11 @@ +### Example Plugin Configuration for EasyEngine + +[info] + +### If enabled, load a plugin named `example` either from the Python module +### `ee.cli.plugins.example` or from the file path +### `/var/lib/ee/plugins/example.py` +enable_plugin = true + +### Additional plugin configuration settings +foo = bar diff --git a/ee/cli/bootstrap.py b/ee/cli/bootstrap.py index 48b62d3b..a14aacd2 100644 --- a/ee/cli/bootstrap.py +++ b/ee/cli/bootstrap.py @@ -6,10 +6,8 @@ from cement.core import handler from ee.cli.controllers.base import EEBaseController from ee.cli.controllers.isl import EEImportslowlogController -from ee.cli.controllers.info import EEInfoController def load(app): handler.register(EEBaseController) - handler.register(EEInfoController) handler.register(EEImportslowlogController) diff --git a/ee/cli/controllers/info.py b/ee/cli/controllers/info.py deleted file mode 100644 index 70e56ae3..00000000 --- a/ee/cli/controllers/info.py +++ /dev/null @@ -1,26 +0,0 @@ -from cement.core.controller import CementBaseController, expose - - -class EEInfoController(CementBaseController): - class Meta: - label = 'info' - stacked_on = 'base' - stacked_type = 'nested' - description = 'info command used for debugging issued with stack or \ - site specific configuration' - arguments = [ - (['--mysql'], - dict(help='get mysql configuration information', - action='store_true')), - (['--php'], - dict(help='get php configuration information', - action='store_true')), - (['--nginx'], - dict(help='get nginx configuration information', - action='store_true')), - ] - - @expose(hide=True) - def default(self): - # TODO Default action for ee debug command - print("Inside EEInfoController.default().") diff --git a/ee/cli/main.py b/ee/cli/main.py index 17c8281f..fd2c5285 100644 --- a/ee/cli/main.py +++ b/ee/cli/main.py @@ -1,4 +1,13 @@ """EasyEngine main application entry point.""" +import sys + +# 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 @@ -42,6 +51,8 @@ class EEApp(foundation.CementApp): # default output handler output_handler = 'mustache' + debug = TOGGLE_DEBUG + class EETestApp(EEApp): """A test app that is better suited for testing.""" diff --git a/ee/cli/plugins/info.py b/ee/cli/plugins/info.py new file mode 100644 index 00000000..58a81ab5 --- /dev/null +++ b/ee/cli/plugins/info.py @@ -0,0 +1,197 @@ +"""EEInfo Plugin for EasyEngine.""" + +from cement.core.controller import CementBaseController, expose +from cement.core import handler, hook +from pynginxconfig import NginxConfig +from ee.core.aptget import EEAptGet +from ee.core.shellexec import EEShellExec +import os +import configparser + + +def info_plugin_hook(app): + # do something with the ``app`` object here. + pass + + +class EEInfoController(CementBaseController): + class Meta: + label = 'info' + stacked_on = 'base' + stacked_type = 'nested' + description = 'info command used for debugging issued with stack or \ + site specific configuration' + arguments = [ + (['--mysql'], + dict(help='get mysql configuration information', + action='store_true')), + (['--php'], + dict(help='get php configuration information', + action='store_true')), + (['--nginx'], + dict(help='get nginx configuration information', + action='store_true')), + ] + + @expose(hide=True) + def info_nginx(self): + 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] + if os.path.isfile('/etc/nginx/conf.d/ee-nginx.conf'): + nc.loadf('/etc/nginx/conf.d/ee-nginx.conf') + fastcgi_read_timeout = nc.get('fastcgi_read_timeout')[1] + client_max_body_size = nc.get('client_max_body_size')[1] + else: + 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): + version = os.popen("php -v | head -n1 | cut -d' ' -f2 |" + " cut -d'+' -f1 | tr -d '\n'").read + config = configparser.ConfigParser() + config.read('/etc/php5/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/php5/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/php5/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): + 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): + if (not self.app.pargs.nginx and not self.app.pargs.php + and not self.app.pargs.mysql): + self.app.pargs.nginx = True + self.app.pargs.php = True + self.app.pargs.mysql = True + + if self.app.pargs.nginx: + if EEAptGet.is_installed('nginx-common'): + self.info_nginx() + else: + print("Nginx is not installed") + + if self.app.pargs.php: + if EEAptGet.is_installed('php5-fpm'): + self.info_php() + else: + print("PHP5 is installed") + + if self.app.pargs.mysql: + if EEShellExec.cmd_exec(self, "mysqladmin ping"): + self.info_mysql() + else: + print("MySQL is not installed") + + +def load(app): + # register the plugin class.. this only happens if the plugin is enabled + handler.register(EEInfoController) + + # register a hook (function) to run after arguments are parsed. + hook.register('post_argument_parsing', info_plugin_hook) diff --git a/ee/cli/plugins/site.py b/ee/cli/plugins/site.py index b0b69962..597ce5cb 100644 --- a/ee/cli/plugins/site.py +++ b/ee/cli/plugins/site.py @@ -17,7 +17,8 @@ from subprocess import Popen def ee_site_hook(app): # do something with the ``app`` object here. - pass + from ee.core.database import init_db + init_db() class EESiteController(CementBaseController): @@ -34,8 +35,7 @@ class EESiteController(CementBaseController): @expose(hide=True) def default(self): - # TODO Default action for ee site command - print("Inside EESiteController.default().") + self.app.args.print_help() @expose(help="enable site example.com") def enable(self): @@ -43,13 +43,13 @@ class EESiteController(CementBaseController): if os.path.isfile('/etc/nginx/sites-available/{0}' .format(ee_domain)): EEFileUtils.create_symlink(self, - ['/etc/nginx/sites-available/{0}.conf' - .format(ee_domain_name), - '/etc/nginx/sites-enabled/{0}.conf' - .format(ee_domain_name)]) + ['/etc/nginx/sites-available/{0}' + .format(ee_domain), + '/etc/nginx/sites-enabled/{0}' + .format(ee_domain)]) + updateSiteInfo(self, ee_domain, enabled=True) else: - Log.error(self, "site {0} does not exists".format(ee_domain)) - sys.exit(1) + Log.error(self, " site {0} does not exists".format(ee_domain)) @expose(help="disable site example.com") def disable(self): @@ -57,13 +57,11 @@ class EESiteController(CementBaseController): if os.path.isfile('/etc/nginx/sites-available/{0}' .format(ee_domain)): EEFileUtils.remove_symlink(self, - ['/etc/nginx/sites-available/{0}.conf' - .format(ee_domain_name), - '/etc/nginx/sites-enabled/{0}.conf' - .format(ee_domain_name)]) + '/etc/nginx/sites-enabled/{0}' + .format(ee_domain)) + updateSiteInfo(self, ee_domain, enabled=False) else: - Log.error(self, "site {0} does not exists".format(ee_domain)) - sys.exit(1) + Log.error(self, " site {0} does not exists".format(ee_domain)) @expose(help="get example.com information") def info(self): @@ -95,8 +93,7 @@ class EESiteController(CementBaseController): dbpass=ee_db_pass) self.app.render((data), 'siteinfo.mustache') else: - Log.error(self, "site {0} does not exists".format(ee_domain)) - sys.exit(1) + Log.error(self, " site {0} does not exists".format(ee_domain)) @expose(help="Monitor example.com logs") def log(self): @@ -106,8 +103,7 @@ class EESiteController(CementBaseController): EEShellExec.cmd_exec(self, 'tail -f /var/log/nginx/{0}.*.log' .format(ee_domain)) else: - Log.error(self, "site {0} does not exists".format(ee_domain)) - sys.exit(1) + Log.error(self, " site {0} does not exists".format(ee_domain)) @expose(help="Edit example.com's nginx configuration") def edit(self): @@ -123,8 +119,7 @@ class EESiteController(CementBaseController): # Reload NGINX EEService.reload_service(self, 'nginx') else: - Log.error(self, "site {0} does not exists".format(ee_domain)) - sys.exit(1) + Log.error(self, " site {0} does not exists".format(ee_domain)) @expose(help="Display example.com's nginx configuration") def show(self): @@ -139,15 +134,9 @@ class EESiteController(CementBaseController): print(text) f.close() else: - Log.error(self, "site {0} does not exists".format(ee_domain)) - sys.exit(1) - - @expose(help="list sites currently available") - def list(self): - # TODO Write code for ee site list command here - print("Inside EESiteController.list().") + Log.error(self, " site {0} does not exists".format(ee_domain)) - @expose(help="change to example.com's webroot") + @expose(help="change directory to site webroot") def cd(self): (ee_domain, ee_www_domain) = ValidateDomain(self.app.pargs.site_name) @@ -158,9 +147,8 @@ class EESiteController(CementBaseController): try: subprocess.call(['bash']) except OSError as e: - Log.error(self, "Unable to edit file \ {0}{1}" - .format(e.errno, e.strerror)) - sys.exit(1) + Log.debug(self, "{0}{1}".format(e.errno, e.strerror)) + Log.error(self, " cannot change directory") class EESiteCreateController(CementBaseController): @@ -172,31 +160,35 @@ class EESiteCreateController(CementBaseController): help of the following subcommands' arguments = [ (['site_name'], - dict(help='the notorious foo option')), + dict(help='domain name for the site to be created.')), (['--html'], - dict(help="html site", action='store_true')), + dict(help="create html site", action='store_true')), (['--php'], - dict(help="php site", action='store_true')), + dict(help="create php site", action='store_true')), (['--mysql'], - dict(help="mysql site", action='store_true')), + dict(help="create mysql site", action='store_true')), (['--wp'], - dict(help="wordpress site", action='store_true')), + dict(help="create wordpress single site", + action='store_true')), (['--wpsubdir'], - dict(help="wpsubdir site", action='store_true')), + dict(help="create wordpress multisite with subdirectory setup", + action='store_true')), (['--wpsubdomain'], - dict(help="wpsubdomain site", action='store_true')), + dict(help="create wordpress multisite with subdomain setup", + action='store_true')), (['--w3tc'], - dict(help="w3tc", action='store_true')), + dict(help="create wordpress single/multi site with w3tc cache", + action='store_true')), (['--wpfc'], - dict(help="wpfc", action='store_true')), + dict(help="create wordpress single/multi site with wpfc cache", + action='store_true')), (['--wpsc'], - dict(help="wpsc", action='store_true')), + dict(help="create wordpress single/multi site with wpsc cache", + action='store_true')), ] @expose(hide=True) def default(self): - # TODO Default action for ee site command - # data = dict(foo='EESiteCreateController.default().') # self.app.render((data), 'default.mustache') # Check domain name validation (ee_domain, ee_www_domain) = ValidateDomain(self.app.pargs.site_name) @@ -205,9 +197,8 @@ class EESiteCreateController(CementBaseController): # Check if doain previously exists or not if os.path.isfile('/etc/nginx/sites-available/{0}' .format(ee_domain)): - self.app.log.error(self, "site {0} already exists" - .format(ee_domain)) - sys.exit(1) + Log.error(self, " site {0} already exists" + .format(ee_domain)) # setup nginx configuration for site # HTML @@ -223,7 +214,7 @@ class EESiteCreateController(CementBaseController): stype = 'html' cache = 'basic' - #PHP + # PHP if (self.app.pargs.php and not (self.app.pargs.html or self.app.pargs.mysql or self.app.pargs.wp or self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc or @@ -235,7 +226,7 @@ class EESiteCreateController(CementBaseController): wpsubdir=False, webroot=ee_site_webroot) stype = 'php' cache = 'basic' - #MySQL + # MySQL if (self.app.pargs.mysql and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.wp or self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc or @@ -249,7 +240,7 @@ class EESiteCreateController(CementBaseController): ee_db_host='') stype = 'mysql' cache = 'basic' - #WP + # WP if ((self.app.pargs.wp or self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc) and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.mysql or @@ -303,7 +294,7 @@ class EESiteCreateController(CementBaseController): stype = 'wp' cache = 'wpsc' - #WPSUBDIR + # WPSUBDIR if (self.app.pargs.wpsubdir and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.mysql or self.app.pargs.wpsubdomain or self.app.pargs.wp)): @@ -355,7 +346,7 @@ class EESiteCreateController(CementBaseController): stype = 'wpsubdir' cache = 'wpsc' - #WPSUBDOAIN + # WPSUBDOAIN if (self.app.pargs.wpsubdomain and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.mysql or self.app.pargs.wpsubdir or self.app.pargs.wp)): @@ -408,11 +399,17 @@ class EESiteCreateController(CementBaseController): stype = 'wpsubdomain' cache = 'wpsc' + if not data: + self.app.args.print_help() + self.app.close(1) + + # Check rerequired packages are installed or not + site_package_check(self, stype) # setup NGINX configuration, and webroot - SetupDomain(self, data) + setupDomain(self, data) # Setup database for MySQL site if 'ee_db_name' in data.keys() and not data['wp']: - data = SetupDatabase(self, data) + data = setupDatabase(self, data) try: eedbconfig = open("{0}/ee-config.php".format(ee_site_webroot), 'w') @@ -425,15 +422,15 @@ class EESiteCreateController(CementBaseController): data['ee_db_pass'], data['ee_db_host'])) eedbconfig.close() - stype = mysql + stype = 'mysql' except IOError as e: - self.app.log.error("Unable to create ee-config.php for " - "{2} ({0}): {1}" - .format(e.errno, e.strerror, ee_domain)) - sys.exit(1) + Log.debug(self, "{2} ({0}): {1}" + .format(e.errno, e.strerror, ee_domain)) + Log.error(self, " Unable to create ee-config.php for ") + # Setup WordPress if Wordpress site if data['wp']: - ee_wp_creds = SetupWordpress(self, data) + ee_wp_creds = setupWordpress(self, data) # Service Nginx Reload EEService.reload_service(self, 'nginx') @@ -492,42 +489,47 @@ class EESiteUpdateController(CementBaseController): check_site = getSiteInfo(self, ee_domain) if check_site is None: - Log.error(self, "Site {0} does not exist.".format(ee_domain)) + Log.error(self, " Site {0} does not exist.".format(ee_domain)) else: oldsitetype = check_site.site_type oldcachetype = check_site.cache_type + print(oldsitetype, oldcachetype) + if (self.app.pargs.html and not (self.app.pargs.php or self.app.pargs.mysql or self.app.pargs.wp or self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc or self.app.pargs.wpsubdir or self.app.pargs.wpsubdomain)): pass - #PHP + # PHP if (self.app.pargs.php and not (self.app.pargs.html or self.app.pargs.mysql or self.app.pargs.wp or self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc or self.app.pargs.wpsubdir or self.app.pargs.wpsubdomain)): if oldsitetype != 'html': - Log.error("Cannot update {0} to php".format(ee_domain)) - sys.exit(1) + + Log.error(self, " Cannot update {0} {1} to php" + .format(ee_domain, oldsitetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=True, wp=False, w3tc=False, wpfc=False, wpsc=False, multisite=False, wpsubdir=False, webroot=ee_site_webroot, currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'php' + cache = 'basic' - #MySQL + # MySQL if (self.app.pargs.mysql and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.wp or self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc or self.app.pargs.wpsubdir or self.app.pargs.wpsubdomain)): - if oldsitetype != 'html' or oldsitetype != 'php': - Log.error("Cannot update {0} to mysql".format(ee_domain)) - sys.exit(1) + if oldsitetype not in ['html', 'php']: + Log.error(self, " Cannot update {0}, {1} to mysql" + .format(ee_domain, oldsitetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=True, wp=False, w3tc=False, @@ -536,8 +538,10 @@ class EESiteUpdateController(CementBaseController): ee_db_name='', ee_db_user='', ee_db_pass='', ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'mysql' + cache = 'basic' - #WP + # WP if ((self.app.pargs.wp or self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc) and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.mysql or @@ -545,11 +549,11 @@ class EESiteUpdateController(CementBaseController): if (self.app.pargs.wp and not (self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc)): - if (oldsitetype not in ['html', 'php', 'wp'] - and oldsitetype not in ['w3tc', 'wpfc', 'wpsc']): - Log.error("Cannot update {0} to wp basic" - .format(ee_domain)) - sys.exit(1) + if ((oldsitetype in ['html', 'php', 'mysql', 'wp']) + and (oldcachetype not in ['w3tc', 'wpfc', 'wpsc'])): + print(oldsitetype, oldcachetype) + Log.error(self, " Cannot update {0}, {1} {2} to wp basic" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=True, wp=True, w3tc=False, @@ -558,14 +562,16 @@ class EESiteUpdateController(CementBaseController): ee_db_name='', ee_db_user='', ee_db_pass='', ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wp' + cache = 'basic' if (self.app.pargs.w3tc and not (self.app.pargs.wpfc or self.app.pargs.wpsc)): - if (oldsitetype not in ['html', 'php', 'wp'] - and oldsitetype not in ['basic', 'wpfc', 'wpsc']): - Log.error("Cannot update {0} to wp w3tc".format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp'] + and oldcachetype not in ['basic', 'wpfc', 'wpsc']): + Log.error(self, " Cannot update {0}, {1} {2}to wp w3tc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=True, @@ -575,13 +581,16 @@ class EESiteUpdateController(CementBaseController): ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wp' + cache = 'w3tc' + if (self.app.pargs.wpfc and not (self.app.pargs.wpsc or self.app.pargs.w3tc)): - if (oldsitetype not in ['html', 'php', 'wp'] - and oldsitetype not in ['basic', 'w3tc', 'wpsc']): - Log.error("Cannot update {0} to wp wpfc".format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp'] + and oldcachetype not in ['basic', 'w3tc', 'wpsc']): + Log.error(self, "Cannot update {0}, {1} {2} to wp wpfc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=False, @@ -590,14 +599,16 @@ class EESiteUpdateController(CementBaseController): ee_db_name='', ee_db_user='', ee_db_pass='', ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wp' + cache = 'wpfc' if (self.app.pargs.wpsc and not (self.app.pargs.w3tc or self.app.pargs.wpfc)): - if (oldsitetype not in ['html', 'php', 'wp'] - and oldsitetype not in ['basic', 'w3tc', 'wpfc']): - Log.error("Cannot update {0} to wp wpsc".format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp'] + and oldcachetype not in ['basic', 'w3tc', 'wpfc']): + Log.error(self, "Cannot update {0}, {1} {2} to wp wpsc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=False, @@ -606,19 +617,21 @@ class EESiteUpdateController(CementBaseController): ee_db_name='', ee_db_user='', ee_db_pass='', ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wp' + cache = 'wpsc' - #WPSUBDIR + # WPSUBDIR if (self.app.pargs.wpsubdir and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.mysql or self.app.pargs.wpsubdomain or self.app.pargs.wp)): if (self.app.pargs.wpsubdir and not (self.app.pargs.w3tc or self.app.pargs.wpfc or self.app.pargs.wpsc)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdir'] - and oldsitetype not in ['w3tc', 'wpfc', 'wpsc']): - Log.error("Cannot update {0} to wpsubdir basic" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', 'wpsubdir'] + and oldcachetype not in ['w3tc', 'wpfc', 'wpsc']): + Log.error(self, " Cannot update {0}, {1} {2} " + "to wpsubdir basic" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=True, wp=True, w3tc=False, @@ -627,15 +640,17 @@ class EESiteUpdateController(CementBaseController): ee_db_name='', ee_db_user='', ee_db_pass='', ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wpsubdir' + cache = 'basic' if (self.app.pargs.w3tc and not (self.app.pargs.wpfc or self.app.pargs.wpsc)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdir'] - and oldsitetype not in ['basic', 'wpfc', 'wpsc']): - Log.error("Cannot update {0} to wpsubdir w3tc" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', 'wpsubdir'] + and oldcachetype not in ['basic', 'wpfc', 'wpsc']): + Log.error(self, " Cannot update {0} {1} {2}" + "to wpsubdir w3tc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=True, @@ -645,14 +660,17 @@ class EESiteUpdateController(CementBaseController): ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wpsubdir' + cache = 'w3tc' + if (self.app.pargs.wpfc and not (self.app.pargs.wpsc or self.app.pargs.w3tc)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdir'] - and oldsitetype not in ['basic', 'w3tc', 'wpsc']): - Log.error("Cannot update {0} to wpsubdir wpfc" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', 'wpsubdir'] + and oldcachetype not in ['basic', 'w3tc', 'wpsc']): + Log.error(self, " Cannot update {0} {1} {2}" + " to wpsubdir wpfc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=False, @@ -661,15 +679,17 @@ class EESiteUpdateController(CementBaseController): ee_db_name='', ee_db_user='', ee_db_pass='', ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wpsubdir' + cache = 'wpfc' if (self.app.pargs.wpsc and not (self.app.pargs.w3tc or self.app.pargs.wpfc)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdir'] - and oldsitetype not in ['basic', 'w3tc', 'wpfc']): - Log.error("Cannot update {0} to wpsubdir wpsc" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', 'wpsubdir'] + and oldcachetype not in ['basic', 'w3tc', 'wpfc']): + Log.error(self, " Cannot update {0} {1} {2}" + " to wpsubdir wpsc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=False, @@ -678,16 +698,18 @@ class EESiteUpdateController(CementBaseController): ee_db_name='', ee_db_user='', ee_db_pass='', ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wpsubdir' + cache = 'wpsc' if (self.app.pargs.wpsubdomain and not (self.app.pargs.html or self.app.pargs.php or self.app.pargs.mysql or self.app.pargs.wpsubdir or self.app.pargs.wp)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdomain'] - and oldsitetype not in ['w3tc', 'wpfc', 'wpsc']): - Log.error("Cannot update {0} to wpsubdomain basic" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', 'wpsubdomain'] + and oldcachetype not in ['w3tc', 'wpfc', 'wpsc']): + Log.error(self, " Cannot update {0} {1} {2}" + " to wpsubdomain basic" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=True, wp=True, w3tc=False, @@ -697,14 +719,18 @@ class EESiteUpdateController(CementBaseController): ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wpsubdomain' + cache = 'basic' + if (self.app.pargs.w3tc and not (self.app.pargs.wpfc or self.app.pargs.wpsc)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdomain'] - and oldsitetype not in ['basic', 'wpfc', 'wpsc']): - Log.error("Cannot update {0} to wpsubdomain w3tc" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', + 'wpsubdomain'] + and oldcachetype not in ['basic', 'wpfc', 'wpsc']): + Log.error(self, " Cannot update {0}, {1} {2}" + " to wpsubdomain w3tc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=True, @@ -714,14 +740,18 @@ class EESiteUpdateController(CementBaseController): ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wpsubdomain' + cache = 'w3tc' + if (self.app.pargs.wpfc and not (self.app.pargs.wpsc or self.app.pargs.w3tc)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdomain'] - and oldsitetype not in ['basic', 'w3tc', 'wpsc']): - Log.error("Cannot update {0} to wpsubdomain wpfc" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', + 'wpsubdomain'] + and oldcachetype not in ['basic', 'w3tc', 'wpsc']): + Log.error(self, " Cannot update {0}, {1} {2} " + "to wpsubdomain wpfc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=False, @@ -731,14 +761,18 @@ class EESiteUpdateController(CementBaseController): ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) + stype = 'wpsubdomain' + cache = 'wpfc' + if (self.app.pargs.wpsc and not (self.app.pargs.w3tc or self.app.pargs.wpfc)): - if (oldsitetype not in ['html', 'php', 'wp', 'wpsubdomain'] - and oldsitetype not in ['basic', 'w3tc', 'wpfc']): - Log.error("Cannot update {0} to wpsubdomain wpsc" - .format(ee_domain)) - sys.exit(1) + if (oldsitetype in ['html', 'php', 'mysql', 'wp', + 'wpsubdomain'] + and oldcachetype not in ['basic', 'w3tc', 'wpfc']): + Log.error(self, " Cannot update {0}, {1} {2}" + " to wpsubdomain wpsc" + .format(ee_domain, oldsitetype, oldcachetype)) data = dict(site_name=ee_domain, www_domain=ee_www_domain, static=False, basic=False, wp=True, w3tc=False, @@ -748,15 +782,21 @@ class EESiteUpdateController(CementBaseController): ee_db_host='', currsitetype=oldsitetype, currcachetype=oldcachetype) - # TODO take site backup before site update + stype = 'wpsubdomain' + cache = 'wpsc' + + if not data: + Log.error(self, " Cannot update" + .format(ee_domain)) + site_package_check(self, stype) siteBackup(self, data) # TODO Check for required packages before update # setup NGINX configuration, and webroot - SetupDomain(self, data) + setupDomain(self, data) if 'ee_db_name' in data.keys() and not data['wp']: - data = SetupDatabase(self, data) + data = setupDatabase(self, data) try: eedbconfig = open("{0}/ee-config.php".format(ee_site_webroot), 'w') @@ -769,12 +809,11 @@ class EESiteUpdateController(CementBaseController): data['ee_db_pass'], data['ee_db_host'])) eedbconfig.close() - stype = mysql except IOError as e: - self.app.log.error("Unable to create ee-config.php for " - "{2} ({0}): {1}" - .format(e.errno, e.strerror, ee_domain)) - sys.exit(1) + Log.error(self, " Unable to create ee-config.php for " + "{0}" + .format(ee_domain)) + Log.debug(self, "{0} {1}".format(e.errno, e.strerror)) if oldsitetype == 'mysql': config_file = (ee_site_webroot + '/backup/{0}/ee-config.php' @@ -795,24 +834,41 @@ class EESiteUpdateController(CementBaseController): .split(',')[1] .split(')')[0].strip()) - # Setup WordPress if Wordpress site - if data['wp']: - ee_wp_creds = SetupWordpress(self, data) + # Setup WordPress if old sites are html/php/mysql sites + if data['wp'] and oldsitetype in ['html', 'php', 'mysql']: + ee_wp_creds = setupWordpress(self, data) + + # Uninstall unnecessary plugins + if oldsitetype in ['wp', 'wpsubdir', 'wpsubdomain']: + # Setup WordPress Network if update option is multisite + # and oldsite is WordPress single site + if data['multisite'] and oldsitetype == 'wp': + setupWordpressNetwork(self, data) + + if (oldcachetype == 'w3tc' or oldcachetype == 'wpfc' and + not data['w3tc', 'wpfc']): + uninstallWP_Plugin(self, 'w3-total-cache', data) + + if oldcachetype == 'wpsc' and not data['wpsc']: + uninstallWP_Plugin(self, 'wp-super-cache', data) + + if (oldcachetype != 'w3tc' or oldcachetype != 'wpfc') and data['w3tc']: + installWP_Plugin(self, 'w3-total-cache', data) + + if oldcachetype != 'wpsc' and data['wpsc']: + installWP_Plugin(self, 'wp-super-cache', data) + # Service Nginx Reload EEService.reload_service(self, 'nginx') EEGit.add(self, ["/etc/nginx"], - msg="{0} created with {1} {2}" + msg="{0} updated with {1} {2}" .format(ee_www_domain, stype, cache)) # Setup Permissions for webroot - SetWebrootPermissions(self, data['webroot']) - if data['wp']: - Log.info(self, '\033[94m'+"WordPress Admin User :" - " {0}".format(ee_wp_creds['wp_user'])+'\033[0m') - Log.info(self, "WordPress Admin User Password : {0}" - .format(ee_wp_creds['wp_pass'])) - addNewSite(self, ee_www_domain, stype, cache, ee_site_webroot) - Log.info(self, "Successfully created site" + # SetWebrootPermissions(self, data['webroot']) + + updateSiteInfo(self, ee_www_domain, stype=stype, cache=cache) + Log.info(self, "Successfully updated site" " http://{0}".format(ee_domain)) @@ -836,7 +892,7 @@ class EESiteDeleteController(CementBaseController): dict(help="delete webroot only", action='store_true')), ] - @expose(help="update example.com") + @expose(help="delete example.com") def default(self): # TODO Write code for ee site update here (ee_domain, ee_www_domain) = ValidateDomain(self.app.pargs.site_name) @@ -851,43 +907,48 @@ class EESiteDeleteController(CementBaseController): if self.app.pargs.db: if not ee_prompt: - ee_db_prompt = input('Do you want to delete database:[Y/N]' - ) + ee_db_prompt = input('Do you want to delete database:' + '[Y/N] ') else: ee_db_prompt = 'Y' if ee_db_prompt == 'Y': - deleteDB(ee_site_webroot) + self.deleteDB(ee_site_webroot) if self.app.pargs.files: if not ee_prompt: - ee_web_prompt = input('Do you want to delete webroot:[Y/N]' - ) + ee_web_prompt = input('Do you want to delete webroot:' + '[Y/N] ') else: ee_web_prompt = 'Y' if ee_web_prompt == 'Y': - deleteWebRoot(ee_site_webroot) + self.deleteWebRoot(ee_site_webroot) if self.app.pargs.all: if not ee_prompt: - ee_db_prompt = input('Do you want to delete database:[Y/N]' + ee_db_prompt = input('Do you want to delete database:' + '[Y/N] ' ) - ee_web_prompt = input('Do you want to delete webroot:[Y/N]' - ) + ee_web_prompt = input('Do you want to delete webroot:' + '[Y/N] ') ee_nginx_prompt = input('Do you want to delete NGINX' - ' configuration:[Y/N]') + ' configuration:[Y/N] ') else: ee_db_prompt = 'Y' ee_web_prompt = 'Y' ee_nginx_prompt = 'Y' - if ee_db_prompt: - deleteDB(self, ee_site_webroot) - if ee_web_prompt: - deleteWebRoot(ee_site_webroot) - if ee_nginx_prompt: - EEFileutils.delete(self, '/etc/nginx/sites-available/{0}' - .format(ee_domain)) + if ee_db_prompt == 'Y': + self.deleteDB(ee_site_webroot) + if ee_web_prompt == 'Y': + self.deleteWebRoot(ee_site_webroot) + if ee_nginx_prompt == 'Y': + EEFileUtils.rm(self, '/etc/nginx/sites-available/{0}' + .format(ee_domain)) + deleteSiteInfo(self, ee_domain) + else: + Log.error(self, " site {0} does not exists".format(ee_domain)) + @expose(hide=True) def deleteDB(self, webroot): configfiles = glob.glob(webroot + '/*-config.php') if configfiles: @@ -904,19 +965,52 @@ class EESiteDeleteController(CementBaseController): ee_db_host = (EEFileUtils.grep(self, configfiles[0], 'DB_HOST').split(',')[1] .split(')')[0].strip().replace('\'', '')) - - EEMysql.execute(self, - "drop database {0}" - .format(ee_db_name)) - if ee_db_user != 'root': - EEMysql.execute(self, - "drop user {0}@{1}" - .format(ee_db_user, ee_db_host)) + try: EEMysql.execute(self, - "flush privileges") + "drop database {0}".format(ee_db_name), + errormsg='Unable to drop database {0}' + .format(ee_db_name)) + if ee_db_user != 'root': + EEMysql.execute(self, + "drop user {0}@{1}" + .format(ee_db_user, ee_db_host)) + EEMysql.execute(self, + "flush privileges") + except Exception as e: + Log.error(self, " Error occured while deleting database") - def deleteWebRoot(webroot): - EEFileutils.delete(self, webroot) + @expose(hide=True) + def deleteWebRoot(self, webroot): + EEFileUtils.rm(self, webroot) + + +class EESiteListController(CementBaseController): + class Meta: + label = 'list' + stacked_on = 'site' + stacked_type = 'nested' + description = 'list websites' + arguments = [ + (['--enabled'], + dict(help='list enabled sites', action='store_true')), + (['--disabled'], + dict(help="list disabled sites", action='store_true')), + ] + + @expose(help="delete example.com") + def default(self): + sites = getAllsites(self) + if not sites: + self.app.close(1) + + if self.app.pargs.enabled: + for site in sites: + if site.is_enabled: + Log.info(self, "{0}".format(site.sitename)) + elif self.app.pargs.disabled: + for site in sites: + if not site.is_enabled: + Log.info(self, "{0}".format(site.sitename)) def load(app): @@ -925,6 +1019,6 @@ def load(app): handler.register(EESiteCreateController) handler.register(EESiteUpdateController) handler.register(EESiteDeleteController) - + handler.register(EESiteListController) # register a hook (function) to run after arguments are parsed. hook.register('post_argument_parsing', ee_site_hook) diff --git a/ee/cli/plugins/site_functions.py b/ee/cli/plugins/site_functions.py index ef18ae4c..26659719 100644 --- a/ee/cli/plugins/site_functions.py +++ b/ee/cli/plugins/site_functions.py @@ -3,19 +3,21 @@ import random import string import sys import getpass +from ee.cli.plugins.stack import EEStackController from ee.core.fileutils import EEFileUtils from ee.core.mysql import EEMysql from ee.core.shellexec import EEShellExec from ee.core.variables import EEVariables +from ee.core.aptget import EEAptGet from ee.core.logging import Log import glob -def SetupDomain(self, data): +def setupDomain(self, data): ee_domain_name = data['site_name'] ee_site_webroot = data['webroot'] - self.app.log.info("Creating {0} ...".format(ee_domain_name)) + Log.info(self, "Setting up NGINX configuration ", end='') # write nginx config for file try: ee_site_nginx_conf = open('/etc/nginx/sites-available/{0}' @@ -25,12 +27,12 @@ def SetupDomain(self, data): out=ee_site_nginx_conf) ee_site_nginx_conf.close() except IOError as e: - Log.error(self, "Unable to create nginx conf for {2} ({0}): {1}" - .format(e.errno, e.strerror, ee_domain_name)) - sys.exit(1) + Log.debug(self, "{0}".format(e)) + Log.error(self, "\nUnable to create NGINX configuration") except Exception as e: - Log.error(self, "{0}".format(e)) - sys.exit(1) + Log.debug(self, "{0}".format(e)) + Log.error(self, "\nUnable to create NGINX configuration") + Log.info(self, "[Done]") # create symbolic link for EEFileUtils.create_symlink(self, ['/etc/nginx/sites-available/{0}' @@ -39,14 +41,15 @@ def SetupDomain(self, data): .format(ee_domain_name)]) # Creating htdocs & logs directory + Log.info(self, "Setting up webroot ", end='') try: if not os.path.exists('{0}/htdocs'.format(ee_site_webroot)): os.makedirs('{0}/htdocs'.format(ee_site_webroot)) if not os.path.exists('{0}/logs'.format(ee_site_webroot)): os.makedirs('{0}/logs'.format(ee_site_webroot)) except Exception as e: - Log.error(self, "{0}".format(e)) - sys.exit(1) + Log.debug(self, "{0}".format(e)) + Log.error(self, "\nUnable to setup webroot") EEFileUtils.create_symlink(self, ['/var/log/nginx/{0}.access.log' .format(ee_domain_name), @@ -56,9 +59,10 @@ def SetupDomain(self, data): .format(ee_domain_name), '{0}/logs/error.log' .format(ee_site_webroot)]) + Log.info(self, "[Done]") -def SetupDatabase(self, data): +def setupDatabase(self, data): ee_domain_name = data['site_name'] ee_random = (''.join(random.sample(string.ascii_uppercase + string.ascii_lowercase + string.digits, 15))) @@ -75,8 +79,8 @@ def SetupDatabase(self, data): ee_db_name = input('Enter the MySQL database name [{0}]:' .format(ee_replace_dot)) except EOFError as e: - Log.error(self, "{0} {1}".format(e.errorno, e.strerror)) - sys.exit(0) + Log.debug(self, "{0}".format(e)) + Log.error(self, "Unable to input database name") if not ee_db_name: ee_db_name = ee_replace_dot @@ -88,8 +92,8 @@ def SetupDatabase(self, data): ee_db_password = input('Enter the MySQL database password [{0}]: ' .format(ee_random)) except EOFError as e: - Log.error(self, "{0} {1}".format(e.errorno, e.strerror)) - sys.exit(1) + Log.debug(self, "{0}".format(e)) + Log.error(self, "Unable to input database credentials") if not ee_db_username: ee_db_username = ee_replace_dot @@ -97,26 +101,31 @@ def SetupDatabase(self, data): ee_db_password = ee_random if len(ee_db_username) > 16: - self.app.log.info('Autofix MySQL username (ERROR 1470 (HY000)),' - ' please wait...') + Log.info(self, 'Autofix MySQL username (ERROR 1470 (HY000)),' + ' please wait...') ee_random10 = (''.join(random.sample(string.ascii_uppercase + string.ascii_lowercase + string.digits, 10))) ee_db_name = (ee_db_name[0:6] + ee_random10) # create MySQL database - self.app.log.info("Setting Up Database ...") + Log.info(self, "Setting Up Database ", end='') + Log.debug(self, "creating databse {0}".format(ee_db_name)) EEMysql.execute(self, "create database {0}" .format(ee_db_name)) # Create MySQL User + Log.debug(self, "creating user {0}".format(ee_db_username)) EEMysql.execute(self, "create user {0}@{1} identified by '{2}'" .format(ee_db_username, ee_mysql_host, ee_db_password)) # Grant permission + Log.debug(self, "setting up user privileges") EEMysql.execute(self, "grant all privileges on {0}.* to {1}@{2}" .format(ee_db_name, ee_db_username, ee_mysql_host)) + Log.info(self, "[Done]") + data['ee_db_name'] = ee_db_name data['ee_db_user'] = ee_db_username data['ee_db_pass'] = ee_db_password @@ -124,7 +133,7 @@ def SetupDatabase(self, data): return(data) -def SetupWordpress(self, data): +def setupWordpress(self, data): ee_domain_name = data['site_name'] ee_site_webroot = data['webroot'] prompt_wpprefix = self.app.config.get('wordpress', 'prefix') @@ -138,24 +147,25 @@ def SetupWordpress(self, data): ee_wp_user = '' ee_wp_pass = '' - self.app.log.info("Downloading Wordpress...") + Log.info(self, "Downloading Wordpress ", end='') EEFileUtils.chdir(self, '{0}/htdocs/'.format(ee_site_webroot)) EEShellExec.cmd_exec(self, "wp --allow-root core download") + Log.info(self, "[Done]") if not (data['ee_db_name'] and data['ee_db_user'] and data['ee_db_pass']): - data = SetupDatabase(self, data) + data = setupDatabase(self, data) if prompt_wpprefix == 'True' or prompt_wpprefix == 'true': try: ee_wp_prefix = input('Enter the WordPress table prefix [wp_]: ' .format(ee_replace_dot)) while re.match('^[A-Za-z0-9_]*$', ee_wp_prefix): - self.app.log.warn("table prefix can only " - "contain numbers, letters, and underscores") + Log.warn(self, "table prefix can only " + "contain numbers, letters, and underscores") ee_wp_prefix = input('Enter the WordPress table prefix [wp_]: ' ) except EOFError as e: - Log.error(self, "{0} {1}".format(e.errorno, e.strerror)) - sys.exit(1) + Log.debug(self, "{0}".format(e)) + Log.error(self, "Unable to input table prefix") if not ee_wp_prefix: ee_wp_prefix = 'wp_' @@ -163,35 +173,40 @@ def SetupWordpress(self, data): # Modify wp-config.php & move outside the webroot EEFileUtils.chdir(self, '{0}/htdocs/'.format(ee_site_webroot)) - self.app.log.debug("Setting Up WordPress Configuration...") + Log.debug(self, "Setting up wp-config file") if not data['multisite']: + Log.debug(self, "Generating wp-config for WordPress Single site") EEShellExec.cmd_exec(self, "wp --allow-root core config " + "--dbname={0} --dbprefix={1} --dbuser={2} " .format(data['ee_db_name'], ee_wp_prefix, data['ee_db_user']) + "--dbpass={0}".format(data['ee_db_pass'])) else: + Log.debug(self, "Generating wp-config for WordPress multisite") EEShellExec.cmd_exec(self, "php /usr/bin/wp --allow-root core config " + "--dbname={0} --dbprefix={1} " .format(data['ee_db_name'], ee_wp_prefix) + "--dbuser={0} --dbpass={1} " "--extra-php< {1}/{0}.sql" .format(ee_db_name, backup_path), - "Failed: Backup Database") + errormsg="\nFailed: Backup Database") + Log.info(self, "[Done]") # move wp-config.php/ee-config.php to backup - EEFileUtils.mvfile(self, file, backup_path) + if data['currsitetype'] in ['mysql']: + EEFileUtils.mvfile(self, configfiles[0], backup_path) + else: + EEFileUtils.copyfile(self, configfiles[0], backup_path) + + +def site_package_check(self, stype): + apt_packages = [] + packages = [] + stack = EEStackController() + stack.app = self.app + if stype in ['html', 'php', 'mysql', 'wp', 'wpsubdir', 'wpsubdomain']: + Log.debug(self, "Setting apt_packages variable for Nginx") + if not EEAptGet.is_installed(self, 'nginx-common'): + apt_packages = apt_packages + EEVariables.ee_nginx + + if stype in ['php', 'mysql', 'wp', 'wpsubdir', 'wpsubdomain']: + Log.debug(self, "Setting apt_packages variable for PHP") + if not EEAptGet.is_installed(self, 'php5-fpm'): + apt_packages = apt_packages + EEVariables.ee_php + + if stype in ['mysql', 'wp', 'wpsubdir', 'wpsubdomain']: + Log.debug(self, "Setting apt_packages variable for MySQL") + if not EEShellExec.cmd_exec(self, "mysqladmin ping"): + apt_packages = apt_packages + EEVariables.ee_mysql + + if stype in ['php', 'mysql', 'wp', 'wpsubdir', 'wpsubdomain']: + Log.debug(self, "Setting apt_packages variable for PostFix") + if not EEAptGet.is_installed(self, 'postfix'): + apt_packages = apt_packages + EEVariables.ee_postfix + + if stype in ['wp', 'wpsubdir', 'wpsubdomain']: + Log.debug(self, "Setting packages variable for WPCLI") + if not EEShellExec.cmd_exec(self, "which wp"): + packages = packages + [["https://github.com/wp-cli/wp-cli/" + "releases/download/v0.17.1/" + "wp-cli.phar", "/usr/bin/wp", + "WP_CLI"]] + stack.install(apt_packages=apt_packages, packages=packages) diff --git a/ee/cli/plugins/sitedb.py b/ee/cli/plugins/sitedb.py index 165c49c3..c8f2acd6 100644 --- a/ee/cli/plugins/sitedb.py +++ b/ee/cli/plugins/sitedb.py @@ -4,96 +4,66 @@ from sqlalchemy.orm import relationship, backref from sqlalchemy.ext.declarative import declarative_base from ee.core.logging import Log import sys +from ee.core.database import db_session +from ee.core.models import SiteDB -Base = declarative_base() +def addNewSite(self, site, stype, cache, path, + enabled=True, ssl=False, fs='ext4', db='mysql'): + try: + newRec = SiteDB(site, stype, cache, path, enabled, ssl, fs, db) + 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") -class SiteDB(Base): - __tablename__ = 'Site' - id = Column(Integer, primary_key=True) - sitename = Column(String, unique=True) - site_type = Column(String) - cache_type = Column(String) - site_path = Column(String) +def getSiteInfo(self, site): + 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") - # 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()) - site_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) +def updateSiteInfo(self, site, stype='', cache='', + enabled=True, ssl=False, fs='', db=''): + 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 stype and q.site_type != stype: + q.site_type = stype - def __init__(self): - # from sqlalchemy import create_engine - # self.engine = create_engine('sqlite:///orm_in_detail.sqlite') - self.sitename = sitename - self.site_type = site_type - self.cache_type = cache_type - self.site_path = site_path - self.created_on = created_on - self.site_enabled = site_enabled - self.is_ssl = is_ssl - self.storage_fs = storage_fs - self.storage_db = storage_db + if cache and q.cache_type != cache: + q.cache_type = cache -# if __name__ == "__main__": -# -# from sqlalchemy import create_engine -# engine = create_engine('sqlite:///orm_in_detail.sqlite') -# from sqlalchemy.orm import sessionmaker -# session = sessionmaker() -# session.configure(bind=engine) -# Base.metadata.create_all(engine) -# s = session() -# newRec = SiteDB(sitename='exa.in', site_type='wp', cache_type='basic', - # site_path='/var/www', site_enabled=True, is_ssl=False, storage_fs='ext4', - # storage_db='mysql') -# s.add(newRec) -# s.commit() -# s.flush() + if enabled and q.is_enabled != enabled: + q.is_enabled = enabled + if ssl and q.is_ssl != ssl: + q.is_ssl = ssl -def addNewSite(self, site, stype, cache, path, - enabled=True, ssl=False, fs='ext4', db='mysql'): - db_path = self.app.config.get('site', 'db_path') try: - from sqlalchemy import create_engine - engine = create_engine(db_path) - from sqlalchemy.orm import sessionmaker - session = sessionmaker() - session.configure(bind=engine) - Base.metadata.create_all(engine) - s = session() - newRec = SiteDB(sitename=site, site_type=stype, cache_type=cache, - site_path=path, site_enabled=enabled, is_ssl=ssl, - storage_fs=fs, storage_db=db) - s.add(newRec) - s.commit() - s.flush() + q.created_on = func.now() + db_session.commit() except Exception as e: - Log.error(self, "Unable to add site to database : {0}" - .format(e)) - sys.exit(1) + Log.debug(self, "{0}".format(e)) + Log.error(self, "Unable to update site info in application database.") -def getSiteInfo(self, site): - db_path = self.app.config.get('site', 'db_path') +def deleteSiteInfo(self, site): try: - from sqlalchemy import create_engine - engine = create_engine(db_path) - from sqlalchemy.orm import sessionmaker - session = sessionmaker() - session.configure(bind=engine) - Base.metadata.create_all(engine) - s = session() - q = s.query(SiteDB).filter_by(sitename=site).first() - s.flush() - return q + 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 :") + try: + db_session.delete(q) + db_session.commit() except Exception as e: - Log.error(self, "Unable to add site to database : {0}" - .format(e)) - sys.exit(1) + Log.debug(self, "{0}".format(e)) + Log.error(self, "Unable to delete site from application database.") diff --git a/ee/cli/plugins/stack.py b/ee/cli/plugins/stack.py index 1e9f1c5a..103f96f7 100644 --- a/ee/cli/plugins/stack.py +++ b/ee/cli/plugins/stack.py @@ -388,6 +388,14 @@ class EEStackController(CementBaseController): Log.debug(self, "writting PHP5 configartion into " " /etc/php5/fpm/pool.d/debug.conf") config.write(confifile) + + with open("/etc/php5/fpm/pool.d/debug.conf", "a") as myfile: + myfile.write("php_admin_value[xdebug.profiler_output_dir] " + "= /tmp/ \nphp_admin_value[xdebug.profiler_" + "output_name] = cachegrind.out.%p-%H-%R " + "\nphp_admin_flag[xdebug.profiler_enable" + "_trigger] = on \nphp_admin_flag[xdebug." + "profiler_enable] = off\n") EEGit.add(self, ["/etc/php5"], msg="Adding PHP into Git") EEService.reload_service(self, 'php5-fpm') @@ -896,143 +904,156 @@ class EEStackController(CementBaseController): @expose() def install(self, packages=[], apt_packages=[]): self.msg = [] - if self.app.pargs.web: - Log.debug(self, "Setting apt_packages variable for Nginx ,PHP" - " ,MySQL ") - self.app.pargs.nginx = True - self.app.pargs.php = True - self.app.pargs.mysql = True - self.app.pargs.wpcli = True - self.app.pargs.postfix = True - - if self.app.pargs.admin: - self.app.pargs.nginx = True - self.app.pargs.php = True - self.app.pargs.mysql = True - self.app.pargs.adminer = True - self.app.pargs.phpmyadmin = True - self.app.pargs.utils = True - - if self.app.pargs.mail: - self.app.pargs.nginx = True - self.app.pargs.php = True - self.app.pargs.mysql = True - self.app.pargs.postfix = True - - if not EEAptGet.is_installed('dovecot-core'): - Log.debug(self, "Setting apt_packages variable for mail") - apt_packages = apt_packages + EEVariables.ee_mail - packages = packages + [["https://github.com/opensolutions/" - "ViMbAdmin/archive/3.0.10.tar.gz", - "/tmp/vimbadmin.tar.gz", "ViMbAdmin"], - ["https://github.com/roundcube/" - "roundcubemail/releases/download/" - "1.0.4/roundcubemail-1.0.4.tar.gz", - "/tmp/roundcube.tar.gz", - "Roundcube"]] - - if EEVariables.ee_ram > 1024: - apt_packages = apt_packages + EEVariables.ee_mailscanner - else: - Log.info(self, "Mail server is allready installed") - - if self.app.pargs.nginx: - Log.debug(self, "Setting apt_packages variable for Nginx") - if not EEAptGet.is_installed('nginx-common'): - apt_packages = apt_packages + EEVariables.ee_nginx - else: - Log.info(self, "Nginx allready installed") - if self.app.pargs.php: - Log.debug(self, "Setting apt_packages variable for PHP") - if not EEAptGet.is_installed('php5-common'): - apt_packages = apt_packages + EEVariables.ee_php - else: - Log.info(self, "PHP allready installed") - if self.app.pargs.mysql: - Log.debug(self, "Setting apt_packages variable for MySQL") - if not EEShellExec.cmd_exec(self, "mysqladmin ping"): - apt_packages = apt_packages + EEVariables.ee_mysql - else: - Log.info(self, "MySQL connection is allready alive") - if self.app.pargs.postfix: - Log.debug(self, "Setting apt_packages variable for PostFix") - if not EEAptGet.is_installed('postfix'): - apt_packages = apt_packages + EEVariables.ee_postfix - else: - Log.info(self, "Postfix is allready installed") - if self.app.pargs.wpcli: - Log.debug(self, "Setting packages variable for WPCLI") - if not EEShellExec.cmd_exec(self, "which wp"): - packages = packages + [["https://github.com/wp-cli/wp-cli/" - "releases/download/v0.17.1/" - "wp-cli.phar", "/usr/bin/wp", - "WP_CLI"]] - else: - Log.info(self, "WP-CLI is allready installed") - if self.app.pargs.phpmyadmin: - Log.debug(self, "Setting packages varible for phpMyAdmin ") - packages = packages + [["https://github.com/phpmyadmin/phpmyadmin" - "/archive/STABLE.tar.gz", - "/tmp/pma.tar.gz", "phpMyAdmin"]] - - if self.app.pargs.adminer: - Log.debug(self, "Setting packages variable for Adminer ") - packages = packages + [["http://downloads.sourceforge.net/adminer" - "/adminer-4.1.0.php", "/var/www/22222/" - "htdocs/db/adminer/index.php", "Adminer"]] + try: + if self.app.pargs.web: + Log.debug(self, "Setting apt_packages variable for Nginx ,PHP" + " ,MySQL ") + self.app.pargs.nginx = True + self.app.pargs.php = True + self.app.pargs.mysql = True + self.app.pargs.wpcli = True + self.app.pargs.postfix = True + + if self.app.pargs.admin: + self.app.pargs.nginx = True + self.app.pargs.php = True + self.app.pargs.mysql = True + self.app.pargs.adminer = True + self.app.pargs.phpmyadmin = True + self.app.pargs.utils = True + + if self.app.pargs.mail: + self.app.pargs.nginx = True + self.app.pargs.php = True + self.app.pargs.mysql = True + self.app.pargs.postfix = True + + if not EEAptGet.is_installed(self, 'dovecot-core'): + Log.debug(self, "Setting apt_packages variable for mail") + apt_packages = apt_packages + EEVariables.ee_mail + packages = packages + [["https://github.com/opensolutions/" + "ViMbAdmin/archive/3.0.10.tar.gz", + "/tmp/vimbadmin.tar.gz", + "ViMbAdmin"], + ["https://github.com/roundcube/" + "roundcubemail/releases/download/" + "1.0.4/roundcubemail-1.0.4.tar.gz", + "/tmp/roundcube.tar.gz", + "Roundcube"]] + + if EEVariables.ee_ram > 1024: + apt_packages = (apt_packages + + EEVariables.ee_mailscanner) + else: + Log.info(self, "Mail server is allready installed") - if self.app.pargs.utils: - Log.debug(self, "Setting packages variable for utils") - packages = packages + [["http://phpmemcacheadmin.googlecode.com/" - "files/phpMemcachedAdmin-1.2.2" - "-r262.tar.gz", '/tmp/memcache.tar.gz', - 'phpMemcachedAdmin'], - ["https://raw.githubusercontent.com/rtCamp/" - "eeadmin/master/cache/nginx/clean.php", - "/var/www/22222/htdocs/cache/" - "nginx/clean.php", "clean.php"], - ["https://raw.github.com/rlerdorf/opcache-" - "status/master/opcache.php", - "/var/www/22222/htdocs/cache/" - "opcache/opcache.php", "opcache.php"], - ["https://raw.github.com/amnuts/opcache-gui" - "/master/index.php", - "/var/www/22222/htdocs/" - "cache/opcache/opgui.php", "index.php"], - ["https://gist.github.com/ck-on/4959032/raw" - "/0b871b345fd6cfcd6d2be030c1f33d1ad6a475cb" - "/ocp.php", - "/var/www/22222/htdocs/cache/" - "opcache/ocp.php", "ocp.php"], - ["https://github.com/jokkedk/webgrind/" - "archive/master.tar.gz", - '/tmp/webgrind.tar.gz', 'Webgrind'], - ["http://bazaar.launchpad.net/~percona-too" - "lkit-dev/percona-toolkit/2.1/download/he" - "ad:/ptquerydigest-20110624220137-or26tn4" - "expb9ul2a-16/pt-query-digest", - "/usr/bin/pt-query-advisor", - "pt-query-digest"], - ["https://github.com/box/Anemometer/archive" - "/master.tar.gz", - '/tmp/anemometer.tar.gz', 'Anemometer'] - ] - Log.debug(self, "Calling pre_pref ") - self.pre_pref(apt_packages) - if len(apt_packages): - EESwap.add(self) - Log.debug(self, "Updating apt-cache") - EEAptGet.update() - Log.debug(self, "Installing all apt_packages") - EEAptGet.install(apt_packages) - if len(packages): - Log.debug(self, "Downloading all packages") - EEDownload.download(self, packages) - Log.debug(self, "Calling post_pref") - self.post_pref(apt_packages, packages) - if len(self.msg): - for msg in self.msg: - Log.info(self, msg) + if self.app.pargs.nginx: + Log.debug(self, "Setting apt_packages variable for Nginx") + if not EEAptGet.is_installed(self, 'nginx-common'): + apt_packages = apt_packages + EEVariables.ee_nginx + else: + Log.info(self, "Nginx allready installed") + if self.app.pargs.php: + Log.debug(self, "Setting apt_packages variable for PHP") + if not EEAptGet.is_installed(self, 'php5-fpm'): + apt_packages = apt_packages + EEVariables.ee_php + else: + Log.info(self, "PHP allready installed") + if self.app.pargs.mysql: + Log.debug(self, "Setting apt_packages variable for MySQL") + if not EEShellExec.cmd_exec(self, "mysqladmin ping"): + apt_packages = apt_packages + EEVariables.ee_mysql + else: + Log.info(self, "MySQL connection is allready alive") + if self.app.pargs.postfix: + Log.debug(self, "Setting apt_packages variable for PostFix") + if not EEAptGet.is_installed(self, 'postfix'): + apt_packages = apt_packages + EEVariables.ee_postfix + else: + Log.info(self, "Postfix is allready installed") + if self.app.pargs.wpcli: + Log.debug(self, "Setting packages variable for WPCLI") + if not EEShellExec.cmd_exec(self, "which wp"): + packages = packages + [["https://github.com/wp-cli/wp-cli/" + "releases/download/v0.17.1/" + "wp-cli.phar", "/usr/bin/wp", + "WP_CLI"]] + else: + Log.info(self, "WP-CLI is allready installed") + if self.app.pargs.phpmyadmin: + Log.debug(self, "Setting packages varible for phpMyAdmin ") + packages = packages + [["https://github.com/phpmyadmin/" + "phpmyadmin/archive/STABLE.tar.gz", + "/tmp/pma.tar.gz", "phpMyAdmin"]] + + if self.app.pargs.adminer: + Log.debug(self, "Setting packages variable for Adminer ") + packages = packages + [["http://downloads.sourceforge.net/" + "adminer/adminer-4.1.0.php", + "/var/www/22222/" + "htdocs/db/adminer/index.php", + "Adminer"]] + + if self.app.pargs.utils: + Log.debug(self, "Setting packages variable for utils") + packages = packages + [["http://phpmemcacheadmin.googlecode" + ".com/files/phpMemcachedAdmin-1.2.2" + "-r262.tar.gz", '/tmp/memcache.tar.gz', + 'phpMemcachedAdmin'], + ["https://raw.githubusercontent.com" + "/rtCamp/eeadmin/master/cache/nginx/" + "clean.php", + "/var/www/22222/htdocs/cache/" + "nginx/clean.php", "clean.php"], + ["https://raw.github.com/rlerdorf/" + "opcache-status/master/opcache.php", + "/var/www/22222/htdocs/cache/" + "opcache/opcache.php", "opcache.php"], + ["https://raw.github.com/amnuts/" + "opcache-gui/master/index.php", + "/var/www/22222/htdocs/" + "cache/opcache/opgui.php", + "index.php"], + ["https://gist.github.com/ck-on/4959032" + "/raw/0b871b345fd6cfcd6d2be030c1f33d1" + "ad6a475cb/ocp.php", + "/var/www/22222/htdocs/cache/" + "opcache/ocp.php", "ocp.php"], + ["https://github.com/jokkedk/webgrind/" + "archive/master.tar.gz", + '/tmp/webgrind.tar.gz', 'Webgrind'], + ["http://bazaar.launchpad.net/~" + "percona-toolkit-dev/percona-toolkit/" + "2.1/download/head:/ptquerydigest-" + "20110624220137-or26tn4" + "expb9ul2a-16/pt-query-digest", + "/usr/bin/pt-query-advisor", + "pt-query-digest"], + ["https://github.com/box/Anemometer/" + "archive/master.tar.gz", + '/tmp/anemometer.tar.gz', 'Anemometer'] + ] + except Exception as e: + pass + + if len(apt_packages) or len(packages): + Log.debug(self, "Calling pre_pref ") + self.pre_pref(apt_packages) + if len(apt_packages): + EESwap.add(self) + Log.debug(self, "Updating apt-cache") + EEAptGet.update(self) + Log.debug(self, "Installing all apt_packages") + print(apt_packages) + EEAptGet.install(self, apt_packages) + if len(packages): + Log.debug(self, "Downloading all packages") + EEDownload.download(self, packages) + Log.debug(self, "Calling post_pref") + self.post_pref(apt_packages, packages) + if len(self.msg): + for msg in self.msg: + Log.info(self, msg) Log.info(self, "Successfully installed packages") @expose() @@ -1095,7 +1116,7 @@ class EEStackController(CementBaseController): if len(apt_packages): Log.debug(self, "Removing apt_packages") - EEAptGet.remove(apt_packages) + EEAptGet.remove(self, apt_packages) if len(packages): EEFileUtils.remove(self, packages) Log.info(self, "Successfully removed packages") @@ -1160,7 +1181,7 @@ class EEStackController(CementBaseController): ] if len(apt_packages): - EEAptGet.remove(apt_packages, purge=True) + EEAptGet.remove(self, apt_packages, purge=True) if len(packages): EEFileUtils.remove(self, packages) Log.info(self, "Successfully purged packages") diff --git a/ee/cli/templates/info_mysql.mustache b/ee/cli/templates/info_mysql.mustache new file mode 100644 index 00000000..29a5d81e --- /dev/null +++ b/ee/cli/templates/info_mysql.mustache @@ -0,0 +1,9 @@ + +MySQL ({{version}}) on {{host}}: + +port {{port}} +wait_timeout {{wait_timeout}} +interactive_timeout {{interactive_timeout}} +max_used_connections {{max_used_connections}} +datadir {{datadir}} +socket {{socket}} diff --git a/ee/cli/templates/info_nginx.mustache b/ee/cli/templates/info_nginx.mustache new file mode 100644 index 00000000..6420405b --- /dev/null +++ b/ee/cli/templates/info_nginx.mustache @@ -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}} diff --git a/ee/cli/templates/info_php.mustache b/ee/cli/templates/info_php.mustache new file mode 100644 index 00000000..1638cf8a --- /dev/null +++ b/ee/cli/templates/info_php.mustache @@ -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}} diff --git a/ee/core/aptget.py b/ee/core/aptget.py index 40d03b0c..cfa7509c 100644 --- a/ee/core/aptget.py +++ b/ee/core/aptget.py @@ -1,13 +1,16 @@ """EasyEngine package installation using apt-get module.""" import apt +import apt_pkg import sys +from ee.core.logging import Log class EEAptGet(): """Generic apt-get intialisation""" - def update(): + def update(self): """Similar to apt-get update""" + # app.log.debug("Update cache") cache = apt.Cache() fprogress = apt.progress.text.AcquireProgress() @@ -15,7 +18,7 @@ class EEAptGet(): cache.update(fprogress) cache.close() - def upgrade(packages): + def upgrade(self, packages): """Similar to apt-get update""" cache = apt.Cache() fprogress = apt.progress.text.AcquireProgress() @@ -63,7 +66,7 @@ class EEAptGet(): return(False) return(True) - def install(packages): + def install(self, packages): """Installation of packages""" cache = apt.Cache() fprogress = apt.progress.text.AcquireProgress() @@ -110,7 +113,7 @@ class EEAptGet(): .format(req_download=cache.required_download)) print("After this operation, {space} bytes of" "additional disk space will be used." - .format(space=cache.required_space)) + .format(space=cache.required_space/1e6)) try: # Commit changes in cache (actually install) cache.commit(fprogress, iprogress) @@ -122,7 +125,7 @@ class EEAptGet(): cache.close() return(True) - def remove(packages, auto=True, purge=False): + def remove(self, packages, auto=False, purge=False): def __dependencies_loop(cache, deplist, pkg, onelevel=True): """ Loops through pkg's dependencies. Returns a list with every package found. """ @@ -132,15 +135,17 @@ class EEAptGet(): return for depf in pkg.installed.dependencies: for dep in depf: - if (dep.name in cache and not cache[dep.name] - in deplist): - deplist.append(cache[dep.name]) - __dependencies_loop(cache, deplist, cache[dep.name]) - if onelevel: - if dep.name in cache: + # if (dep.name in cache and not cache[dep.name] + # in deplist): + # deplist.append(cache[dep.name]) + # __dependencies_loop(cache, deplist, cache[dep.name]) + # if onelevel: + if dep.name in cache: + if (cache[dep.name].is_installed and + cache[dep.name].is_auto_installed): onelevellist.append(cache[dep.name]) - if onelevel: - return onelevellist + # if onelevel: + return onelevellist cache = apt.Cache() fprogress = apt.progress.text.AcquireProgress() @@ -154,68 +159,48 @@ class EEAptGet(): cache.open() for package in packages: print("processing", package) - package = cache[package] - if not package.is_installed: - print("Package '{package_name}' is not installed," - " so not removed." - .format(package_name=package.name)) + try: + pkg = cache[package] + except KeyError as e: + Log.debug(self, "{0}".format(e)) continue - if package.marked_delete: - my_selected_packages.append(package.name) - # Mark for deletion the first package, to fire up - # auto_removable Purge? - if purge: - package.mark_delete(purge=True) - else: - package.mark_delete(purge=False) + if not pkg.is_installed: + Log.info(self, "Package '{package_name}' is not installed," + " so not removed." + .format(package_name=pkg.name)) continue - else: - my_selected_packages.append(package.name) - print(my_selected_packages) - # How logic works: - # 1) We loop trough dependencies's dependencies and add them to - # the list. - # 2) We sequentially remove every package in list - # - via is_auto_installed we check if we can safely remove it - deplist = [] - onelevel = __dependencies_loop(cache, deplist, package, - onelevel=True) - # Mark for deletion the first package, to fire up - # auto_removable Purge? - if purge: - package.mark_delete(purge=True) - else: - package.mark_delete(purge=False) + my_selected_packages.append(pkg.name) + print(my_selected_packages) + # How logic works: + # 1) We loop trough dependencies's dependencies and add them to + # the list. + # 2) We sequentially remove every package in list + # - via is_auto_installed we check if we can safely remove it + deplist = [] + onelevel = __dependencies_loop(cache, deplist, pkg, + onelevel=True) + # Mark for deletion the first package, to fire up + # auto_removable Purge? + + for dep in onelevel: + my_selected_packages.append(dep.name) + try: + if purge: + dep.mark_delete(purge=True) + else: + dep.mark_delete(purge=False) + except SystemError as e: + Log.debug(self, "{0}".format(e)) + Log.error(self, "Unable to purge depedencies.") - # Also ensure we remove AT LEAST the first level of - # dependencies (that is, the actual package's dependencies). - if auto: - markedauto = [] - for pkg in onelevel: - if (not pkg.marked_install and pkg.is_installed - and not pkg.is_auto_installed): - pkg.mark_auto() - markedauto.append(pkg) - - for pkg in deplist: - if (not pkg.marked_install and pkg.is_installed and - pkg.is_auto_removable): - # Purge? - if purge: - pkg.mark_delete(purge=True) - else: - pkg.mark_delete(purge=False) - # Restore auted items - for pkg in markedauto: - if not pkg.marked_delete: - pkg.mark_auto(False) + try: + if purge: + pkg.mark_delete(purge=True) else: - # We need to ensure that the onelevel packages are not - # marked as automatically installed, otherwise the user may - # drop them via autoremove or aptitude. - for pkg in onelevel: - if pkg.is_installed and pkg.is_auto_installed: - pkg.mark_auto(auto=False) + pkg.mark_delete(purge=False) + except SystemError as e: + Log.debug(self, "{0}".format(e)) + Log.error(self, "Unable to purge packages.") # Check if packages available for remove/update. if cache.delete_count > 0: @@ -239,7 +224,7 @@ class EEAptGet(): cache.close() return(True) - def is_installed(package): + def is_installed(self, package): cache = apt.Cache() fprogress = apt.progress.text.AcquireProgress() iprogress = apt.progress.base.InstallProgress() @@ -258,6 +243,8 @@ class EEAptGet(): else: cache.close() return False + except KeyError as e: + Log.debug(self, "{0}".format(e)) except Exception as e: cache.close() return False diff --git a/ee/core/database.py b/ee/core/database.py new file mode 100644 index 00000000..1cac3452 --- /dev/null +++ b/ee/core/database.py @@ -0,0 +1,19 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import scoped_session, sessionmaker +from sqlalchemy.ext.declarative import declarative_base + +#db_path = self.app.config.get('site', 'db_path') +engine = create_engine('sqlite:////var/lib/ee/ee.sqlite', convert_unicode=True) +db_session = scoped_session(sessionmaker(autocommit=False, + autoflush=False, + bind=engine)) +Base = declarative_base() +Base.query = db_session.query_property() + + +def init_db(): + # import all modules here that might define models so that + # they will be registered properly on the metadata. Otherwise + # you will have to import them first before calling init_db() + import ee.core.models + Base.metadata.create_all(bind=engine) diff --git a/ee/core/logging.py b/ee/core/logging.py index 86c72278..56847a38 100644 --- a/ee/core/logging.py +++ b/ee/core/logging.py @@ -11,9 +11,12 @@ class Log: UNDERLINE = '\033[4m' def error(self, msg): + print(Log.FAIL + msg + Log.ENDC) self.app.log.error(Log.FAIL + msg + Log.ENDC) + self.app.close(1) - def info(self, msg): + def info(self, msg, end='\n'): + print(Log.OKBLUE + msg + Log.ENDC, end=end) self.app.log.info(Log.OKBLUE + msg + Log.ENDC) def warn(self, msg): diff --git a/ee/core/models.py b/ee/core/models.py new file mode 100644 index 00000000..bd62fc43 --- /dev/null +++ b/ee/core/models.py @@ -0,0 +1,40 @@ +from sqlalchemy import Column, DateTime, String, Integer, Boolean, func +from ee.core.database import Base + + +class SiteDB(Base): + __tablename__ = 'sites' + 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) + + 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): + 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 + + # def __repr__(self): + # return '' % (self.site_type) + # + # def getType(self): + # return '%r>' % (self.site_type) diff --git a/ee/core/services.py b/ee/core/services.py index 6392709c..297513b6 100644 --- a/ee/core/services.py +++ b/ee/core/services.py @@ -67,7 +67,7 @@ class EEService(): .format(service_name, "[OK]")) return True else: - Log.debug("{0}".format(retcode[1])) + Log.debug(self, "{0}".format(retcode[1])) Log.error(self, "reload : {0}".format(service_name)) return False diff --git a/ee/core/variables.py b/ee/core/variables.py index 36797587..9077de93 100644 --- a/ee/core/variables.py +++ b/ee/core/variables.py @@ -77,7 +77,7 @@ class EEVariables(): ee_mail = ["dovecot-core", "dovecot-imapd", "dovecot-pop3d", "dovecot-lmtpd", "dovecot-mysql", "dovecot-sieve", "dovecot-managesieved", "postfix-mysql", "php5-cgi", - "php5-json", "php-gettext"] + "php-gettext"] # Mailscanner repo and packages ee_mailscanner_repo = () diff --git a/setup.py b/setup.py index 3064be7d..d98e9f4d 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ setup(name='ee', # "nose", # "coverage", # Required to function - 'cement>=2.4', + 'cement == 2.4', 'pystache', 'python-apt', 'pynginxconfig',