From 292a88d9acd01a524493035517469f40da0466d0 Mon Sep 17 00:00:00 2001 From: harshadyeola Date: Wed, 10 Jun 2015 18:23:10 +0530 Subject: [PATCH] modified stack --- ee/cli/main.py | 1 + ee/cli/plugins/hhvmstack.py | 16 +- ee/cli/plugins/mailscannerstack.py | 5 + ee/cli/plugins/mailstack.py | 587 +++++++++++++++-------------- ee/cli/plugins/mysqlstack.py | 42 ++- ee/cli/plugins/nginxstack.py | 29 +- ee/cli/plugins/phpstack.py | 9 +- ee/cli/plugins/postfixstack.py | 1 + ee/cli/plugins/stack.py | 525 +++++++------------------- ee/cli/plugins/update.py | 7 +- ee/core/fileutils.py | 123 +++--- ee/core/variables.py | 40 ++ setup.py | 5 +- 13 files changed, 608 insertions(+), 782 deletions(-) diff --git a/ee/cli/main.py b/ee/cli/main.py index 9ae2abdc..6aafc422 100644 --- a/ee/cli/main.py +++ b/ee/cli/main.py @@ -64,6 +64,7 @@ class EEApp(foundation.CementApp): argument_handler = EEArgHandler + debug = TOGGLE_DEBUG diff --git a/ee/cli/plugins/hhvmstack.py b/ee/cli/plugins/hhvmstack.py index 9b726453..a6ec3348 100644 --- a/ee/cli/plugins/hhvmstack.py +++ b/ee/cli/plugins/hhvmstack.py @@ -135,17 +135,19 @@ class EEHhvmStack(EEStack): if not EEService.reload_service(self, 'nginx'): self.log.error(self, "Failed to reload Nginx, please check " - "output of `nginx -t`") + "output of `nginx -t`") def install_stack(self): """ Install HHVM stack """ - self.log.info("Installing HHVM stack, please wait...") - self._pre_install_stack() - super(EEHhvmStack, self).install_stack() - self._post_install_stack() + if not self.is_installed(): + self.log.info("Installing HHVM stack, please wait...") + self._pre_install_stack() + super(EEHhvmStack, self).install_stack() + self._post_install_stack() + def remove_stack(self): """ @@ -157,3 +159,7 @@ class EEHhvmStack(EEStack): def purge_stack(self): self.log.info("Purging HHVM stack, please wait...") super(EEHhvmStack, self).purge_stack() + + def is_installed(self): + self.log.info("Checking if hhvm is installed") + return EEAptGet.is_installed(self, 'hhvm') diff --git a/ee/cli/plugins/mailscannerstack.py b/ee/cli/plugins/mailscannerstack.py index b0bc7ee3..05fb3366 100644 --- a/ee/cli/plugins/mailscannerstack.py +++ b/ee/cli/plugins/mailscannerstack.py @@ -46,6 +46,11 @@ class EEMailScannerStack(EEStack): """ Defines pre-install activities done before installing mail stack """ + + if not EEVariables.ee_ram > 1024: + self.log.info("System RAM seems to be less than 1GB, " + "skipping mailsacanner installation") + sys.exit(2) # Add mail repository self._add_repo() diff --git a/ee/cli/plugins/mailstack.py b/ee/cli/plugins/mailstack.py index 5aa5cbf9..768ef0ff 100644 --- a/ee/cli/plugins/mailstack.py +++ b/ee/cli/plugins/mailstack.py @@ -1,6 +1,8 @@ import os import sys import random +import string +import shutil from ee.core.variables import EEVariables from ee.core.aptget import EEAptGet from ee.cli.plugins.eestack import EEStack @@ -12,7 +14,9 @@ from ee.core.services import EEService from ee.cli.plugins.mysqlstack import EEMysqlStack from ee.cli.plugins.nginxstack import EENginxStack from ee.cli.plugins.phpstack import EEPhpStack -from ee.core.logging import Log +from ee.core.download import EEDownload +from ee.core.extract import EEExtract +from ee.core.mysql import EEMysql from ee.cli.main import app @@ -24,19 +28,45 @@ class EEMailStack(EEStack): app = app log = app.log - def __init__(self, packages_name=None): + def __init__(self, package_dict=None, apt_packages=None): """ Initialize packages list in stack pkgs_name : list of packages to be intialized for operations in stack + package_url : list of urls from where packages to be fetched """ - - self.packages_name = self._get_stack() - super(EEMailStack, self).__init__(self.packages_name) + self.apt_packages = apt_packages + self.manual_packages = package_dict + self.packages_name = self._get_stack() + super(EEMailStack, self).__init__(self.apt_packages) def _get_stack(self): + """ + """ + if self.apt_packages or self.manual_packages: + if not self.apt_packages: + return (self.manual_packages) + elif not self.manual_packages: + return (self.apt_packages) + else: + return (self.apt_packages, self.manual_packages) + return EEMailStack.packages_name + def _set_stack(self): + """ + """ + + if type(self.packages_name) is tuple: + for packages in self.packages_name: + if type(packages) is list: + self.apt_packages = packages + if type(packages) is dict: + self.manual_packages = packages + elif type(self.packages_name) is dict: + self.manual_packages = self.packages_name + + def _requirement_check(self): """ Check if requirements for this EEWebmailAdmin stack are fullfilled. @@ -65,275 +95,13 @@ class EEMailStack(EEStack): # update repository information EEAptGet.update(self) - def _pre_install_stack(self): - """ - Defines pre-install activities done before installing mail stack - """ - # Add mail repository - - self._requirement_check() - self._add_repo() - - self.log.debug(self, 'Executing the command debconf-set-selections.') - try: - EEShellExec.cmd_exec(self, "echo \"dovecot-core dovecot-core/" - "create-ssl-cert boolean yes\" " - "| debconf-set-selections") - EEShellExec.cmd_exec(self, "echo \"dovecot-core dovecot-core" - "/ssl-cert-name string $(hostname -f)\"" - " | debconf-set-selections") - except CommandExecutionError as e: - self.log.error("Failed to initialize dovecot packages") - - def _post_install_stack(self): - """ - Defines activities done after installing mail stack - """ - self.log.debug(self, "Adding user") - try: - EEShellExec.cmd_exec(self, "adduser --uid 5000 --home /var" - "/vmail --disabled-password --gecos " - "'' vmail") - except CommandExecutionError as e: - self.log.error(self, "Unable to add vmail user for mail server") - try: - EEShellExec.cmd_exec(self, "openssl req -new -x509 -days" - " 3650 " - "-nodes -subj /commonName={hostname}" - "/emailAddress={email} -out /etc/ssl" - "/certs/dovecot." - "pem -keyout " - "/etc/ssl/private/dovecot.pem" - .format(hostname=EEVariables.ee_fqdn, - email=EEVariables.ee_email)) - except CommandExecutionError as e: - self.log.error(self, "Unable to generate PEM key for dovecot") - self.log.debug(self, "Setting Privileges to " - "/etc/ssl/private/dovecot.pem file ") - EEFileUtils.chmod(self, "/etc/ssl/private/dovecot.pem", 0o600) - - # Custom Dovecot configuration by EasyEngine - data = dict() - self.log.debug(self, "Writting configuration into file" - "/etc/dovecot/conf.d/auth-sql.conf.ext ") - ee_dovecot = open('/etc/dovecot/conf.d/auth-sql.conf.ext', - encoding='utf-8', mode='w') - app.render((data), 'auth-sql-conf.mustache', - out=ee_dovecot) - ee_dovecot.close() - - data = dict(email=EEVariables.ee_email) - self.log.debug(self, "Writting configuration into file" - "/etc/dovecot/conf.d/99-ee.conf ") - ee_dovecot = open('/etc/dovecot/conf.d/99-ee.conf', - encoding='utf-8', mode='w') - app.render((data), 'dovecot.mustache', out=ee_dovecot) - ee_dovecot.close() - try: - EEShellExec.cmd_exec(self, "sed -i \"s/\\!include " - "auth-system.conf.ext/#\\!include " - "auth-system.conf.ext/\" " - "/etc/dovecot/conf.d/10-auth.conf") - - EEShellExec.cmd_exec(self, "sed -i \"s\'/etc/dovecot/" - "dovecot.pem\'/etc/ssl/certs/" - "dovecot.pem" - "\'\" /etc/dovecot/conf.d/" - "10-ssl.conf") - EEShellExec.cmd_exec(self, "sed -i \"s\'/etc/dovecot/" - "private/dovecot.pem\'/etc/ssl/" - "private" - "/dovecot.pem\'\" /etc/dovecot/" - "conf.d/" - "10-ssl.conf") - - # Custom Postfix configuration needed with Dovecot - # Changes in master.cf - # TODO: Find alternative for sed in Python - EEShellExec.cmd_exec(self, "sed -i \'s/#submission/" - "submission/\'" - " /etc/postfix/master.cf") - EEShellExec.cmd_exec(self, "sed -i \'s/#smtps/smtps/\'" - " /etc/postfix/master.cf") - - EEShellExec.cmd_exec(self, "postconf -e \"smtpd_sasl_type " - "= dovecot\"") - EEShellExec.cmd_exec(self, "postconf -e \"smtpd_sasl_path " - "= private/auth\"") - EEShellExec.cmd_exec(self, "postconf -e \"" - "smtpd_sasl_auth_enable = " - "yes\"") - EEShellExec.cmd_exec(self, "postconf -e \"" - " smtpd_relay_restrictions =" - " permit_sasl_authenticated, " - " permit_mynetworks, " - " reject_unauth_destination\"") - - EEShellExec.cmd_exec(self, "postconf -e \"" - "smtpd_tls_mandatory_" - "protocols = !SSLv2,!SSLv3\"") - EEShellExec.cmd_exec(self, "postconf -e \"smtp_tls_" - "mandatory_protocols = !SSLv2," - "!SSLv3\"") - EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls" - "_protocols = !SSLv2,!SSLv3\"") - EEShellExec.cmd_exec(self, "postconf -e \"smtp_tls" - "_protocols = !SSLv2,!SSLv3\"") - EEShellExec.cmd_exec(self, "postconf -e \"mydestination " - "= localhost\"") - EEShellExec.cmd_exec(self, "postconf -e \"virtual" - "_transport " - "= lmtp:unix:private/dovecot-lmtp\"") - EEShellExec.cmd_exec(self, "postconf -e \"virtual_uid_" - "maps = static:5000\"") - EEShellExec.cmd_exec(self, "postconf -e \"virtual_gid_" - "maps = static:5000\"") - EEShellExec.cmd_exec(self, "postconf -e \"" - " virtual_mailbox_domains = " - "mysql:/etc/postfix/mysql/virtual_" - "domains_maps.cf\"") - EEShellExec.cmd_exec(self, "postconf -e \"virtual_mailbox" - "_maps" - " = mysql:/etc/postfix/mysql/virtual_" - "mailbox_maps.cf\"") - EEShellExec.cmd_exec(self, "postconf -e \"virtual_alias" - "_maps " - "= mysql:/etc/postfix/mysql/virtual_" - "alias_maps.cf\"") - EEShellExec.cmd_exec(self, "openssl req -new -x509 -days " - " 3650 -nodes -subj /commonName=" - "{hostname}/emailAddress={email}" - " -out /etc/ssl/certs/postfix.pem" - " -keyout /etc/ssl/private/" - "postfix.pem" - .format(hostname=EEVariables.ee_fqdn, - email=EEVariables.ee_email)) - EEShellExec.cmd_exec(self, "chmod 0600 /etc/ssl/private" - "/postfix.pem") - EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls_cert_" - "file = /etc/ssl/certs/postfix.pem\"") - EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls_key_" - "file = /etc/ssl/private/" - "postfix.pem\"") - - except CommandExecutionError as e: - self.log.error(self, "Failed to update Dovecot configuration") - - # Sieve configuration - if not os.path.exists('/var/lib/dovecot/sieve/'): - self.log.debug(self, 'Creating directory ' - '/var/lib/dovecot/sieve/ ') - os.makedirs('/var/lib/dovecot/sieve/') - - # Custom sieve configuration by EasyEngine - data = dict() - self.log.debug(self, "Writting configuration of EasyEngine into " - "file /var/lib/dovecot/sieve/default.sieve") - ee_sieve = open('/var/lib/dovecot/sieve/default.sieve', - encoding='utf-8', mode='w') - app.render((data), 'default-sieve.mustache', - out=ee_sieve) - ee_sieve.close() - - # Compile sieve rules - self.log.debug(self, "Setting Privileges to dovecot ") - # EEShellExec.cmd_exec(self, "chown -R vmail:vmail /var/lib" - # "/dovecot") - EEFileUtils.chown(self, "/var/lib/dovecot", 'vmail', 'vmail', - recursive=True) - try: - EEShellExec.cmd_exec(self, "sievec /var/lib/dovecot/" - "/sieve/default.sieve") - except CommandExecutionError as e: - raise SiteError("Failed to compile default.sieve") - - EEGit.add(self, ["/etc/postfix", "/etc/dovecot"], - msg="Installed mail server") - EEService.restart_service(self, 'dovecot') - EEService.reload_service(self, 'postfix') - - def install_stack(self): - """ - Install MAIL stack - """ - self.log.info("Installing MAIL stack, please wait...") - self._pre_install_stack() - super(EEMailStack, self).install_stack() - self._post_install_stack() - EEWebmailAdmin(self).install_stack() - - def remove_stack(self): - """ - Remove MAIL stack - """ - self.log.info("Removing MAIL stack, please wait...") - super(EEMailStack, self).remove_stack() - - def purge_stack(self): - self.log.info("Purging MAIL stack, please wait...") - super(EEMailStack, self).purge_stack() - EEWebmailAdmin(self).purge_stack() - - -import string -import shutil -from ee.core.download import EEDownload -from ee.core.extract import EEExtract -from ee.core.mysql import EEMysql - -class EEWebmailAdmin (EEStack): - """ - EasyEngine Web Mail stack - VimbAdmin + Roundcube - """ - packages_name = { - 'Vimbadmin': "https://github.com/opensolutions/ViMbAdmin/archive/{0}.tar.gz".format(EEVariables.ee_vimbadmin), - 'Roundcube': "https://github.com/roundcube/roundcubemail/releases/download/{0}/roundcubemail-{0}.tar.gz".format(EEVariables.ee_roundcube) - } - app = app - log = app.log - - def __init__(self, package_name=None, package_url=None): - """ - Initialize packages list in stack - pkgs_name : list of packages to be intialized for operations - in stack - package_url : list of urls from where packages to be fetched - """ - - self.packages_name = self._get_stack() - - super(EEWebmailAdmin, self).__init__(self.packages_name) - - def _get_stack(self): - return EEWebmailAdmin.packages_name - - def _get_package_url(self, package_name): - return self.packages_name[package_name] - - def _get_package_path(self, package): - return "/tmp/{0}.tar.gz".format(package) - - def _pre_install(self): - """ - """ - for pkg in self.packages_name: - print([self._get_package_url(pkg), '/tmp/{0}.tar.gz'.format(pkg), pkg]) - print() - EEDownload.download(self, [[self._get_package_url(pkg), '/tmp/{0}.tar.gz'.format(pkg), pkg]]) - - def _post_install(self): - """ - """ - pass - - def _install_vimbadmin(self): + def _install_vimbadmin(self, file_path): """ """ self.log.debug(self, "Extracting ViMbAdmin.tar.gz to " - "location /tmp/") - EEExtract.extract(self, self._get_package_path('Vimbadmin'), '/tmp/') + "location {0}".format(EEVariables.ee_downloads)) + EEExtract.extract(self, file_path, EEVariables.ee_downloads) if not os.path.exists('{0}22222/htdocs/' .format(EEVariables.ee_webroot)): self.log.debug(self, "Creating directory " @@ -341,8 +109,8 @@ class EEWebmailAdmin (EEStack): .format(EEVariables.ee_webroot)) os.makedirs('{0}22222/htdocs/' .format(EEVariables.ee_webroot)) - shutil.move('/tmp/ViMbAdmin-{0}/' - .format(EEVariables.ee_vimbadmin), + shutil.move('{0}ViMbAdmin-{1}/' + .format(EEVariables.ee_downloads, EEVariables.ee_vimbadmin), '{0}22222/htdocs/vimbadmin/' .format(EEVariables.ee_webroot)) @@ -471,14 +239,14 @@ class EEWebmailAdmin (EEStack): print("Vimbadmin Security Salt : "+ vm_salt) - def _install_roundcube(self): + def _install_roundcube(self, file_path): """ Install and configure roundcube for mailstack """ # Extract RoundCubemail - self.log.debug(self, "Extracting file /tmp/roundcube.tar.gz " - "to location /tmp/ ") - EEExtract.extract(self, self._get_package_path('Roundcube'), '/tmp/') + self.log.debug(self, "Extracting file {0}roundcube.tar.gz " + "to location {0} ".format(EEVariables.ee_downloads)) + EEExtract.extract(self, file_path, EEVariables.ee_downloads) if not os.path.exists('{0}roundcubemail' .format(EEVariables.ee_webroot)): self.log.debug(self, "Creating new directory " @@ -486,8 +254,8 @@ class EEWebmailAdmin (EEStack): .format(EEVariables.ee_webroot)) os.makedirs('{0}roundcubemail/' .format(EEVariables.ee_webroot)) - shutil.move('/tmp/roundcubemail-{0}/' - .format(EEVariables.ee_roundcube), + shutil.move('{0}roundcubemail-{1}/' + .format(EEVariables.ee_downloads, EEVariables.ee_roundcube), '{0}roundcubemail/htdocs' .format(EEVariables.ee_webroot)) @@ -563,23 +331,262 @@ class EEWebmailAdmin (EEStack): ee_rc.close() - def install_stack(self): + def _remove_vimbadmin(self): """ + Remove Vimbadmin Stack """ - self._pre_install() - self._install_vimbadmin() - self._install_roundcube() + self.log.info("Removing Vimbadmin, please wait...") + # Remove Vimbadmin database + if EEShellExec.cmd_exec(self, "mysqladmin ping"): + EEMysql.execute(self, "drop database IF EXISTS vimbadmin") - def purge_stack(self): + # Remove Vimbadmin + if EEFileUtils.isexist(self, "{0}22222/htdocs/vimbadmin" + .format(EEVariables.ee_webroot)): + EEFileUtils.remove(self, ["{0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)]) + + def _remove_roundcube(self): """ + Remove Roundcube Stack """ - print("Inside webmailstack purge .....") + + self.log.info("Removing Roundcube, please wait...") + # Remove Roundcube database if EEShellExec.cmd_exec(self, "mysqladmin ping"): - EEMysql.execute(self, "drop database IF EXISTS vimbadmin") EEMysql.execute(self, "drop database IF EXISTS roundcubemail") - if EEFileUtils.isexist(self, "{0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)): - print("Removing : {0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)) - EEFileUtils.remove(self, "{0}22222/htdocs/vimbadmin".format(EEVariables.ee_webroot)) + + # Remove Roundcube files if EEFileUtils.isexist(self, "{0}roundcubemail".format(EEVariables.ee_webroot)): - print("Removing: {0}roundcubemail".format(EEVariables.ee_webroot)) - EEFileUtils.remove(self, "{0}roundcubemail".format(EEVariables.ee_webroot)) \ No newline at end of file + EEFileUtils.remove(self, ["{0}roundcubemail".format(EEVariables.ee_webroot)]) + + + def _pre_install_stack(self): + """ + Defines pre-install activities done before installing mail stack + """ + # Add mail repository + + self._requirement_check() + self._add_repo() + + self.log.debug(self, 'Executing the command debconf-set-selections.') + try: + EEShellExec.cmd_exec(self, "echo \"dovecot-core dovecot-core/" + "create-ssl-cert boolean yes\" " + "| debconf-set-selections") + EEShellExec.cmd_exec(self, "echo \"dovecot-core dovecot-core" + "/ssl-cert-name string $(hostname -f)\"" + " | debconf-set-selections") + except CommandExecutionError as e: + self.log.error("Failed to initialize dovecot packages") + + def _post_install_stack(self): + """ + Defines activities done after installing mail stack + """ + self.log.debug(self, "Adding user") + try: + EEShellExec.cmd_exec(self, "adduser --uid 5000 --home /var" + "/vmail --disabled-password --gecos " + "'' vmail") + except CommandExecutionError as e: + self.log.error(self, "Unable to add vmail user for mail server") + try: + EEShellExec.cmd_exec(self, "openssl req -new -x509 -days" + " 3650 " + "-nodes -subj /commonName={hostname}" + "/emailAddress={email} -out /etc/ssl" + "/certs/dovecot." + "pem -keyout " + "/etc/ssl/private/dovecot.pem" + .format(hostname=EEVariables.ee_fqdn, + email=EEVariables.ee_email)) + except CommandExecutionError as e: + self.log.error(self, "Unable to generate PEM key for dovecot") + self.log.debug(self, "Setting Privileges to " + "/etc/ssl/private/dovecot.pem file ") + EEFileUtils.chmod(self, "/etc/ssl/private/dovecot.pem", 0o600) + + # Custom Dovecot configuration by EasyEngine + data = dict() + self.log.debug(self, "Writting configuration into file" + "/etc/dovecot/conf.d/auth-sql.conf.ext ") + ee_dovecot = open('/etc/dovecot/conf.d/auth-sql.conf.ext', + encoding='utf-8', mode='w') + app.render((data), 'auth-sql-conf.mustache', + out=ee_dovecot) + ee_dovecot.close() + + data = dict(email=EEVariables.ee_email) + self.log.debug(self, "Writting configuration into file" + "/etc/dovecot/conf.d/99-ee.conf ") + ee_dovecot = open('/etc/dovecot/conf.d/99-ee.conf', + encoding='utf-8', mode='w') + app.render((data), 'dovecot.mustache', out=ee_dovecot) + ee_dovecot.close() + try: + EEShellExec.cmd_exec(self, "sed -i \"s/\\!include " + "auth-system.conf.ext/#\\!include " + "auth-system.conf.ext/\" " + "/etc/dovecot/conf.d/10-auth.conf") + + EEShellExec.cmd_exec(self, "sed -i \"s\'/etc/dovecot/" + "dovecot.pem\'/etc/ssl/certs/" + "dovecot.pem" + "\'\" /etc/dovecot/conf.d/" + "10-ssl.conf") + EEShellExec.cmd_exec(self, "sed -i \"s\'/etc/dovecot/" + "private/dovecot.pem\'/etc/ssl/" + "private" + "/dovecot.pem\'\" /etc/dovecot/" + "conf.d/" + "10-ssl.conf") + + # Custom Postfix configuration needed with Dovecot + # Changes in master.cf + # TODO: Find alternative for sed in Python + EEShellExec.cmd_exec(self, "sed -i \'s/#submission/" + "submission/\'" + " /etc/postfix/master.cf") + EEShellExec.cmd_exec(self, "sed -i \'s/#smtps/smtps/\'" + " /etc/postfix/master.cf") + + EEShellExec.cmd_exec(self, "postconf -e \"smtpd_sasl_type " + "= dovecot\"") + EEShellExec.cmd_exec(self, "postconf -e \"smtpd_sasl_path " + "= private/auth\"") + EEShellExec.cmd_exec(self, "postconf -e \"" + "smtpd_sasl_auth_enable = " + "yes\"") + EEShellExec.cmd_exec(self, "postconf -e \"" + " smtpd_relay_restrictions =" + " permit_sasl_authenticated, " + " permit_mynetworks, " + " reject_unauth_destination\"") + + EEShellExec.cmd_exec(self, "postconf -e \"" + "smtpd_tls_mandatory_" + "protocols = !SSLv2,!SSLv3\"") + EEShellExec.cmd_exec(self, "postconf -e \"smtp_tls_" + "mandatory_protocols = !SSLv2," + "!SSLv3\"") + EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls" + "_protocols = !SSLv2,!SSLv3\"") + EEShellExec.cmd_exec(self, "postconf -e \"smtp_tls" + "_protocols = !SSLv2,!SSLv3\"") + EEShellExec.cmd_exec(self, "postconf -e \"mydestination " + "= localhost\"") + EEShellExec.cmd_exec(self, "postconf -e \"virtual" + "_transport " + "= lmtp:unix:private/dovecot-lmtp\"") + EEShellExec.cmd_exec(self, "postconf -e \"virtual_uid_" + "maps = static:5000\"") + EEShellExec.cmd_exec(self, "postconf -e \"virtual_gid_" + "maps = static:5000\"") + EEShellExec.cmd_exec(self, "postconf -e \"" + " virtual_mailbox_domains = " + "mysql:/etc/postfix/mysql/virtual_" + "domains_maps.cf\"") + EEShellExec.cmd_exec(self, "postconf -e \"virtual_mailbox" + "_maps" + " = mysql:/etc/postfix/mysql/virtual_" + "mailbox_maps.cf\"") + EEShellExec.cmd_exec(self, "postconf -e \"virtual_alias" + "_maps " + "= mysql:/etc/postfix/mysql/virtual_" + "alias_maps.cf\"") + EEShellExec.cmd_exec(self, "openssl req -new -x509 -days " + " 3650 -nodes -subj /commonName=" + "{hostname}/emailAddress={email}" + " -out /etc/ssl/certs/postfix.pem" + " -keyout /etc/ssl/private/" + "postfix.pem" + .format(hostname=EEVariables.ee_fqdn, + email=EEVariables.ee_email)) + EEShellExec.cmd_exec(self, "chmod 0600 /etc/ssl/private" + "/postfix.pem") + EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls_cert_" + "file = /etc/ssl/certs/postfix.pem\"") + EEShellExec.cmd_exec(self, "postconf -e \"smtpd_tls_key_" + "file = /etc/ssl/private/" + "postfix.pem\"") + + except CommandExecutionError as e: + self.log.error(self, "Failed to update Dovecot configuration") + + # Sieve configuration + if not os.path.exists('/var/lib/dovecot/sieve/'): + self.log.debug(self, 'Creating directory ' + '/var/lib/dovecot/sieve/ ') + os.makedirs('/var/lib/dovecot/sieve/') + + # Custom sieve configuration by EasyEngine + data = dict() + self.log.debug(self, "Writting configuration of EasyEngine into " + "file /var/lib/dovecot/sieve/default.sieve") + ee_sieve = open('/var/lib/dovecot/sieve/default.sieve', + encoding='utf-8', mode='w') + app.render((data), 'default-sieve.mustache', + out=ee_sieve) + ee_sieve.close() + + # Compile sieve rules + self.log.debug(self, "Setting Privileges to dovecot ") + # EEShellExec.cmd_exec(self, "chown -R vmail:vmail /var/lib" + # "/dovecot") + EEFileUtils.chown(self, "/var/lib/dovecot", 'vmail', 'vmail', + recursive=True) + try: + EEShellExec.cmd_exec(self, "sievec /var/lib/dovecot/" + "/sieve/default.sieve") + except CommandExecutionError as e: + raise SiteError("Failed to compile default.sieve") + + EEGit.add(self, ["/etc/postfix", "/etc/dovecot"], + msg="Installed mail server") + EEService.restart_service(self, 'dovecot') + EEService.reload_service(self, 'postfix') + + def install_stack(self): + """ + Install MAIL stack + """ + self.log.info("Installing MAIL stack, please wait...") + self._set_stack() + self._pre_install_stack() + + if self.apt_packages: + super(EEMailStack, self).install_stack() + self._post_install_stack() + + if self.manual_packages: + for key in self.manual_packages.keys(): + path = EEDownload(('%s' %key), self.manual_packages[key]).download() + print("Evaluating function %s..." %key) + print("self._install_{0}(self, '{1}')".format(key, path)) + eval("self._install_{0}('{1}')".format(key, path)) + + def remove_stack(self): + """ + Remove MAIL stack + """ + self.log.info("Removing MAIL stack, please wait...") + self._set_stack() + if self.apt_packages: + super(EEMailStack, self).remove_stack() + if self.manual_packages: + for key in self.manual_packages.keys(): + print("Evaluating function %s..." %key) + print("self._remove_{0}(self)".format(key)) + eval("self._remove_{0}()".format(key)) + + def purge_stack(self): + self.log.info("Purging MAIL stack, please wait...") + self._set_stack() + if self.apt_packages: + super(EEMailStack, self).purge_stack() + if self.manual_packages: + for key in self.manual_packages.keys(): + print("Evaluating function %s..." %key) + print("self._remove_{0}(self)".format(key)) + eval("self._remove_{0}()".format(key)) diff --git a/ee/cli/plugins/mysqlstack.py b/ee/cli/plugins/mysqlstack.py index f5000faf..533e0a4c 100644 --- a/ee/cli/plugins/mysqlstack.py +++ b/ee/cli/plugins/mysqlstack.py @@ -1,11 +1,15 @@ import os import sys import random +import shutil import string import configparser from ee.core.variables import EEVariables from ee.core.aptget import EEAptGet from ee.core.apt_repo import EERepo +from ee.core.fileutils import EEFileUtils +from ee.core.git import EEGit +from ee.core.services import EEService from ee.cli.plugins.eestack import EEStack from ee.core.shellexec import EEShellExec from ee.core.shellexec import CommandExecutionError @@ -18,7 +22,7 @@ class EEMysqlStack(EEStack): """ EasyEngine MYSQL stack """ - packages_name = ["mariadb-server", "percona-toolkit"] + packages_name = EEVariables.ee_mysql app = app log = app.log @@ -50,23 +54,29 @@ class EEMysqlStack(EEStack): if EEVariables.ee_platform_codename != 'jessie': EERepo.add(self, repo_url=EEVariables.ee_mysql_repo) self.log.debug('Adding key for {0}' - .format(EEVariables.ee_mysql_repo)) + .format(EEVariables.ee_mysql_repo)) EERepo.add_key(self, '0xcbcb082a1bb943db', keyserver="keyserver.ubuntu.com") EEAptGet.update(self) - def setup_mysqltuner(self): + def _setup_mysqltuner(self): """ - + This function sets up mysqltuner """ - EEDownload.download(self, [["https://raw.githubusercontent.com/" - "major/MySQLTuner-perl" - "/master/mysqltuner.pl", - "/usr/bin/mysqltuner", "MySQLTuner"]]) + self.log.info("setting up mysqltuner, please wait...") + path = EEDownload('mysqltuner', url="https://raw.githubusercontent.com/" + "major/MySQLTuner-perl/master/mysqltuner.pl").download() + + shutil.move(path, "/usr/bin/mysqltuner") # Set MySQLTuner permission EEFileUtils.chmod(self, "/usr/bin/mysqltuner", 0o775) - + def _remove_mysqltuner(self): + """ + Remove mysqltuner + """ + self.log.info("Removing mysqltuner, please wait...") + EEFileUtils.remove(self, ['/usr/bin/mysqltuner']) def _pre_install_stack(self): """ @@ -122,7 +132,7 @@ class EEMysqlStack(EEStack): """ Defines activities done after installing mysql stack """ - self.setup_mysqltuner() + self._setup_mysqltuner() if not os.path.isfile("/etc/mysql/my.cnf"): config = ("[mysqld]\nwait_timeout = 30\n" "interactive_timeout=60\nperformance_schema = 0" @@ -149,10 +159,11 @@ class EEMysqlStack(EEStack): """ Install MYSQL stack """ - self.log.info("Installing MySQL stack, please wait...") - self._pre_install_stack() - super(EEMysqlStack, self).install_stack() - self._post_install_stack() + if not self.is_installed(): + self.log.info("Installing MySQL stack, please wait...") + self._pre_install_stack() + super(EEMysqlStack, self).install_stack() + self._post_install_stack() def remove_stack(self): """ @@ -164,8 +175,9 @@ class EEMysqlStack(EEStack): def purge_stack(self): self.log.info("Purging MySQL stack, please wait...") super(EEMysqlStack, self).purge_stack() + self.remove_mysqltuner() def is_installed(self): - self.log.info("Checking if mysql is installed") + self.log.info("checking if mysql is installed") return EEShellExec.cmd_exec(self, "mysqladmin ping") diff --git a/ee/cli/plugins/nginxstack.py b/ee/cli/plugins/nginxstack.py index df693340..bc48f6e2 100644 --- a/ee/cli/plugins/nginxstack.py +++ b/ee/cli/plugins/nginxstack.py @@ -33,7 +33,11 @@ class EENginxStack(EEStack): in stack """ - self.packages_name = self._get_stack() + self.packages_name = self._get_stack() + self.http_auth_user = 'easyengine' + self.http_auth_pass = (''.join([random.choice + (string.ascii_letters + string.digits) + for n in range(6)])) super(EENginxStack, self).__init__(self.packages_name) def _get_stack(self): @@ -63,6 +67,8 @@ class EENginxStack(EEStack): """ Defines activities done after installing nginx stack """ + self.log.debug("Running post install, please wait...") + if ((not EEShellExec.cmd_exec(self, "grep -q -Hr EasyEngine " "/etc/nginx")) and os.path.isfile('/etc/nginx/nginx.conf')): nc = NginxConfig() @@ -251,16 +257,14 @@ class EENginxStack(EEStack): out=ee_nginx) ee_nginx.close() - passwd = ''.join([random.choice - (string.ascii_letters + string.digits) - for n in range(6)]) try: - EEShellExec.cmd_exec(self, "printf \"easyengine:" + EEShellExec.cmd_exec(self, "printf \"{user}:" "$(openssl passwd -crypt " "{password} 2> /dev/null)\n\"" "> /etc/nginx/htpasswd-ee " "2>/dev/null" - .format(password=passwd)) + .format(user=self.http_auth_user, + password=self.http_auth_pass)) except CommandExecutionError as e: self.log.error(self, "Failed to save HTTP Auth") @@ -339,6 +343,8 @@ class EENginxStack(EEStack): EEGit.add(self, ["/etc/nginx"], msg="Adding Nginx into Git") EEService.reload_service(self, 'nginx') + + # self.msg = (self.msg + ["HTTP Auth User Name: easyengine"] # + ["HTTP Auth Password : {0}".format(passwd)]) @@ -347,10 +353,13 @@ class EENginxStack(EEStack): """ Install NGINX stack """ - self.log.info("Installing NGINX stack, please wait...") - self._pre_install_stack() - super(EENginxStack, self).install_stack() - self._post_install_stack() + if not self.is_installed(): + self.log.info("Installing NGINX stack, please wait...") + self._pre_install_stack() + super(EENginxStack, self).install_stack() + self._post_install_stack() + return (self.http_auth_user, self.http_auth_pass) + def remove_stack(self): """ diff --git a/ee/cli/plugins/phpstack.py b/ee/cli/plugins/phpstack.py index cfacb9e5..5adcc8be 100644 --- a/ee/cli/plugins/phpstack.py +++ b/ee/cli/plugins/phpstack.py @@ -211,10 +211,11 @@ class EEPhpStack(EEStack): """ Install PHP stack """ - self.log.info("Installing PHP stack, please wait...") - self._pre_install_stack() - super(EEPhpStack, self).install_stack() - self._post_install_stack() + if not self.is_installed(): + self.log.info("Installing PHP stack, please wait...") + self._pre_install_stack() + super(EEPhpStack, self).install_stack() + self._post_install_stack() def remove_stack(self): """ diff --git a/ee/cli/plugins/postfixstack.py b/ee/cli/plugins/postfixstack.py index 451f6e7d..9c79a589 100644 --- a/ee/cli/plugins/postfixstack.py +++ b/ee/cli/plugins/postfixstack.py @@ -15,6 +15,7 @@ class EEPostfixStack(EEStack): EasyEngine Postfix stack """ packages_name = EEVariables.ee_postfix + app = app log = app.log def __init__(self, packages_name=None): diff --git a/ee/cli/plugins/stack.py b/ee/cli/plugins/stack.py index 60bfa9c9..69e2fadd 100644 --- a/ee/cli/plugins/stack.py +++ b/ee/cli/plugins/stack.py @@ -2,7 +2,6 @@ from cement.core.controller import CementBaseController, expose from cement.core import handler, hook -from ee.core.variables import EEVariables from ee.core.aptget import EEAptGet from ee.core.download import EEDownload from ee.core.shellexec import EEShellExec @@ -15,7 +14,6 @@ from ee.core.git import EEGit from ee.core.checkfqdn import check_fqdn from pynginxconfig import NginxConfig from ee.core.services import EEService -from ee.core.variables import EEVariables import random import string import configparser @@ -29,6 +27,15 @@ import platform from ee.cli.plugins.stack_services import EEStackStatusController from ee.cli.plugins.stack_migrate import EEStackMigrateController from ee.cli.plugins.stack_upgrade import EEStackUpgradeController +from ee.cli.plugins.nginxstack import EENginxStack +from ee.cli.plugins.phpstack import EEPhpStack +from ee.cli.plugins.mysqlstack import EEMysqlStack +from ee.cli.plugins.hhvmstack import EEHhvmStack +from ee.cli.plugins.adminstack import EEAdminStack +from ee.cli.plugins.postfixstack import EEPostfixStack +from ee.cli.plugins.mailstack import EEMailStack +from ee.cli.plugins.mailscannerstack import EEMailScannerStack +from ee.core.variables import EEVariables from ee.core.logging import Log def ee_stack_hook(app): @@ -77,249 +84,84 @@ class EEStackController(CementBaseController): @expose(hide=True) def default(self): """default action of ee stack command""" - from ee.cli.plugins.mailstack import EEMailStack - EEMailStack(self).install_stack() + from ee.cli.plugins.adminstack import EEAdminStack + EEAdminStack(package_dict=EEVariables.ee_admin).install_stack() self.app.args.print_help() - EEMailStack(self).purged_stack() + #EEAdminStack(self).purge_stack() @expose(help="Install packages") def install(self, packages=[], apt_packages=[], disp_msg=True): """Start installation of packages""" self.msg = [] - try: - # Default action for stack installation - if ((not self.app.pargs.web) and (not self.app.pargs.admin) and - (not self.app.pargs.mail) and (not self.app.pargs.nginx) and - (not self.app.pargs.php) and (not self.app.pargs.mysql) and - (not self.app.pargs.postfix) and (not self.app.pargs.wpcli) and - (not self.app.pargs.phpmyadmin) and (not self.app.pargs.hhvm) - and - (not self.app.pargs.adminer) and (not self.app.pargs.utils) and - (not self.app.pargs.mailscanner) and (not self.app.pargs.all)): - self.app.pargs.web = True - self.app.pargs.admin = True - - if self.app.pargs.all: - self.app.pargs.web = True - self.app.pargs.admin = True - self.app.pargs.mail = True - - if self.app.pargs.web: - 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 - self.app.pargs.hhvm = 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'): - check_fqdn(self, - os.popen("hostname -f | tr -d '\n'").read()) - Log.debug(self, "Setting apt_packages variable for mail") - apt_packages = apt_packages + EEVariables.ee_mail - packages = packages + [["https://github.com/opensolutions/" - "ViMbAdmin/archive/{0}.tar.gz" - .format(EEVariables.ee_vimbadmin), - "/tmp/vimbadmin.tar.gz", - "ViMbAdmin"], - ["https://github.com/roundcube/" - "roundcubemail/releases/download/" - "{0}/roundcubemail-{0}.tar.gz" - .format(EEVariables.ee_roundcube), - "/tmp/roundcube.tar.gz", - "Roundcube"]] - - if EEVariables.ee_ram > 1024: - self.app.pargs.mailscanner = True - else: - Log.info(self, "System RAM is less than 1GB\nMail " - "scanner packages are not going to install" - " automatically") - else: - Log.info(self, "Mail server is already installed") - - if self.app.pargs.nginx: - Log.debug(self, "Setting apt_packages variable for Nginx") - - if EEVariables.ee_platform_distro == 'debian': - check_nginx = 'nginx-extras' - else: - check_nginx = 'nginx-custom' - - if not EEAptGet.is_installed(self, check_nginx): - apt_packages = apt_packages + EEVariables.ee_nginx - else: - Log.debug(self, "Nginx already installed") - Log.info(self, "Nginx already 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.debug(self, "PHP already installed") - Log.info(self, "PHP already installed") - - if self.app.pargs.hhvm: - Log.debug(self, "Setting apt packages variable for HHVM") - if platform.architecture()[0] is '32bit': - Log.error(self, "HHVM is not supported by 32bit system") - if not EEAptGet.is_installed(self, 'hhvm'): - apt_packages = apt_packages + EEVariables.ee_hhvm - else: - Log.debug(self, "HHVM already installed") - Log.info(self, "HHVM already 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 - packages = packages + [["https://raw." - "githubusercontent.com/" - "major/MySQLTuner-perl" - "/master/mysqltuner.pl", - "/usr/bin/mysqltuner", - "MySQLTuner"]] - - else: - Log.debug(self, "MySQL connection is already alive") - Log.info(self, "MySQL connection is already 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.debug(self, "Postfix is already installed") - Log.info(self, "Postfix is already installed") - if self.app.pargs.wpcli: - Log.debug(self, "Setting packages variable for WP-CLI") - if not EEShellExec.cmd_exec(self, "which wp"): - packages = packages + [["https://github.com/wp-cli/wp-cli/" - "releases/download/v{0}/" - "wp-cli-{0}.phar" - "".format(EEVariables.ee_wp_cli), - "/usr/bin/wp", - "WP-CLI"]] - else: - Log.debug(self, "WP-CLI is already installed") - Log.info(self, "WP-CLI is already 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-{0}.php" - "".format(EEVariables.ee_adminer), - "{0}22222/" - "htdocs/db/adminer/index.php" - .format(EEVariables.ee_webroot), - "Adminer"]] - - if self.app.pargs.mailscanner: - if not EEAptGet.is_installed(self, 'amavisd-new'): - if (EEAptGet.is_installed(self, 'dovecot-core') or - self.app.pargs.mail): - apt_packages = (apt_packages + - EEVariables.ee_mailscanner) - else: - Log.error(self, "Failed to find installed Dovecot") - else: - Log.error(self, "Mail scanner already 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", - "{0}22222/htdocs/cache/" - "nginx/clean.php" - .format(EEVariables.ee_webroot), - "clean.php"], - ["https://raw.github.com/rlerdorf/" - "opcache-status/master/opcache.php", - "{0}22222/htdocs/cache/" - "opcache/opcache.php" - .format(EEVariables.ee_webroot), - "opcache.php"], - ["https://raw.github.com/amnuts/" - "opcache-gui/master/index.php", - "{0}22222/htdocs/" - "cache/opcache/opgui.php" - .format(EEVariables.ee_webroot), - "Opgui"], - ["https://gist.github.com/ck-on/4959032" - "/raw/0b871b345fd6cfcd6d2be030c1f33d1" - "ad6a475cb/ocp.php", - "{0}22222/htdocs/cache/" - "opcache/ocp.php" - .format(EEVariables.ee_webroot), - "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-advisor"], - ["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.info(self, "Updating apt-cache, please wait...") - EEAptGet.update(self) - Log.info(self, "Installing packages, please wait...") - EEAptGet.install(self, apt_packages) - if len(packages): - Log.debug(self, "Downloading following: {0}".format(packages)) - EEDownload.download(self, packages) - Log.debug(self, "Calling post_pref") - self.post_pref(apt_packages, packages) - if disp_msg: - if len(self.msg): - for msg in self.msg: - Log.info(self, Log.ENDC + msg) - Log.info(self, "Successfully installed packages") - else: - return self.msg + + # Default action for stack installation + if ((not self.app.pargs.web) and (not self.app.pargs.admin) and + (not self.app.pargs.mail) and (not self.app.pargs.nginx) and + (not self.app.pargs.php) and (not self.app.pargs.mysql) and + (not self.app.pargs.postfix) and (not self.app.pargs.wpcli) and + (not self.app.pargs.phpmyadmin) and (not self.app.pargs.hhvm) + and + (not self.app.pargs.adminer) and (not self.app.pargs.utils) and + (not self.app.pargs.mailscanner) and (not self.app.pargs.all)): + self.app.pargs.web = True + self.app.pargs.admin = True + + if self.app.pargs.all: + self.app.pargs.web = True + self.app.pargs.admin = True + self.app.pargs.mail = True + + if self.app.pargs.web: + EEMysqlStack().install_stack() + EENginxStack().install_stack() + EEPhpStack().install_stack() + EEHhvmStack().install_stack() + EEAdminStack(package_dict=EEVariables.ee_wpclistack).install_stack() + EEPostfixStack().install_stack() + + if self.app.pargs.admin: + EEAdminStack(package_dict=EEVariables.ee_admin).install_stack() + + if self.app.pargs.mail: + EEMailStack(package_dict=EEVariables.ee_webmailstack, apt_packages=EEVariables.ee_mail).install_stack() + + if self.app.pargs.nginx: + EENginxStack().install_stack() + + + if self.app.pargs.php: + EEPhpStack().install_stack() + + + if self.app.pargs.hhvm: + EEHhvmStack().install_stack() + + if self.app.pargs.mysql: + EEMysqlStack().install_stack() + + if self.app.pargs.postfix: + EEPostfixStack().install_stack() + + if self.app.pargs.wpcli: + EEAdminStack(package_dict=EEVariables.ee_wpclistack).install_stack() + + if self.app.pargs.phpmyadmin: + EEAdminStack(package_dict=EEVariables.ee_phpmyadminstack).install_stack() + + if self.app.pargs.adminer: + EEAdminStack(package_dict=EEVariables.ee_adminerstack).install_stack() + + if self.app.pargs.mailscanner: + EEMailScannerStack().install_stack() + + if self.app.pargs.utils: + EEAdminStack(package_dict=EEVariables.ee_utils).install_stack() + @expose(help="Remove packages") def remove(self): """Start removal of packages""" - apt_packages = [] - packages = [] # Default action for stack remove if ((not self.app.pargs.web) and (not self.app.pargs.admin) and @@ -338,105 +180,56 @@ class EEStackController(CementBaseController): self.app.pargs.mail = True if self.app.pargs.web: - self.app.pargs.nginx = True - self.app.pargs.php = True - self.app.pargs.hhvm = True - self.app.pargs.mysql = True - self.app.pargs.wpcli = True - self.app.pargs.postfix = True + EEMysqlStack().remove_stack() + EENginxStack().remove_stack() + EEPhpStack().remove_stack() + EEHhvmStack().remove_stack() + EEAdminStack(package_dict=EEVariables.ee_wpclistack).remove_stack() + EEPostfixStack().remove_stack() if self.app.pargs.admin: - self.app.pargs.adminer = True - self.app.pargs.phpmyadmin = True - self.app.pargs.utils = True + EEAdminStack(package_dict=EEVariables.ee_admin).remove_stack() if self.app.pargs.mail: - Log.debug(self, "Removing mail server packages") - apt_packages = apt_packages + EEVariables.ee_mail - apt_packages = apt_packages + EEVariables.ee_mailscanner - packages = packages + ["{0}22222/htdocs/vimbadmin" - .format(EEVariables.ee_webroot), - "{0}roundcubemail" - .format(EEVariables.ee_webroot)] - if EEShellExec.cmd_exec(self, "mysqladmin ping"): - EEMysql.execute(self, "drop database IF EXISTS vimbadmin") - EEMysql.execute(self, "drop database IF EXISTS roundcubemail") - - if self.app.pargs.mailscanner: - apt_packages = (apt_packages + EEVariables.ee_mailscanner) + EEMailStack(package_dict=EEVariables.ee_webmailstack, apt_packages=EEVariables.ee_mail).remove_stack() if self.app.pargs.nginx: - Log.debug(self, "Removing apt_packages variable of Nginx") - apt_packages = apt_packages + EEVariables.ee_nginx + EENginxStack().remove_stack() + + if self.app.pargs.php: - Log.debug(self, "Removing apt_packages variable of PHP") - apt_packages = apt_packages + EEVariables.ee_php + EEPhpStack().remove_stack() + if self.app.pargs.hhvm: - if EEAptGet.is_installed(self, 'hhvm'): - Log.debug(self, "Removing apt_packages varible of HHVM") - apt_packages = apt_packages + EEVariables.ee_hhvm + EEHhvmStack().remove_stack() if self.app.pargs.mysql: - Log.debug(self, "Removing apt_packages variable of MySQL") - apt_packages = apt_packages + EEVariables.ee_mysql - packages = packages + ['/usr/bin/mysqltuner'] + EEMysqlStack().remove_stack() + if self.app.pargs.postfix: - Log.debug(self, "Removing apt_packages variable of Postfix") - apt_packages = apt_packages + EEVariables.ee_postfix + EEPostfixStack().remove_stack() + if self.app.pargs.wpcli: - Log.debug(self, "Removing package variable of WPCLI ") - packages = packages + ['/usr/bin/wp'] + EEAdminStack(package_dict=EEVariables.ee_wpclistack).remove_stack() + if self.app.pargs.phpmyadmin: - Log.debug(self, "Removing package variable of phpMyAdmin ") - packages = packages + ['{0}22222/htdocs/db/pma' - .format(EEVariables.ee_webroot)] + EEAdminStack(package_dict=EEVariables.ee_phpmyadminstack).remove_stack() + if self.app.pargs.adminer: - Log.debug(self, "Removing package variable of Adminer ") - packages = packages + ['{0}22222/htdocs/db/adminer' - .format(EEVariables.ee_webroot)] + EEAdminStack(package_dict=EEVariables.ee_adminerstack).remove_stack() + + if self.app.pargs.mailscanner: + EEMailScannerStack().remove_stack() + if self.app.pargs.utils: - Log.debug(self, "Removing package variable of utils ") - packages = packages + ['{0}22222/htdocs/php/webgrind/' - .format(EEVariables.ee_webroot), - '{0}22222/htdocs/cache/opcache' - .format(EEVariables.ee_webroot), - '{0}22222/htdocs/cache/nginx/' - 'clean.php'.format(EEVariables.ee_webroot), - '{0}22222/htdocs/cache/memcache' - .format(EEVariables.ee_webroot), - '/usr/bin/pt-query-advisor', - '{0}22222/htdocs/db/anemometer' - .format(EEVariables.ee_webroot)] - ee_prompt = input('Are you sure you to want to' - ' purge from server.' - 'Package configuration will remain' - ' on server after this operation.\n' - 'Any answer other than ' - '"yes" will be stop this' - ' operation : ') - - if len(apt_packages): - if ee_prompt == 'YES' or ee_prompt == 'yes': - Log.debug(self, "Removing apt_packages") - Log.info(self, "Removing packages, please wait...") - EEAptGet.remove(self, apt_packages) - EEAptGet.auto_remove(self) - - if len(packages): - if ee_prompt == 'YES' or ee_prompt == 'yes': - EEFileUtils.remove(self, packages) - EEAptGet.auto_remove(self) - - if ee_prompt == 'YES' or ee_prompt == 'yes': - Log.info(self, "Successfully removed packages") + EEAdminStack(package_dict=EEVariables.ee_utils).remove_stack() + + @expose(help="Purge packages") def purge(self): """Start purging of packages""" - apt_packages = [] - packages = [] - # Default action for stack purge if ((not self.app.pargs.web) and (not self.app.pargs.admin) and (not self.app.pargs.mail) and (not self.app.pargs.nginx) and @@ -454,96 +247,50 @@ class EEStackController(CementBaseController): self.app.pargs.mail = True if self.app.pargs.web: - 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 - self.app.pargs.hhvm = True + EEMysqlStack().purge_stack() + EENginxStack().purge_stack() + EEPhpStack().purge_stack() + EEHhvmStack().purge_stack() + EEAdminStack(package_dict=EEVariables.ee_wpclistack).purge_stack() + EEPostfixStack().purge_stack() if self.app.pargs.admin: - self.app.pargs.adminer = True - self.app.pargs.phpmyadmin = True - self.app.pargs.utils = True + EEAdminStack(package_dict=EEVariables.ee_admin).purge_stack() if self.app.pargs.mail: - Log.debug(self, "Removing mail server packages") - apt_packages = apt_packages + EEVariables.ee_mail - apt_packages = apt_packages + EEVariables.ee_mailscanner - packages = packages + ["{0}22222/htdocs/vimbadmin" - .format(EEVariables.ee_webroot), - "{0}roundcubemail" - .format(EEVariables.ee_webroot)] - if EEShellExec.cmd_exec(self, "mysqladmin ping"): - EEMysql.execute(self, "drop database IF EXISTS vimbadmin") - EEMysql.execute(self, "drop database IF EXISTS roundcubemail") - - if self.app.pargs.mailscanner: - apt_packages = (apt_packages + EEVariables.ee_mailscanner) + EEMailStack(package_dict=EEVariables.ee_webmailstack, apt_packages=EEVariables.ee_mail).purge_stack() if self.app.pargs.nginx: - Log.debug(self, "Purge apt_packages variable of Nginx") - apt_packages = apt_packages + EEVariables.ee_nginx + EENginxStack().purge_stack() + + if self.app.pargs.php: - Log.debug(self, "Purge apt_packages variable PHP") - apt_packages = apt_packages + EEVariables.ee_php + EEPhpStack().purge_stack() + + if self.app.pargs.hhvm: - if EEAptGet.is_installed(self, 'hhvm'): - Log.debug(self, "Removing apt_packages varible of HHVM") - apt_packages = apt_packages + EEVariables.ee_hhvm + EEHhvmStack().purge_stack() + if self.app.pargs.mysql: - Log.debug(self, "Purge apt_packages variable MySQL") - apt_packages = apt_packages + EEVariables.ee_mysql - packages = packages + ['/usr/bin/mysqltuner'] + EEMysqlStack().purge_stack() + if self.app.pargs.postfix: - Log.debug(self, "Purge apt_packages variable PostFix") - apt_packages = apt_packages + EEVariables.ee_postfix + EEPostfixStack().purge_stack() + if self.app.pargs.wpcli: - Log.debug(self, "Purge package variable WPCLI") - packages = packages + ['/usr/bin/wp'] + EEAdminStack(package_dict=EEVariables.ee_wpclistack).purge_stack() + if self.app.pargs.phpmyadmin: - packages = packages + ['{0}22222/htdocs/db/pma'. - format(EEVariables.ee_webroot)] - Log.debug(self, "Purge package variable phpMyAdmin") + EEAdminStack(package_dict=EEVariables.ee_phpmyadminstack).purge_stack() + if self.app.pargs.adminer: - Log.debug(self, "Purge package variable Adminer") - packages = packages + ['{0}22222/htdocs/db/adminer' - .format(EEVariables.ee_webroot)] + EEAdminStack(package_dict=EEVariables.ee_adminerstack).purge_stack() + + if self.app.pargs.mailscanner: + EEMailScannerStack().purge_stack() + if self.app.pargs.utils: - Log.debug(self, "Purge package variable utils") - packages = packages + ['{0}22222/htdocs/php/webgrind/' - .format(EEVariables.ee_webroot), - '{0}22222/htdocs/cache/opcache' - .format(EEVariables.ee_webroot), - '{0}22222/htdocs/cache/nginx/' - 'clean.php'.format(EEVariables.ee_webroot), - '{0}22222/htdocs/cache/memcache' - .format(EEVariables.ee_webroot), - '/usr/bin/pt-query-advisor', - '{0}22222/htdocs/db/anemometer' - .format(EEVariables.ee_webroot) - ] - - ee_prompt = input('Are you sure you to want to purge ' - 'from server ' - 'alongwith their configuration' - ' packages,\nAny answer other than ' - '"yes" will be stop this ' - 'operation :') - - if len(apt_packages): - if ee_prompt == 'YES' or ee_prompt == 'yes': - Log.info(self, "Purging packages, please wait...") - EEAptGet.remove(self, apt_packages, purge=True) - EEAptGet.auto_remove(self) - - if len(packages): - if ee_prompt == 'YES' or ee_prompt == 'yes': - EEFileUtils.remove(self, packages) - EEAptGet.auto_remove(self) - - if ee_prompt == 'YES' or ee_prompt == 'yes': - Log.info(self, "Successfully purged packages") + EEAdminStack(package_dict=EEVariables.ee_utils).purge_stack() def load(app): diff --git a/ee/cli/plugins/update.py b/ee/cli/plugins/update.py index 8680d68e..6b1fe055 100644 --- a/ee/cli/plugins/update.py +++ b/ee/cli/plugins/update.py @@ -24,12 +24,11 @@ class EEUpdateController(CementBaseController): @expose(hide=True) def default(self): filename = "eeupdate" + time.strftime("%Y%m%d-%H%M%S") - EEDownload.download(self, [["http://rt.cx/eeup", - "/tmp/{0}".format(filename), - "update script"]]) + path = EEDownload('EasyEngine update script', url="http://rt.cx/eeup", + out_file=filename).download() try: Log.info(self, "updating EasyEngine, please wait...") - os.system("bash /tmp/{0}".format(filename)) + os.system("bash {0}".format(path)) except OSError as e: Log.debug(self, str(e)) Log.error(self, "EasyEngine update failed !") diff --git a/ee/core/fileutils.py b/ee/core/fileutils.py index 496e1672..9e3c6db2 100644 --- a/ee/core/fileutils.py +++ b/ee/core/fileutils.py @@ -7,10 +7,12 @@ import shutil import pwd import fileinput from ee.core.logging import Log - +from ee.cli.main import app class EEFileUtils(): """Utilities to operate on files""" + app = app + log = app.log def __init__(): pass @@ -18,20 +20,15 @@ class EEFileUtils(): """remove files from given path""" for file in filelist: if os.path.isfile(file): - Log.info(self, "Removing {0:65}".format(file), end=' ') + self.log.info( "Removing {0:65}".format(file)) os.remove(file) - Log.info(self, "{0}".format("[" + Log.ENDC + "Done" + - Log.OKBLUE + "]")) - Log.debug(self, 'file Removed') if os.path.isdir(file): try: - Log.info(self, "Removing {0:65}".format(file), end=' ') + self.log.info( "Removing {0:65}".format(file)) shutil.rmtree(file) - Log.info(self, "{0}".format("[" + Log.ENDC + "Done" + - Log.OKBLUE + "]")) except shutil.Error as e: - Log.debug(self, "{err}".format(err=str(e.reason))) - Log.error(self, 'Unable to Remove file ') + self.log.debug( "{err}".format(err=str(e.reason))) + self.log.error( 'Unable to Remove file ') def create_symlink(self, paths, errormsg=''): """ @@ -42,25 +39,25 @@ class EEFileUtils(): dst = paths[1] if not os.path.islink(dst): try: - Log.debug(self, "Creating Symbolic link, Source:{0}, Dest:{1}" + self.log.debug( "Creating Symbolic link, Source:{0}, Dest:{1}" .format(src, dst)) os.symlink(src, dst) except Exception as e: - Log.debug(self, "{0}{1}".format(e.errno, e.strerror)) - Log.error(self, "Unable to create symbolic link ...\n ") + self.log.debug( "{0}{1}".format(e.errno, e.strerror)) + self.log.error( "Unable to create symbolic link ...\n ") else: - Log.debug(self, "Destination: {0} exists".format(dst)) + self.log.debug( "Destination: {0} exists".format(dst)) def remove_symlink(self, filepath): """ Removes symbolic link for the path provided with filepath """ try: - Log.debug(self, "Removing symbolic link: {0}".format(filepath)) + self.log.debug( "Removing symbolic link: {0}".format(filepath)) os.unlink(filepath) except Exception as e: - Log.debug(self, "{0}".format(e)) - Log.error(self, "Unable to reomove symbolic link ...\n") + self.log.debug( "{0}".format(e)) + self.log.error( "Unable to reomove symbolic link ...\n") def copyfile(self, src, dest): """ @@ -69,17 +66,17 @@ class EEFileUtils(): dest : destination path """ try: - Log.debug(self, "Copying file, Source:{0}, Dest:{1}" + self.log.debug( "Copying file, Source:{0}, Dest:{1}" .format(src, dest)) shutil.copy2(src, dest) except shutil.Error as e: - Log.debug(self, "{0}".format(e)) - Log.error(self, 'Unable to copy file from {0} to {1}' + self.log.debug( "{0}".format(e)) + self.log.error( 'Unable to copy file from {0} to {1}' .format(src, dest)) except IOError as e: - Log.debug(self, "{e}".format(e.strerror)) - Log.error(self, "Unable to copy file from {0} to {1}" - .format(src, dest)) + self.log.debug( "{e}".format(e.strerror)) + self.log.error( "Unable to copy file from {0} to {1}" + .format(src, dest)) def searchreplace(self, fnm, sstr, rstr): """ @@ -89,15 +86,15 @@ class EEFileUtils(): rstr: replace string """ try: - Log.debug(self, "Doning search and replace, File:{0}," - "Source string:{1}, Dest String:{2}" - .format(fnm, sstr, rstr)) + self.log.debug( "Doning search and replace, File:{0}," + "Source string:{1}, Dest String:{2}" + .format(fnm, sstr, rstr)) for line in fileinput.input(fnm, inplace=True): print(line.replace(sstr, rstr), end='') fileinput.close() except Exception as e: - Log.debug(self, "{0}".format(e)) - Log.error(self, "Unable to search {0} and replace {1} {2}" + self.log.debug( "{0}".format(e)) + self.log.error( "Unable to search {0} and replace {1} {2}" .format(fnm, sstr, rstr)) def mvfile(self, src, dst): @@ -107,11 +104,11 @@ class EEFileUtils(): dst : Destination path """ try: - Log.debug(self, "Moving file from {0} to {1}".format(src, dst)) + self.log.debug( "Moving file from {0} to {1}".format(src, dst)) shutil.move(src, dst) except Exception as e: - Log.debug(self, "{err}".format(err=e)) - Log.error(self, 'Unable to move file from {0} to {1}' + self.log.debug( "{err}".format(err=e)) + self.log.error( 'Unable to move file from {0} to {1}' .format(src, dst)) def chdir(self, path): @@ -120,12 +117,12 @@ class EEFileUtils(): Path : path for destination directory """ try: - Log.debug(self, "Changing directory to {0}" - .format(path)) + self.log.debug( "Changing directory to {0}" + .format(path)) os.chdir(path) except OSError as e: - Log.debug(self, "{err}".format(err=e.strerror)) - Log.error(self, 'Unable to Change Directory {0}'.format(path)) + self.log.debug( "{err}".format(err=e.strerror)) + self.log.error( 'Unable to Change Directory {0}'.format(path)) def chown(self, path, user, group, recursive=False): """ @@ -139,8 +136,8 @@ class EEFileUtils(): userid = pwd.getpwnam(user)[2] groupid = pwd.getpwnam(user)[3] try: - Log.debug(self, "Changing ownership of {0}, Userid:{1},Groupid:{2}" - .format(path, userid, groupid)) + self.log.debug( "Changing ownership of {0}, Userid:{1},Groupid:{2}" + .format(path, userid, groupid)) # Change inside files/directory permissions only if recursive flag # is set if recursive: @@ -153,11 +150,11 @@ class EEFileUtils(): groupid) os.chown(path, userid, groupid) except shutil.Error as e: - Log.debug(self, "{0}".format(e)) - Log.error(self, "Unable to change owner : {0}".format(path)) + self.log.debug( "{0}".format(e)) + self.log.error( "Unable to change owner : {0}".format(path)) except Exception as e: - Log.debug(self, "{0}".format(e)) - Log.error(self, "Unable to change owner : {0} ".format(path)) + self.log.debug( "{0}".format(e)) + self.log.error( "Unable to change owner : {0} ".format(path)) def chmod(self, path, perm, recursive=False): """ @@ -167,8 +164,8 @@ class EEFileUtils(): recursive: change permission recursively for all files """ try: - Log.debug(self, "Changing permission of {0}, Perm:{1}" - .format(path, perm)) + self.log.debug( "Changing permission of {0}, Perm:{1}" + .format(path, perm)) if recursive: for root, dirs, files in os.walk(path): for d in dirs: @@ -178,8 +175,8 @@ class EEFileUtils(): else: os.chmod(path, perm) except OSError as e: - Log.debug(self, "{0}".format(e.strerror)) - Log.error(self, "Unable to change owner : {0}".format(path)) + self.log.debug( "{0}".format(e.strerror)) + self.log.error( "Unable to change owner : {0}".format(path)) def mkdir(self, path): """ @@ -188,12 +185,12 @@ class EEFileUtils(): Similar to `mkdir -p` """ try: - Log.debug(self, "Creating directories: {0}" - .format(path)) + self.log.debug( "Creating directories: {0}" + .format(path)) os.makedirs(path) except OSError as e: - Log.debug(self, "{0}".format(e.strerror)) - Log.error(self, "Unable to create directory {0} ".format(path)) + self.log.debug( "{0}".format(e.strerror)) + self.log.error( "Unable to create directory {0} ".format(path)) def isexist(self, path): """ @@ -205,30 +202,30 @@ class EEFileUtils(): else: return (False) except OSError as e: - Log.debug(self, "{0}".format(e.strerror)) - Log.error(self, "Unable to check path {0}".format(path)) + self.log.debug( "{0}".format(e.strerror)) + self.log.error( "Unable to check path {0}".format(path)) def grep(self, fnm, sstr): """ Searches for string in file and returns the matched line. """ try: - Log.debug(self, "Finding string {0} to file {1}" - .format(sstr, fnm)) + self.log.debug( "Finding string {0} to file {1}" + .format(sstr, fnm)) for line in open(fnm, encoding='utf-8'): if sstr in line: return line return False except OSError as e: - Log.debug(self, "{0}".format(e.strerror)) - Log.error(self, "Unable to Search string {0} in {1}" - .format(sstr, fnm)) + self.log.debug( "{0}".format(e.strerror)) + self.log.error( "Unable to Search string {0} in {1}" + .format(sstr, fnm)) def rm(self, path): """ Remove files """ - Log.debug(self, "Removing {0}".format(path)) + self.log.debug( "Removing {0}".format(path)) if EEFileUtils.isexist(self, path): try: if os.path.isdir(path): @@ -236,10 +233,10 @@ class EEFileUtils(): else: os.remove(path) except shutil.Error as e: - Log.debug(self, "{0}".format(e)) - Log.error(self, "Unable to remove directory : {0} " - .format(path)) + self.log.debug( "{0}".format(e)) + self.log.error( "Unable to remove directory : {0} " + .format(path)) except OSError as e: - Log.debug(self, "{0}".format(e)) - Log.error(self, "Unable to remove file : {0} " - .format(path)) + self.log.debug( "{0}".format(e)) + self.log.error( "Unable to remove file : {0} " + .format(path)) diff --git a/ee/core/variables.py b/ee/core/variables.py index ed7bf127..2ec0d52c 100644 --- a/ee/core/variables.py +++ b/ee/core/variables.py @@ -14,6 +14,8 @@ class EEVariables(): # EasyEngine version ee_version = "3.1.9" + ee_downloads = "/tmp/ee/downloads/" + # EasyEngine packages versions ee_wp_cli = "0.19.1" ee_adminer = "4.2.1" @@ -146,6 +148,44 @@ class EEVariables(): ee_hhvm = ["hhvm"] + ee_wpclistack = { + 'wpcli': "https://github.com/wp-cli/wp-cli/releases/download/" + "v{0}/wp-cli-{0}.phar".format(ee_wp_cli) + } + + ee_phpmyadminstack = { + 'phpmyadmin': "https://github.com/phpmyadmin/phpmyadmin/archive/STABLE.tar.gz", + } + + ee_adminerstack = { + 'adminer': "http://downloads.sourceforge.net/adminer/adminer-{0}.php".format(ee_adminer), + } + + ee_admin = { + 'phpmyadmin': "https://github.com/phpmyadmin/phpmyadmin/archive/STABLE.tar.gz", + 'adminer': "http://downloads.sourceforge.net/adminer/adminer-{0}.php".format(ee_adminer), + 'phpmemcacheadmin' : "http://phpmemcacheadmin.googlecode.com/files/phpMemcachedAdmin-1.2.2-r262.tar.gz", + 'cleancache' : "https://raw.githubusercontent.com/rtCamp/eeadmin/master/cache/nginx/clean.php", + 'opcache' : "https://raw.github.com/rlerdorf/opcache-status/master/opcache.php", + 'webgrind' : "https://github.com/jokkedk/webgrind/archive/master.tar.gz", + 'ptqueryadvisor' : "http://bazaar.launchpad.net/~percona-toolkit-dev/percona-toolkit/2.1/download/head:/ptquerydigest-20110624220137-or26tn4expb9ul2a-16/pt-query-digest", + 'anemometer' : "https://github.com/box/Anemometer/archive/master.tar.gz", + } + + ee_utils = { + 'phpmemcacheadmin' : "http://phpmemcacheadmin.googlecode.com/files/phpMemcachedAdmin-1.2.2-r262.tar.gz", + 'cleancache' : "https://raw.githubusercontent.com/rtCamp/eeadmin/master/cache/nginx/clean.php", + 'opcache' : "https://raw.github.com/rlerdorf/opcache-status/master/opcache.php", + 'webgrind' : "https://github.com/jokkedk/webgrind/archive/master.tar.gz", + 'ptqueryadvisor' : "http://bazaar.launchpad.net/~percona-toolkit-dev/percona-toolkit/2.1/download/head:/ptquerydigest-20110624220137-or26tn4expb9ul2a-16/pt-query-digest", + 'anemometer' : "https://github.com/box/Anemometer/archive/master.tar.gz", + } + + ee_webmailstack = { + 'vimbadmin': "https://github.com/opensolutions/ViMbAdmin/archive/{0}.tar.gz".format(ee_vimbadmin), + 'roundcube': "https://github.com/roundcube/roundcubemail/releases/download/{0}/roundcubemail-{0}.tar.gz".format(ee_roundcube) + } + # Repo path ee_repo_file = "ee-repo.list" ee_repo_file_path = ("/etc/apt/sources.list.d/" + ee_repo_file) diff --git a/setup.py b/setup.py index b658791c..27c5b687 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ except Exception as e: os.system("git config --global user.email {0}".format(ee_email)) setup(name='ee', - version='3.1.9', + version='3.2.x', description=long_description, long_description=long_description, classifiers=[], @@ -75,7 +75,8 @@ setup(name='ee', # "nose", # "coverage", # Required to function - 'cement == 2.4', + 'cement == 2.6', + 'colorlog', 'pystache', 'python-apt', 'pynginxconfig',