Files
CyberPanel/install/universal_os_fixes.py

795 lines
32 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
CyberPanel Universal OS Compatibility Fixes
Ensures installer works on ALL supported operating systems
"""
import os
import sys
import subprocess
import platform
import json
import logging
from typing import Dict, List, Tuple, Optional
class UniversalOSFixes:
"""Universal OS compatibility fixes for CyberPanel installer"""
def __init__(self):
self.os_info = self.detect_os_info()
self.logger = self.setup_logging()
# Supported OS matrix
self.supported_os = {
'ubuntu': ['24.04', '22.04', '20.04'],
'debian': ['13', '12', '11'],
'almalinux': ['10', '9', '8'],
'rocky': ['9', '8'],
'rhel': ['9', '8'],
'cloudlinux': ['9', '8'],
'centos': ['7', '9'],
'centos_stream': ['9']
}
# Package mappings for different OS
self.package_mappings = {
'ubuntu': {
'python_dev': 'python3-dev',
'build_tools': 'build-essential',
'ssl_dev': 'libssl-dev',
'ffi_dev': 'libffi-dev',
'mysql_dev': 'libmariadb-dev',
'memcached_dev': 'libmemcached-dev',
'curl_dev': 'libcurl4-openssl-dev',
'zlib_dev': 'zlib1g-dev',
'xml_dev': 'libxml2-dev',
'xslt_dev': 'libxslt1-dev',
'jpeg_dev': 'libjpeg-dev',
'png_dev': 'libpng-dev',
'freetype_dev': 'libfreetype6-dev',
'icu_dev': 'libicu-dev',
'oniguruma_dev': 'libonig-dev',
'aspell_dev': 'libaspell-dev',
'enchant_dev': 'libenchant-2-dev',
'tidy_dev': 'libtidy-dev',
'zip_dev': 'libzip-dev',
'sqlite_dev': 'libsqlite3-dev',
'readline_dev': 'libreadline-dev',
'ncurses_dev': 'libncurses5-dev',
'bz2_dev': 'libbz2-dev',
'lzma_dev': 'liblzma-dev',
'gdbm_dev': 'libgdbm-dev',
'db_dev': 'libdb-dev',
'nss_dev': 'libnss3-dev',
'krb5_dev': 'libkrb5-dev',
'ldap_dev': 'libldap2-dev',
'sasl_dev': 'libsasl2-dev',
'gssapi_dev': 'libgssapi-krb5-2',
'expat_dev': 'libexpat1-dev',
'cairo_dev': 'libcairo2-dev',
'pango_dev': 'libpango1.0-dev',
'atk_dev': 'libatk1.0-dev',
'gtk_dev': 'libgtk-3-dev',
'gdk_dev': 'libgdk-pixbuf2.0-dev',
'x11_dev': 'libx11-dev',
'xext_dev': 'libxext-dev',
'xrender_dev': 'libxrender-dev',
'xfixes_dev': 'libxfixes-dev',
'xdamage_dev': 'libxdamage-dev',
'xcomposite_dev': 'libxcomposite-dev',
'xrandr_dev': 'libxrandr-dev',
'xss_dev': 'libxss-dev',
'xinerama_dev': 'libxinerama-dev',
'xcursor_dev': 'libxcursor-dev',
'xi_dev': 'libxi-dev',
'xtst_dev': 'libxtst-dev',
'xrandr_dev': 'libxrandr-dev',
'xss_dev': 'libxss-dev',
'xinerama_dev': 'libxinerama-dev',
'xcursor_dev': 'libxcursor-dev',
'xi_dev': 'libxi-dev',
'xtst_dev': 'libxtst-dev'
},
'debian': {
'python_dev': 'python3-dev',
'build_tools': 'build-essential',
'ssl_dev': 'libssl-dev',
'ffi_dev': 'libffi-dev',
'mysql_dev': 'libmariadb-dev',
'memcached_dev': 'libmemcached-dev',
'curl_dev': 'libcurl4-openssl-dev',
'zlib_dev': 'zlib1g-dev',
'xml_dev': 'libxml2-dev',
'xslt_dev': 'libxslt1-dev',
'jpeg_dev': 'libjpeg-dev',
'png_dev': 'libpng-dev',
'freetype_dev': 'libfreetype6-dev',
'icu_dev': 'libicu-dev',
'oniguruma_dev': 'libonig-dev',
'aspell_dev': 'libaspell-dev',
'enchant_dev': 'libenchant-2-dev',
'tidy_dev': 'libtidy-dev',
'zip_dev': 'libzip-dev',
'sqlite_dev': 'libsqlite3-dev',
'readline_dev': 'libreadline-dev',
'ncurses_dev': 'libncurses5-dev',
'bz2_dev': 'libbz2-dev',
'lzma_dev': 'liblzma-dev',
'gdbm_dev': 'libgdbm-dev',
'db_dev': 'libdb-dev',
'nss_dev': 'libnss3-dev',
'krb5_dev': 'libkrb5-dev',
'ldap_dev': 'libldap2-dev',
'sasl_dev': 'libsasl2-dev',
'gssapi_dev': 'libgssapi-krb5-2',
'expat_dev': 'libexpat1-dev'
},
'almalinux': {
'python_dev': 'python3-devel',
'build_tools': 'gcc gcc-c++ make',
'ssl_dev': 'openssl-devel',
'ffi_dev': 'libffi-devel',
'mysql_dev': 'mariadb-devel',
'memcached_dev': 'libmemcached-devel',
'curl_dev': 'libcurl-devel',
'zlib_dev': 'zlib-devel',
'xml_dev': 'libxml2-devel',
'xslt_dev': 'libxslt-devel',
'jpeg_dev': 'libjpeg-turbo-devel',
'png_dev': 'libpng-devel',
'freetype_dev': 'freetype-devel',
'icu_dev': 'libicu-devel',
'oniguruma_dev': 'oniguruma-devel',
'aspell_dev': 'aspell-devel',
'enchant_dev': 'enchant-devel',
'tidy_dev': 'tidy-devel',
'zip_dev': 'libzip-devel',
'sqlite_dev': 'sqlite-devel',
'readline_dev': 'readline-devel',
'ncurses_dev': 'ncurses-devel',
'bz2_dev': 'bzip2-devel',
'lzma_dev': 'xz-devel',
'gdbm_dev': 'gdbm-devel',
'db_dev': 'db4-devel',
'nss_dev': 'nss-devel',
'krb5_dev': 'krb5-devel',
'ldap_dev': 'openldap-devel',
'sasl_dev': 'cyrus-sasl-devel',
'gssapi_dev': 'libgssapi-krb5',
'expat_dev': 'expat-devel',
'cairo_dev': 'cairo-devel',
'pango_dev': 'pango-devel',
'atk_dev': 'atk-devel',
'gtk_dev': 'gtk3-devel',
'gdk_dev': 'gdk-pixbuf2-devel',
'x11_dev': 'libX11-devel',
'xext_dev': 'libXext-devel',
'xrender_dev': 'libXrender-devel',
'xfixes_dev': 'libXfixes-devel',
'xdamage_dev': 'libXdamage-devel',
'xcomposite_dev': 'libXcomposite-devel',
'xrandr_dev': 'libXrandr-devel',
'xss_dev': 'libXScrnSaver-devel',
'xinerama_dev': 'libXinerama-devel',
'xcursor_dev': 'libXcursor-devel',
'xi_dev': 'libXi-devel',
'xtst_dev': 'libXtst-devel'
},
'rocky': {
'python_dev': 'python3-devel',
'build_tools': 'gcc gcc-c++ make',
'ssl_dev': 'openssl-devel',
'ffi_dev': 'libffi-devel',
'mysql_dev': 'mariadb-devel',
'memcached_dev': 'libmemcached-devel',
'curl_dev': 'libcurl-devel',
'zlib_dev': 'zlib-devel',
'xml_dev': 'libxml2-devel',
'xslt_dev': 'libxslt-devel',
'jpeg_dev': 'libjpeg-turbo-devel',
'png_dev': 'libpng-devel',
'freetype_dev': 'freetype-devel',
'icu_dev': 'libicu-devel',
'oniguruma_dev': 'oniguruma-devel',
'aspell_dev': 'aspell-devel',
'enchant_dev': 'enchant-devel',
'tidy_dev': 'tidy-devel',
'zip_dev': 'libzip-devel',
'sqlite_dev': 'sqlite-devel',
'readline_dev': 'readline-devel',
'ncurses_dev': 'ncurses-devel',
'bz2_dev': 'bzip2-devel',
'lzma_dev': 'xz-devel',
'gdbm_dev': 'gdbm-devel',
'db_dev': 'db4-devel',
'nss_dev': 'nss-devel',
'krb5_dev': 'krb5-devel',
'ldap_dev': 'openldap-devel',
'sasl_dev': 'cyrus-sasl-devel',
'gssapi_dev': 'libgssapi-krb5',
'expat_dev': 'expat-devel'
},
'rhel': {
'python_dev': 'python3-devel',
'build_tools': 'gcc gcc-c++ make',
'ssl_dev': 'openssl-devel',
'ffi_dev': 'libffi-devel',
'mysql_dev': 'mariadb-devel',
'memcached_dev': 'libmemcached-devel',
'curl_dev': 'libcurl-devel',
'zlib_dev': 'zlib-devel',
'xml_dev': 'libxml2-devel',
'xslt_dev': 'libxslt-devel',
'jpeg_dev': 'libjpeg-turbo-devel',
'png_dev': 'libpng-devel',
'freetype_dev': 'freetype-devel',
'icu_dev': 'libicu-devel',
'oniguruma_dev': 'oniguruma-devel',
'aspell_dev': 'aspell-devel',
'enchant_dev': 'enchant-devel',
'tidy_dev': 'tidy-devel',
'zip_dev': 'libzip-devel',
'sqlite_dev': 'sqlite-devel',
'readline_dev': 'readline-devel',
'ncurses_dev': 'ncurses-devel',
'bz2_dev': 'bzip2-devel',
'lzma_dev': 'xz-devel',
'gdbm_dev': 'gdbm-devel',
'db_dev': 'db4-devel',
'nss_dev': 'nss-devel',
'krb5_dev': 'krb5-devel',
'ldap_dev': 'openldap-devel',
'sasl_dev': 'cyrus-sasl-devel',
'gssapi_dev': 'libgssapi-krb5',
'expat_dev': 'expat-devel'
},
'cloudlinux': {
'python_dev': 'python3-devel',
'build_tools': 'gcc gcc-c++ make',
'ssl_dev': 'openssl-devel',
'ffi_dev': 'libffi-devel',
'mysql_dev': 'mariadb-devel',
'memcached_dev': 'libmemcached-devel',
'curl_dev': 'libcurl-devel',
'zlib_dev': 'zlib-devel',
'xml_dev': 'libxml2-devel',
'xslt_dev': 'libxslt-devel',
'jpeg_dev': 'libjpeg-turbo-devel',
'png_dev': 'libpng-devel',
'freetype_dev': 'freetype-devel',
'icu_dev': 'libicu-devel',
'oniguruma_dev': 'oniguruma-devel',
'aspell_dev': 'aspell-devel',
'enchant_dev': 'enchant-devel',
'tidy_dev': 'tidy-devel',
'zip_dev': 'libzip-devel',
'sqlite_dev': 'sqlite-devel',
'readline_dev': 'readline-devel',
'ncurses_dev': 'ncurses-devel',
'bz2_dev': 'bzip2-devel',
'lzma_dev': 'xz-devel',
'gdbm_dev': 'gdbm-devel',
'db_dev': 'db4-devel',
'nss_dev': 'nss-devel',
'krb5_dev': 'krb5-devel',
'ldap_dev': 'openldap-devel',
'sasl_dev': 'cyrus-sasl-devel',
'gssapi_dev': 'libgssapi-krb5',
'expat_dev': 'expat-devel'
},
'centos': {
'python_dev': 'python3-devel',
'build_tools': 'gcc gcc-c++ make',
'ssl_dev': 'openssl-devel',
'ffi_dev': 'libffi-devel',
'mysql_dev': 'mariadb-devel',
'memcached_dev': 'libmemcached-devel',
'curl_dev': 'libcurl-devel',
'zlib_dev': 'zlib-devel',
'xml_dev': 'libxml2-devel',
'xslt_dev': 'libxslt-devel',
'jpeg_dev': 'libjpeg-turbo-devel',
'png_dev': 'libpng-devel',
'freetype_dev': 'freetype-devel',
'icu_dev': 'libicu-devel',
'oniguruma_dev': 'oniguruma-devel',
'aspell_dev': 'aspell-devel',
'enchant_dev': 'enchant-devel',
'tidy_dev': 'tidy-devel',
'zip_dev': 'libzip-devel',
'sqlite_dev': 'sqlite-devel',
'readline_dev': 'readline-devel',
'ncurses_dev': 'ncurses-devel',
'bz2_dev': 'bzip2-devel',
'lzma_dev': 'xz-devel',
'gdbm_dev': 'gdbm-devel',
'db_dev': 'db4-devel',
'nss_dev': 'nss-devel',
'krb5_dev': 'krb5-devel',
'ldap_dev': 'openldap-devel',
'sasl_dev': 'cyrus-sasl-devel',
'gssapi_dev': 'libgssapi-krb5',
'expat_dev': 'expat-devel'
}
}
# Repository configurations
self.repo_configs = {
'ubuntu': {
'mariadb': 'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'litespeed': 'http://rpms.litespeedtech.com/ubuntu/',
'php': 'https://packages.sury.org/php/'
},
'debian': {
'mariadb': 'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'litespeed': 'http://rpms.litespeedtech.com/debian/',
'php': 'https://packages.sury.org/php/'
},
'almalinux': {
'mariadb': 'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'litespeed': 'http://rpms.litespeedtech.com/centos/',
'php': 'https://rpms.remirepo.net/enterprise/'
},
'rocky': {
'mariadb': 'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'litespeed': 'http://rpms.litespeedtech.com/centos/',
'php': 'https://rpms.remirepo.net/enterprise/'
},
'rhel': {
'mariadb': 'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'litespeed': 'http://rpms.litespeedtech.com/centos/',
'php': 'https://rpms.remirepo.net/enterprise/'
},
'cloudlinux': {
'mariadb': 'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'litespeed': 'http://rpms.litespeedtech.com/centos/',
'php': 'https://rpms.remirepo.net/enterprise/'
},
'centos': {
'mariadb': 'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'litespeed': 'http://rpms.litespeedtech.com/centos/',
'php': 'https://rpms.remirepo.net/enterprise/'
}
}
def detect_os_info(self) -> Dict[str, str]:
"""Detect operating system information"""
try:
with open('/etc/os-release', 'r') as f:
os_release = {}
for line in f:
if '=' in line:
key, value = line.strip().split('=', 1)
os_release[key] = value.strip('"')
# Normalize OS names
os_name = os_release.get('NAME', '').lower()
os_id = os_release.get('ID', '').lower()
os_version = os_release.get('VERSION_ID', '')
# Handle special cases
if 'ubuntu' in os_name or os_id == 'ubuntu':
return {'name': 'ubuntu', 'version': os_version, 'id': 'ubuntu'}
elif 'debian' in os_name or os_id == 'debian':
return {'name': 'debian', 'version': os_version, 'id': 'debian'}
elif 'almalinux' in os_name or os_id == 'almalinux':
return {'name': 'almalinux', 'version': os_version, 'id': 'almalinux'}
elif 'rocky' in os_name or os_id == 'rocky':
return {'name': 'rocky', 'version': os_version, 'id': 'rocky'}
elif 'red hat' in os_name or os_id == 'rhel':
return {'name': 'rhel', 'version': os_version, 'id': 'rhel'}
elif 'cloudlinux' in os_name or os_id == 'cloudlinux':
return {'name': 'cloudlinux', 'version': os_version, 'id': 'cloudlinux'}
elif 'centos' in os_name or os_id == 'centos':
return {'name': 'centos', 'version': os_version, 'id': 'centos'}
else:
return {'name': os_name, 'version': os_version, 'id': os_id}
except Exception as e:
self.logger.error(f"Error detecting OS: {e}")
return {'name': 'unknown', 'version': 'unknown', 'id': 'unknown'}
def setup_logging(self) -> logging.Logger:
"""Setup logging"""
logger = logging.getLogger('UniversalOSFixes')
logger.setLevel(logging.INFO)
if not logger.handlers:
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
def is_os_supported(self) -> bool:
"""Check if current OS is supported"""
os_id = self.os_info['id']
os_version = self.os_info['version']
if os_id in self.supported_os:
if os_version in self.supported_os[os_id]:
return True
else:
self.logger.warning(f"OS version {os_version} not explicitly supported for {os_id}")
return True # Still try to install
return False
def get_package_name(self, package_key: str) -> str:
"""Get package name for current OS"""
os_id = self.os_info['id']
if os_id in self.package_mappings:
return self.package_mappings[os_id].get(package_key, package_key)
return package_key
def get_package_manager_command(self) -> str:
"""Get package manager command for current OS"""
os_id = self.os_info['id']
if os_id in ['ubuntu', 'debian']:
return 'apt'
elif os_id in ['almalinux', 'rocky', 'rhel', 'cloudlinux', 'centos']:
# Check if dnf is available
try:
subprocess.run(['which', 'dnf'], check=True, capture_output=True)
return 'dnf'
except subprocess.CalledProcessError:
return 'yum'
return 'unknown'
def install_packages(self, packages: List[str]) -> bool:
"""Install packages using appropriate package manager"""
try:
package_manager = self.get_package_manager_command()
if package_manager == 'apt':
cmd = ['apt', 'update']
subprocess.run(cmd, check=True)
cmd = ['apt', 'install', '-y'] + packages
elif package_manager == 'dnf':
cmd = ['dnf', 'install', '-y'] + packages
elif package_manager == 'yum':
cmd = ['yum', 'install', '-y'] + packages
else:
self.logger.error(f"Unknown package manager: {package_manager}")
return False
subprocess.run(cmd, check=True)
self.logger.info(f"Successfully installed packages: {packages}")
return True
except subprocess.CalledProcessError as e:
self.logger.error(f"Failed to install packages {packages}: {e}")
return False
def setup_mariadb_repository(self) -> bool:
"""Setup MariaDB repository for current OS"""
try:
os_id = self.os_info['id']
if os_id in ['ubuntu', 'debian']:
# Ubuntu/Debian MariaDB setup
cmd = [
'curl', '-LsS',
'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'|', 'sudo', 'bash', '-s', '--', '--mariadb-server-version=12.1'
]
else:
# RHEL family MariaDB setup
cmd = [
'curl', '-LsS',
'https://downloads.mariadb.com/MariaDB/mariadb_repo_setup',
'|', 'sudo', 'bash', '-s', '--', '--mariadb-server-version=12.1'
]
subprocess.run(' '.join(cmd), shell=True, check=True)
self.logger.info("MariaDB repository setup completed")
return True
except subprocess.CalledProcessError as e:
self.logger.error(f"Failed to setup MariaDB repository: {e}")
return False
def setup_litespeed_repository(self) -> bool:
"""Setup LiteSpeed repository for current OS"""
try:
os_id = self.os_info['id']
os_version = self.os_info['version']
if os_id in ['ubuntu', 'debian']:
# Ubuntu/Debian LiteSpeed setup
cmd = [
'wget', '-O', '-',
'https://cyberpanel.sh/litespeed/litespeed-repo.sh'
]
subprocess.run(cmd, check=True)
cmd = ['bash', 'litespeed-repo.sh']
subprocess.run(cmd, check=True)
else:
# RHEL family LiteSpeed setup
# Use el8 repository for AlmaLinux 9/10 compatibility
if os_id in ['almalinux', 'rocky', 'rhel'] and int(os_version.split('.')[0]) >= 9:
repo_url = 'http://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el8.noarch.rpm'
else:
repo_url = f'http://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el{os_version.split(".")[0]}.noarch.rpm'
cmd = ['rpm', '-Uvh', repo_url]
subprocess.run(cmd, check=True)
self.logger.info("LiteSpeed repository setup completed")
return True
except subprocess.CalledProcessError as e:
self.logger.error(f"Failed to setup LiteSpeed repository: {e}")
return False
def install_essential_packages(self) -> bool:
"""Install essential packages for CyberPanel"""
try:
os_id = self.os_info['id']
# Common packages
common_packages = [
'curl', 'wget', 'git', 'python3', 'python3-pip',
'unzip', 'tar', 'gzip', 'bzip2', 'xz'
]
# OS-specific packages
if os_id in ['ubuntu', 'debian']:
packages = common_packages + [
'build-essential', 'python3-dev', 'libssl-dev',
'libffi-dev', 'libmariadb-dev', 'libcurl4-openssl-dev',
'zlib1g-dev', 'libxml2-dev', 'libxslt1-dev',
'libjpeg-dev', 'libpng-dev', 'libfreetype6-dev',
'libicu-dev', 'libonig-dev', 'libaspell-dev',
'libenchant-2-dev', 'libtidy-dev', 'libzip-dev',
'libsqlite3-dev', 'libreadline-dev', 'libncurses5-dev',
'libbz2-dev', 'liblzma-dev', 'libgdbm-dev',
'libdb-dev', 'libnss3-dev', 'libkrb5-dev',
'libldap2-dev', 'libsasl2-dev', 'libgssapi-krb5-2',
'libexpat1-dev'
]
else:
# RHEL family packages
packages = common_packages + [
'gcc', 'gcc-c++', 'make', 'python3-devel',
'openssl-devel', 'libffi-devel', 'mariadb-devel',
'libcurl-devel', 'zlib-devel', 'libxml2-devel',
'libxslt-devel', 'libjpeg-turbo-devel', 'libpng-devel',
'freetype-devel', 'libicu-devel', 'oniguruma-devel',
'aspell-devel', 'enchant-devel', 'tidy-devel',
'libzip-devel', 'sqlite-devel', 'readline-devel',
'ncurses-devel', 'bzip2-devel', 'xz-devel',
'gdbm-devel', 'db4-devel', 'nss-devel',
'krb5-devel', 'openldap-devel', 'cyrus-sasl-devel',
'libgssapi-krb5', 'expat-devel'
]
return self.install_packages(packages)
except Exception as e:
self.logger.error(f"Failed to install essential packages: {e}")
return False
def install_mariadb(self) -> bool:
"""Install MariaDB for current OS"""
try:
os_id = self.os_info['id']
if os_id in ['ubuntu', 'debian']:
packages = ['mariadb-server', 'mariadb-client', 'mariadb-common']
else:
packages = ['mariadb-server', 'mariadb', 'mariadb-devel']
return self.install_packages(packages)
except Exception as e:
self.logger.error(f"Failed to install MariaDB: {e}")
return False
def install_openlitespeed(self) -> bool:
"""Install OpenLiteSpeed for current OS"""
try:
os_id = self.os_info['id']
if os_id in ['ubuntu', 'debian']:
packages = ['openlitespeed']
else:
packages = ['openlitespeed']
return self.install_packages(packages)
except Exception as e:
self.logger.error(f"Failed to install OpenLiteSpeed: {e}")
return False
def create_systemd_services(self) -> bool:
"""Create systemd services for CyberPanel"""
try:
# Create LiteSpeed service
lsws_service = """[Unit]
Description=LiteSpeed Web Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/lsws/bin/lswsctrl start
ExecReload=/usr/local/lsws/bin/lswsctrl restart
ExecStop=/usr/local/lsws/bin/lswsctrl stop
PIDFile=/usr/local/lsws/logs/httpd.pid
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
"""
with open('/etc/systemd/system/lsws.service', 'w') as f:
f.write(lsws_service)
# Create CyberPanel service
cyberpanel_service = """[Unit]
Description=CyberPanel
After=network.target lsws.service
[Service]
Type=simple
User=root
WorkingDirectory=/usr/local/CyberCP
ExecStart=/usr/local/CyberPanel-venv/bin/python3 manage.py runserver 0.0.0.0:8090
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
"""
with open('/etc/systemd/system/cyberpanel.service', 'w') as f:
f.write(cyberpanel_service)
# Reload systemd
subprocess.run(['systemctl', 'daemon-reload'], check=True)
self.logger.info("Systemd services created successfully")
return True
except Exception as e:
self.logger.error(f"Failed to create systemd services: {e}")
return False
def apply_os_specific_fixes(self) -> bool:
"""Apply OS-specific fixes"""
try:
os_id = self.os_info['id']
os_version = self.os_info['version']
if os_id == 'almalinux' and int(os_version.split('.')[0]) >= 9:
# AlmaLinux 9+ specific fixes
self.logger.info("Applying AlmaLinux 9+ specific fixes...")
# Enable PowerTools repository
try:
subprocess.run(['dnf', 'config-manager', '--set-enabled', 'powertools'], check=True)
except subprocess.CalledProcessError:
try:
subprocess.run(['dnf', 'config-manager', '--set-enabled', 'PowerTools'], check=True)
except subprocess.CalledProcessError:
self.logger.warning("Could not enable PowerTools repository")
# Install compatibility packages
compatibility_packages = [
'compat-openssl11', 'compat-openssl11-devel',
'libxcrypt-compat', 'libnsl'
]
for package in compatibility_packages:
try:
subprocess.run(['dnf', 'install', '-y', package], check=True)
except subprocess.CalledProcessError:
self.logger.warning(f"Could not install compatibility package: {package}")
elif os_id == 'rocky' and int(os_version.split('.')[0]) >= 9:
# RockyLinux 9+ specific fixes
self.logger.info("Applying RockyLinux 9+ specific fixes...")
# Enable PowerTools repository
try:
subprocess.run(['dnf', 'config-manager', '--set-enabled', 'powertools'], check=True)
except subprocess.CalledProcessError:
try:
subprocess.run(['dnf', 'config-manager', '--set-enabled', 'PowerTools'], check=True)
except subprocess.CalledProcessError:
self.logger.warning("Could not enable PowerTools repository")
elif os_id == 'ubuntu' and os_version in ['24.04', '22.04']:
# Ubuntu 24.04/22.04 specific fixes
self.logger.info("Applying Ubuntu 24.04/22.04 specific fixes...")
# Update package lists
subprocess.run(['apt', 'update'], check=True)
# Install additional packages
additional_packages = [
'software-properties-common', 'apt-transport-https',
'ca-certificates', 'gnupg', 'lsb-release'
]
self.install_packages(additional_packages)
return True
except Exception as e:
self.logger.error(f"Failed to apply OS-specific fixes: {e}")
return False
def run_comprehensive_setup(self) -> bool:
"""Run comprehensive setup for all supported OS"""
try:
self.logger.info(f"Starting comprehensive setup for {self.os_info['name']} {self.os_info['version']}")
# Check OS support
if not self.is_os_supported():
self.logger.error(f"OS {self.os_info['name']} {self.os_info['version']} is not supported")
return False
# Apply OS-specific fixes
if not self.apply_os_specific_fixes():
self.logger.error("Failed to apply OS-specific fixes")
return False
# Setup repositories
if not self.setup_mariadb_repository():
self.logger.error("Failed to setup MariaDB repository")
return False
if not self.setup_litespeed_repository():
self.logger.error("Failed to setup LiteSpeed repository")
return False
# Install packages
if not self.install_essential_packages():
self.logger.error("Failed to install essential packages")
return False
if not self.install_mariadb():
self.logger.error("Failed to install MariaDB")
return False
if not self.install_openlitespeed():
self.logger.error("Failed to install OpenLiteSpeed")
return False
# Create services
if not self.create_systemd_services():
self.logger.error("Failed to create systemd services")
return False
self.logger.info("Comprehensive setup completed successfully")
return True
except Exception as e:
self.logger.error(f"Comprehensive setup failed: {e}")
return False
def main():
"""Main function"""
fixes = UniversalOSFixes()
print(f"CyberPanel Universal OS Compatibility Fixes")
print(f"Detected OS: {fixes.os_info['name']} {fixes.os_info['version']}")
print(f"OS ID: {fixes.os_info['id']}")
if fixes.run_comprehensive_setup():
print("✅ Setup completed successfully!")
return 0
else:
print("❌ Setup failed!")
return 1
if __name__ == "__main__":
sys.exit(main())