mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-10-26 00:36:34 +02:00
Update PHP version references and improve AlmaLinux 9 compatibility
- Changed PHP symlink from version 8.0 to 8.3 in various scripts to ensure compatibility with the latest PHP version. - Updated documentation links in the FAQ to point to the new community support page. - Added checks and fixes for MariaDB installation issues specific to AlmaLinux 9. - Enhanced the installation script to support additional PHP versions and improve overall installation reliability.
This commit is contained in:
@@ -39,9 +39,9 @@ CyberPanel supports a wide range of PHP versions across different operating syst
|
||||
|
||||
### ☑️ **Currently Supported PHP Versions**
|
||||
|
||||
- **PHP 8.5** - Latest stable version (EOL: Dec 2028)
|
||||
- **PHP 8.5** - Latest stable version (EOL: Dec 2028) ⭐ **NEW!**
|
||||
- **PHP 8.4** - Stable version (EOL: Dec 2027)
|
||||
- **PHP 8.3** - Stable version (EOL: Dec 2027)
|
||||
- **PHP 8.3** - **Default version** - Stable version (EOL: Dec 2027) 🎯
|
||||
- **PHP 8.2** - Stable version (EOL: Dec 2026)
|
||||
- **PHP 8.1** - Stable version (EOL: Dec 2025)
|
||||
- **PHP 8.0** - Legacy support (EOL: Nov 2023)
|
||||
|
||||
@@ -2278,7 +2278,7 @@ echo "echo \$@ > /etc/cyberpanel/adminPass" >> /usr/bin/adminPass
|
||||
chmod 700 /usr/bin/adminPass
|
||||
|
||||
rm -f /usr/bin/php
|
||||
ln -s /usr/local/lsws/lsphp80/bin/php /usr/bin/php
|
||||
ln -s /usr/local/lsws/lsphp83/bin/php /usr/bin/php
|
||||
|
||||
if [[ "$Server_OS" = "CentOS" ]] ; then
|
||||
#all centos 7/8 post change goes here
|
||||
|
||||
14
faq.sh
14
faq.sh
@@ -28,7 +28,7 @@ ${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
${PURPLE}3.${NC} How to access LiteSpeed webadmin console ?
|
||||
|
||||
Please check this post: ${GREEN}https://forums.cyberpanel.net/discussion/87/tutorial-how-to-setup-and-login-to-openlitespeed-webadmin-console/p1${NC}
|
||||
Please check this post: ${GREEN}https://community.cyberpanel.net/c/support/55${NC}
|
||||
|
||||
${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
@@ -52,9 +52,9 @@ ${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
${PURPLE}6.${NC} How to raise upload limit for cyberpanel's phpMyAdmin and File Manager?
|
||||
|
||||
edit file ${RED}/usr/local/lsws/lsphp73/etc/php.ini${NC} for CentOS or openEuler
|
||||
edit file ${RED}/usr/local/lsws/lsphp83/etc/php.ini${NC} for CentOS or openEuler
|
||||
|
||||
${RED}/usr/local/lsws/lsphp73/etc/php/7.3/litespeed/php.ini${NC} for Ubbuntu
|
||||
${RED}/usr/local/lsws/lsphp83/etc/php/8.3/litespeed/php.ini${NC} for Ubuntu
|
||||
|
||||
find 2 configurations:
|
||||
|
||||
@@ -66,9 +66,9 @@ ${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
${PURPLE}7.${NC} How to add more IPs to my website(s) ?
|
||||
|
||||
For OpenLiteSpeed, please check this post: ${GREEN}https://forums.cyberpanel.net/discussion/126/tutorial-how-to-add-2nd-ip-for-websites/p1${NC}
|
||||
For OpenLiteSpeed, please check this post: ${GREEN}https://community.cyberpanel.net/c/support/55${NC}
|
||||
|
||||
For LiteSpeed Enterprise, please check this post: ${GREEN}https://forums.cyberpanel.net/discussion/3745/tutorial-how-to-add-2nd-ip-for-litespeed-enterprise/p1${NC}
|
||||
For LiteSpeed Enterprise, please check this post: ${GREEN}https://community.cyberpanel.net/c/support/55${NC}
|
||||
|
||||
${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
@@ -80,7 +80,7 @@ ${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
${PURPLE}9.${NC} How to enable Auto-Index for my site ?
|
||||
|
||||
Please check this post ${GREEN}https://forums.cyberpanel.net/discussion/3850/tutorial-how-to-enable-auto-index-on-openlitespeed-and-litespeed-enterprise${NC}
|
||||
Please check this post ${GREEN}https://community.cyberpanel.net/c/support/55${NC}
|
||||
|
||||
${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
@@ -111,5 +111,5 @@ ${BLUE}------------------------------------------------------------${NC}
|
||||
|
||||
${PURPLE}13.${NC} How to enable PHP error log ?
|
||||
|
||||
Please check this post ${GREEN}https://forums.cyberpanel.net/discussion/3977/tutorial-how-to-enable-php-error-log/p1${NC}
|
||||
Please check this post ${GREEN}https://community.cyberpanel.net/c/support/55${NC}
|
||||
"
|
||||
@@ -1,190 +0,0 @@
|
||||
import os
|
||||
import shutil
|
||||
import pathlib
|
||||
import stat
|
||||
|
||||
|
||||
def mkdir_p(path, exist_ok=True):
|
||||
"""
|
||||
Creates the directory and paths leading up to it like unix mkdir -p .
|
||||
Defaults to exist_ok so if it exists were not throwing fatal errors
|
||||
https://docs.python.org/3.7/library/os.html#os.makedirs
|
||||
"""
|
||||
if not os.path.exists(path):
|
||||
print('creating directory: ' + path)
|
||||
os.makedirs(path, exist_ok)
|
||||
|
||||
|
||||
def chmod_digit(file_path, perms):
|
||||
"""
|
||||
Helper function to chmod like you would in unix without having to preface 0o or converting to octal yourself.
|
||||
Credits: https://stackoverflow.com/a/60052847/1621381
|
||||
"""
|
||||
try:
|
||||
os.chmod(file_path, int(str(perms), base=8))
|
||||
except:
|
||||
print(f'Could not chmod : {file_path} to {perms}')
|
||||
pass
|
||||
|
||||
|
||||
def touch(filepath: str, exist_ok=True):
|
||||
"""
|
||||
Touches a file like unix `touch somefile` would.
|
||||
"""
|
||||
try:
|
||||
pathlib.Path(filepath).touch(exist_ok)
|
||||
except FileExistsError:
|
||||
print('Could touch : ' + filepath)
|
||||
pass
|
||||
|
||||
|
||||
def symlink(src, dst):
|
||||
"""
|
||||
Symlink a path to another if the src exists.
|
||||
"""
|
||||
try:
|
||||
if os.access(src, os.R_OK):
|
||||
os.symlink(src, dst)
|
||||
except:
|
||||
print(f'Could not symlink Source: {src} > Destination: {dst}')
|
||||
pass
|
||||
|
||||
|
||||
def chown(path, user, group=-1):
|
||||
"""
|
||||
Chown file/path to user/group provided. Passing -1 to user or group will leave it unchanged.
|
||||
Useful if just changing user or group vs both.
|
||||
"""
|
||||
try:
|
||||
shutil.chown(path, user, group)
|
||||
except PermissionError:
|
||||
print(f'Could not change permissions for: {path} to {user}:{group}')
|
||||
pass
|
||||
|
||||
|
||||
def recursive_chown(path, owner, group=-1):
|
||||
"""
|
||||
Recursively chown a path and contents to owner.
|
||||
https://docs.python.org/3/library/shutil.html
|
||||
"""
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
try:
|
||||
shutil.chown(dirpath, owner, group)
|
||||
except PermissionError:
|
||||
print('Could not change permissions for: ' + dirpath + ' to: ' + owner)
|
||||
pass
|
||||
for filename in filenames:
|
||||
try:
|
||||
shutil.chown(os.path.join(dirpath, filename), owner, group)
|
||||
except PermissionError:
|
||||
print('Could not change permissions for: ' + os.path.join(dirpath, filename) + ' to: ' + owner)
|
||||
pass
|
||||
|
||||
|
||||
def recursive_permissions(path, dir_mode=755, file_mode=644, topdir=True):
|
||||
"""
|
||||
Recursively chmod a path and contents to mode.
|
||||
Defaults to chmod top level directory but can be optionally
|
||||
toggled off when you want to chmod only contents of like a user's homedir vs homedir itself
|
||||
https://docs.python.org/3.6/library/os.html#os.walk
|
||||
"""
|
||||
|
||||
# Here we are converting the integers to string and then to octal.
|
||||
# so this function doesn't need to be called with 0o prefixed for the file and dir mode
|
||||
dir_mode = int(str(dir_mode), base=8)
|
||||
file_mode = int(str(file_mode), base=8)
|
||||
|
||||
if topdir:
|
||||
# Set chmod on top level path
|
||||
try:
|
||||
os.chmod(path, dir_mode)
|
||||
except:
|
||||
print('Could not chmod :' + path + ' to ' + str(dir_mode))
|
||||
for root, dirs, files in os.walk(path):
|
||||
for d in dirs:
|
||||
try:
|
||||
os.chmod(os.path.join(root, d), dir_mode)
|
||||
except:
|
||||
print('Could not chmod :' + os.path.join(root, d) + ' to ' + str(dir_mode))
|
||||
pass
|
||||
for f in files:
|
||||
try:
|
||||
os.chmod(os.path.join(root, f), file_mode)
|
||||
except:
|
||||
print('Could not chmod :' + path + ' to ' + str(file_mode))
|
||||
pass
|
||||
|
||||
|
||||
# Left intentionally here for reference.
|
||||
# Set recursive chown for a path
|
||||
# recursive_chown(my_path, 'root', 'root')
|
||||
# for changing group recursively without affecting user
|
||||
# recursive_chown('/usr/local/lscp/cyberpanel/rainloop/data', -1, 'lscpd')
|
||||
|
||||
# explicitly set permissions for directories/folders to 0755 and files to 0644
|
||||
# recursive_permissions(my_path, 755, 644)
|
||||
|
||||
# Fix permissions and use default values
|
||||
# recursive_permissions(my_path)
|
||||
# =========================================================
|
||||
# Below is a helper class for getting and working with permissions
|
||||
# Original credits to : https://github.com/keysemble/perfm
|
||||
|
||||
def perm_octal_digit(rwx):
|
||||
digit = 0
|
||||
if rwx[0] == 'r':
|
||||
digit += 4
|
||||
if rwx[1] == 'w':
|
||||
digit += 2
|
||||
if rwx[2] == 'x':
|
||||
digit += 1
|
||||
return digit
|
||||
|
||||
|
||||
class FilePerm:
|
||||
def __init__(self, filepath):
|
||||
filemode = stat.filemode(os.stat(filepath).st_mode)
|
||||
permissions = [filemode[-9:][i:i + 3] for i in range(0, len(filemode[-9:]), 3)]
|
||||
self.filepath = filepath
|
||||
self.access_dict = dict(zip(['user', 'group', 'other'], [list(perm) for perm in permissions]))
|
||||
|
||||
def mode(self):
|
||||
mode = 0
|
||||
for shift, digit in enumerate(self.octal()[::-1]):
|
||||
mode += digit << (shift * 3)
|
||||
return mode
|
||||
|
||||
def digits(self):
|
||||
"""Get the octal chmod equivalent value 755 in single string"""
|
||||
return "".join(map(str, self.octal()))
|
||||
|
||||
def octal(self):
|
||||
"""Get the octal value in a list [7, 5, 5]"""
|
||||
return [perm_octal_digit(p) for p in self.access_dict.values()]
|
||||
|
||||
def access_bits(self, access):
|
||||
if access in self.access_dict.keys():
|
||||
r, w, x = self.access_dict[access]
|
||||
return [r == 'r', w == 'w', x == 'x']
|
||||
|
||||
def update_bitwise(self, settings):
|
||||
def perm_list(read=False, write=False, execute=False):
|
||||
pl = ['-', '-', '-']
|
||||
if read:
|
||||
pl[0] = 'r'
|
||||
if write:
|
||||
pl[1] = 'w'
|
||||
if execute:
|
||||
pl[2] = 'x'
|
||||
return pl
|
||||
|
||||
self.access_dict = dict(
|
||||
[(access, perm_list(read=r, write=w, execute=x)) for access, [r, w, x] in settings.items()])
|
||||
os.chmod(self.filepath, self.mode())
|
||||
|
||||
# project_directory = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
# home_directory = os.path.expanduser('~')
|
||||
# print(f'Path: {home_directory} Mode: {FilePerm(home_directory).mode()} Octal: {FilePerm(home_directory).octal()} '
|
||||
# f'Digits: {FilePerm(home_directory).digits()}')
|
||||
# Example: Output
|
||||
# Path: /home/cooluser Mode: 493 Octal: [7, 5, 5] Digits: 755
|
||||
@@ -2969,7 +2969,7 @@ echo $oConfig->Save() ? 'Done' : 'Error';
|
||||
writeToFile.write(content)
|
||||
writeToFile.close()
|
||||
|
||||
command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php'
|
||||
command = '/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/public/snappymail.php'
|
||||
subprocess.call(shlex.split(command))
|
||||
|
||||
command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,62 @@ FetchCloudLinuxAlmaVersionVersion = install_utils.FetchCloudLinuxAlmaVersionVers
|
||||
class InstallCyberPanel:
|
||||
mysql_Root_password = ""
|
||||
mysqlPassword = ""
|
||||
|
||||
def is_almalinux9(self):
|
||||
"""Check if running on AlmaLinux 9"""
|
||||
if os.path.exists('/etc/almalinux-release'):
|
||||
try:
|
||||
with open('/etc/almalinux-release', 'r') as f:
|
||||
content = f.read()
|
||||
return 'release 9' in content
|
||||
except:
|
||||
return False
|
||||
return False
|
||||
|
||||
def fix_almalinux9_mariadb(self):
|
||||
"""Fix AlmaLinux 9 MariaDB installation issues"""
|
||||
if not self.is_almalinux9():
|
||||
return
|
||||
|
||||
self.stdOut("Applying AlmaLinux 9 MariaDB fixes...", 1)
|
||||
|
||||
try:
|
||||
# Disable problematic MariaDB MaxScale repository
|
||||
self.stdOut("Disabling problematic MariaDB MaxScale repository...", 1)
|
||||
command = "dnf config-manager --disable mariadb-maxscale 2>/dev/null || true"
|
||||
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
|
||||
|
||||
# Remove problematic repository files
|
||||
self.stdOut("Removing problematic repository files...", 1)
|
||||
problematic_repos = [
|
||||
'/etc/yum.repos.d/mariadb-maxscale.repo',
|
||||
'/etc/yum.repos.d/mariadb-maxscale.repo.rpmnew'
|
||||
]
|
||||
for repo_file in problematic_repos:
|
||||
if os.path.exists(repo_file):
|
||||
os.remove(repo_file)
|
||||
self.stdOut(f"Removed {repo_file}", 1)
|
||||
|
||||
# Clean DNF cache
|
||||
self.stdOut("Cleaning DNF cache...", 1)
|
||||
command = "dnf clean all"
|
||||
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
|
||||
|
||||
# Install MariaDB from official repository
|
||||
self.stdOut("Setting up official MariaDB repository...", 1)
|
||||
command = "curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version='10.11'"
|
||||
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
|
||||
|
||||
# Install MariaDB packages
|
||||
self.stdOut("Installing MariaDB packages...", 1)
|
||||
mariadb_packages = "MariaDB-server MariaDB-client MariaDB-backup MariaDB-devel"
|
||||
command = f"dnf install -y {mariadb_packages}"
|
||||
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
|
||||
|
||||
self.stdOut("AlmaLinux 9 MariaDB fixes completed", 1)
|
||||
|
||||
except Exception as e:
|
||||
self.stdOut(f"Error applying AlmaLinux 9 MariaDB fixes: {str(e)}", 0)
|
||||
CloudLinux8 = 0
|
||||
|
||||
def install_package(self, package_name, options=""):
|
||||
@@ -335,7 +391,7 @@ class InstallCyberPanel:
|
||||
return self.reStartLiteSpeed()
|
||||
|
||||
def installAllPHPVersions(self):
|
||||
php_versions = ['71', '72', '73', '74', '80', '81', '82', '83']
|
||||
php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85']
|
||||
|
||||
if self.distro == ubuntu:
|
||||
# Install base PHP 7.x packages
|
||||
@@ -563,6 +619,12 @@ gpgcheck=1
|
||||
|
||||
if self.remotemysql == 'OFF':
|
||||
############## Start mariadb ######################
|
||||
|
||||
# Check if AlmaLinux 9 and apply fixes
|
||||
if self.is_almalinux9():
|
||||
self.stdOut("AlmaLinux 9 detected - applying MariaDB fixes", 1)
|
||||
self.fix_almalinux9_mariadb()
|
||||
|
||||
self.manage_service('mariadb', 'start')
|
||||
|
||||
############## Enable mariadb at system startup ######################
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,121 +0,0 @@
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Mail Functions - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Mail Functions" %}</h2>
|
||||
<p>{% trans "Manage email accounts on this page." %}</p>
|
||||
</div>
|
||||
|
||||
<div class="panel col-md-12">
|
||||
<div class="panel-body">
|
||||
<h3 class="content-box-header">
|
||||
{% trans "Available Functions" %}
|
||||
</h3>
|
||||
|
||||
<div class="example-box-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'createEmailAccount' %}" title="{% trans 'Create Email' %}"
|
||||
class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Create Email" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-plus-square"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'listEmails' %}" title="{% trans 'List Emails' %}"
|
||||
class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "List Emails" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-plus-square"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'deleteEmailAccount' %}" title="{% trans 'Delete Email' %}"
|
||||
class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Delete Email" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-trash"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'emailForwarding' %}" title="{% trans 'Email Forwarding' %}"
|
||||
class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Email Forwarding" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-plus-square"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'changeEmailAccountPassword' %}" title="{% trans 'Change Password' %}"
|
||||
class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Change Password" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-key"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="{% url 'dkimManager' %}" title="{% trans 'DKIM Manager' %}"
|
||||
class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "DKIM Manager" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-key"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 btn-min-width">
|
||||
<a href="/snappymail/index.php" title="{% trans 'Access Webmail' %}"
|
||||
class="tile-box tile-box-shortcut btn-primary">
|
||||
<div class="tile-header">
|
||||
{% trans "Access Webmail" %}
|
||||
</div>
|
||||
<div class="tile-content-wrapper">
|
||||
<i class="fa fa-key"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -1372,7 +1372,7 @@ echo $oConfig->Save() ? 'Done' : 'Error';
|
||||
command = 'chmod 640 /usr/local/lscp/cyberpanel/logs/access.log'
|
||||
ProcessUtilities.executioner(command, 'root', True)
|
||||
|
||||
command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php'
|
||||
command = '/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/public/snappymail.php'
|
||||
ProcessUtilities.executioner(command, 'root', True)
|
||||
|
||||
command = 'chmod 600 /usr/local/CyberCP/public/snappymail.php'
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
import os
|
||||
import shutil
|
||||
import pathlib
|
||||
import stat
|
||||
|
||||
|
||||
def mkdir_p(path, exist_ok=True):
|
||||
"""
|
||||
Creates the directory and paths leading up to it like unix mkdir -p .
|
||||
Defaults to exist_ok so if it exists were not throwing fatal errors
|
||||
https://docs.python.org/3.7/library/os.html#os.makedirs
|
||||
"""
|
||||
if not os.path.exists(path):
|
||||
print('creating directory: ' + path)
|
||||
os.makedirs(path, exist_ok)
|
||||
|
||||
|
||||
def chmod_digit(file_path, perms):
|
||||
"""
|
||||
Helper function to chmod like you would in unix without having to preface 0o or converting to octal yourself.
|
||||
Credits: https://stackoverflow.com/a/60052847/1621381
|
||||
"""
|
||||
try:
|
||||
os.chmod(file_path, int(str(perms), base=8))
|
||||
except:
|
||||
print(f'Could not chmod : {file_path} to {perms}')
|
||||
pass
|
||||
|
||||
|
||||
def touch(filepath: str, exist_ok=True):
|
||||
"""
|
||||
Touches a file like unix `touch somefile` would.
|
||||
"""
|
||||
try:
|
||||
pathlib.Path(filepath).touch(exist_ok)
|
||||
except FileExistsError:
|
||||
print('Could touch : ' + filepath)
|
||||
pass
|
||||
|
||||
|
||||
def symlink(src, dst):
|
||||
"""
|
||||
Symlink a path to another if the src exists.
|
||||
"""
|
||||
try:
|
||||
if os.access(src, os.R_OK):
|
||||
os.symlink(src, dst)
|
||||
except:
|
||||
print(f'Could not symlink Source: {src} > Destination: {dst}')
|
||||
pass
|
||||
|
||||
|
||||
def chown(path, user, group=-1):
|
||||
"""
|
||||
Chown file/path to user/group provided. Passing -1 to user or group will leave it unchanged.
|
||||
Useful if just changing user or group vs both.
|
||||
"""
|
||||
try:
|
||||
shutil.chown(path, user, group)
|
||||
except PermissionError:
|
||||
print(f'Could not change permissions for: {path} to {user}:{group}')
|
||||
pass
|
||||
|
||||
|
||||
def recursive_chown(path, owner, group=-1):
|
||||
"""
|
||||
Recursively chown a path and contents to owner.
|
||||
https://docs.python.org/3/library/shutil.html
|
||||
"""
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
try:
|
||||
shutil.chown(dirpath, owner, group)
|
||||
except PermissionError:
|
||||
print('Could not change permissions for: ' + dirpath + ' to: ' + owner)
|
||||
pass
|
||||
for filename in filenames:
|
||||
try:
|
||||
shutil.chown(os.path.join(dirpath, filename), owner, group)
|
||||
except PermissionError:
|
||||
print('Could not change permissions for: ' + os.path.join(dirpath, filename) + ' to: ' + owner)
|
||||
pass
|
||||
|
||||
|
||||
def recursive_permissions(path, dir_mode=755, file_mode=644, topdir=True):
|
||||
"""
|
||||
Recursively chmod a path and contents to mode.
|
||||
Defaults to chmod top level directory but can be optionally
|
||||
toggled off when you want to chmod only contents of like a user's homedir vs homedir itself
|
||||
https://docs.python.org/3.6/library/os.html#os.walk
|
||||
"""
|
||||
|
||||
# Here we are converting the integers to string and then to octal.
|
||||
# so this function doesn't need to be called with 0o prefixed for the file and dir mode
|
||||
dir_mode = int(str(dir_mode), base=8)
|
||||
file_mode = int(str(file_mode), base=8)
|
||||
|
||||
if topdir:
|
||||
# Set chmod on top level path
|
||||
try:
|
||||
os.chmod(path, dir_mode)
|
||||
except:
|
||||
print('Could not chmod :' + path + ' to ' + str(dir_mode))
|
||||
for root, dirs, files in os.walk(path):
|
||||
for d in dirs:
|
||||
try:
|
||||
os.chmod(os.path.join(root, d), dir_mode)
|
||||
except:
|
||||
print('Could not chmod :' + os.path.join(root, d) + ' to ' + str(dir_mode))
|
||||
pass
|
||||
for f in files:
|
||||
try:
|
||||
os.chmod(os.path.join(root, f), file_mode)
|
||||
except:
|
||||
print('Could not chmod :' + path + ' to ' + str(file_mode))
|
||||
pass
|
||||
|
||||
|
||||
# Left intentionally here for reference.
|
||||
# Set recursive chown for a path
|
||||
# recursive_chown(my_path, 'root', 'root')
|
||||
# for changing group recursively without affecting user
|
||||
# recursive_chown('/usr/local/lscp/cyberpanel/rainloop/data', -1, 'lscpd')
|
||||
|
||||
# explicitly set permissions for directories/folders to 0755 and files to 0644
|
||||
# recursive_permissions(my_path, 755, 644)
|
||||
|
||||
# Fix permissions and use default values
|
||||
# recursive_permissions(my_path)
|
||||
# =========================================================
|
||||
# Below is a helper class for getting and working with permissions
|
||||
# Original credits to : https://github.com/keysemble/perfm
|
||||
|
||||
def perm_octal_digit(rwx):
|
||||
digit = 0
|
||||
if rwx[0] == 'r':
|
||||
digit += 4
|
||||
if rwx[1] == 'w':
|
||||
digit += 2
|
||||
if rwx[2] == 'x':
|
||||
digit += 1
|
||||
return digit
|
||||
|
||||
|
||||
class FilePerm:
|
||||
def __init__(self, filepath):
|
||||
filemode = stat.filemode(os.stat(filepath).st_mode)
|
||||
permissions = [filemode[-9:][i:i + 3] for i in range(0, len(filemode[-9:]), 3)]
|
||||
self.filepath = filepath
|
||||
self.access_dict = dict(zip(['user', 'group', 'other'], [list(perm) for perm in permissions]))
|
||||
|
||||
def mode(self):
|
||||
mode = 0
|
||||
for shift, digit in enumerate(self.octal()[::-1]):
|
||||
mode += digit << (shift * 3)
|
||||
return mode
|
||||
|
||||
def digits(self):
|
||||
"""Get the octal chmod equivalent value 755 in single string"""
|
||||
return "".join(map(str, self.octal()))
|
||||
|
||||
def octal(self):
|
||||
"""Get the octal value in a list [7, 5, 5]"""
|
||||
return [perm_octal_digit(p) for p in self.access_dict.values()]
|
||||
|
||||
def access_bits(self, access):
|
||||
if access in self.access_dict.keys():
|
||||
r, w, x = self.access_dict[access]
|
||||
return [r == 'r', w == 'w', x == 'x']
|
||||
|
||||
def update_bitwise(self, settings):
|
||||
def perm_list(read=False, write=False, execute=False):
|
||||
pl = ['-', '-', '-']
|
||||
if read:
|
||||
pl[0] = 'r'
|
||||
if write:
|
||||
pl[1] = 'w'
|
||||
if execute:
|
||||
pl[2] = 'x'
|
||||
return pl
|
||||
|
||||
self.access_dict = dict(
|
||||
[(access, perm_list(read=r, write=w, execute=x)) for access, [r, w, x] in settings.items()])
|
||||
os.chmod(self.filepath, self.mode())
|
||||
|
||||
# project_directory = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
# home_directory = os.path.expanduser('~')
|
||||
# print(f'Path: {home_directory} Mode: {FilePerm(home_directory).mode()} Octal: {FilePerm(home_directory).octal()} '
|
||||
# f'Digits: {FilePerm(home_directory).digits()}')
|
||||
# Example: Output
|
||||
# Path: /home/cooluser Mode: 493 Octal: [7, 5, 5] Digits: 755
|
||||
@@ -861,7 +861,7 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
command = f'wget -q -O /usr/local/CyberCP/snappymail_cyberpanel.php https://raw.githubusercontent.com/the-djmaze/snappymail/master/integrations/cyberpanel/install.php'
|
||||
Upgrade.executioner_silent(command, 'verify certificate', 0)
|
||||
|
||||
command = f'/usr/local/lsws/lsphp80/bin/php /usr/local/CyberCP/snappymail_cyberpanel.php'
|
||||
command = f'/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/snappymail_cyberpanel.php'
|
||||
Upgrade.executioner_silent(command, 'verify certificate', 0)
|
||||
|
||||
# labsPath = '/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini'
|
||||
@@ -3121,7 +3121,7 @@ echo $oConfig->Save() ? 'Done' : 'Error';
|
||||
command = 'chmod 640 /usr/local/lscp/cyberpanel/logs/access.log'
|
||||
Upgrade.executioner(command, 0)
|
||||
|
||||
command = '/usr/local/lsws/lsphp72/bin/php /usr/local/CyberCP/public/snappymail.php'
|
||||
command = '/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/public/snappymail.php'
|
||||
Upgrade.executioner_silent(command, 'Configure SnappyMail')
|
||||
|
||||
command = 'chmod 600 /usr/local/CyberCP/public/snappymail.php'
|
||||
@@ -3182,44 +3182,221 @@ echo $oConfig->Save() ? 'Done' : 'Error';
|
||||
command = '/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt'
|
||||
Upgrade.executioner(command, command, 0)
|
||||
|
||||
@staticmethod
|
||||
def check_package_availability(package_name):
|
||||
"""Check if a package is available in the repositories"""
|
||||
try:
|
||||
# Try to search for the package without installing
|
||||
if os.path.exists('/etc/yum.repos.d/') or os.path.exists('/etc/dnf/dnf.conf'):
|
||||
# RHEL-based systems
|
||||
command = f"dnf search --quiet {package_name} 2>/dev/null | grep -q '^Last metadata expiration' || yum search --quiet {package_name} 2>/dev/null | head -1"
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
return result.returncode == 0
|
||||
else:
|
||||
# Ubuntu/Debian systems
|
||||
command = f"apt-cache search {package_name} 2>/dev/null | head -1"
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
return result.returncode == 0 and result.stdout.strip() != ""
|
||||
except Exception as e:
|
||||
Upgrade.stdOut(f"Error checking package availability for {package_name}: {str(e)}", 0)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def is_almalinux9():
|
||||
"""Check if running on AlmaLinux 9"""
|
||||
if os.path.exists('/etc/almalinux-release'):
|
||||
try:
|
||||
with open('/etc/almalinux-release', 'r') as f:
|
||||
content = f.read()
|
||||
return 'release 9' in content
|
||||
except:
|
||||
return False
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def fix_almalinux9_mariadb():
|
||||
"""Fix AlmaLinux 9 MariaDB installation issues"""
|
||||
if not Upgrade.is_almalinux9():
|
||||
return
|
||||
|
||||
Upgrade.stdOut("Applying AlmaLinux 9 MariaDB fixes...", 1)
|
||||
|
||||
try:
|
||||
# Disable problematic MariaDB MaxScale repository
|
||||
Upgrade.stdOut("Disabling problematic MariaDB MaxScale repository...", 1)
|
||||
command = "dnf config-manager --disable mariadb-maxscale 2>/dev/null || true"
|
||||
subprocess.run(command, shell=True, capture_output=True)
|
||||
|
||||
# Remove problematic repository files
|
||||
Upgrade.stdOut("Removing problematic repository files...", 1)
|
||||
problematic_repos = [
|
||||
'/etc/yum.repos.d/mariadb-maxscale.repo',
|
||||
'/etc/yum.repos.d/mariadb-maxscale.repo.rpmnew'
|
||||
]
|
||||
for repo_file in problematic_repos:
|
||||
if os.path.exists(repo_file):
|
||||
os.remove(repo_file)
|
||||
Upgrade.stdOut(f"Removed {repo_file}", 1)
|
||||
|
||||
# Clean DNF cache
|
||||
Upgrade.stdOut("Cleaning DNF cache...", 1)
|
||||
command = "dnf clean all"
|
||||
subprocess.run(command, shell=True, capture_output=True)
|
||||
|
||||
# Install MariaDB from official repository
|
||||
Upgrade.stdOut("Setting up official MariaDB repository...", 1)
|
||||
command = "curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version='10.11'"
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
Upgrade.stdOut(f"Warning: MariaDB repo setup failed: {result.stderr}", 0)
|
||||
|
||||
# Install MariaDB packages
|
||||
Upgrade.stdOut("Installing MariaDB packages...", 1)
|
||||
mariadb_packages = "MariaDB-server MariaDB-client MariaDB-backup MariaDB-devel"
|
||||
command = f"dnf install -y {mariadb_packages}"
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
Upgrade.stdOut(f"Warning: MariaDB installation issues: {result.stderr}", 0)
|
||||
|
||||
# Start and enable MariaDB service
|
||||
Upgrade.stdOut("Starting MariaDB service...", 1)
|
||||
services = ['mariadb', 'mysql', 'mysqld']
|
||||
for service in services:
|
||||
try:
|
||||
command = f"systemctl start {service}"
|
||||
result = subprocess.run(command, shell=True, capture_output=True)
|
||||
if result.returncode == 0:
|
||||
command = f"systemctl enable {service}"
|
||||
subprocess.run(command, shell=True, capture_output=True)
|
||||
Upgrade.stdOut(f"MariaDB service started as {service}", 1)
|
||||
break
|
||||
except:
|
||||
continue
|
||||
|
||||
Upgrade.stdOut("AlmaLinux 9 MariaDB fixes completed", 1)
|
||||
|
||||
except Exception as e:
|
||||
Upgrade.stdOut(f"Error applying AlmaLinux 9 MariaDB fixes: {str(e)}", 0)
|
||||
|
||||
@staticmethod
|
||||
def get_available_php_versions():
|
||||
"""Get list of available PHP versions based on OS"""
|
||||
# Check for AlmaLinux 9+ first
|
||||
if os.path.exists('/etc/almalinux-release'):
|
||||
try:
|
||||
with open('/etc/almalinux-release', 'r') as f:
|
||||
content = f.read()
|
||||
if 'release 9' in content or 'release 10' in content:
|
||||
Upgrade.stdOut("AlmaLinux 9+ detected - checking available PHP versions", 1)
|
||||
# AlmaLinux 9+ doesn't have PHP 7.1, 7.2, 7.3
|
||||
php_versions = ['74', '80', '81', '82', '83', '84', '85']
|
||||
else:
|
||||
php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85']
|
||||
except:
|
||||
php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85']
|
||||
else:
|
||||
# Check other OS versions
|
||||
os_info = Upgrade.findOperatingSytem()
|
||||
if os_info in [Ubuntu24, CENTOS8]:
|
||||
php_versions = ['74', '80', '81', '82', '83', '84', '85']
|
||||
else:
|
||||
php_versions = ['71', '72', '73', '74', '80', '81', '82', '83', '84', '85']
|
||||
|
||||
# Check availability of each version
|
||||
available_versions = []
|
||||
for version in php_versions:
|
||||
if Upgrade.check_package_availability(f'lsphp{version}'):
|
||||
available_versions.append(version)
|
||||
else:
|
||||
Upgrade.stdOut(f"PHP {version} not available on this OS", 0)
|
||||
|
||||
return available_versions
|
||||
|
||||
@staticmethod
|
||||
def fixLiteSpeedConfig():
|
||||
"""Fix LiteSpeed configuration issues by creating missing files"""
|
||||
try:
|
||||
Upgrade.stdOut("Checking and fixing LiteSpeed configuration...", 1)
|
||||
|
||||
# Check if LiteSpeed is installed
|
||||
if not os.path.exists('/usr/local/lsws'):
|
||||
Upgrade.stdOut("LiteSpeed not found at /usr/local/lsws", 0)
|
||||
return
|
||||
|
||||
# Create missing configuration files
|
||||
config_files = [
|
||||
"/usr/local/lsws/conf/httpd_config.xml",
|
||||
"/usr/local/lsws/conf/httpd.conf",
|
||||
"/usr/local/lsws/conf/modsec.conf"
|
||||
]
|
||||
|
||||
for config_file in config_files:
|
||||
if not os.path.exists(config_file):
|
||||
Upgrade.stdOut(f"Missing LiteSpeed config: {config_file}", 0)
|
||||
|
||||
# Create directory if it doesn't exist
|
||||
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
||||
|
||||
# Create minimal config file
|
||||
if config_file.endswith('httpd_config.xml'):
|
||||
with open(config_file, 'w') as f:
|
||||
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
|
||||
f.write('<httpServerConfig>\n')
|
||||
f.write(' <!-- Minimal LiteSpeed configuration -->\n')
|
||||
f.write(' <listener>\n')
|
||||
f.write(' <name>Default</name>\n')
|
||||
f.write(' <address>*:8088</address>\n')
|
||||
f.write(' </listener>\n')
|
||||
f.write('</httpServerConfig>\n')
|
||||
elif config_file.endswith('httpd.conf'):
|
||||
with open(config_file, 'w') as f:
|
||||
f.write('# Minimal LiteSpeed HTTP configuration\n')
|
||||
f.write('# This file will be updated by CyberPanel\n')
|
||||
elif config_file.endswith('modsec.conf'):
|
||||
with open(config_file, 'w') as f:
|
||||
f.write('# ModSecurity configuration\n')
|
||||
f.write('# This file will be updated by CyberPanel\n')
|
||||
|
||||
Upgrade.stdOut(f"Created minimal config: {config_file}", 1)
|
||||
else:
|
||||
Upgrade.stdOut(f"LiteSpeed config exists: {config_file}", 1)
|
||||
|
||||
except Exception as e:
|
||||
Upgrade.stdOut(f"Error fixing LiteSpeed config: {str(e)}", 0)
|
||||
|
||||
@staticmethod
|
||||
def installPHP73():
|
||||
try:
|
||||
if Upgrade.installedOutput.find('lsphp73') == -1:
|
||||
command = 'yum install -y lsphp73 lsphp73-json lsphp73-xmlrpc lsphp73-xml lsphp73-tidy lsphp73-soap lsphp73-snmp ' \
|
||||
'lsphp73-recode lsphp73-pspell lsphp73-process lsphp73-pgsql lsphp73-pear lsphp73-pdo lsphp73-opcache ' \
|
||||
'lsphp73-odbc lsphp73-mysqlnd lsphp73-mcrypt lsphp73-mbstring lsphp73-ldap lsphp73-intl lsphp73-imap ' \
|
||||
'lsphp73-gmp lsphp73-gd lsphp73-enchant lsphp73-dba lsphp73-common lsphp73-bcmath'
|
||||
Upgrade.executioner(command, 'Install PHP 73, 0')
|
||||
|
||||
if Upgrade.installedOutput.find('lsphp74') == -1:
|
||||
command = 'yum install -y lsphp74 lsphp74-json lsphp74-xmlrpc lsphp74-xml lsphp74-tidy lsphp74-soap lsphp74-snmp ' \
|
||||
'lsphp74-recode lsphp74-pspell lsphp74-process lsphp74-pgsql lsphp74-pear lsphp74-pdo lsphp74-opcache ' \
|
||||
'lsphp74-odbc lsphp74-mysqlnd lsphp74-mcrypt lsphp74-mbstring lsphp74-ldap lsphp74-intl lsphp74-imap ' \
|
||||
'lsphp74-gmp lsphp74-gd lsphp74-enchant lsphp74-dba lsphp74-common lsphp74-bcmath'
|
||||
|
||||
Upgrade.executioner(command, 'Install PHP 74, 0')
|
||||
|
||||
if Upgrade.installedOutput.find('lsphp80') == -1:
|
||||
command = 'yum install lsphp80* -y'
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
if Upgrade.installedOutput.find('lsphp81') == -1:
|
||||
command = 'yum install lsphp81* -y'
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
if Upgrade.installedOutput.find('lsphp82') == -1:
|
||||
command = 'yum install lsphp82* -y'
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
command = 'yum install lsphp83* -y'
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
command = 'yum install lsphp84* -y'
|
||||
subprocess.call(command, shell=True)
|
||||
|
||||
command = 'yum install lsphp85* -y'
|
||||
Upgrade.stdOut("Installing PHP versions based on OS compatibility...", 1)
|
||||
|
||||
# Get available PHP versions
|
||||
available_versions = Upgrade.get_available_php_versions()
|
||||
|
||||
if not available_versions:
|
||||
Upgrade.stdOut("No PHP versions available for installation", 0)
|
||||
return
|
||||
|
||||
Upgrade.stdOut(f"Installing available PHP versions: {', '.join(available_versions)}", 1)
|
||||
|
||||
for version in available_versions:
|
||||
try:
|
||||
if version in ['71', '72', '73', '74']:
|
||||
# PHP 7.x versions with specific extensions
|
||||
if Upgrade.installedOutput.find(f'lsphp{version}') == -1:
|
||||
extensions = ['json', 'xmlrpc', 'xml', 'tidy', 'soap', 'snmp', 'recode', 'pspell', 'process', 'pgsql', 'pear', 'pdo', 'opcache', 'odbc', 'mysqlnd', 'mcrypt', 'mbstring', 'ldap', 'intl', 'imap', 'gmp', 'gd', 'enchant', 'dba', 'common', 'bcmath']
|
||||
package_list = f"lsphp{version} " + " ".join([f"lsphp{version}-{ext}" for ext in extensions])
|
||||
command = f"yum install -y {package_list}"
|
||||
Upgrade.executioner(command, f'Install PHP {version}', 0)
|
||||
else:
|
||||
# PHP 8.x versions
|
||||
if Upgrade.installedOutput.find(f'lsphp{version}') == -1:
|
||||
command = f"yum install lsphp{version}* -y"
|
||||
subprocess.call(command, shell=True)
|
||||
Upgrade.stdOut(f"Installed PHP {version}", 1)
|
||||
|
||||
except Exception as e:
|
||||
Upgrade.stdOut(f"Error installing PHP {version}: {str(e)}", 0)
|
||||
continue
|
||||
|
||||
except:
|
||||
command = 'DEBIAN_FRONTEND=noninteractive apt-get -y install ' \
|
||||
@@ -3997,9 +4174,20 @@ pm.max_spare_servers = 3
|
||||
@staticmethod
|
||||
def setupPHPSymlink():
|
||||
try:
|
||||
# Check if PHP 8.3 exists
|
||||
if not os.path.exists('/usr/local/lsws/lsphp83/bin/php'):
|
||||
Upgrade.stdOut("PHP 8.3 not found, installing it first...")
|
||||
# Try to find available PHP version (prioritize modern stable versions)
|
||||
# Priority: 8.3 (recommended), 8.2, 8.4, 8.5, 8.1, 8.0, then older versions
|
||||
php_versions = ['83', '82', '84', '85', '81', '80', '74', '73', '72', '71']
|
||||
selected_php = None
|
||||
|
||||
for version in php_versions:
|
||||
if os.path.exists(f'/usr/local/lsws/lsphp{version}/bin/php'):
|
||||
selected_php = version
|
||||
Upgrade.stdOut(f"Found PHP {version}, using as default", 1)
|
||||
break
|
||||
|
||||
if not selected_php:
|
||||
# Try to install PHP 8.3 as fallback (modern stable version)
|
||||
Upgrade.stdOut("No PHP found, installing PHP 8.3 as fallback...")
|
||||
|
||||
# Install PHP 8.3 based on OS
|
||||
if os.path.exists(Upgrade.CentOSPath) or os.path.exists(Upgrade.openEulerPath):
|
||||
@@ -4013,16 +4201,17 @@ pm.max_spare_servers = 3
|
||||
if not os.path.exists('/usr/local/lsws/lsphp83/bin/php'):
|
||||
Upgrade.stdOut('[ERROR] Failed to install PHP 8.3')
|
||||
return 0
|
||||
selected_php = '83'
|
||||
|
||||
# Remove existing PHP symlink if it exists
|
||||
if os.path.exists('/usr/bin/php'):
|
||||
os.remove('/usr/bin/php')
|
||||
|
||||
# Create symlink to PHP 8.3
|
||||
command = 'ln -s /usr/local/lsws/lsphp83/bin/php /usr/bin/php'
|
||||
Upgrade.executioner(command, 'Setup PHP Symlink to 8.3', 0)
|
||||
# Create symlink to selected PHP version
|
||||
command = f'ln -s /usr/local/lsws/lsphp{selected_php}/bin/php /usr/bin/php'
|
||||
Upgrade.executioner(command, f'Setup PHP Symlink to {selected_php}', 0)
|
||||
|
||||
Upgrade.stdOut("PHP symlink updated to PHP 8.3 successfully.")
|
||||
Upgrade.stdOut(f"PHP symlink updated to PHP {selected_php} successfully.")
|
||||
|
||||
except BaseException as msg:
|
||||
Upgrade.stdOut('[ERROR] ' + str(msg) + " [setupPHPSymlink]")
|
||||
@@ -4150,6 +4339,9 @@ pm.max_spare_servers = 3
|
||||
Upgrade.manageServiceMigrations()
|
||||
Upgrade.enableServices()
|
||||
|
||||
# Apply AlmaLinux 9 fixes before other installations
|
||||
Upgrade.fix_almalinux9_mariadb()
|
||||
|
||||
Upgrade.installPHP73()
|
||||
Upgrade.setupCLI()
|
||||
Upgrade.someDirectories()
|
||||
@@ -4158,6 +4350,9 @@ pm.max_spare_servers = 3
|
||||
|
||||
## Fix Apache configuration issues after upgrade
|
||||
Upgrade.fixApacheConfiguration()
|
||||
|
||||
# Fix LiteSpeed configuration files if missing
|
||||
Upgrade.fixLiteSpeedConfig()
|
||||
|
||||
### General migrations are not needed any more
|
||||
|
||||
@@ -4191,8 +4386,32 @@ pm.max_spare_servers = 3
|
||||
except:
|
||||
pass
|
||||
|
||||
command = 'cp /usr/local/lsws/lsphp80/bin/lsphp %s' % (phpPath)
|
||||
# Try to find available PHP binary in order of preference (modern stable first)
|
||||
php_versions = ['83', '82', '84', '85', '81', '80', '74', '73', '72', '71']
|
||||
php_binary_found = False
|
||||
|
||||
for version in php_versions:
|
||||
php_binary = f'/usr/local/lsws/lsphp{version}/bin/lsphp'
|
||||
if os.path.exists(php_binary):
|
||||
command = f'cp {php_binary} {phpPath}'
|
||||
Upgrade.executioner(command, 0)
|
||||
Upgrade.stdOut(f"Using PHP {version} for LSCPD", 1)
|
||||
php_binary_found = True
|
||||
break
|
||||
|
||||
if not php_binary_found:
|
||||
Upgrade.stdOut("Warning: No PHP binary found for LSCPD", 0)
|
||||
# Try to create a symlink to any available PHP
|
||||
try:
|
||||
command = 'find /usr/local/lsws -name "lsphp" -type f 2>/dev/null | head -1'
|
||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||
if result.stdout.strip():
|
||||
php_binary = result.stdout.strip()
|
||||
command = f'cp {php_binary} {phpPath}'
|
||||
Upgrade.executioner(command, 0)
|
||||
Upgrade.stdOut(f"Using found PHP binary: {php_binary}", 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
if Upgrade.SoftUpgrade == 0:
|
||||
try:
|
||||
@@ -4200,6 +4419,42 @@ pm.max_spare_servers = 3
|
||||
Upgrade.executioner(command, 'Start LSCPD', 0)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Try to start other services if they exist
|
||||
# Enhanced service startup with AlmaLinux 9 support
|
||||
services_to_start = ['fastapi_ssh_server', 'cyberpanel']
|
||||
|
||||
# Special handling for AlmaLinux 9 MariaDB service
|
||||
if Upgrade.is_almalinux9():
|
||||
Upgrade.stdOut("AlmaLinux 9 detected - applying enhanced service management", 1)
|
||||
mariadb_services = ['mariadb', 'mysql', 'mysqld']
|
||||
for service in mariadb_services:
|
||||
try:
|
||||
check_command = f"systemctl list-unit-files | grep -q {service}"
|
||||
result = subprocess.run(check_command, shell=True, capture_output=True)
|
||||
if result.returncode == 0:
|
||||
command = f"systemctl restart {service}"
|
||||
Upgrade.executioner(command, f'Restart {service} for AlmaLinux 9', 0)
|
||||
command = f"systemctl enable {service}"
|
||||
Upgrade.executioner(command, f'Enable {service} for AlmaLinux 9', 0)
|
||||
Upgrade.stdOut(f"MariaDB service managed as {service} on AlmaLinux 9", 1)
|
||||
break
|
||||
except Exception as e:
|
||||
Upgrade.stdOut(f"Could not manage MariaDB service {service}: {str(e)}", 0)
|
||||
continue
|
||||
|
||||
for service in services_to_start:
|
||||
try:
|
||||
# Check if service exists
|
||||
check_command = f"systemctl list-unit-files | grep -q {service}"
|
||||
result = subprocess.run(check_command, shell=True, capture_output=True)
|
||||
if result.returncode == 0:
|
||||
command = f"systemctl start {service}"
|
||||
Upgrade.executioner(command, f'Start {service}', 0)
|
||||
else:
|
||||
Upgrade.stdOut(f"Service {service} not found, skipping", 0)
|
||||
except Exception as e:
|
||||
Upgrade.stdOut(f"Could not start {service}: {str(e)}", 0)
|
||||
|
||||
# Remove CSF if installed and restore firewalld (CSF is being discontinued on August 31, 2025)
|
||||
if os.path.exists('/etc/csf'):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user