from __future__ import absolute_import
import dataclasses
import re
from clwpos.cl_wpos_exceptions import PhpBrokenException
from clwpos.utils import run_in_cagefs_if_needed
@dataclasses.dataclass
class PHP:
# e.g. 'alt-php67', must be unique
identifier: str
# e.g. '5.6'
version: str
# e.g. '/opt/alt/php51/usr/lib64/php/modules/'
modules_dir: str
# e.g. '/opt/alt/php80/usr/bin/php'
bin: str
# e.g. '/opt/alt/php51/etc/php.ini'
ini: str
# e.g. '/opt/alt/php51/'
dir: str
def __hash__(self):
return hash(self.identifier)
def __eq__(self, other: 'PHP'):
return self.identifier == other.identifier
def __gt__(self, other):
return self.identifier > other.identifier
def apply_php_selector(self) -> 'PHP':
"""
PHP selector can replace path with symlink.
It's a reason why we need normalization.
"""
# there is no need to execute binary
# when we see that it is not a link
# TODO: uncomment and check how it works
# if not os.path.islink(self.bin):
# return self
command = [self.bin, '-r', 'echo php_ini_loaded_file();']
result = run_in_cagefs_if_needed(command, env={})
# example:
# /opt/cpanel/ea-php74/root/etc/php.ini'
if result.stderr and not result.stdout:
raise PhpBrokenException(str(self.bin), result.stderr)
# check for alt version and replace if found
alt_pattern = re.compile(r"alt.*php[^/]*/")
captured_version = alt_pattern.search(result.stdout)
if captured_version:
php_name = captured_version[0].strip("/").replace("/", "-")
# we don't want to be dependent on
# whether panel supports alt-php or not
from clwpos.php.alt_php import create_generic_php
return create_generic_php(php_name)
return self
|