Merge pull request #1531 from master3395/v2.5.5-dev

Enhance virtual environment setup and MariaDB installation process

Added checks to ensure the Python virtual environment is properly set up before running migrations.
Implemented logic to find the correct Python executable from multiple potential paths.
Improved MariaDB installation by trying different package combinations for AlmaLinux 9 and checking for service file existence.
Enhanced service management to handle symlinks and alternative service names for MariaDB.
Added error handling for missing MySQL/MariaDB client commands and ensured proper cleanup of conflicting service files.
This commit is contained in:
Master3395 2025-09-24 13:57:06 +02:00 committed by GitHub
commit 8018a4a496
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 196 additions and 36 deletions

View File

@ -768,14 +768,40 @@ password="%s"
logging.InstallLog.writeToFile("Fixing baseTemplate migrations...")
self.fixBaseTemplateMigrations()
# Ensure virtual environment is properly set up
logging.InstallLog.writeToFile("Ensuring virtual environment is properly set up...")
if not self.ensureVirtualEnvironmentSetup():
logging.InstallLog.writeToFile("ERROR: Virtual environment setup failed!", 0)
preFlightsChecks.stdOut("ERROR: Virtual environment setup failed!", 0)
return False
# Find the correct Python virtual environment path
python_paths = [
"/usr/local/CyberPanel/bin/python",
"/usr/local/CyberCP/bin/python",
"/usr/local/CyberPanel-venv/bin/python"
]
python_path = None
for path in python_paths:
if os.path.exists(path):
python_path = path
logging.InstallLog.writeToFile(f"Found Python virtual environment at: {path}")
break
if not python_path:
logging.InstallLog.writeToFile("ERROR: No Python virtual environment found!", 0)
preFlightsChecks.stdOut("ERROR: No Python virtual environment found!", 0)
return False
# Create all migrations at once - Django will handle dependencies
logging.InstallLog.writeToFile("Creating fresh migrations for all apps...")
command = "/usr/local/CyberPanel-venv/bin/python manage.py makemigrations --noinput"
command = f"{python_path} manage.py makemigrations --noinput"
preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
# Apply all migrations
logging.InstallLog.writeToFile("Applying all migrations...")
command = "/usr/local/CyberPanel-venv/bin/python manage.py migrate --noinput"
command = f"{python_path} manage.py migrate --noinput"
preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
logging.InstallLog.writeToFile("Django migrations completed successfully!")
@ -784,7 +810,7 @@ password="%s"
if not os.path.exists("/usr/local/CyberCP/public"):
os.mkdir("/usr/local/CyberCP/public")
command = "/usr/local/CyberPanel-venv/bin/python manage.py collectstatic --noinput --clear"
command = f"{python_path} manage.py collectstatic --noinput --clear"
preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
## Moving static content to lscpd location
@ -2428,11 +2454,26 @@ user_query = SELECT email as user, password, 'vmail' as uid, 'vmail' as gid, '/h
def ensureVirtualEnvironmentSetup(self):
"""Ensure virtual environment is properly set up and accessible"""
try:
# Check if CyberCP virtual environment exists
if os.path.exists('/usr/local/CyberCP/bin/python'):
preFlightsChecks.stdOut("CyberCP virtual environment found", 1)
# Create symlink if CyberPanel path doesn't exist
# Check multiple possible virtual environment locations
venv_paths = [
'/usr/local/CyberCP/bin/python',
'/usr/local/CyberPanel/bin/python',
'/usr/local/CyberPanel-venv/bin/python'
]
found_venv = None
for path in venv_paths:
if os.path.exists(path):
found_venv = path
preFlightsChecks.stdOut(f"Virtual environment found at: {path}", 1)
break
if not found_venv:
preFlightsChecks.stdOut("No virtual environment found in expected locations", 0)
return False
# Create symlinks for compatibility if needed
if found_venv == '/usr/local/CyberCP/bin/python':
if not os.path.exists('/usr/local/CyberPanel/bin/python'):
if not os.path.exists('/usr/local/CyberPanel'):
preFlightsChecks.stdOut("Creating CyberPanel symlink for compatibility", 1)
@ -2440,12 +2481,19 @@ user_query = SELECT email as user, password, 'vmail' as uid, 'vmail' as gid, '/h
else:
preFlightsChecks.stdOut("CyberPanel directory exists but Python not found", 0)
return False
return True
else:
preFlightsChecks.stdOut("CyberCP virtual environment not found", 0)
# Test if Python is executable
try:
result = os.system(f"{found_venv} --version > /dev/null 2>&1")
if result != 0:
preFlightsChecks.stdOut(f"Python at {found_venv} is not executable", 0)
return False
except Exception as e:
preFlightsChecks.stdOut(f"Error testing Python executable: {str(e)}", 0)
return False
return True
except Exception as e:
preFlightsChecks.stdOut(f"Error setting up virtual environment: {str(e)}", 0)
return False

