diff --git a/install/install.py b/install/install.py index 504e34512..a0d04b107 100644 --- a/install/install.py +++ b/install/install.py @@ -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 diff --git a/install/installCyberPanel.py b/install/installCyberPanel.py index 3164915ac..c105dc2cb 100644 --- a/install/installCyberPanel.py +++ b/install/installCyberPanel.py @@ -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")