import os import shutil from cement.core.controller import CementBaseController, expose from wo.cli.plugins.stack_pref import post_pref, pre_pref, pre_stack from wo.core.aptget import WOAptGet from wo.core.download import WODownload from wo.core.extract import WOExtract from wo.core.fileutils import WOFileUtils from wo.core.logging import Log from wo.core.shellexec import WOShellExec from wo.core.variables import WOVar from wo.core.services import WOService from wo.core.mysql import WOMysql class WOStackUpgradeController(CementBaseController): class Meta: label = 'upgrade' stacked_on = 'stack' stacked_type = 'nested' description = ('Upgrade stack safely') arguments = [ (['--all'], dict(help='Upgrade all stack', action='store_true')), (['--web'], dict(help='Upgrade web stack', action='store_true')), (['--admin'], dict(help='Upgrade admin tools stack', action='store_true')), (['--security'], dict(help='Upgrade security stack', action='store_true')), (['--nginx'], dict(help='Upgrade OpenLiteSpeed stack', action='store_true')), (['--php'], dict(help='Upgrade PHP stack', action='store_true')), (['--mysql'], dict(help='Upgrade MySQL stack', action='store_true')), (['--mariadb'], dict(help='Upgrade MySQL stack alias', action='store_true')), (['--wpcli'], dict(help='Upgrade WPCLI', action='store_true')), (['--redis'], dict(help='Upgrade Redis', action='store_true')), (['--netdata'], dict(help='Upgrade Netdata', action='store_true')), (['--fail2ban'], dict(help='Upgrade Fail2Ban', action='store_true')), (['--dashboard'], dict(help='Upgrade WordOps Dashboard', action='store_true')), (['--composer'], dict(help='Upgrade Composer', action='store_true')), (['--mysqltuner'], dict(help='Upgrade MySQLTuner', action='store_true')), (['--phpmyadmin'], dict(help='Upgrade phpMyAdmin', action='store_true')), (['--adminer'], dict(help='Upgrade Adminer', action='store_true')), (['--no-prompt'], dict(help="Upgrade Packages without any prompt", action='store_true')), (['--force'], dict(help="Force Packages upgrade without any prompt", action='store_true')), ] for php_version, php_number in WOVar.wo_php_versions.items(): arguments.append(([f'--{php_version}'], dict(help=f'Upgrade PHP {php_number} stack', action='store_true'))) @expose(hide=True) def default(self, disp_msg=False): # All package update apt_packages = [] packages = [] self.msg = [] pargs = self.app.pargs wo_phpmyadmin = WODownload.pma_release(self) if all(value is None or value is False for value in vars(pargs).values()): pargs.web = True pargs.admin = True pargs.security = True if pargs.mariadb: pargs.mysql = True if pargs.php: if self.app.config.has_section('php'): config_php_ver = self.app.config.get( 'php', 'version') current_php = config_php_ver.replace(".", "") setattr(self.app.pargs, 'php{0}'.format(current_php), True) if pargs.all: pargs.web = True pargs.admin = True pargs.security = True pargs.redis = True if pargs.web: pargs.nginx = True pargs.php74 = True pargs.php80 = True pargs.php81 = True pargs.php82 = True pargs.php83 = True pargs.php84 = True pargs.php85 = True pargs.mysql = True pargs.wpcli = True if pargs.admin: pargs.netdata = True pargs.composer = True pargs.dashboard = True pargs.phpmyadmin = True pargs.wpcli = True pargs.adminer = True pargs.mysqltuner = True if pargs.security: pargs.fail2ban = True # OpenLiteSpeed if pargs.nginx: if WOAptGet.is_installed(self, 'openlitespeed'): apt_packages = apt_packages + WOVar.wo_ols else: if os.path.isfile('/usr/local/lsws/bin/openlitespeed'): Log.info(self, "Updating OpenLiteSpeed templates") post_pref(self, WOVar.wo_ols, []) else: Log.info(self, "OpenLiteSpeed is not already installed") wo_vars = { 'php74': WOVar.wo_php74, 'php80': WOVar.wo_php80, 'php81': WOVar.wo_php81, 'php82': WOVar.wo_php82, 'php83': WOVar.wo_php83, 'php84': WOVar.wo_php84, 'php85': WOVar.wo_php85, } for parg_version, version in WOVar.wo_php_versions.items(): if getattr(pargs, parg_version, False): short_ver = version.replace('.', '') Log.debug(self, f"Setting apt_packages variable for PHP {version}") if WOAptGet.is_installed(self, f'lsphp{short_ver}'): apt_packages = apt_packages + wo_vars[parg_version] + WOVar.wo_php_extra else: Log.debug(self, f"PHP {version} not installed") Log.info(self, f"PHP {version} not installed") # mysql if pargs.mysql: if WOMysql.mariadb_ping(self): apt_packages = apt_packages + ['mariadb-server'] # redis if pargs.redis: if WOAptGet.is_installed(self, 'redis-server'): apt_packages = apt_packages + ['redis-server'] # fail2ban if pargs.fail2ban: if WOAptGet.is_installed(self, 'fail2ban'): apt_packages = apt_packages + ['fail2ban'] # wp-cli if pargs.wpcli: if os.path.isfile('/usr/local/bin/wp'): packages = packages + [[f"{WOVar.wpcli_url}", "/usr/local/bin/wp", "WP-CLI"]] else: Log.info(self, "WPCLI is not installed with WordOps") # netdata if pargs.netdata: # detect static binaries install if (os.path.isdir('/opt/netdata') or os.path.isdir('/etc/netdata')): packages = packages + [[ f"{WOVar.netdata_script_url}", '/var/lib/wo/tmp/kickstart.sh', 'Netdata']] else: Log.info(self, 'Netdata is not installed') # wordops dashboard if pargs.dashboard: if (os.path.isfile('/var/www/22222/htdocs/index.php') or os.path.isfile('/var/www/22222/htdocs/index.html')): packages = packages + [[ "https://github.com/WordOps/wordops-dashboard/" "releases/download/v{0}/wordops-dashboard.tar.gz" .format(WOVar.wo_dashboard), "/var/lib/wo/tmp/wo-dashboard.tar.gz", "WordOps Dashboard"]] else: Log.info(self, 'WordOps dashboard is not installed') # phpmyadmin if pargs.phpmyadmin: if os.path.isdir('/var/www/22222/htdocs/db/pma'): packages = packages + [[ "https://files.phpmyadmin.net" "/phpMyAdmin/{0}/phpMyAdmin-{0}-" "all-languages.tar.gz" .format(wo_phpmyadmin), "/var/lib/wo/tmp/pma.tar.gz", "PHPMyAdmin"]] else: Log.info(self, "phpMyAdmin isn't installed") # adminer if pargs.adminer: if os.path.isfile("{0}22222/htdocs/db/" "adminer/index.php" .format(WOVar.wo_webroot)): Log.debug(self, "Setting packages variable for Adminer ") packages = packages + [[ "https://www.adminer.org/latest.php", "{0}22222/" "htdocs/db/adminer/index.php" .format(WOVar.wo_webroot), "Adminer"], ["https://raw.githubusercontent.com" "/vrana/adminer/master/designs/" "pepa-linha/adminer.css", "{0}22222/" "htdocs/db/adminer/adminer.css" .format(WOVar.wo_webroot), "Adminer theme"]] else: Log.debug(self, "Adminer isn't installed") Log.info(self, "Adminer isn't installed") # composer if pargs.composer: if os.path.isfile('/usr/local/bin/composer'): packages = packages + [[ "https://getcomposer.org/installer", "/var/lib/wo/tmp/composer-install", "Composer"]] else: Log.info(self, "Composer isn't installed") # mysqltuner if pargs.mysqltuner: if WOAptGet.is_exec(self, 'mysqltuner'): Log.debug(self, "Setting packages variable " "for MySQLTuner ") packages = packages + [["https://raw." "githubusercontent.com/" "major/MySQLTuner-perl" "/master/mysqltuner.pl", "/usr/bin/mysqltuner", "MySQLTuner"]] if not apt_packages and not packages: self.app.args.print_help() else: pre_stack(self) if apt_packages: # Check if critical packages are being upgraded has_critical = False for pkg in apt_packages: if pkg in ['openlitespeed', 'redis-server', 'mariadb-server'] or pkg.startswith('lsphp'): has_critical = True break if has_critical: Log.warn( self, "Your sites may be down for few seconds if " "you are upgrading OpenLiteSpeed, LSPHP, " "MariaDB or Redis") # Check prompt if not (pargs.no_prompt or pargs.force): start_upgrade = input("Do you want to continue:[y/N]") if start_upgrade != "Y" and start_upgrade != "y": Log.error(self, "Not starting package update") # additional pre_pref if "openlitespeed" in apt_packages: pre_pref(self, WOVar.wo_ols) Log.wait(self, "Updating APT cache") # apt-get update WOAptGet.update(self) Log.valide(self, "Updating APT cache") # redis pre_pref if "redis-server" in apt_packages: pre_pref(self, WOVar.wo_redis) # upgrade packages WOAptGet.install(self, apt_packages) Log.wait(self, "Configuring APT Packages") post_pref(self, apt_packages, [], True) Log.valide(self, "Configuring APT Packages") # Post Actions after package updates if packages: if WOAptGet.is_selected(self, 'WP-CLI', packages): WOFileUtils.rm(self, '/usr/local/bin/wp') if WOAptGet.is_selected(self, 'Netdata', packages): WOFileUtils.rm(self, '/var/lib/wo/tmp/kickstart.sh') if WOAptGet.is_selected(self, 'WordOps Dashboard', packages): if os.path.isfile('/var/www/22222/htdocs/index.php'): WOFileUtils.rm(self, '/var/www/22222/htdocs/index.php') if os.path.isfile('/var/www/22222/htdocs/index.html'): WOFileUtils.rm( self, '/var/www/22222/htdocs/index.html') Log.debug(self, "Downloading following: {0}".format(packages)) WODownload.download(self, packages) if WOAptGet.is_selected(self, 'WP-CLI', packages): WOFileUtils.chmod(self, "/usr/local/bin/wp", 0o775) if WOAptGet.is_selected(self, 'MySQLTuner', packages): WOFileUtils.chmod(self, "/usr/bin/mysqltuner", 0o775) if os.path.exists('/usr/local/bin/mysqltuner'): WOFileUtils.rm(self, '/usr/local/bin/mysqltuner') # Netdata if WOAptGet.is_selected(self, 'Netdata', packages): WOService.stop_service(self, 'netdata') if os.path.exists('/opt/netdata/usr/libexec/netdata/netdata-uninstaller.sh'): WOShellExec.cmd_exec(self, "/opt/netdata/usr/libexec/" "netdata/netdata-uninstaller.sh --yes --force", log=False) Log.wait(self, "Upgrading Netdata") # detect static binaries install WOShellExec.cmd_exec( self, "bash /var/lib/wo/tmp/kickstart.sh " "--dont-wait --no-updates --stable-channel " "--reinstall-even-if-unsafe", errormsg='', log=False) Log.valide(self, "Upgrading Netdata") if WOAptGet.is_selected(self, 'WordOps Dashboard', packages): post_pref( self, [], [["https://github.com/WordOps" "/wordops-dashboard/" "releases/download/v{0}/" "wordops-dashboard.tar.gz" .format(WOVar.wo_dashboard), "/var/lib/wo/tmp/wo-dashboard.tar.gz", "WordOps Dashboard"]]) if WOAptGet.is_selected(self, 'Composer', packages): Log.wait(self, "Upgrading Composer") if WOShellExec.cmd_exec( self, '/usr/bin/php -v'): WOShellExec.cmd_exec( self, "php -q /var/lib/wo" "/tmp/composer-install " "--install-dir=/var/lib/wo/tmp/") shutil.copyfile('/var/lib/wo/tmp/composer.phar', '/usr/local/bin/composer') WOFileUtils.chmod(self, "/usr/local/bin/composer", 0o775) Log.valide(self, "Upgrading Composer ") if WOAptGet.is_selected(self, 'PHPMyAdmin', packages): Log.wait(self, "Upgrading phpMyAdmin") WOExtract.extract(self, '/var/lib/wo/tmp/pma.tar.gz', '/var/lib/wo/tmp/') shutil.copyfile(('{0}22222/htdocs/db/pma' '/config.inc.php' .format(WOVar.wo_webroot)), ('/var/lib/wo/tmp/phpMyAdmin-{0}' '-all-languages/config.inc.php' .format(wo_phpmyadmin)) ) WOFileUtils.rm(self, '{0}22222/htdocs/db/pma' .format(WOVar.wo_webroot)) shutil.move('/var/lib/wo/tmp/phpMyAdmin-{0}' '-all-languages/' .format(wo_phpmyadmin), '{0}22222/htdocs/db/pma/' .format(WOVar.wo_webroot)) WOFileUtils.chown(self, "{0}22222/htdocs" .format(WOVar.wo_webroot), 'www-data', 'www-data', recursive=True) Log.valide(self, "Upgrading phpMyAdmin") if os.path.exists('{0}22222/htdocs'.format(WOVar.wo_webroot)): WOFileUtils.chown(self, "{0}22222/htdocs" .format(WOVar.wo_webroot), 'www-data', 'www-data', recursive=True) Log.info(self, "Successfully updated packages")