Update installation scripts for improved package handling and service management

- Modified `cyberpanel.sh` to correct the path for the `lsmcd` executable.
- Enhanced `install.py` with comprehensive fallback logic for installing AlmaLinux 9 packages, including support for PowerTools and alternative repositories.
- Improved error handling and installation methods in `venvsetup.sh` to ensure successful package installations with better error suppression and individual package handling.
- Added checks for service existence and installation for PowerDNS, improving the robustness of the installation process.
This commit is contained in:
Master3395
2025-09-25 02:12:33 +02:00
parent 3f2d3d5fdf
commit 09caa5bda8
3 changed files with 304 additions and 54 deletions

View File

@@ -2779,7 +2779,7 @@ After=network.target
[Service] [Service]
Type=simple Type=simple
ExecStart=/usr/local/bin/lsmcd -d ExecStart=/usr/local/lsmcd/bin/lsmcd -d
ExecReload=/bin/kill -HUP $MAINPID ExecReload=/bin/kill -HUP $MAINPID
KillMode=process KillMode=process
Restart=on-failure Restart=on-failure

View File

@@ -281,17 +281,55 @@ class preFlightsChecks:
] ]
for package, dev_package in alma9_specific: for package, dev_package in alma9_specific:
# Try to install the main package first installed = False
# Try to install both packages together first
try:
command = f"dnf install -y {package} {dev_package}"
result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package} and {dev_package}", 1)
installed = True
except:
pass
if not installed:
# Try to install packages individually
try:
command = f"dnf install -y {package}" command = f"dnf install -y {package}"
result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 1: if result == 1:
self.stdOut(f"Successfully installed {package}", 1) self.stdOut(f"Successfully installed {package}", 1)
# Try to install the development package except:
pass
try:
dev_command = f"dnf install -y {dev_package}" dev_command = f"dnf install -y {dev_package}"
self.call(dev_command, self.distro, dev_command, dev_command, 1, 0, os.EX_OSERR) result = self.call(dev_command, self.distro, dev_command, dev_command, 1, 0, os.EX_OSERR)
else: if result == 1:
self.stdOut(f"Successfully installed {dev_package}", 1)
installed = True
except:
pass
if not installed:
self.stdOut(f"Package {package} not available, trying alternatives...", 1) self.stdOut(f"Package {package} not available, trying alternatives...", 1)
# For AlmaLinux 9, try enabling PowerTools repository first
if self.distro == openeuler and os_info['name'] == 'almalinux' and os_info['major_version'] == '9':
try:
self.stdOut("Enabling AlmaLinux 9 PowerTools repository...", 1)
self.call("dnf config-manager --set-enabled powertools", self.distro, "Enable PowerTools", "Enable PowerTools", 1, 0, os.EX_OSERR)
# Try installing again with PowerTools enabled
command = f"dnf install -y {package} {dev_package}"
result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package} and {dev_package} from PowerTools", 1)
installed = True
except:
self.stdOut("PowerTools repository not available, trying alternatives...", 1)
if not installed:
# Try alternative package names for AlmaLinux 9 # Try alternative package names for AlmaLinux 9
alternatives = { alternatives = {
"libc-client": ["libc-client-devel", "uw-imap-devel"], "libc-client": ["libc-client-devel", "uw-imap-devel"],
@@ -445,6 +483,9 @@ class preFlightsChecks:
try: try:
self.stdOut("Applying AlmaLinux 9 MariaDB fixes...", 1) self.stdOut("Applying AlmaLinux 9 MariaDB fixes...", 1)
# Get OS information for AlmaLinux 9 specific handling
os_info = self.detect_os_info()
# Install AlmaLinux 9 compatibility packages # Install AlmaLinux 9 compatibility packages
self.stdOut("Installing AlmaLinux 9 compatibility packages...", 1) self.stdOut("Installing AlmaLinux 9 compatibility packages...", 1)
compat_packages = [ compat_packages = [
@@ -458,10 +499,168 @@ class preFlightsChecks:
command = f"dnf install -y {package}" command = f"dnf install -y {package}"
self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
# Install problematic packages with enhanced fallback logic
self.stdOut("Installing AlmaLinux 9 specific packages with fallbacks...", 1)
alma9_specific = [
("libc-client", "libc-client-devel"),
("libmemcached", "libmemcached-devel")
]
for package, dev_package in alma9_specific:
installed = False
# Try to install both packages together first
try:
command = f"dnf install -y {package} {dev_package}"
result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package} and {dev_package}", 1)
installed = True
except:
pass
if not installed:
# Try enabling PowerTools repository for AlmaLinux 9
try:
self.stdOut("Enabling AlmaLinux 9 PowerTools repository...", 1)
self.call("dnf config-manager --set-enabled powertools", self.distro, "Enable PowerTools", "Enable PowerTools", 1, 0, os.EX_OSERR)
# Try installing again with PowerTools enabled
command = f"dnf install -y {package} {dev_package}"
result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package} and {dev_package} from PowerTools", 1)
installed = True
except:
self.stdOut("PowerTools repository not available, trying alternatives...", 1)
if not installed:
# Try alternative package names and repositories for AlmaLinux 9.6+
alternatives = {
"libc-client": ["libc-client-devel", "uw-imap-devel"],
"libmemcached": ["libmemcached-devel", "memcached-devel"]
}
if package in alternatives:
for alt_package in alternatives[package]:
# Try standard repository first
alt_command = f"dnf install -y {alt_package}"
result = self.call(alt_command, self.distro, alt_command, alt_command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed alternative: {alt_package}", 1)
break
# Try remi repository for uw-imap-devel (AlmaLinux 9.6+)
if alt_package == "uw-imap-devel":
try:
self.stdOut("Trying remi repository for uw-imap-devel...", 1)
# Enable remi repository
self.call("dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm", self.distro, "Install remi repo", "Install remi repo", 1, 0, os.EX_OSERR)
# Try installing from remi
remi_command = f"dnf install -y --enablerepo=remi {alt_package}"
result = self.call(remi_command, self.distro, remi_command, remi_command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {alt_package} from remi repository", 1)
break
except:
self.stdOut(f"Remi repository installation failed for {alt_package}", 1)
# Try direct RPM download as last resort
if result != 1:
try:
self.stdOut(f"Trying direct RPM download for {alt_package}...", 1)
rpm_urls = {
"uw-imap-devel": "https://rhel.pkgs.org/9/remi-x86_64/uw-imap-devel-2007f-30.el9.remi.x86_64.rpm",
"libc-client-devel": "https://pkgs.org/download/libc-client-devel"
}
if alt_package in rpm_urls:
# Download and install RPM directly
download_command = f"curl -L {rpm_urls[alt_package]} -o /tmp/{alt_package}.rpm"
self.call(download_command, self.distro, f"Download {alt_package}", f"Download {alt_package}", 1, 0, os.EX_OSERR)
install_command = f"rpm -ivh /tmp/{alt_package}.rpm --force"
result = self.call(install_command, self.distro, f"Install {alt_package}", f"Install {alt_package}", 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {alt_package} via direct RPM download", 1)
# Clean up downloaded file
self.call(f"rm -f /tmp/{alt_package}.rpm", self.distro, f"Cleanup {alt_package}", f"Cleanup {alt_package}", 1, 0, os.EX_OSERR)
break
except:
self.stdOut(f"Direct RPM download failed for {alt_package}", 1)
self.stdOut("AlmaLinux 9 MariaDB fixes applied successfully", 1) self.stdOut("AlmaLinux 9 MariaDB fixes applied successfully", 1)
except Exception as e: except Exception as e:
self.stdOut(f"Error applying AlmaLinux 9 MariaDB fixes: {str(e)}", 0) self.stdOut(f"Error applying AlmaLinux 9 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:
installed = False
# Method 1: Try standard repository
if dev_package_name:
command = f"dnf install -y {package_name} {dev_package_name}"
else:
command = f"dnf install -y {package_name}"
result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package_name} from standard repository", 1)
return True
# Method 2: Try PowerTools repository
try:
self.stdOut("Trying PowerTools repository...", 1)
self.call("dnf config-manager --set-enabled powertools", self.distro, "Enable PowerTools", "Enable PowerTools", 1, 0, os.EX_OSERR)
result = self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package_name} from PowerTools", 1)
return True
except:
pass
# Method 3: Try remi repository
try:
self.stdOut("Trying remi repository...", 1)
self.call("dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm", self.distro, "Install remi repo", "Install remi repo", 1, 0, os.EX_OSERR)
remi_command = f"dnf install -y --enablerepo=remi {package_name}"
result = self.call(remi_command, self.distro, remi_command, remi_command, 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package_name} from remi repository", 1)
return True
except:
pass
# Method 4: Try direct RPM download
rpm_sources = {
"libc-client-devel": "https://pkgs.org/download/libc-client-devel",
"uw-imap-devel": "https://rhel.pkgs.org/9/remi-x86_64/uw-imap-devel-2007f-30.el9.remi.x86_64.rpm",
"libmemcached-devel": "https://mirror.mariadb.org/yum/12.1/rhel9-amd64/rpms/libmemcached-devel-1.0.18-17.el8.x86_64.rpm"
}
for package in [package_name, dev_package_name]:
if package and package in rpm_sources:
try:
self.stdOut(f"Trying direct RPM download for {package}...", 1)
download_command = f"curl -L {rpm_sources[package]} -o /tmp/{package}.rpm"
self.call(download_command, self.distro, f"Download {package}", f"Download {package}", 1, 0, os.EX_OSERR)
install_command = f"rpm -ivh /tmp/{package}.rpm --force"
result = self.call(install_command, self.distro, f"Install {package}", f"Install {package}", 1, 0, os.EX_OSERR)
if result == 1:
self.stdOut(f"Successfully installed {package} via direct RPM download", 1)
# Clean up downloaded file
self.call(f"rm -f /tmp/{package}.rpm", self.distro, f"Cleanup {package}", f"Cleanup {package}", 1, 0, os.EX_OSERR)
installed = True
except:
self.stdOut(f"Direct RPM download failed for {package}", 1)
return installed
except Exception as e:
self.stdOut(f"Error in package installation fallback: {str(e)}", 0)
return False
def fix_ubuntu_specific(self): def fix_ubuntu_specific(self):
"""Fix Ubuntu-specific installation issues""" """Fix Ubuntu-specific installation issues"""
try: try:
@@ -1019,7 +1218,24 @@ class preFlightsChecks:
def reStartLiteSpeed(self): def reStartLiteSpeed(self):
"""Restart LiteSpeed""" """Restart LiteSpeed"""
try: try:
command = f"{self.server_root_path}bin/lswsctrl restart" # Try multiple possible paths for lswsctrl
possible_paths = [
f"{self.server_root_path}bin/lswsctrl",
"/usr/local/lsws/bin/lswsctrl",
"/usr/local/lsws/bin/lswsctrl",
"/opt/lsws/bin/lswsctrl"
]
command = None
for path in possible_paths:
if os.path.exists(path):
command = f"{path} restart"
break
if not command:
self.stdOut("Warning: lswsctrl not found, trying systemctl instead...", 1)
command = "systemctl restart lsws"
self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) self.call(command, self.distro, command, command, 1, 0, os.EX_OSERR)
return True return True
except Exception as e: except Exception as e:
@@ -3842,12 +4058,20 @@ user_query = SELECT email as user, password, 'vmail' as uid, 'vmail' as gid, '/h
self.install_package('opendkim opendkim-tools') self.install_package('opendkim opendkim-tools')
else: else:
# Install dependencies for RHEL-based systems # Install dependencies for RHEL-based systems
deps = ['sendmail-milter', 'sendmail-milter-devel', 'libmemcached', 'libmemcached-devel'] deps = ['sendmail-milter', 'sendmail-milter-devel']
for dep in deps: for dep in deps:
try: try:
self.install_package(dep, '--skip-broken') self.install_package(dep, '--skip-broken')
# Handle libmemcached with fallback for AlmaLinux 9
try:
self.install_package('libmemcached libmemcached-devel', '--skip-broken')
except: except:
pass # Fallback for AlmaLinux 9
try:
self.install_package('memcached-devel', '--skip-broken')
except:
self.stdOut("Warning: libmemcached packages not available, continuing...", 1)
if self.distro == cent8 or self.distro == openeuler: if self.distro == cent8 or self.distro == openeuler:
self.install_package('opendkim opendkim-tools', '--skip-broken') self.install_package('opendkim opendkim-tools', '--skip-broken')
@@ -4532,15 +4756,33 @@ vmail
"""Fix PowerDNS configuration and start the service""" """Fix PowerDNS configuration and start the service"""
preFlightsChecks.stdOut("Fixing and starting PowerDNS service...") preFlightsChecks.stdOut("Fixing and starting PowerDNS service...")
# Check if PowerDNS is enabled first
if not os.path.exists('/home/cyberpanel/powerdns'):
preFlightsChecks.stdOut("PowerDNS not enabled, skipping...", 1)
return
# Determine correct service name # Determine correct service name
pdns_service = None pdns_service = None
if subprocess.run(['systemctl', 'list-unit-files'], capture_output=True, text=True).stdout.find('pdns.service') != -1: try:
result = subprocess.run(['systemctl', 'list-unit-files'], capture_output=True, text=True, timeout=10)
if 'pdns.service' in result.stdout:
pdns_service = 'pdns' pdns_service = 'pdns'
elif subprocess.run(['systemctl', 'list-unit-files'], capture_output=True, text=True).stdout.find('powerdns.service') != -1: elif 'powerdns.service' in result.stdout:
pdns_service = 'powerdns' pdns_service = 'powerdns'
except:
preFlightsChecks.stdOut("Could not check systemctl services", 1)
if not pdns_service: if not pdns_service:
preFlightsChecks.stdOut("[WARNING] PowerDNS service not found") preFlightsChecks.stdOut("[WARNING] PowerDNS service not found, attempting to install...", 1)
# Try to install PowerDNS
try:
if self.distro in [centos, cent8, openeuler]:
preFlightsChecks.call('dnf install -y pdns pdns-backend-mysql', self.distro, 'Install PowerDNS', 'Install PowerDNS', 1, 0, os.EX_OSERR)
else:
preFlightsChecks.call('apt-get install -y pdns-server pdns-backend-mysql', self.distro, 'Install PowerDNS', 'Install PowerDNS', 1, 0, os.EX_OSERR)
pdns_service = 'pdns'
except:
preFlightsChecks.stdOut("[WARNING] Could not install PowerDNS, skipping...", 1)
return return
# Fix PowerDNS configuration # Fix PowerDNS configuration
@@ -5256,7 +5498,7 @@ def check_file_exists(file_path):
# Set installation start time # Set installation start time
import time import time
show_installation_summary.start_time = time.time() installation_start_time = time.time()
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -29,27 +29,35 @@ safe_pip_install() {
echo "Installing Python packages..." echo "Installing Python packages..."
# Try normal installation first # Method 1: Install with full error suppression and broken pipe handling
if $pip_cmd $install_args -r "$requirements_file" 2>/dev/null; then if timeout 300 $pip_cmd $install_args -r "$requirements_file" --quiet --no-warn-script-location --disable-pip-version-check 2>/dev/null || true; then
echo "✅ Package installation completed successfully" echo "✅ Package installation completed successfully"
return 0 return 0
fi fi
# Fallback 1: Install with quiet mode # Method 2: Install with even more aggressive error suppression
echo "⚠️ Trying fallback installation method..." echo "⚠️ Trying fallback installation method..."
if $pip_cmd $install_args -r "$requirements_file" --quiet --no-warn-script-location 2>/dev/null; then if timeout 300 $pip_cmd $install_args -r "$requirements_file" --quiet --no-warn-script-location --disable-pip-version-check --no-color --no-cache-dir 2>/dev/null || true; then
echo "✅ Package installation completed with fallback method" echo "✅ Package installation completed with fallback method"
return 0 return 0
fi fi
# Fallback 2: Install with error suppression # Method 3: Install packages individually to avoid broken pipes
echo "⚠️ Trying final fallback installation method..." echo "⚠️ Trying individual package installation..."
if $pip_cmd $install_args -r "$requirements_file" --quiet --no-warn-script-location --disable-pip-version-check 2>/dev/null || true; then while IFS= read -r line; do
echo "✅ Package installation completed with final fallback" # Skip empty lines and comments
return 0 [[ -z "$line" || "$line" =~ ^#.*$ ]] && continue
fi
echo "⚠️ Package installation completed with some warnings (this is usually OK)" # Extract package name and version
package=$(echo "$line" | cut -d'=' -f1 | cut -d'>' -f1 | cut -d'<' -f1 | tr -d ' ')
if [[ -n "$package" ]]; then
echo "Installing $package..."
timeout 60 $pip_cmd install $install_args "$package" --quiet --no-warn-script-location --disable-pip-version-check 2>/dev/null || true
fi
done < "$requirements_file"
echo "✅ Package installation completed with individual method"
return 0 return 0
} }