View File

@ -86,16 +86,53 @@ class InstallCyberPanel:
command = "dnf clean all"
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
# Install MariaDB from official repository
# Install MariaDB from official repository using shell=True for pipe commands
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_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR, shell=True)
# Install MariaDB packages
# Install MariaDB packages - use correct package names for AlmaLinux 9
self.stdOut("Installing MariaDB packages...", 1)
mariadb_packages = "mariadb-server mariadb-devel mariadb-client-utils"
command = f"dnf install -y {mariadb_packages}"
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
# Try different package combinations for AlmaLinux 9
mariadb_packages_attempts = [
"mariadb-server mariadb-devel mariadb-client",
"mariadb-server mariadb-devel",
"mariadb-server mariadb-devel mariadb-common"
]
installed = False
for packages in mariadb_packages_attempts:
command = f"dnf install -y {packages}"
result = install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 0:
self.stdOut(f"Successfully installed MariaDB packages: {packages}", 1)
installed = True
break
else:
self.stdOut(f"Failed to install packages: {packages}, trying next combination...", 1)
if not installed:
self.stdOut("Warning: Some MariaDB packages may not have installed correctly", 0)
# Check if MariaDB service exists and create it if needed
self.stdOut("Checking MariaDB service configuration...", 1)
if not os.path.exists('/usr/lib/systemd/system/mariadb.service'):
# Try to find the correct service file
possible_services = [
'/usr/lib/systemd/system/mysqld.service',
'/usr/lib/systemd/system/mysql.service'
]
for service_file in possible_services:
if os.path.exists(service_file):
self.stdOut(f"Found service file: {service_file}", 1)
# Create symlink to mariadb.service
try:
os.symlink(service_file, '/usr/lib/systemd/system/mariadb.service')
self.stdOut("Created symlink for mariadb.service", 1)
except OSError as e:
self.stdOut(f"Could not create symlink: {str(e)}", 0)
break
self.stdOut("AlmaLinux 9 MariaDB fixes completed", 1)
@ -115,7 +152,7 @@ class InstallCyberPanel:
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
def manage_service(self, service_name, action="start"):
"""Unified service management"""
"""Unified service management with symlink detection"""
service_map = {
'mariadb': 'mariadb',
'pureftpd': 'pure-ftpd-mysql' if self.distro == ubuntu else 'pure-ftpd',
@ -124,16 +161,33 @@ class InstallCyberPanel:
actual_service = service_map.get(service_name, service_name)
# For AlmaLinux 9, try both mariadb and mysqld services
if service_name == 'mariadb' and (self.distro == cent8 or self.distro == openeuler):
# Try mariadb first, then mysqld if mariadb fails
command = f'systemctl {action} {actual_service}'
result = install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result != 0:
# If mariadb service fails, try mysqld
command = f'systemctl {action} mysqld'
# For MariaDB, check if mysqld.service is a symlink to mariadb.service
if service_name == 'mariadb':
# Check if mysqld.service is a symlink to mariadb.service
if os.path.islink('/etc/systemd/system/mysqld.service'):
try:
target = os.readlink('/etc/systemd/system/mysqld.service')
if 'mariadb.service' in target:
self.stdOut(f"mysqld.service is a symlink to mariadb.service, skipping duplicate {action}", 1)
# Only run the action on mariadb, not mysqld
command = f'systemctl {action} mariadb'
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
except OSError:
pass
# For AlmaLinux 9, try both mariadb and mysqld services
if self.distro == cent8 or self.distro == openeuler:
# Try mariadb first, then mysqld if mariadb fails
command = f'systemctl {action} {actual_service}'
result = install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result != 0:
# If mariadb service fails, try mysqld
command = f'systemctl {action} mysqld'
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
return result
else:
command = f'systemctl {action} {actual_service}'
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
return result
else:
command = f'systemctl {action} {actual_service}'
return install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR)
@ -802,17 +856,43 @@ gpgcheck=1
passwordCMD = "use mysql;DROP DATABASE IF EXISTS test;DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%%';GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '%s';flush privileges;" % (
InstallCyberPanel.mysql_Root_password)
# Find the correct MySQL/MariaDB client command
mysql_commands = ['mysql', 'mariadb', '/usr/bin/mysql', '/usr/bin/mariadb', '/usr/local/bin/mysql', '/usr/local/bin/mariadb']
mysql_cmd = None
for cmd in mysql_commands:
if os.path.exists(cmd) or self.command_exists(cmd):
mysql_cmd = cmd
self.stdOut(f"Found MySQL client: {cmd}", 1)
break
if not mysql_cmd:
self.stdOut("ERROR: No MySQL/MariaDB client found!", 0)
return False
# For AlmaLinux 9, try mysql command first, then mariadb
if self.distro == cent8 or self.distro == openeuler:
command = 'mysql -u root -e "' + passwordCMD + '"'
command = f'{mysql_cmd} -u root -e "{passwordCMD}"'
result = install_utils.call(command, self.distro, command, command, 0, 0, os.EX_OSERR)
if result != 0:
# If mysql command fails, try mariadb
command = 'mariadb -u root -e "' + passwordCMD + '"'
install_utils.call(command, self.distro, command, command, 0, 0, os.EX_OSERR)
for alt_cmd in ['mariadb', '/usr/bin/mariadb']:
if alt_cmd != mysql_cmd and (os.path.exists(alt_cmd) or self.command_exists(alt_cmd)):
command = f'{alt_cmd} -u root -e "{passwordCMD}"'
result = install_utils.call(command, self.distro, command, command, 0, 0, os.EX_OSERR)
if result == 0:
break
else:
command = 'mariadb -u root -e "' + passwordCMD + '"'
command = f'{mysql_cmd} -u root -e "{passwordCMD}"'
install_utils.call(command, self.distro, command, command, 0, 0, os.EX_OSERR)
def command_exists(self, command):
"""Check if a command exists in PATH"""
try:
result = subprocess.run(['which', command], capture_output=True, text=True)
return result.returncode == 0
except:
return False
def startMariaDB(self):
@ -824,16 +904,48 @@ gpgcheck=1
self.stdOut("AlmaLinux 9 detected - applying MariaDB fixes", 1)
self.fix_almalinux9_mariadb()
self.manage_service('mariadb', 'start')
# Try to start MariaDB service
self.stdOut("Starting MariaDB service...", 1)
start_result = self.manage_service('mariadb', 'start')
if start_result != 0:
self.stdOut("MariaDB service start failed, trying alternative approaches...", 1)
# Try to start mysqld service as fallback
command = 'systemctl start mysqld'
result = install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 0:
self.stdOut("Successfully started mysqld service", 1)
else:
self.stdOut("Warning: Could not start MariaDB/MySQL service", 0)
############## Enable mariadb at system startup ######################
# Clean up any conflicting service files
if os.path.exists('/etc/systemd/system/mysqld.service'):
os.remove('/etc/systemd/system/mysqld.service')
if os.path.islink('/etc/systemd/system/mysqld.service'):
self.stdOut("Removing symlink: /etc/systemd/system/mysqld.service", 1)
os.remove('/etc/systemd/system/mysqld.service')
else:
self.stdOut("Removing file: /etc/systemd/system/mysqld.service", 1)
os.remove('/etc/systemd/system/mysqld.service')
if os.path.exists('/etc/systemd/system/mariadb.service'):
os.remove('/etc/systemd/system/mariadb.service')
if os.path.islink('/etc/systemd/system/mariadb.service'):
self.stdOut("Removing symlink: /etc/systemd/system/mariadb.service", 1)
os.remove('/etc/systemd/system/mariadb.service')
else:
self.stdOut("Removing file: /etc/systemd/system/mariadb.service", 1)
os.remove('/etc/systemd/system/mariadb.service')
self.manage_service('mariadb', 'enable')
# Reload systemd daemon after removing service files
os.system('systemctl daemon-reload')
# Try to enable MariaDB service
enable_result = self.manage_service('mariadb', 'enable')
if enable_result != 0:
self.stdOut("MariaDB service enable failed, trying mysqld...", 1)
command = 'systemctl enable mysqld'
install_utils.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
def fixMariaDB(self):
self.stdOut("Setup MariaDB so it can support Cyberpanel's needs")