Skip to content

Commit

Permalink
Re-implement PHP version checkers
Browse files Browse the repository at this point in the history
Based on changes for moveing to the dist-upgrader submodule.
Now we check database is fine before the checks, so there should not
be fails on the start when database is disabled.
  • Loading branch information
Mikhail Sandakov committed Feb 20, 2024
1 parent adccab6 commit 34fe403
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 79 deletions.
166 changes: 91 additions & 75 deletions actions/common_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import platform
import shutil
import subprocess
import typing

from common import action, files, log, plesk, rpm, version
from common import action, files, log, packages, php, plesk, rpm, version


class PleskInstallerNotInProgress(action.CheckAction):
Expand Down Expand Up @@ -95,131 +96,146 @@ def _do_check(self) -> bool:
return False


class CheckOutdatedPHP(action.CheckAction):
def __init__(self):
self.name = "checking outdated PHP"
self.description = """Outdated PHP versions were detected: '{}'.
class AssertMinPhpVersionInstalled(action.CheckAction):
min_version: version.PHPVersion

def __init__(
self,
min_version: str,
):
self.name = "check for outdated PHP versions"
self.min_version = version.PHPVersion(min_version)
self.description = """Outdated PHP versions were detected: {versions}.
\tRemove outdated PHP packages via Plesk Installer to proceed with the conversion:
\tYou can do it by calling the following command:
\t> plesk installer remove --components {}
\tplesk installer remove --components {remove_arg}
"""

def _do_check(self) -> bool:
outdated_php_packages = {
"plesk-php52": "PHP 5.2",
"plesk-php53": "PHP 5.3",
"plesk-php54": "PHP 5.4",
"plesk-php55": "PHP 5.5",
"plesk-php56": "PHP 5.6",
"plesk-php70": "PHP 7.0",
"plesk-php71": "PHP 7.1",
}

installed_pkgs = rpm.filter_installed_packages(outdated_php_packages.keys())
log.debug(f"Checking for minimum installed PHP version of {self.min_version}")
# TODO: get rid of the explicit version list
known_php_versions = php.get_known_php_versions()

log.debug(f"Known PHP versions: {known_php_versions}")
outdated_php_versions = [php for php in known_php_versions if php < self.min_version]
outdated_php_packages = {f"plesk-php{php.major}{php.minor}": str(php) for php in outdated_php_versions}
log.debug(f"Outdated PHP versions: {outdated_php_versions}")

installed_pkgs = packages.filter_installed_packages(outdated_php_packages.keys())
log.debug(f"Outdated PHP packages installed: {installed_pkgs}")
if len(installed_pkgs) == 0:
log.debug("No outdated PHP versions installed")
return True

self.description = self.description.format(
", ".join([outdated_php_packages[installed] for installed in installed_pkgs]),
" ".join(outdated_php_packages[installed].replace(" ", "") for installed in installed_pkgs).lower())
versions=", ".join([outdated_php_packages[installed] for installed in installed_pkgs]),
remove_arg=" ".join(outdated_php_packages[installed].replace(" ", "") for installed in installed_pkgs).lower()
)

log.debug("Outdated PHP versions found")
return False


class CheckWebsitesUsesOutdatedPHP(action.CheckAction):
def __init__(self):
class AssertMinPhpVersionUsedByWebsites(action.CheckAction):
min_version: version.PHPVersion

def __init__(
self,
min_version: str,
optional: bool = True,
):
self.name = "checking domains uses outdated PHP"
self.min_version = version.PHPVersion(min_version)
self.optional = optional
self.description = """We have identified that the domains are using older versions of PHP.
\tSwitch the following domains to PHP 7.2 or later to proceed with the conversion:
\t- {}
\tSwitch the following domains to {modern} or later in order to continue with the conversion process:
\t- {domains}
\tYou can achieve this by executing the following command:
\t> plesk bin domain -u [domain] -php_handler_id plesk-php80-fastcgi
"""

def _do_check(self) -> bool:
outdated_php_packages = {
"plesk-php52": "PHP 5.2",
"plesk-php53": "PHP 5.3",
"plesk-php54": "PHP 5.4",
"plesk-php55": "PHP 5.5",
"plesk-php56": "PHP 5.6",
"plesk-php70": "PHP 7.0",
"plesk-php71": "PHP 7.1",
}

php_hanlers = {"'{}-fastcgi'", "'{}-fpm'", "'{}-fpm-dedicated'"}
outdated_php_handlers = []
for installed in outdated_php_packages.keys():
outdated_php_handlers += [handler.format(installed) for handler in php_hanlers]
log.debug(f"Checking the minimum PHP version being used by the websites. The restriction is: {self.min_version}")
if not plesk.is_plesk_database_ready():
if self.optional:
log.info("Plesk database is not ready. Skipping the minimum PHP for websites check.")
return True
raise RuntimeError("Plesk database is not ready. Skipping the minimum PHP for websites check.")

outdated_php_handlers = [f"'{handler}'" for handler in php.get_outdated_php_handlers(self.min_version)]
log.debug(f"Outdated PHP handlers: {outdated_php_handlers}")
try:
looking_for_domains_sql_request = """
SELECT d.name FROM domains d JOIN hosting h ON d.id = h.dom_id WHERE h.php_handler_id in ({});
""".format(", ".join(outdated_php_handlers))
outdated_php_domains = subprocess.check_output(["/usr/sbin/plesk", "db", looking_for_domains_sql_request],
universal_newlines=True)
outdated_php_domains = [domain[2:-2] for domain in outdated_php_domains.splitlines()
if domain.startswith("|") and not domain.startswith("| name ")]
if len(outdated_php_domains) <= 0:

outdated_php_domains = plesk.get_from_plesk_database(looking_for_domains_sql_request)
if not outdated_php_domains:
return True

log.debug(f"Outdated PHP domains: {outdated_php_domains}")
outdated_php_domains = "\n\t- ".join(outdated_php_domains)
self.description = self.description.format(outdated_php_domains)
self.description = self.description.format(
modern=self.min_version,
domains=outdated_php_domains
)
except Exception as ex:
log.err("Unable to get domains list from plesk database!")
raise RuntimeError("Unable to get domains list from plesk database!") from ex

return False
except Exception:
log.error("Unable to get domains list from plesk database!")
return False

return True

class AssertMinPhpVersionUsedByCron(action.CheckAction):
min_version: version.PHPVersion

class CheckCronUsesOutdatedPHP(action.CheckAction):
def __init__(self):
def __init__(
self,
min_version: str,
optional: bool = True,
):
self.name = "checking cronjob uses outdated PHP"
self.min_version = version.PHPVersion(min_version)
self.optional = optional
self.description = """We have detected that some cronjobs are using outdated PHP versions.
\tSwitch the following cronjobs to PHP 7.2 handler or a later version to proceed with the conversion:"
\t- {}
\tSwitch the following cronjobs to {modern} or later in order to continue with the conversion process:"
\t- {cronjobs}
\tYou can do this in the Plesk web interface by going “Tools & Settings” → “Scheduled Tasks”.
"""

def _do_check(self) -> bool:
outdated_php = [
"plesk-php52",
"plesk-php53",
"plesk-php54",
"plesk-php55",
"plesk-php56",
"plesk-php70",
"plesk-php71",
]

php_hanlers = {"'{}-cgi'", "'{}-fastcgi'", "'{}-fpm'", "'{}-fpm-dedicated'"}
outdated_php_handlers = []
for installed in outdated_php:
outdated_php_handlers += [handler.format(installed) for handler in php_hanlers]
log.debug(f"Checking the minimum PHP version used in cronjobs. Restriction is: {self.min_version}")
if not plesk.is_plesk_database_ready():
if self.optional:
log.info("Plesk database is not ready. Skipping the minimum PHP for cronjobs check.")
return True
raise RuntimeError("Plesk database is not ready. Skipping the minimum PHP for cronjobs check.")

outdated_php_handlers = [f"'{handler}'" for handler in php.get_outdated_php_handlers(self.min_version)]
log.debug(f"Outdated PHP handlers: {outdated_php_handlers}")

try:
looking_for_cronjobs_sql_request = """
SELECT command from ScheduledTasks WHERE type = "php" and phpHandlerId in ({});
""".format(", ".join(outdated_php_handlers))

outdated_php_cronjobs = subprocess.check_output(["/usr/sbin/plesk", "db", looking_for_cronjobs_sql_request],
universal_newlines=True)
outdated_php_cronjobs = [domain[2:-2] for domain in outdated_php_cronjobs.splitlines()
if domain.startswith("|") and not domain.startswith("| command ")]
if len(outdated_php_cronjobs) <= 0:
outdated_php_cronjobs = plesk.get_from_plesk_database(looking_for_cronjobs_sql_request)
if not outdated_php_cronjobs:
return True

log.debug(f"Outdated PHP cronjobs: {outdated_php_cronjobs}")
outdated_php_cronjobs = "\n\t- ".join(outdated_php_cronjobs)

self.description = self.description.format(outdated_php_cronjobs)
return False
except Exception:
log.error("Unable to get domains list from plesk database!")
self.description = self.description.format(
modern=self.min_version,
cronjobs=outdated_php_cronjobs)
except Exception as ex:
log.err("Unable to get cronjobs list from plesk database!")
raise RuntimeError("Unable to get cronjobs list from plesk database!") from ex

return True
return False


class CheckGrubInstalled(action.CheckAction):
Expand Down
2 changes: 1 addition & 1 deletion common
6 changes: 3 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ def is_required_conditions_satisfied(options: typing.Any, stage_flag: Stages) ->
actions.PleskVersionIsActual(),
actions.PleskInstallerNotInProgress(),
actions.CheckAvailableSpace(),
actions.CheckOutdatedPHP(),
actions.CheckWebsitesUsesOutdatedPHP(),
actions.CheckCronUsesOutdatedPHP(),
actions.AssertMinPhpVersionInstalled("7.2"),
actions.AssertMinPhpVersionUsedByWebsites("7.2"),
actions.AssertMinPhpVersionUsedByCron("7.2"),
actions.CheckGrubInstalled(),
actions.CheckNoMoreThenOneKernelNamedNIC(),
actions.CheckIsInContainer(),
Expand Down

0 comments on commit 34fe403

Please sign in to comment.