From 9627770c99e57bc6ee3cb47fbcabc272ad44494b Mon Sep 17 00:00:00 2001 From: master3395 Date: Thu, 26 Mar 2026 01:04:48 +0100 Subject: [PATCH] fix(install): Ubuntu MaxScale apt repo (#1740), AlmaLinux 10 prereqs (#1736) - Add install_utils.strip_mariadb_maxscale_apt_repos() after mariadb_repo_setup so noble/jammy apt-get update succeeds (GH usmannasir/cyberpanel#1740). - AlmaLinux 10: skip early return after universal fixes; add is_almalinux10, fix_almalinux10_mariadb (EPEL, CRB, MariaDB.org repo, maxscale disable). - EL10 maps to rhel9 for OLS custom binary URLs until el10 builds exist. - Mirror MaxScale strip in install.py _attemptMariaDBUpgrade Ubuntu path. --- install/install.py | 51 +++++++++++++++++++++++++++++++- install/installCyberPanel.py | 7 +++-- install/install_utils.py | 56 ++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/install/install.py b/install/install.py index 765f8b5a3..1fa4829d7 100644 --- a/install/install.py +++ b/install/install.py @@ -236,6 +236,11 @@ class preFlightsChecks: os_info = self.detect_os_info() return os_info['name'] == 'almalinux' and os_info['major_version'] == 9 + def is_almalinux10(self): + """Check if running on AlmaLinux 10 (GH usmannasir/cyberpanel#1736)""" + os_info = self.detect_os_info() + return os_info['name'] == 'almalinux' and os_info['major_version'] == 10 + def is_ubuntu(self): """Check if running on Ubuntu""" os_info = self.detect_os_info() @@ -651,6 +656,34 @@ class preFlightsChecks: except Exception as e: self.stdOut(f"Error applying AlmaLinux 9 MariaDB fixes: {str(e)}", 0) + def fix_almalinux10_mariadb(self): + """EPEL/CRB + MariaDB official repo for AlmaLinux 10 (installer prereqs, GH #1736).""" + if not self.is_almalinux10(): + return + try: + self.stdOut("Applying AlmaLinux 10 MariaDB / repo fixes...", 1) + for cmd, desc in ( + ("dnf install -y epel-release", "EPEL"), + ("dnf config-manager --set-enabled crb 2>/dev/null || dnf config-manager --set-enabled powertools 2>/dev/null || true", "CRB/PowerTools"), + ("dnf install -y htop 2>/dev/null || true", "htop"), + ): + self.call(cmd, self.distro, desc, desc, 1, 0, os.EX_OSERR) + for cmd, desc in ( + ("dnf config-manager --disable mariadb-maxscale 2>/dev/null || true", "disable maxscale"), + ("rm -f /etc/yum.repos.d/mariadb-maxscale.repo /etc/yum.repos.d/mariadb-maxscale.repo.rpmnew 2>/dev/null || true", "remove maxscale repo files"), + ): + self.call(cmd, self.distro, desc, desc, 1, 0, os.EX_OSERR) + self.stdOut("Setting up MariaDB official repository (11.8 LTS, EL10)...", 1) + cmd = "curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version='11.8'" + self.call(cmd, self.distro, cmd, cmd, 1, 0, os.EX_OSERR) + self.call("dnf config-manager --disable mariadb-maxscale 2>/dev/null || true", self.distro, "disable maxscale after setup", "disable maxscale after setup", 1, 0, os.EX_OSERR) + self.stdOut("Installing MariaDB packages from MariaDB.org repo...", 1) + pkgs = "MariaDB-server MariaDB-client MariaDB-backup MariaDB-devel" + self.call(f"dnf install -y --nobest {pkgs}", self.distro, "MariaDB packages", "MariaDB packages", 1, 0, os.EX_OSERR) + self.stdOut("AlmaLinux 10 MariaDB fixes applied successfully", 1) + except Exception as e: + self.stdOut(f"Error applying AlmaLinux 10 MariaDB fixes: {str(e)}", 0) + def install_package_with_fallbacks(self, package_name, dev_package_name=None): """Install package with comprehensive fallback methods for AlmaLinux 9.6+""" try: @@ -826,7 +859,11 @@ class preFlightsChecks: universal_fixes = UniversalOSFixes() if universal_fixes.run_comprehensive_setup(): self.stdOut("Universal OS fixes applied successfully", 1) - return True + os_i = self.detect_os_info() + if os_i.get('name') == 'almalinux' and os_i.get('major_version') == 10: + self.stdOut("AlmaLinux 10: running legacy RHEL integration steps after universal fixes...", 1) + else: + return True else: self.stdOut("Universal OS fixes failed, falling back to legacy fixes...", 1) except ImportError: @@ -842,6 +879,8 @@ class preFlightsChecks: for fix in fixes_needed: if fix == 'mariadb' and self.is_almalinux9(): self.fix_almalinux9_mariadb() + elif fix == 'mariadb' and self.is_almalinux10(): + self.fix_almalinux10_mariadb() elif fix == 'ubuntu_specific' and self.is_ubuntu(): self.fix_ubuntu_specific() elif fix == 'debian_specific' and self.is_debian(): @@ -889,6 +928,11 @@ class preFlightsChecks: if any(distro in content for distro in ['red hat', 'almalinux', 'rocky', 'cloudlinux', 'centos']): return 'rhel9' + # EL10: use rhel9 OLS/custom binaries until el10-specific builds ship (GLIBC-compatible) + if 'version="10.' in content or 'version_id="10.' in content or 'version_id="10"' in content: + if any(distro in content for distro in ['red hat', 'almalinux', 'rocky', 'cloudlinux', 'centos']): + return 'rhel9' + # Default to rhel8 if can't detect (safer default - rhel9 binaries may require GLIBC 2.35) self.stdOut("WARNING: Could not detect platform, defaulting to rhel8", 1) return 'rhel8' @@ -1711,6 +1755,11 @@ module cyberpanel_ols { if result.returncode != 0: logging.InstallLog.writeToFile(f"Failed to setup MariaDB repository: {result.stderr}") return False + try: + import install_utils + install_utils.strip_mariadb_maxscale_apt_repos() + except Exception: + pass command = 'DEBIAN_FRONTEND=noninteractive apt-get update -y' result = subprocess.run(command, shell=True, capture_output=True, universal_newlines=True) diff --git a/install/installCyberPanel.py b/install/installCyberPanel.py index 0e8b3e38a..8f04b70a4 100644 --- a/install/installCyberPanel.py +++ b/install/installCyberPanel.py @@ -38,6 +38,7 @@ def get_Ubuntu_code_name(): return "xenial" + # Using shared function from install_utils FetchCloudLinuxAlmaVersionVersion = install_utils.FetchCloudLinuxAlmaVersionVersion @@ -996,9 +997,11 @@ deb [arch=amd64,arm64,ppc64el,s390x signed-by=/usr/share/keyrings/mariadb-keyrin install_utils.writeToFile("Manual MariaDB repository configuration completed.") + # GH #1740: strip broken MaxScale apt entries after mariadb_repo_setup (noble/jammy+) + if get_Ubuntu_release() > 21.00: + install_utils.strip_mariadb_maxscale_apt_repos() - - command = 'DEBIAN_FRONTEND=noninteractive apt-get update -y' + command = 'DEBIAN_FRONTEND=noninteractive apt-get update -y' install_utils.call(command, self.distro, command, command, 1, 1, os.EX_OSERR, True) diff --git a/install/install_utils.py b/install/install_utils.py index 5e856a503..53285a8d8 100644 --- a/install/install_utils.py +++ b/install/install_utils.py @@ -5,6 +5,7 @@ This module contains shared functions used by both install.py and installCyberPa """ import os +import glob import sys import time import logging @@ -676,6 +677,61 @@ def generate_random_string(length=32, include_special=False): return ''.join(secrets.choice(alphabet) for _ in range(length)) + +def strip_mariadb_maxscale_apt_repos(): + """ + MariaDB mariadb_repo_setup adds MaxScale apt repo; Ubuntu noble has no Release (GH usmannasir/cyberpanel#1740). + """ + slist = '/etc/apt/sources.list.d' + try: + if not os.path.isdir(slist): + return + for pattern in ( + 'mariadb-maxscale*.list', 'mariadb-maxscale*.sources', + '*maxscale*.list', '*maxscale*.sources', + ): + for fp in glob.glob(os.path.join(slist, pattern)): + try: + os.remove(fp) + except OSError: + pass + for fp in glob.glob(os.path.join(slist, 'mariadb*.list')): + try: + with open(fp, 'r', encoding='utf-8', errors='replace') as handle: + lines = handle.readlines() + new_lines = [ + ln for ln in lines + if 'maxscale' not in ln.lower() + and 'dlm.mariadb.com/repo/maxscale' not in ln + ] + if new_lines != lines: + with open(fp, 'w', encoding='utf-8') as handle: + handle.writelines(new_lines) + except OSError: + pass + for fp in glob.glob(os.path.join(slist, 'mariadb*.sources')): + try: + with open(fp, 'r', encoding='utf-8', errors='replace') as handle: + content = handle.read() + if 'maxscale' not in content.lower() and 'dlm.mariadb.com/repo/maxscale' not in content: + continue + blocks = content.split('\n\n') + kept = [] + for block in blocks: + bl = block.lower() + if 'maxscale' in bl or 'dlm.mariadb.com/repo/maxscale' in block: + continue + kept.append(block) + new_content = '\n\n'.join(kept) + if new_content.strip() != content.strip(): + with open(fp, 'w', encoding='utf-8') as handle: + handle.write(new_content) + except OSError: + pass + except Exception: + pass + + def writeToFile(message): """ Write a message to the installation log file