From 0f1ef2f101e8f518648ec6c33cacf4573d3a0c13 Mon Sep 17 00:00:00 2001 From: master3395 Date: Mon, 16 Feb 2026 00:09:42 +0100 Subject: [PATCH 1/2] Fix ACL Delete DNS Zone (issue #1701): permission UI and legacy config - plogical/acl.py: use config.get() for DNS permissions so old ACLs without deleteZone key do not cause KeyError - baseTemplate: add deleteZone/addDeleteRecords CSS classes to DNS menu links for correct permission-based hiding - system-status.js: fix swapped selectors (deleteZone hides .deleteZone, addDeleteRecords hides .addDeleteRecords instead of .deleteDatabase) --- .../static/baseTemplate/custom-js/system-status.js | 4 ++-- baseTemplate/templates/baseTemplate/index.html | 8 ++++---- plogical/acl.py | 10 +++++----- public/static/baseTemplate/custom-js/system-status.js | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/baseTemplate/static/baseTemplate/custom-js/system-status.js b/baseTemplate/static/baseTemplate/custom-js/system-status.js index eb72873e0..4da778e02 100644 --- a/baseTemplate/static/baseTemplate/custom-js/system-status.js +++ b/baseTemplate/static/baseTemplate/custom-js/system-status.js @@ -282,11 +282,11 @@ app.controller('adminController', function ($scope, $http, $timeout) { } if (!Boolean(response.data.deleteZone)) { - $('.addDeleteRecords').hide(); + $('.deleteZone').hide(); } if (!Boolean(response.data.addDeleteRecords)) { - $('.deleteDatabase').hide(); + $('.addDeleteRecords').hide(); } // Email Management diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 72909a0e2..940fc8fa8 100644 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -1696,22 +1696,22 @@ {% endif %} {% if admin or deleteZone %} - + Delete Zone {% endif %} {% if admin or addDeleteRecords %} - + Add/Delete Records {% endif %} {% if admin or addDeleteRecords %} - + CloudFlare {% endif %} {% if admin or addDeleteRecords %} - + Reset DNS Configurations {% endif %} diff --git a/plogical/acl.py b/plogical/acl.py index cbebf217e..bc06d31b2 100644 --- a/plogical/acl.py +++ b/plogical/acl.py @@ -247,10 +247,10 @@ class ACLManager: ## DNS Management - finalResponse['createNameServer'] = config['createNameServer'] - finalResponse['createDNSZone'] = config['createDNSZone'] - finalResponse['deleteZone'] = config['deleteZone'] - finalResponse['addDeleteRecords'] = config['addDeleteRecords'] + finalResponse['createNameServer'] = config.get('createNameServer', 0) + finalResponse['createDNSZone'] = config.get('createDNSZone', 0) + finalResponse['deleteZone'] = config.get('deleteZone', 0) + finalResponse['addDeleteRecords'] = config.get('addDeleteRecords', 0) ## Email Management @@ -1325,7 +1325,7 @@ echo $oConfig->Save() ? 'Done' : 'Error'; command = "chown -R root:root /usr/local/lscp" ProcessUtilities.executioner(command, 'root', True) - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop" + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail" ProcessUtilities.executioner(command, 'root', True) command = "chmod 700 /usr/local/CyberCP/cli/cyberPanel.py" diff --git a/public/static/baseTemplate/custom-js/system-status.js b/public/static/baseTemplate/custom-js/system-status.js index 83680b1d5..e1f884373 100644 --- a/public/static/baseTemplate/custom-js/system-status.js +++ b/public/static/baseTemplate/custom-js/system-status.js @@ -247,11 +247,11 @@ app.controller('adminController', function ($scope, $http, $timeout) { } if (!Boolean(response.data.deleteZone)) { - $('.addDeleteRecords').hide(); + $('.deleteZone').hide(); } if (!Boolean(response.data.addDeleteRecords)) { - $('.deleteDatabase').hide(); + $('.addDeleteRecords').hide(); } // Email Management From b63317b7af71d5c350d29c10f16d7161cf61b112 Mon Sep 17 00:00:00 2001 From: master3395 Date: Mon, 16 Feb 2026 00:12:03 +0100 Subject: [PATCH 2/2] Install/upgrade and UI updates: monolithic install, SnappyMail, firewall, to-do docs - Install: monolithic install script, venvsetup_modules and venvsetup_monolithic, install_modules (parse_main, menus, actions, etc.), remove legacy email-configs and php-configs from repo, add install/snappymail and Rainloop->SnappyMail migration script - CyberPanel: urls.py, cyberpanel.sh, cyberpanel_upgrade_monolithic.sh tweaks - Firewall: firewall.js and firewall.html updates - plogical: mailUtilities.py, upgrade.py; upgrade_modules 10_post_tweak.sh - pluginHolder: deploy-plugins-template.sh - to-do: docs (git conflicts, HTTP 500 recovery, phpMyAdmin, plugins, SnappyMail rename, install/upgrade OS support, security whitelist, etc.) - upgrade_modules: 02_checks_part1/part2.txt --- CPScripts/migrate_rainloop_to_snappymail.sh | 89 + CyberCP/urls.py | 7 + cyberpanel.sh | 2962 +---------------- cyberpanel_install_monolithic.sh | 2945 ++++++++++++++++ cyberpanel_upgrade_monolithic.sh | 35 + firewall/static/firewall/firewall.js | 2 + firewall/templates/firewall/firewall.html | 4 +- install.sh | 8 + install/email-configs/access | 476 --- install/email-configs/canonical | 278 -- install/email-configs/cert.pem | 21 - install/email-configs/dovecot-sql.conf.ext | 4 - install/email-configs/dovecot.conf | 85 - install/email-configs/generic | 240 -- install/email-configs/header_checks | 496 --- install/email-configs/key.pem | 28 - install/email-configs/main.cf | 66 - install/email-configs/master.cf | 129 - .../email-configs/mysql-virtual_domains.cf | 5 - .../mysql-virtual_email2email.cf | 5 - .../mysql-virtual_forwardings.cf | 5 - .../email-configs/mysql-virtual_mailboxes.cf | 5 - install/email-configs/relocated | 171 - install/email-configs/transport | 294 -- install/email-configs/virtual | 294 -- install/install.py | 26 +- install/php-configs/php.ini | 1835 ---------- install/php-configs/www.conf | 424 --- .../cyberpanel.net.ini | 0 install/venvsetup.sh | 1433 +------- .../01_vars_install_required.sh | 423 +++ .../venvsetup_modules/02_memcached_main.sh | 499 +++ install/venvsetup_modules/03_main_run_pip.sh | 125 + install/venvsetup_modules/04_after_install.sh | 239 ++ install/venvsetup_modules/05_argument_main.sh | 156 + install/venvsetup_monolithic.sh | 1433 ++++++++ install_modules/00_common.sh | 418 +++ install_modules/01_verify_deps.sh | 129 + install_modules/02_install_core.sh | 390 +++ install_modules/03_install_direct.sh | 411 +++ install_modules/04_fixes_status.sh | 210 ++ install_modules/05_menus_main.sh | 328 ++ install_modules/06_menus_update.sh | 247 ++ install_modules/07_menus_advanced.sh | 273 ++ install_modules/08_actions.sh | 317 ++ install_modules/09_parse_main.sh | 247 ++ plogical/mailUtilities.py | 32 +- plogical/upgrade.py | 60 +- pluginHolder/deploy-plugins-template.sh | 55 + .../CYBERCP-GIT-PULL-CONFLICTS-V2.5.5-DEV.md | 63 + to-do/HTTP-500-AFTER-GIT-SYNC-RECOVERY.md | 113 + to-do/INSTALL-MODULES-DESIGN.md | 36 + to-do/PHPMYADMIN-404-AFTER-UPGRADE.md | 49 + to-do/PHPMYADMIN-MARIADB-VERSION-MISMATCH.md | 44 + to-do/PLUGINS-INSTALLED-GRID-VERIFY.md | 45 + to-do/PLUGINS-TEMPLATE-DEPLOY.md | 44 + to-do/RAINLOOP-TO-SNAPPYMAIL-RENAME.md | 41 + to-do/REMOVED-UNUSED-INSTALL-FOLDERS.md | 21 + to-do/SUPPORTED-OS-INSTALL-UPGRADE.md | 37 + ...HITELIST-RM-UPGRADE_LOGS-SECURITY-ALERT.md | 119 + ...ix-phpmyadmin-mariadb-version-on-server.md | 36 + upgrade_modules/02_checks_part1.txt | 130 + upgrade_modules/02_checks_part2.txt | 53 + upgrade_modules/10_post_tweak.sh | 38 + 64 files changed, 9982 insertions(+), 9251 deletions(-) create mode 100644 CPScripts/migrate_rainloop_to_snappymail.sh create mode 100644 cyberpanel_install_monolithic.sh delete mode 100644 install/email-configs/access delete mode 100644 install/email-configs/canonical delete mode 100644 install/email-configs/cert.pem delete mode 100644 install/email-configs/dovecot-sql.conf.ext delete mode 100644 install/email-configs/dovecot.conf delete mode 100644 install/email-configs/generic delete mode 100644 install/email-configs/header_checks delete mode 100644 install/email-configs/key.pem delete mode 100644 install/email-configs/main.cf delete mode 100644 install/email-configs/master.cf delete mode 100644 install/email-configs/mysql-virtual_domains.cf delete mode 100644 install/email-configs/mysql-virtual_email2email.cf delete mode 100644 install/email-configs/mysql-virtual_forwardings.cf delete mode 100644 install/email-configs/mysql-virtual_mailboxes.cf delete mode 100644 install/email-configs/relocated delete mode 100644 install/email-configs/transport delete mode 100644 install/email-configs/virtual delete mode 100644 install/php-configs/php.ini delete mode 100644 install/php-configs/www.conf rename install/{rainloop => snappymail}/cyberpanel.net.ini (100%) create mode 100644 install/venvsetup_modules/01_vars_install_required.sh create mode 100644 install/venvsetup_modules/02_memcached_main.sh create mode 100644 install/venvsetup_modules/03_main_run_pip.sh create mode 100644 install/venvsetup_modules/04_after_install.sh create mode 100644 install/venvsetup_modules/05_argument_main.sh create mode 100644 install/venvsetup_monolithic.sh create mode 100644 install_modules/00_common.sh create mode 100644 install_modules/01_verify_deps.sh create mode 100644 install_modules/02_install_core.sh create mode 100644 install_modules/03_install_direct.sh create mode 100644 install_modules/04_fixes_status.sh create mode 100644 install_modules/05_menus_main.sh create mode 100644 install_modules/06_menus_update.sh create mode 100644 install_modules/07_menus_advanced.sh create mode 100644 install_modules/08_actions.sh create mode 100644 install_modules/09_parse_main.sh create mode 100644 pluginHolder/deploy-plugins-template.sh create mode 100644 to-do/CYBERCP-GIT-PULL-CONFLICTS-V2.5.5-DEV.md create mode 100644 to-do/HTTP-500-AFTER-GIT-SYNC-RECOVERY.md create mode 100644 to-do/INSTALL-MODULES-DESIGN.md create mode 100644 to-do/PHPMYADMIN-404-AFTER-UPGRADE.md create mode 100644 to-do/PHPMYADMIN-MARIADB-VERSION-MISMATCH.md create mode 100644 to-do/PLUGINS-INSTALLED-GRID-VERIFY.md create mode 100644 to-do/PLUGINS-TEMPLATE-DEPLOY.md create mode 100644 to-do/RAINLOOP-TO-SNAPPYMAIL-RENAME.md create mode 100644 to-do/REMOVED-UNUSED-INSTALL-FOLDERS.md create mode 100644 to-do/SUPPORTED-OS-INSTALL-UPGRADE.md create mode 100644 to-do/WHITELIST-RM-UPGRADE_LOGS-SECURITY-ALERT.md create mode 100644 to-do/fix-phpmyadmin-mariadb-version-on-server.md create mode 100644 upgrade_modules/02_checks_part1.txt create mode 100644 upgrade_modules/02_checks_part2.txt diff --git a/CPScripts/migrate_rainloop_to_snappymail.sh b/CPScripts/migrate_rainloop_to_snappymail.sh new file mode 100644 index 000000000..1edb5cd3f --- /dev/null +++ b/CPScripts/migrate_rainloop_to_snappymail.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# Migrate RainLoop to SnappyMail on live server: rename public folder and/or install SnappyMail if missing, migrate data, fix paths, restart, test. +# Run as root: bash /usr/local/CyberCP/CPScripts/migrate_rainloop_to_snappymail.sh +set -e +LOG="/var/log/cyberpanel_upgrade_debug.log" +log() { echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] $*" | tee -a "$LOG"; } +SNAPPY_VERSION="${SNAPPY_VERSION:-2.38.2}" + +log "=== RainLoop -> SnappyMail migration ===" + +# 1) Ensure public/snappymail exists: rename rainloop -> snappymail OR download and install SnappyMail +if [ -d "/usr/local/CyberCP/public/rainloop" ] && [ ! -d "/usr/local/CyberCP/public/snappymail" ]; then + log "Renaming public/rainloop to public/snappymail..." + mv /usr/local/CyberCP/public/rainloop /usr/local/CyberCP/public/snappymail + log "Renamed public/rainloop -> public/snappymail" + if [ -f "/usr/local/CyberCP/public/snappymail/include.php" ]; then + sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' /usr/local/CyberCP/public/snappymail/include.php + log "Updated include.php data path" + fi + for inc in /usr/local/CyberCP/public/snappymail/snappymail/v/*/include.php /usr/local/CyberCP/public/snappymail/rainloop/v/*/include.php; do + [ -f "$inc" ] && sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' "$inc" && log "Updated $inc" && break + done 2>/dev/null || true +elif [ ! -d "/usr/local/CyberCP/public/snappymail" ]; then + log "public/snappymail missing - installing SnappyMail v${SNAPPY_VERSION}..." + cd /usr/local/CyberCP/public || exit 1 + if ! wget -q "https://github.com/the-djmaze/snappymail/releases/download/v${SNAPPY_VERSION}/snappymail-${SNAPPY_VERSION}.zip" -O "snappymail-${SNAPPY_VERSION}.zip"; then + log "ERROR: wget SnappyMail failed" + exit 1 + fi + unzip -q "snappymail-${SNAPPY_VERSION}.zip" -d /usr/local/CyberCP/public/snappymail + rm -f "snappymail-${SNAPPY_VERSION}.zip" + find /usr/local/CyberCP/public/snappymail -type d -exec chmod 755 {} \; + find /usr/local/CyberCP/public/snappymail -type f -exec chmod 644 {} \; + log "SnappyMail installed" + # Configure data path and run CyberPanel integration + wget -q -O /usr/local/CyberCP/snappymail_cyberpanel.php "https://raw.githubusercontent.com/the-djmaze/snappymail/master/integrations/cyberpanel/install.php" 2>/dev/null || true + if [ -f /usr/local/CyberCP/snappymail_cyberpanel.php ]; then + for php in /usr/local/lsws/lsphp83/bin/php /usr/local/lsws/lsphp82/bin/php /usr/local/lsws/lsphp81/bin/php /usr/local/lsws/lsphp80/bin/php; do + [ -x "$php" ] && $php /usr/local/CyberCP/snappymail_cyberpanel.php 2>/dev/null && break + done + fi +else + log "public/snappymail already exists" +fi + +# 2) Data migration: lscp/cyberpanel/rainloop/data -> snappymail/data +mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/ +mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/domains/ +mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/storage/ +mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/temp/ +mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/cache/ + +if [ -d "/usr/local/lscp/cyberpanel/rainloop/data" ] && [ "$(ls -A /usr/local/lscp/cyberpanel/rainloop/data 2>/dev/null)" ]; then + log "Migrating rainloop data to snappymail..." + rsync -av --ignore-existing /usr/local/lscp/cyberpanel/rainloop/data/ /usr/local/lscp/cyberpanel/snappymail/data/ 2>&1 | tee -a "$LOG" + if [ -f "/usr/local/CyberCP/public/snappymail/include.php" ]; then + sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' /usr/local/CyberCP/public/snappymail/include.php + fi + find /usr/local/lscp/cyberpanel/snappymail/data -type f \( -name "*.ini" -o -name "*.json" -o -name "*.php" -o -name "*.cfg" \) -exec grep -l "rainloop" {} \; 2>/dev/null | while read -r f; do + sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g; s|/rainloop/|/snappymail/|g; s|rainloop/data|snappymail/data|g' "$f" + done + log "Data migration done" +fi + +# 3) Ownership and permissions +if id -u lscpd >/dev/null 2>&1; then + chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/ + chown -R lscpd:lscpd /usr/local/CyberCP/public/snappymail/ 2>/dev/null || true + log "Set ownership lscpd:lscpd" +fi +chmod -R 775 /usr/local/lscp/cyberpanel/snappymail/data/ 2>/dev/null || true + +# 4) Restart panel +log "Restarting lscpd..." +systemctl restart lscpd +sleep 2 + +# 5) Test +PORT=$(cat /usr/local/lscp/conf/bind.conf 2>/dev/null | grep -oE '[0-9]+' | head -1) +PORT=${PORT:-8090} +log "Testing https://127.0.0.1:${PORT}/snappymail/index.php ..." +CODE=$(curl -sk -o /dev/null -w "%{http_code}" "https://127.0.0.1:${PORT}/snappymail/index.php" 2>/dev/null || echo "000") +if [ "$CODE" = "200" ] || [ "$CODE" = "302" ]; then + log "OK: SnappyMail URL returned HTTP $CODE" +else + log "WARNING: SnappyMail URL returned HTTP $CODE (expected 200 or 302)" +fi + +log "=== Migration script finished ===" diff --git a/CyberCP/urls.py b/CyberCP/urls.py index e6ccfaa15..69692fa4c 100644 --- a/CyberCP/urls.py +++ b/CyberCP/urls.py @@ -13,11 +13,13 @@ Including another URLconf 1. Import the include() function: from django.urls import path, include 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +import os from django.urls import path, re_path, include from django.contrib import admin from django.conf import settings from django.conf.urls.static import static from django.views.static import serve +from django.views.generic import RedirectView from firewall import views as firewall_views # Plugin routes are no longer hardcoded here; pluginHolder.urls dynamically @@ -34,6 +36,11 @@ except ModuleNotFoundError: urlpatterns = [ # Serve static files first (before catch-all routes) re_path(r'^static/(?P.*)$', serve, {'document_root': settings.STATIC_ROOT}), + # Serve SnappyMail and phpMyAdmin from public directory (fixes 404 when panel is served by Django/lscpd on :2087/:8090) + re_path(r'^snappymail/?$', RedirectView.as_view(url='/snappymail/index.php', permanent=False)), + re_path(r'^snappymail/(?P.*)$', serve, {'document_root': os.path.join(settings.PUBLIC_ROOT, 'snappymail')}), + re_path(r'^phpmyadmin/?$', RedirectView.as_view(url='/phpmyadmin/index.php', permanent=False)), + re_path(r'^phpmyadmin/(?P.*)$', serve, {'document_root': os.path.join(settings.PUBLIC_ROOT, 'phpmyadmin')}), path('base/', include('baseTemplate.urls')), path('imunifyav/', firewall_views.imunifyAV, name='imunifyav_root'), path('ImunifyAV/', firewall_views.imunifyAV, name='imunifyav_root_legacy'), diff --git a/cyberpanel.sh b/cyberpanel.sh index 338293d2e..0d5ecbc1f 100644 --- a/cyberpanel.sh +++ b/cyberpanel.sh @@ -1,2941 +1,43 @@ #!/bin/bash - -# CyberPanel Simple Installer -# Ultra-simple version that works reliably in all terminals +# CyberPanel install – modular loader. Sources install_modules/*.sh then runs main. +# When install_modules/ is missing (e.g. one-liner), downloads modules from GitHub. set -e -# Global variables -SERVER_OS="" -OS_FAMILY="" -PACKAGE_MANAGER="" -ARCHITECTURE="" -BRANCH_NAME="" -MARIADB_VER="" -DEBUG_MODE=false -AUTO_INSTALL=false -INSTALLATION_TYPE="" -# Prefer mariadb CLI (mysql is deprecated) -MDB_CLI="mariadb"; command -v mariadb >/dev/null 2>&1 || MDB_CLI="mysql" - -# Logging function -log_message() { - # Ensure log directory exists - mkdir -p "/var/log/CyberPanel" - echo "[$(date '+%Y-%m-%d %H:%M:%S')] [CYBERPANEL] $1" | tee -a "/var/log/CyberPanel/install.log" 2>/dev/null || echo "[$(date '+%Y-%m-%d %H:%M:%S')] [CYBERPANEL] $1" -} - -# Print status -print_status() { - local message="$1" - echo "$message" - log_message "$message" -} - -# Function to show banner -show_banner() { - clear - echo "" - echo "===============================================================================================================" - echo " CYBERPANEL COMPLETE INSTALLER" - echo "===============================================================================================================" - echo "" - echo " The Ultimate Web Hosting Control Panel" - echo " Powered by OpenLiteSpeed • Fast • Secure • Scalable" - echo "" - echo " Interactive Menus • Version Selection • Advanced Options" - echo "" - echo "===============================================================================================================" - echo "" -} - -# Function to detect OS -detect_os() { - # Check if we're running from a file (not via curl) and modules are available - if [ -f "modules/os/detect.sh" ]; then - # Load the OS detection module for enhanced support - source "modules/os/detect.sh" - detect_os - return $? - fi - - print_status "Detecting operating system..." - - # Detect architecture - ARCHITECTURE=$(uname -m) - case $ARCHITECTURE in - x86_64) - print_status "Architecture: x86_64 (Supported)" - ;; - aarch64|arm64) - print_status "Architecture: $ARCHITECTURE (Limited support)" - ;; - *) - print_status "Architecture: $ARCHITECTURE (Not supported)" - return 1 - ;; - esac - - # Get OS release information - local OUTPUT=$(cat /etc/*release 2>/dev/null) - if [ -z "$OUTPUT" ]; then - print_status "ERROR: Cannot read OS release information" - return 1 - fi - - # Detect OS - if echo $OUTPUT | grep -q "AlmaLinux 10" ; then - SERVER_OS="AlmaLinux10" - OS_FAMILY="rhel" - PACKAGE_MANAGER="dnf" - print_status "Detected: AlmaLinux 10" - elif echo $OUTPUT | grep -q "AlmaLinux 9" ; then - SERVER_OS="AlmaLinux9" - OS_FAMILY="rhel" - PACKAGE_MANAGER="dnf" - print_status "Detected: AlmaLinux 9" - elif echo $OUTPUT | grep -q "AlmaLinux 8" ; then - SERVER_OS="AlmaLinux8" - OS_FAMILY="rhel" - PACKAGE_MANAGER="yum" - print_status "Detected: AlmaLinux 8" - elif echo $OUTPUT | grep -q "CentOS Linux 9" ; then - SERVER_OS="CentOS9" - OS_FAMILY="rhel" - PACKAGE_MANAGER="dnf" - print_status "Detected: CentOS Linux 9" - elif echo $OUTPUT | grep -q "CentOS Linux 8" ; then - SERVER_OS="CentOS8" - OS_FAMILY="rhel" - PACKAGE_MANAGER="yum" - print_status "Detected: CentOS Linux 8" - elif echo $OUTPUT | grep -q "Rocky Linux 9" ; then - SERVER_OS="RockyLinux9" - OS_FAMILY="rhel" - PACKAGE_MANAGER="dnf" - print_status "Detected: Rocky Linux 9" - elif echo $OUTPUT | grep -q "Rocky Linux 8" ; then - SERVER_OS="RockyLinux8" - OS_FAMILY="rhel" - PACKAGE_MANAGER="yum" - print_status "Detected: Rocky Linux 8" - elif echo $OUTPUT | grep -q "Ubuntu 24.04" ; then - SERVER_OS="Ubuntu2404" - OS_FAMILY="debian" - PACKAGE_MANAGER="apt" - print_status "Detected: Ubuntu 24.04" - elif echo $OUTPUT | grep -q "Ubuntu 22.04" ; then - SERVER_OS="Ubuntu2204" - OS_FAMILY="debian" - PACKAGE_MANAGER="apt" - print_status "Detected: Ubuntu 22.04" - elif echo $OUTPUT | grep -q "Ubuntu 20.04" ; then - SERVER_OS="Ubuntu2004" - OS_FAMILY="debian" - PACKAGE_MANAGER="apt" - print_status "Detected: Ubuntu 20.04" - elif echo $OUTPUT | grep -q "Debian GNU/Linux 13" ; then - SERVER_OS="Debian13" - OS_FAMILY="debian" - PACKAGE_MANAGER="apt" - print_status "Detected: Debian GNU/Linux 13" - elif echo $OUTPUT | grep -q "Debian GNU/Linux 12" ; then - SERVER_OS="Debian12" - OS_FAMILY="debian" - PACKAGE_MANAGER="apt" - print_status "Detected: Debian GNU/Linux 12" - elif echo $OUTPUT | grep -q "Debian GNU/Linux 11" ; then - SERVER_OS="Debian11" - OS_FAMILY="debian" - PACKAGE_MANAGER="apt" - print_status "Detected: Debian GNU/Linux 11" - else - print_status "ERROR: Unsupported OS detected" - print_status "Supported OS: AlmaLinux 8/9/10, CentOS 8/9, Rocky Linux 8/9, Ubuntu 20.04/22.04/24.04, Debian 11/12/13" - return 1 - fi - - return 0 -} - -# Function to fix static file permissions (critical for LiteSpeed) -fix_static_file_permissions() { - echo " 🔧 Fixing static file permissions for web server access..." - - # CRITICAL: Fix ownership and permissions for all public files - # LiteSpeed requires files to be owned by lscpd and NOT have execute permissions - - # Check if the public directory exists - if [ -d "/usr/local/CyberCP/public/" ]; then - echo " • Setting ownership to lscpd:lscpd for public directory..." - chown -R lscpd:lscpd /usr/local/CyberCP/public/ 2>/dev/null || true - - echo " • Setting directory permissions to 755..." - find /usr/local/CyberCP/public/ -type d -exec chmod 755 {} \; 2>/dev/null || true - - echo " • Setting file permissions to 644 (removing execute bit)..." - find /usr/local/CyberCP/public/ -type f -exec chmod 644 {} \; 2>/dev/null || true - - # Ensure parent directories have correct permissions - chmod 755 /usr/local/CyberCP/public/ 2>/dev/null || true - chmod 755 /usr/local/CyberCP/public/static/ 2>/dev/null || true - - echo " ✅ Static file permissions fixed successfully" - else - echo " ⚠️ Warning: /usr/local/CyberCP/public/ directory not found" - fi - - # Also check the alternative path - if [ -d "/usr/local/CyberPanel/public/" ]; then - echo " • Fixing permissions for /usr/local/CyberPanel/public/..." - chown -R lscpd:lscpd /usr/local/CyberPanel/public/ 2>/dev/null || true - find /usr/local/CyberPanel/public/ -type d -exec chmod 755 {} \; 2>/dev/null || true - find /usr/local/CyberPanel/public/ -type f -exec chmod 644 {} \; 2>/dev/null || true - fi -} - -# Function to fix post-installation issues -fix_post_install_issues() { - echo " 🔧 Fixing database connection issues..." - - # Wait for services to start - sleep 10 - - # Start and enable MariaDB if not running - if ! systemctl is-active --quiet mariadb; then - echo " Starting MariaDB service..." - systemctl start mariadb - systemctl enable mariadb - sleep 5 - fi - - # Start and enable LiteSpeed if not running - if ! systemctl is-active --quiet lsws; then - echo " Starting LiteSpeed service..." - systemctl start lsws - systemctl enable lsws - sleep 5 - fi - - # Fix database user permissions - echo " Fixing database user permissions..." - - # Wait for MariaDB to be ready - local retry_count=0 - while [ $retry_count -lt 10 ]; do - if $MDB_CLI -e "SELECT 1;" >/dev/null 2>&1; then - break - fi - echo " Waiting for MariaDB to be ready... ($((retry_count + 1))/10)" - sleep 2 - retry_count=$((retry_count + 1)) - done - - # Create database user with proper permissions - echo " Dropping existing cyberpanel user..." - $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'localhost';" 2>/dev/null || true - $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'%';" 2>/dev/null || true - - echo " Creating cyberpanel user with correct password..." - $MDB_CLI -e "CREATE USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true - $MDB_CLI -e "CREATE USER 'cyberpanel'@'%' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true - - echo " Granting privileges..." - $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'localhost' WITH GRANT OPTION;" 2>/dev/null || true - $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'%' WITH GRANT OPTION;" 2>/dev/null || true - $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true - - # Verify the user was created correctly - echo " Verifying database user..." - if $MDB_CLI -u cyberpanel -pcyberpanel -e "SELECT 1;" >/dev/null 2>&1; then - echo " ✅ Database user verification successful" - else - echo " ⚠️ Database user verification failed, trying alternative approach..." - # Alternative: use root to create the user - $MDB_CLI -e "CREATE OR REPLACE USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true - $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'localhost' WITH GRANT OPTION;" 2>/dev/null || true - $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true - fi - - # Create CyberPanel database if it doesn't exist - $MDB_CLI -e "CREATE DATABASE IF NOT EXISTS cyberpanel;" 2>/dev/null || true - $MDB_CLI -e "GRANT ALL PRIVILEGES ON cyberpanel.* TO 'cyberpanel'@'localhost';" 2>/dev/null || true - $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true - - # Get or set unified password for both CyberPanel and OpenLiteSpeed - local unified_password="" - if [ -f "/root/.cyberpanel_password" ]; then - unified_password=$(cat /root/.cyberpanel_password 2>/dev/null) - fi - - # If no password was captured from installation, use default - if [ -z "$unified_password" ]; then - unified_password="1234567" - # Save password to file for later retrieval - echo "$unified_password" > /root/.cyberpanel_password 2>/dev/null || true - chmod 600 /root/.cyberpanel_password 2>/dev/null || true - fi - - echo " Setting unified password for CyberPanel and OpenLiteSpeed..." - echo " Password: $unified_password" - - # First, ensure the cyberpanel user exists and has correct password - $MDB_CLI -e "ALTER USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true - $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true - - # Wait a moment for the database to be ready - sleep 2 - - # Reset CyberPanel admin password - echo " Setting CyberPanel admin password..." - /usr/local/CyberCP/bin/python3 /usr/local/CyberCP/plogical/adminPass.py 2>/dev/null || { - echo " Admin password reset failed, trying alternative method..." - # Alternative method: directly update the database - $MDB_CLI -u cyberpanel -pcyberpanel cyberpanel -e "UPDATE Administrator SET password = '$unified_password' WHERE id = 1;" 2>/dev/null || true - } - - # Set OpenLiteSpeed admin password - echo " Setting OpenLiteSpeed admin password..." - if [ -f "/usr/local/lsws/admin/htpasswd" ]; then - # Create OpenLiteSpeed admin user with the same password - /usr/local/lsws/admin/misc/admpass.sh -u admin -p "$unified_password" 2>/dev/null || { - echo " OpenLiteSpeed password set via alternative method..." - # Alternative method: directly create htpasswd entry - echo "admin:$(openssl passwd -apr1 '$unified_password')" > /usr/local/lsws/admin/htpasswd 2>/dev/null || true - } - fi - - # Fix PHP configuration files - echo " Fixing PHP configuration..." - - # Find the reference PHP version (usually lsphp82) - local reference_php="" - for php_version in lsphp82 lsphp81 lsphp80 lsphp84 lsphp83 lsphp74 lsphp73 lsphp72; do - if [ -d "/usr/local/lsws/$php_version" ] && [ -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then - reference_php="$php_version" - echo " Using $php_version as reference for PHP configuration" - break - fi - done - - if [ -n "$reference_php" ]; then - for php_version in lsphp72 lsphp73 lsphp74 lsphp80 lsphp81 lsphp82 lsphp83 lsphp84; do - if [ -d "/usr/local/lsws/$php_version" ]; then - # Create missing php.ini if it doesn't exist - if [ ! -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then - echo " Creating missing php.ini for $php_version..." - cp "/usr/local/lsws/$reference_php/etc/php.ini" "/usr/local/lsws/$php_version/etc/php.ini" 2>/dev/null || true - fi - - # Ensure the directory exists - mkdir -p "/usr/local/lsws/$php_version/etc" 2>/dev/null || true - fi - done - else - echo " ⚠️ No reference PHP configuration found, creating basic php.ini files..." - for php_version in lsphp72 lsphp73 lsphp74 lsphp80 lsphp81 lsphp82 lsphp83 lsphp84; do - if [ -d "/usr/local/lsws/$php_version" ]; then - mkdir -p "/usr/local/lsws/$php_version/etc" 2>/dev/null || true - if [ ! -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then - echo " Creating basic php.ini for $php_version..." - cat > "/usr/local/lsws/$php_version/etc/php.ini" << 'EOF' -[PHP] -engine = On -short_open_tag = Off -precision = 14 -output_buffering = 4096 -zlib.output_compression = Off -implicit_flush = Off -unserialize_callback_func = -serialize_precision = -1 -disable_functions = -disable_classes = -zend.enable_gc = On -expose_php = Off -max_execution_time = 30 -max_input_time = 60 -memory_limit = 128M -error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT -display_errors = Off -display_startup_errors = Off -log_errors = On -log_errors_max_len = 1024 -ignore_repeated_errors = Off -ignore_repeated_source = Off -report_memleaks = On -variables_order = "GPCS" -request_order = "GP" -register_argc_argv = Off -auto_globals_jit = On -post_max_size = 8M -auto_prepend_file = -auto_append_file = -default_mimetype = "text/html" -default_charset = "UTF-8" -file_uploads = On -upload_max_filesize = 2M -max_file_uploads = 20 -allow_url_fopen = On -allow_url_include = Off -default_socket_timeout = 60 -EOF - fi - fi - done - fi - - # Restart services - echo " Restarting services..." - systemctl restart mariadb - systemctl restart lsws - - # Wait for services to stabilize - sleep 10 - - # Verify services are running - if systemctl is-active --quiet mariadb && systemctl is-active --quiet lsws; then - echo " ✅ Post-installation fixes completed successfully" - - # Run final verification - verify_installation - else - echo " ⚠️ Some services may need manual attention" - echo " 🔧 Attempting additional fixes..." - - # Additional service fixes - systemctl daemon-reload - systemctl reset-failed mariadb lsws - systemctl start mariadb lsws - - sleep 5 - verify_installation - fi -} - -# Function to verify installation -verify_installation() { - echo "" - echo " 🔍 Verifying installation..." - - local issues=0 - - # Check MariaDB - if systemctl is-active --quiet mariadb; then - echo " ✅ MariaDB is running" - else - echo " ❌ MariaDB is not running" - issues=$((issues + 1)) - fi - - # Check LiteSpeed - if systemctl is-active --quiet lsws; then - echo " ✅ LiteSpeed is running" - else - echo " ❌ LiteSpeed is not running" - issues=$((issues + 1)) - fi - - # Check web interface - if curl -s -k --connect-timeout 5 https://localhost:8090 >/dev/null 2>&1; then - echo " ✅ Web interface is accessible" - else - echo " ⚠️ Web interface may not be accessible yet (this is normal)" - fi - - # Check database connection - if $MDB_CLI -e "SELECT 1;" >/dev/null 2>&1; then - echo " ✅ Database connection is working" - else - echo " ❌ Database connection failed" - issues=$((issues + 1)) - fi - - if [ $issues -eq 0 ]; then - echo "" - echo " 🎉 Installation verification completed successfully!" - echo " 🌐 CyberPanel: https://$(curl -s ifconfig.me):8090 (admin/1234567)" - echo " 🌐 OpenLiteSpeed: https://$(curl -s ifconfig.me):7080 (admin/1234567)" - echo " 🔑 Both services use the same password for convenience" - else - echo "" - echo " ⚠️ Installation completed with $issues issue(s)" - echo " 🔧 Some manual intervention may be required" - echo " 📋 Check the logs at: /var/log/CyberPanel/" - fi -} - -# Function to install dependencies -install_dependencies() { - # Check if we're running from a file (not via curl) and modules are available - if [ -f "modules/deps/manager.sh" ]; then - # Load the dependency manager module for enhanced support - source "modules/deps/manager.sh" - install_dependencies "$SERVER_OS" "$OS_FAMILY" "$PACKAGE_MANAGER" - return $? - fi - - print_status "Installing dependencies..." - echo "" - echo "Installing system dependencies for $SERVER_OS..." - echo "This may take a few minutes depending on your internet speed." - echo "" - - case $OS_FAMILY in - "rhel") - echo "Step 1/4: Installing EPEL repository..." - $PACKAGE_MANAGER install -y epel-release 2>/dev/null || true - echo " ✓ EPEL repository installed" - echo "" - - echo "Step 2/4: Installing development tools..." - $PACKAGE_MANAGER groupinstall -y 'Development Tools' 2>/dev/null || { - $PACKAGE_MANAGER install -y gcc gcc-c++ make kernel-devel 2>/dev/null || true - } - echo " ✓ Development tools installed" - echo "" - - echo "Step 3/4: Installing core packages..." - if [ "$SERVER_OS" = "AlmaLinux9" ] || [ "$SERVER_OS" = "AlmaLinux10" ] || [ "$SERVER_OS" = "CentOS9" ] || [ "$SERVER_OS" = "RockyLinux9" ]; then - # AlmaLinux 9/10 / CentOS 9 / Rocky Linux 9 - $PACKAGE_MANAGER install -y ImageMagick gd libicu oniguruma python3 python3-pip python3-devel 2>/dev/null || true - $PACKAGE_MANAGER install -y aspell 2>/dev/null || print_status "WARNING: aspell not available, skipping..." - $PACKAGE_MANAGER install -y libc-client-devel 2>/dev/null || print_status "WARNING: libc-client-devel not available, skipping..." - else - # AlmaLinux 8 / CentOS 8 / Rocky Linux 8 - $PACKAGE_MANAGER install -y ImageMagick gd libicu oniguruma aspell libc-client-devel python3 python3-pip python3-devel 2>/dev/null || true - fi - echo " ✓ Core packages installed" - echo "" - - echo "Step 4/4: Verifying installation..." - echo " ✓ All dependencies verified" - ;; - "debian") - echo "Step 1/4: Updating package lists..." - apt update -qq 2>/dev/null || true - echo " ✓ Package lists updated" - echo "" - - echo "Step 2/4: Installing essential packages..." - apt install -y -qq curl wget git unzip tar gzip bzip2 2>/dev/null || true - echo " ✓ Essential packages installed" - echo "" - - echo "Step 3/4: Installing development tools..." - apt install -y -qq build-essential gcc g++ make python3-dev python3-pip 2>/dev/null || true - echo " ✓ Development tools installed" - echo "" - - echo "Step 4/4: Installing core packages..." - apt install -y -qq imagemagick php-gd libicu-dev libonig-dev 2>/dev/null || true - apt install -y -qq aspell 2>/dev/null || print_status "WARNING: aspell not available, skipping..." - apt install -y -qq libc-client-dev 2>/dev/null || print_status "WARNING: libc-client-dev not available, skipping..." - echo " ✓ Core packages installed" - ;; - esac - - echo "" - print_status "SUCCESS: Dependencies installed successfully" -} - -# Function to install CyberPanel -install_cyberpanel() { - print_status "Installing CyberPanel..." - echo "" - echo "===============================================================================================================" - echo " CYBERPANEL INSTALLATION IN PROGRESS" - echo "===============================================================================================================" - echo "" - echo "This process may take 10-15 minutes depending on your internet speed." - echo "Please DO NOT close this terminal or interrupt the installation." - echo "" - echo "Current Status:" - echo " ✓ Dependencies installed" - echo " 🔄 Starting CyberPanel installation using working method..." - echo "" - - # Use the working CyberPanel installation method - install_cyberpanel_direct -} - -# Function to check if CyberPanel is already installed -check_cyberpanel_installed() { - if [ -d "/usr/local/CyberPanel" ] || [ -d "/usr/local/CyberCP" ] || [ -f "/usr/local/lsws/bin/lswsctrl" ]; then - return 0 # CyberPanel is installed - else - return 1 # CyberPanel is not installed - fi -} - -# Function to clean up existing CyberPanel installation -cleanup_existing_cyberpanel() { - echo " 🧹 Cleaning up existing CyberPanel installation..." - - # Stop services - systemctl stop lsws mariadb 2>/dev/null || true - - # Remove CyberPanel directories - rm -rf /usr/local/CyberPanel 2>/dev/null || true - rm -rf /usr/local/CyberCP 2>/dev/null || true - rm -rf /usr/local/lsws 2>/dev/null || true - - # Remove systemd services - systemctl disable lsws mariadb 2>/dev/null || true - rm -f /etc/systemd/system/lsws.service 2>/dev/null || true - - # Clean up databases - $MDB_CLI -e "DROP DATABASE IF EXISTS cyberpanel;" 2>/dev/null || true - $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'localhost';" 2>/dev/null || true - - echo " ✅ Cleanup completed" -} - -# Function to install CyberPanel directly using the working method -install_cyberpanel_direct() { - # Ask web server (OpenLiteSpeed vs LiteSpeed Enterprise) BEFORE MariaDB; default OpenLiteSpeed - if [ -z "$LS_ENT" ]; then - if [ "$AUTO_INSTALL" = true ]; then - LS_ENT="" - echo " Using OpenLiteSpeed (auto mode)." - else - echo "" - echo " Web server: 1) OpenLiteSpeed (default), 2) LiteSpeed Enterprise" - read -r -t 60 -p " Enter 1 or 2 [1]: " LS_CHOICE || true - LS_CHOICE="${LS_CHOICE:-1}" - LS_CHOICE="${LS_CHOICE// /}" - if [ "$LS_CHOICE" = "2" ]; then - echo " LiteSpeed Enterprise selected. Enter serial/key (required):" - read -r -t 120 -p " Serial: " LS_SERIAL || true - LS_SERIAL="${LS_SERIAL:-}" - if [ -z "$LS_SERIAL" ]; then - echo " No serial provided. Defaulting to OpenLiteSpeed." - LS_ENT="" - else - LS_ENT="ent" - echo " Using LiteSpeed Enterprise with provided serial." - fi - else - LS_ENT="" - echo " Using OpenLiteSpeed." - fi - echo "" - fi - fi - - # Ask MariaDB version (after web server choice) if not set via --mariadb-version - if [ -z "$MARIADB_VER" ]; then - echo "" - echo " MariaDB version: 10.11, 11.8 (LTS, default) or 12.1?" - read -r -t 60 -p " Enter 10.11, 11.8 or 12.1 [11.8]: " MARIADB_VER || true - MARIADB_VER="${MARIADB_VER:-11.8}" - MARIADB_VER="${MARIADB_VER// /}" - if [ "$MARIADB_VER" != "10.11" ] && [ "$MARIADB_VER" != "11.8" ] && [ "$MARIADB_VER" != "12.1" ]; then - MARIADB_VER="11.8" - fi - echo " Using MariaDB $MARIADB_VER" - echo "" - fi - - echo " 🔄 Downloading CyberPanel installation files..." - - # Check if CyberPanel is already installed - if check_cyberpanel_installed; then - echo " ⚠️ CyberPanel is already installed but may not be working properly" - echo " 🔧 Cleaning up existing installation and reinstalling..." - cleanup_existing_cyberpanel - fi - - # Pre-installation system checks - echo " 🔍 Running pre-installation checks..." - - # Ensure system is up to date - if command -v dnf >/dev/null 2>&1; then - echo " Updating system packages..." - dnf update -y >/dev/null 2>&1 || true - elif command -v yum >/dev/null 2>&1; then - echo " Updating system packages..." - yum update -y >/dev/null 2>&1 || true - elif command -v apt >/dev/null 2>&1; then - echo " Updating system packages..." - apt update -y >/dev/null 2>&1 || true - apt upgrade -y >/dev/null 2>&1 || true - fi - - # Ensure required services are available - echo " Checking system services..." - systemctl enable mariadb 2>/dev/null || true - systemctl enable lsws 2>/dev/null || true - - # Clear any previous install temp folders so we never use stale extracted files - rm -rf /tmp/cyberpanel_install_* 2>/dev/null || true - - # Create temporary directory for installation - local temp_dir="/tmp/cyberpanel_install_$$" - mkdir -p "$temp_dir" - cd "$temp_dir" || return 1 - - # Only add dnf exclude when we want to KEEP the current MariaDB (same version as user chose). - # If user chose 11.8 but 10.11 is installed, do NOT exclude — allow install.py to upgrade. - if command -v rpm >/dev/null 2>&1; then - if rpm -qa | grep -qiE "^(mariadb-server|mysql-server|MariaDB-server)" 2>/dev/null; then - local mariadb_version=$(mysql --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) - if [ -n "$mariadb_version" ]; then - local major_ver=$(echo "$mariadb_version" | cut -d. -f1) - local minor_ver=$(echo "$mariadb_version" | cut -d. -f2) - local installed_majmin="${major_ver}.${minor_ver}" - local chosen_ver="${MARIADB_VER:-11.8}" - # Only add exclude when installed version matches user's choice (preserve, no upgrade) - if [ "$installed_majmin" = "$chosen_ver" ]; then - print_status "MariaDB $mariadb_version matches chosen $chosen_ver, adding dnf exclude to preserve it" - - # Add MariaDB-server to dnf excludes (multiple formats for compatibility) - local dnf_conf="/etc/dnf/dnf.conf" - local exclude_added=false - - if [ -f "$dnf_conf" ]; then - # Check if [main] section exists - if grep -q "^\[main\]" "$dnf_conf" 2>/dev/null; then - # [main] section exists, add exclude there - if ! grep -q "exclude=.*MariaDB-server" "$dnf_conf" 2>/dev/null; then - if grep -q "^exclude=" "$dnf_conf" 2>/dev/null; then - # Append to existing exclude line in [main] section - sed -i '/^\[main\]/,/^\[/ { /^exclude=/ s/$/ MariaDB-server*/ }' "$dnf_conf" - else - # Add new exclude line after [main] - sed -i '/^\[main\]/a exclude=MariaDB-server*' "$dnf_conf" - fi - exclude_added=true - fi - else - # No [main] section, add it with exclude - if ! grep -q "exclude=.*MariaDB-server" "$dnf_conf" 2>/dev/null; then - echo "" >> "$dnf_conf" - echo "[main]" >> "$dnf_conf" - echo "exclude=MariaDB-server*" >> "$dnf_conf" - exclude_added=true - fi - fi - else - # Create dnf.conf with exclude - echo "[main]" > "$dnf_conf" - echo "exclude=MariaDB-server*" >> "$dnf_conf" - exclude_added=true - fi - - if [ "$exclude_added" = true ]; then - print_status "Added MariaDB-server* to dnf excludes in $dnf_conf" - fi - - # Also add to yum.conf for compatibility - local yum_conf="/etc/yum.conf" - if [ -f "$yum_conf" ]; then - if ! grep -q "exclude=.*MariaDB-server" "$yum_conf" 2>/dev/null; then - if grep -q "^exclude=" "$yum_conf" 2>/dev/null; then - sed -i 's/^exclude=\(.*\)/exclude=\1 MariaDB-server*/' "$yum_conf" - else - echo "exclude=MariaDB-server*" >> "$yum_conf" - fi - print_status "Added MariaDB-server* to yum excludes" - fi - fi - - # Create a function to disable MariaDB repositories (will be called after repository setup) - disable_mariadb_repos() { - local repo_files=( - "/etc/yum.repos.d/mariadb-main.repo" - "/etc/yum.repos.d/mariadb.repo" - "/etc/yum.repos.d/mariadb-12.1.repo" - ) - - # Also check for any mariadb repo files - while IFS= read -r repo_file; do - repo_files+=("$repo_file") - done < <(find /etc/yum.repos.d -name "*mariadb*.repo" 2>/dev/null) - - for repo_file in "${repo_files[@]}"; do - if [ -f "$repo_file" ] && [ -n "$repo_file" ]; then - # First, try to disable by setting enabled=0 - sed -i 's/^enabled\s*=\s*1/enabled=0/g' "$repo_file" 2>/dev/null - - # If file contains MariaDB 12.1 references, disable or remove it - if grep -qi "mariadb.*12\|12.*mariadb\|mariadb-main" "$repo_file" 2>/dev/null; then - # Try to add enabled=0 to each [mariadb...] section - python3 -c " -import re -import sys -try: - with open('$repo_file', 'r') as f: - content = f.read() - - # Replace enabled=1 with enabled=0 - content = re.sub(r'(enabled\s*=\s*)1', r'\g<1>0', content, flags=re.IGNORECASE) - - # Add enabled=0 after [mariadb...] sections if not present - lines = content.split('\n') - new_lines = [] - in_mariadb_section = False - has_enabled = False - - for i, line in enumerate(lines): - new_lines.append(line) - if re.match(r'^\s*\[.*mariadb.*\]', line, re.IGNORECASE): - in_mariadb_section = True - has_enabled = False - elif in_mariadb_section: - if re.match(r'^\s*enabled\s*=', line, re.IGNORECASE): - has_enabled = True - elif re.match(r'^\s*\[', line) and not re.match(r'^\s*\[.*mariadb.*\]', line, re.IGNORECASE): - if not has_enabled: - new_lines.insert(-1, 'enabled=0') - in_mariadb_section = False - has_enabled = False - - if in_mariadb_section and not has_enabled: - new_lines.append('enabled=0') - - with open('$repo_file', 'w') as f: - f.write('\n'.join(new_lines)) -except: - # Fallback: just rename the file - import os - os.rename('$repo_file', '${repo_file}.disabled') -" 2>/dev/null || \ - # Fallback: rename the file to disable it - mv "$repo_file" "${repo_file}.disabled" 2>/dev/null || true - fi - fi - done - } - - # Export function so it can be called from installer - export -f disable_mariadb_repos - export MARIADB_VERSION="$mariadb_version" - - # Also set up a background process to monitor and disable repos - ( - while [ ! -f /tmp/cyberpanel_install_complete ]; do - sleep 2 - if [ -f /etc/yum.repos.d/mariadb-main.repo ] || [ -f /etc/yum.repos.d/mariadb.repo ]; then - disable_mariadb_repos - fi - done - ) & - local monitor_pid=$! - echo "$monitor_pid" > /tmp/cyberpanel_repo_monitor.pid - print_status "Started background process to monitor and disable MariaDB repositories" - else - # User chose a different version (e.g. 11.8) than installed (e.g. 10.11) — allow upgrade - print_status "MariaDB $mariadb_version installed but you chose $chosen_ver; not adding dnf exclude (installer will upgrade)" - # Remove any existing MariaDB exclude from a previous run so install can proceed - for c in /etc/dnf/dnf.conf /etc/yum.conf; do - if [ -f "$c" ] && grep -q "exclude=.*MariaDB-server" "$c" 2>/dev/null; then - sed -i 's/ *MariaDB-server\* *//g; s/exclude= *$/exclude=/; s/exclude=\s*$/exclude=/' "$c" 2>/dev/null - if grep -q "^exclude=\s*$" "$c" 2>/dev/null; then - sed -i '/^exclude=\s*$/d' "$c" 2>/dev/null - fi - print_status "Removed MariaDB-server from excludes in $c to allow upgrade" - fi - done - fi - fi - fi - fi - - # Download the working CyberPanel installation files from upstream (usmannasir/cyberpanel) - echo "Downloading from: https://raw.githubusercontent.com/usmannasir/cyberpanel/v2.5.5-dev/cyberpanel.sh" - - # First, try to download the repository archive to get the correct installer - # GitHub: branch archives use refs/heads/BRANCH; GitHub returns 302 redirect to codeload, so we must use -L - local archive_url="" - local installer_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/v2.5.5-dev/cyberpanel.sh" - if curl -s -L --head "https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" | grep -q "200 OK"; then - archive_url="https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" - echo " Using development branch (v2.5.5-dev) from usmannasir/cyberpanel" - elif curl -s -L --head "https://github.com/usmannasir/cyberpanel/archive/v2.5.5-dev.tar.gz" | grep -q "200 OK"; then - archive_url="https://github.com/usmannasir/cyberpanel/archive/v2.5.5-dev.tar.gz" - echo " Using development branch (v2.5.5-dev) from usmannasir/cyberpanel" - else - echo " Development branch archive not available, trying installer script directly..." - if ! curl -s -L --head "$installer_url" | grep -q "200 OK"; then - echo " Development branch not available, falling back to stable" - installer_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" - archive_url="https://github.com/usmannasir/cyberpanel/archive/stable.tar.gz" - else - archive_url="https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" - fi - fi - - curl --silent -o cyberpanel_installer.sh "$installer_url" 2>/dev/null - if [ $? -ne 0 ] || [ ! -s "cyberpanel_installer.sh" ]; then - print_status "ERROR: Failed to download CyberPanel installer" - return 1 - fi - - # Do NOT patch installer to add --exclude=MariaDB-server*: it blocks initial MariaDB install - # and causes "MariaDB-server requires MariaDB-client but none of the providers can be installed". - - # Make script executable (use full path in case cwd has noexec) - chmod 755 cyberpanel_installer.sh 2>/dev/null || chmod +x cyberpanel_installer.sh 2>/dev/null || true - if [ ! -x "cyberpanel_installer.sh" ]; then - print_status "Note: Script will be run with bash (executable bit not set)" - fi - - # Download the install directory (use archive_url set above; may be branch or stable) - echo "Downloading installation files..." - if [ -z "$archive_url" ] || [ "$installer_url" = "https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" ]; then - archive_url="https://github.com/usmannasir/cyberpanel/archive/stable.tar.gz" - fi - # Append cache-bust so CDNs/proxies don't serve old installer (GitHub ignores query params) - archive_url="${archive_url}?nocache=$(date +%s 2>/dev/null || echo 0)" - - curl --silent -L -o install_files.tar.gz "$archive_url" 2>/dev/null - if [ $? -ne 0 ] || [ ! -s "install_files.tar.gz" ]; then - print_status "ERROR: Failed to download installation files" - return 1 - fi - - # Extract the installation files - tar -xzf install_files.tar.gz 2>/dev/null - if [ $? -ne 0 ]; then - print_status "ERROR: Failed to extract installation files" - return 1 - fi - - # Copy install directory to current location - if [ "$installer_url" = "https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" ]; then - if [ -d "cyberpanel-stable" ]; then - cp -r cyberpanel-stable/install . 2>/dev/null || true - cp -r cyberpanel-stable/install.sh . 2>/dev/null || true - fi - else - if [ -d "cyberpanel-v2.5.5-dev" ]; then - cp -r cyberpanel-v2.5.5-dev/install . 2>/dev/null || true - cp -r cyberpanel-v2.5.5-dev/install.sh . 2>/dev/null || true - fi - fi - - # Verify install directory was copied - if [ ! -d "install" ]; then - print_status "ERROR: install directory not found after extraction" - print_status "Archive contents:" - ls -la 2>/dev/null | head -20 - return 1 - fi - - print_status "Verified install directory exists" - - echo " ✓ CyberPanel installation files downloaded" - echo " 🔄 Starting CyberPanel installation..." - echo "" - echo "IMPORTANT: The installation is now running in the background." - echo "You will see detailed output from the CyberPanel installer below." - echo "This is normal and expected - the installation is proceeding!" - echo "" - echo "===============================================================================================================" - echo "" - - # Run the installer with live progress monitoring - echo "Starting CyberPanel installation process..." - echo "This may take several minutes. Please be patient." - echo "" - - # Create log directory (same as v2.4.4: installer logs go here) - mkdir -p /var/log/CyberPanel - echo " Installation logs:" - echo " • /var/log/CyberPanel/install.log (installer script messages)" - echo " • /var/log/CyberPanel/install_output.log (Python installer stdout/stderr)" - echo " • /var/log/installLogs.txt (install.py detailed log)" - echo "" - - # Run the installer with live output monitoring - echo "Starting CyberPanel installer with live progress monitoring..." - echo "" - echo "===============================================================================================================" - echo " LIVE INSTALLATION PROGRESS" - echo "===============================================================================================================" - echo "" - - # Set branch environment variable for the installer - if [ -n "$BRANCH_NAME" ]; then - export CYBERPANEL_BRANCH="$BRANCH_NAME" - echo "Setting installation branch to: $BRANCH_NAME" - else - export CYBERPANEL_BRANCH="stable" - echo "Using default stable branch" - fi - echo "" - - # CRITICAL: Use install/install.py directly instead of cyberpanel_installer.sh - # The cyberpanel_installer.sh is the old wrapper that doesn't support auto-install - # install/install.py is the actual installer that we can control - local installer_py="install/install.py" - if [ -f "$installer_py" ]; then - print_status "Using install/install.py directly for installation (non-interactive mode)" - - # NOTE: We do NOT patch install.py to add --exclude=MariaDB-server* to dnf install. - # That would block the initial MariaDB-server install. install.py now clears dnf exclude - # before installing MariaDB and uses official MariaDB-server packages. - - # Clear MariaDB-server from dnf/yum exclude so the installer can install or reinstall it - # (cyberpanel.sh may have added it earlier when 10.x was detected; partial installs leave exclude in place) - for conf in /etc/dnf/dnf.conf /etc/yum.conf; do - if [ -f "$conf" ] && grep -q "exclude=.*MariaDB-server" "$conf" 2>/dev/null; then - sed -i '/^exclude=/s/MariaDB-server\*\s*//g' "$conf" - sed -i '/^exclude=/s/\s*MariaDB-server\*//g' "$conf" - sed -i '/^exclude=/s/MariaDB-server\s*//g' "$conf" - sed -i '/^exclude=\s*$/d' "$conf" - sed -i '/^exclude=$/d' "$conf" - print_status "Cleared MariaDB-server from exclude in $conf for installation" - fi - done - - # If MariaDB 10.x is installed, disable repositories right before running installer - if [ -n "$MARIADB_VERSION" ] && [ -f /tmp/cyberpanel_repo_monitor.pid ]; then - # Call the disable function one more time before installer runs - if type disable_mariadb_repos >/dev/null 2>&1; then - disable_mariadb_repos - fi - fi - - # Get server IP address (required by install.py) - local server_ip - if command -v curl >/dev/null 2>&1; then - server_ip=$(curl -s --max-time 5 https://api.ipify.org 2>/dev/null || curl -s --max-time 5 https://icanhazip.com 2>/dev/null || echo "") - fi - - if [ -z "$server_ip" ]; then - # Fallback: try to get IP from network interfaces - server_ip=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $7; exit}' || \ - hostname -I 2>/dev/null | awk '{print $1}' || \ - echo "127.0.0.1") - fi - - if [ -z "$server_ip" ] || [ "$server_ip" = "127.0.0.1" ]; then - print_status "WARNING: Could not detect public IP, using 127.0.0.1" - server_ip="127.0.0.1" - fi - - print_status "Detected server IP: $server_ip" - - # CRITICAL: Install Python MySQL dependencies before running install.py - # installCyberPanel.py requires MySQLdb (mysqlclient) which needs development headers - echo "" - echo "===============================================================================================================" - echo "Installing Python MySQL dependencies (required for installCyberPanel.py)..." - echo "===============================================================================================================" - print_status "Installing Python MySQL dependencies..." - - # Detect OS for package installation - local os_family="" - if [ -f /etc/os-release ]; then - . /etc/os-release - case "$ID" in - almalinux|rocky|centos|rhel|fedora) - os_family="rhel" - print_status "Detected RHEL-based OS: $ID" - ;; - ubuntu|debian) - os_family="debian" - print_status "Detected Debian-based OS: $ID" - ;; - *) - print_status "Unknown OS ID: $ID, defaulting to RHEL-based" - os_family="rhel" - ;; - esac - else - print_status "WARNING: /etc/os-release not found, defaulting to RHEL-based" - os_family="rhel" - fi - - # Install MariaDB/MySQL development headers and Python mysqlclient - if [ "$os_family" = "rhel" ]; then - # RHEL-based (AlmaLinux, Rocky, CentOS, RHEL) - print_status "Installing MariaDB development headers for RHEL-based system..." - - # Try to install mariadb-devel (works with MariaDB 10.x and 12.x) - # NOTE: We need mariadb-devel even if we excluded MariaDB-server - # The exclude only applies to MariaDB-server, not development packages - if command -v dnf >/dev/null 2>&1; then - # For AlmaLinux 9/10 and newer - show output for debugging - print_status "Attempting to install mariadb-devel (development headers only, not server)..." - # Temporarily remove exclude for devel packages if needed - local dnf_exclude_backup="" - if [ -f /etc/dnf/dnf.conf ] && grep -q "exclude=.*MariaDB" /etc/dnf/dnf.conf; then - # Check if exclude is too broad - if grep -q "exclude=.*MariaDB-server.*MariaDB-devel" /etc/dnf/dnf.conf || \ - grep -q "exclude=.*MariaDB\*" /etc/dnf/dnf.conf; then - print_status "Temporarily adjusting dnf exclude to allow mariadb-devel installation..." - # We only want to exclude MariaDB-server, not devel packages - sed -i 's/exclude=\(.*\)MariaDB-server\(.*\)MariaDB-devel\(.*\)/exclude=\1MariaDB-server\2\3/' /etc/dnf/dnf.conf 2>/dev/null || true - sed -i 's/exclude=\(.*\)MariaDB\*\(.*\)/exclude=\1MariaDB-server*\2/' /etc/dnf/dnf.conf 2>/dev/null || true - fi - fi - - if dnf install -y --allowerasing --skip-broken --nobest \ - mariadb-devel pkgconfig gcc python3-devel python3-pip; then - print_status "✓ Successfully installed mariadb-devel" - elif dnf install -y --allowerasing --skip-broken --nobest \ - mysql-devel pkgconfig gcc python3-devel python3-pip; then - print_status "✓ Successfully installed mysql-devel" - elif dnf install -y --allowerasing --skip-broken --nobest \ - mariadb-connector-c-devel pkgconfig gcc python3-devel python3-pip; then - print_status "✓ Successfully installed mariadb-connector-c-devel" - else - print_status "⚠️ WARNING: Failed to install MariaDB development headers" - print_status "This may cause MySQLdb installation to fail" - fi - else - # For older systems with yum - print_status "Using yum to install mariadb-devel..." - if yum install -y mariadb-devel pkgconfig gcc python3-devel python3-pip; then - print_status "✓ Successfully installed mariadb-devel" - elif yum install -y mysql-devel pkgconfig gcc python3-devel python3-pip; then - print_status "✓ Successfully installed mysql-devel" - else - print_status "⚠️ WARNING: Failed to install MariaDB development headers" - fi - fi - - # Install mysqlclient Python package - print_status "Installing mysqlclient Python package..." - python3 -m pip install --upgrade pip setuptools wheel 2>&1 | grep -v "already satisfied" || true - if python3 -m pip install mysqlclient 2>&1; then - print_status "✓ Successfully installed mysqlclient" - else - # If pip install fails, try with build dependencies - print_status "Retrying mysqlclient installation with build dependencies..." - python3 -m pip install --no-cache-dir mysqlclient 2>&1 || { - print_status "⚠️ WARNING: Failed to install mysqlclient, trying alternative method..." - # Try installing from source - python3 -m pip install --no-binary mysqlclient mysqlclient 2>&1 || true - } - fi - - elif [ "$os_family" = "debian" ]; then - # Debian-based (Ubuntu, Debian) - print_status "Installing MariaDB development headers for Debian-based system..." - apt-get update -y - if apt-get install -y libmariadb-dev libmariadb-dev-compat pkg-config build-essential python3-dev python3-pip; then - print_status "✓ Successfully installed MariaDB development headers" - elif apt-get install -y default-libmysqlclient-dev pkg-config build-essential python3-dev python3-pip; then - print_status "✓ Successfully installed MySQL development headers" - else - print_status "⚠️ WARNING: Failed to install MariaDB/MySQL development headers" - fi - - # Install mysqlclient Python package - print_status "Installing mysqlclient Python package..." - python3 -m pip install --upgrade pip setuptools wheel 2>&1 | grep -v "already satisfied" || true - if python3 -m pip install mysqlclient 2>&1; then - print_status "✓ Successfully installed mysqlclient" - else - print_status "Retrying mysqlclient installation with build dependencies..." - python3 -m pip install --no-cache-dir mysqlclient 2>&1 || true - fi - fi - - # Verify MySQLdb is available (mysqlclient; some builds lack __version__) - print_status "Verifying MySQLdb module availability..." - if python3 -c "import MySQLdb; getattr(MySQLdb, '__version__', 'ok'); print('MySQLdb OK')" 2>/dev/null || \ - python3 -c "import MySQLdb; MySQLdb; print('MySQLdb OK')" 2>/dev/null; then - print_status "✓ MySQLdb module is available and working" - else - print_status "⚠️ WARNING: MySQLdb module not available" - print_status "Attempting to diagnose the issue..." - python3 -c "import sys; print('Python path:', sys.path)" 2>&1 || true - python3 -m pip list | grep -i mysql || print_status "No MySQL-related packages found in pip list" - print_status "Attempting to continue anyway, but installation may fail..." - fi - echo "" - - # Build installer arguments based on user preferences - # install.py requires publicip as first positional argument - local install_args=("$server_ip") - - # Web server: OpenLiteSpeed (default) or LiteSpeed Enterprise (--ent + --serial) - if [ -n "$LS_ENT" ] && [ -n "$LS_SERIAL" ]; then - install_args+=("--ent" "$LS_ENT" "--serial" "$LS_SERIAL") - fi - # Default: OpenLiteSpeed, Full installation (postfix, powerdns, ftp), Local MySQL - install_args+=("--postfix" "ON") - install_args+=("--powerdns" "ON") - install_args+=("--ftp" "ON") - install_args+=("--remotemysql" "OFF") - # Only pass --mariadb-version if this install.py supports it (avoids "unrecognized arguments" on older archives) - if grep -q "mariadb-version\|mariadb_version" "$installer_py" 2>/dev/null; then - install_args+=("--mariadb-version" "${MARIADB_VER:-11.8}") - fi - - if [ "$DEBUG_MODE" = true ]; then - # Note: install.py doesn't have --debug, but we can set it via environment - export DEBUG_MODE=true - fi - - # CRITICAL: If CyberPanel Python does not exist yet, patch installer to use system Python. - # Fixes FileNotFoundError when archive is cached/old and still references /usr/local/CyberPanel/bin/python. - if [ ! -f /usr/local/CyberPanel/bin/python ]; then - sys_python="/usr/bin/python3" - [ -x "$sys_python" ] || sys_python="/usr/local/bin/python3" - if [ -x "$sys_python" ]; then - for f in install/install_utils.py install/install.py; do - if [ -f "$f" ] && grep -q '/usr/local/CyberPanel/bin/python' "$f" 2>/dev/null; then - sed -i "s|/usr/local/CyberPanel/bin/python|$sys_python|g" "$f" - print_status "Patched $f to use $sys_python (CyberPanel python not yet installed)" - fi - done - fi - fi - - # Run the Python installer directly - if [ "$DEBUG_MODE" = true ]; then - python3 "$installer_py" "${install_args[@]}" 2>&1 | tee /var/log/CyberPanel/install_output.log - else - python3 "$installer_py" "${install_args[@]}" 2>&1 | tee /var/log/CyberPanel/install_output.log - fi - else - # Fallback to cyberpanel_installer.sh if install.py not found - print_status "WARNING: install/install.py not found, using cyberpanel_installer.sh (may be interactive)" - - local installer_script="cyberpanel_installer.sh" - if [ ! -f "$installer_script" ]; then - print_status "ERROR: cyberpanel_installer.sh not found in current directory: $(pwd)" - return 1 - fi - - # Get absolute path to installer script - local installer_path - if [[ "$installer_script" = /* ]]; then - installer_path="$installer_script" - else - installer_path="$(pwd)/$installer_script" - fi - - # If MariaDB 10.x is installed, disable repositories right before running installer - if [ -n "$MARIADB_VERSION" ] && [ -f /tmp/cyberpanel_repo_monitor.pid ]; then - # Call the disable function one more time before installer runs - if type disable_mariadb_repos >/dev/null 2>&1; then - disable_mariadb_repos - fi - fi - - if [ "$DEBUG_MODE" = true ]; then - bash "$installer_path" --debug 2>&1 | tee /var/log/CyberPanel/install_output.log - else - bash "$installer_path" 2>&1 | tee /var/log/CyberPanel/install_output.log - fi - fi - - local install_exit_code=${PIPESTATUS[0]} - - # Stop the repository monitor - if [ -f /tmp/cyberpanel_repo_monitor.pid ]; then - local monitor_pid=$(cat /tmp/cyberpanel_repo_monitor.pid 2>/dev/null) - if [ -n "$monitor_pid" ] && kill -0 "$monitor_pid" 2>/dev/null; then - kill "$monitor_pid" 2>/dev/null - fi - rm -f /tmp/cyberpanel_repo_monitor.pid - fi - touch /tmp/cyberpanel_install_complete 2>/dev/null || true - - local install_exit_code=${PIPESTATUS[0]} - - # Extract the generated password from the installation output - local generated_password=$(grep "Panel password:" /var/log/CyberPanel/install_output.log | awk '{print $NF}') - if [ -n "$generated_password" ]; then - echo "Captured CyberPanel password: $generated_password" - echo "$generated_password" > /root/.cyberpanel_password - chmod 600 /root/.cyberpanel_password - fi - - echo "" - echo "===============================================================================================================" - echo " INSTALLATION COMPLETED" - echo "===============================================================================================================" - echo "" - echo " Installation logs (for troubleshooting):" - echo " • /var/log/CyberPanel/install.log (installer script messages)" - echo " • /var/log/CyberPanel/install_output.log (Python installer stdout/stderr)" - echo " • /var/log/installLogs.txt (install.py detailed log)" - echo "" - - # Check if installation was successful - if [ $install_exit_code -ne 0 ]; then - print_status "ERROR: CyberPanel installation failed with exit code $install_exit_code" - echo "" - echo "Installation log (last 50 lines):" - echo "===============================================================================================================" - tail -50 /var/log/CyberPanel/install_output.log 2>/dev/null || echo "Could not read installation log" - echo "===============================================================================================================" - echo "" - echo "Full installation log available at: /var/log/CyberPanel/install_output.log" - echo "" - return 1 - fi - - # Clean up temporary directory - cd /tmp - rm -rf "$temp_dir" 2>/dev/null || true - - # Check if installation was successful - if [ $install_exit_code -eq 0 ]; then - # Installation succeeded, but don't print success message yet - # The CyberPanel installer has already shown its summary - - # Run static file permission fixes (critical for LiteSpeed) silently - fix_static_file_permissions >/dev/null 2>&1 - - return 0 - else - print_status "ERROR: CyberPanel installation failed (exit code: $install_exit_code)" - echo "" - echo "===============================================================================================================" - echo " INSTALLATION FAILED" - echo "===============================================================================================================" - echo "" - echo "The CyberPanel installation has failed. Here's how to troubleshoot:" - echo "" - echo "📋 LOG FILES LOCATION:" - echo " • Main installer log: /var/log/CyberPanel/install.log" - echo " • Installation output: /var/log/CyberPanel/install_output.log" - echo " • System logs: /var/log/messages" - echo "" - echo "🔍 TROUBLESHOOTING STEPS:" - echo " 1. Check the installation output log for specific errors" - echo " 2. Verify your system meets the requirements" - echo " 3. Ensure you have sufficient disk space and memory" - echo " 4. Check your internet connection" - echo " 5. Try running the installer again" - echo "" - echo "📄 LAST 30 LINES OF INSTALLATION LOG:" - echo "===============================================================================================================" - if [ -f "/var/log/CyberPanel/install_output.log" ]; then - tail -30 /var/log/CyberPanel/install_output.log 2>/dev/null || echo "Could not read installation log" - else - echo "Installation log not found at /var/log/CyberPanel/install_output.log" - fi - echo "===============================================================================================================" - echo "" - echo "💡 QUICK DEBUG COMMANDS:" - echo " • View full log: cat /var/log/CyberPanel/install_output.log" - echo " • Check system: free -h && df -h" - echo " • Check network: ping -c 3 google.com" - echo " • Retry installation: Run the installer again" - echo "" - echo "🆘 NEED HELP?" - echo " • CyberPanel Documentation: https://docs.cyberpanel.net" - echo " • CyberPanel Community: https://forums.cyberpanel.net" - echo " • GitHub Issues: https://github.com/usmannasir/cyberpanel/issues" - echo "" - return 1 - fi -} - -# Function to apply fixes -apply_fixes() { - echo "" - echo "Applying post-installation configurations..." - - # Get the actual password that was generated during installation - local admin_password="" - if [ -f "/root/.cyberpanel_password" ]; then - admin_password=$(cat /root/.cyberpanel_password 2>/dev/null) - fi - - # If no password was captured, use the default - if [ -z "$admin_password" ]; then - admin_password="1234567" - echo "$admin_password" > /root/.cyberpanel_password - chmod 600 /root/.cyberpanel_password - fi - - # Fix database issues - systemctl start mariadb 2>/dev/null || true - systemctl enable mariadb 2>/dev/null || true - - # Fix LiteSpeed service only if the web server was actually installed - if [ -x /usr/local/lsws/bin/lswsctrl ] || [ -x /usr/local/lsws/bin/lsctrl ] || [ -f /usr/local/lsws/bin/openlitespeed ]; then - cat > /etc/systemd/system/lsws.service << 'EOF' -[Unit] -Description=LiteSpeed Web Server -After=network.target - -[Service] -Type=forking -User=root -Group=root -ExecStart=/usr/local/lsws/bin/lswsctrl start -ExecStop=/usr/local/lsws/bin/lswsctrl stop -ExecReload=/usr/local/lsws/bin/lswsctrl restart -Restart=always -RestartSec=5 - -[Install] -WantedBy=multi-user.target -EOF - - systemctl daemon-reload - systemctl enable lsws - systemctl start lsws || true - else - echo " • LiteSpeed/OpenLiteSpeed not found at /usr/local/lsws - skipping lsws.service (install may have skipped web server)" - echo " • If the installer failed earlier (e.g. Python error), re-run the installer. Once it completes, open ports 8090 and 7080 in your cloud security group (e.g. AWS EC2 Security Group inbound rules)." - systemctl disable lsws 2>/dev/null || true - rm -f /etc/systemd/system/lsws.service - systemctl daemon-reload - fi - - # Set OpenLiteSpeed admin password to match CyberPanel - echo " • Configuring OpenLiteSpeed admin password..." - if [ -f "/usr/local/lsws/admin/misc/admpass.sh" ]; then - # Auto-answer the prompts for username and password - (echo "admin"; echo "$admin_password"; echo "$admin_password") | /usr/local/lsws/admin/misc/admpass.sh >/dev/null 2>&1 || { - # Alternative method: directly create htpasswd entry - echo "admin:$(openssl passwd -apr1 '$admin_password')" > /usr/local/lsws/admin/htpasswd 2>/dev/null || true - } - echo " ✓ OpenLiteSpeed configured" - fi - - # Ensure CyberPanel (lscpd) service is running - echo " • Starting CyberPanel service..." - systemctl enable lscpd 2>/dev/null || true - systemctl start lscpd 2>/dev/null || true - - # Give services a moment to start - sleep 3 - - # Ensure both 8090 (CyberPanel) and 7080 (LiteSpeed/OLS) are accessible - echo " • Ensuring ports 8090 and 7080 are accessible..." - port_check() { - local port=$1 - command -v ss >/dev/null 2>&1 && ss -tlnp 2>/dev/null | grep -q ":$port " && return 0 - command -v netstat >/dev/null 2>&1 && netstat -tlnp 2>/dev/null | grep -q ":$port " && return 0 - return 1 - } - max_attempts=18 - attempt=0 - while [ $attempt -lt $max_attempts ]; do - need_restart=false - systemctl is-active --quiet mariadb || { systemctl start mariadb 2>/dev/null; need_restart=true; } - systemctl is-active --quiet lsws 2>/dev/null || { [ -x /usr/local/lsws/bin/lswsctrl ] && systemctl start lsws 2>/dev/null; need_restart=true; } - systemctl is-active --quiet lscpd 2>/dev/null || { systemctl start lscpd 2>/dev/null; need_restart=true; } - [ "$need_restart" = true ] && sleep 5 - if port_check 8090 && port_check 7080; then - echo " ✓ Port 8090 (CyberPanel) and 7080 (OpenLiteSpeed) are listening" - break - fi - attempt=$((attempt + 1)) - [ $attempt -lt $max_attempts ] && sleep 5 - done - if ! port_check 8090 || ! port_check 7080; then - systemctl start lscpd 2>/dev/null - systemctl start lsws 2>/dev/null - sleep 10 - if port_check 8090 && port_check 7080; then - echo " ✓ Port 8090 and 7080 are now listening" - else - echo " ⚠ One or both ports not yet listening. Run: systemctl start mariadb lsws lscpd" - echo " ⚠ On AWS/cloud: add inbound rules for TCP 8090 and 7080 in the instance security group." - fi - fi - - echo " ✓ Post-installation configurations completed" -} - -# Helper: check if a port is listening -_port_listening() { - local port=$1 - command -v ss >/dev/null 2>&1 && ss -tlnp 2>/dev/null | grep -q ":$port " && return 0 - command -v netstat >/dev/null 2>&1 && netstat -tlnp 2>/dev/null | grep -q ":$port " && return 0 - return 1 -} - -# Function to show status summary -show_status_summary() { - # Last-chance: try to start services so 8090 and 7080 are accessible - if ! _port_listening 8090 || ! _port_listening 7080; then - systemctl start mariadb 2>/dev/null || true - systemctl start lsws 2>/dev/null || true - systemctl start lscpd 2>/dev/null || true - sleep 8 - fi - - echo "===============================================================================================================" - echo " FINAL STATUS CHECK" - echo "===============================================================================================================" - echo "" - - # Quick service check - local all_services_running=true - - echo "Service Status:" - if systemctl is-active --quiet mariadb; then - echo " ✓ MariaDB Database - Running" - else - echo " ✗ MariaDB Database - Not Running" - all_services_running=false - fi - - if systemctl is-active --quiet lsws; then - echo " ✓ LiteSpeed Web Server - Running" - else - echo " ✗ LiteSpeed Web Server - Not Running" - all_services_running=false - fi - - if systemctl is-active --quiet lscpd; then - echo " ✓ CyberPanel Application - Running" - else - echo " ✗ CyberPanel Application - Not Running (may take a moment to start)" - all_services_running=false - fi - - echo "" - echo "Port Accessibility:" - if _port_listening 8090; then - echo " ✓ Port 8090 (CyberPanel) - Accessible" - else - echo " ✗ Port 8090 (CyberPanel) - Not listening (run: systemctl start lscpd)" - all_services_running=false - fi - if _port_listening 7080; then - echo " ✓ Port 7080 (OpenLiteSpeed) - Accessible" - else - echo " ✗ Port 7080 (OpenLiteSpeed) - Not listening (run: systemctl start lsws)" - all_services_running=false - fi - - # Get the actual password that was set - local admin_password="" - local server_ip=$(curl -s ifconfig.me 2>/dev/null || echo "your-server-ip") - - # Check if password was set in /root/.cyberpanel_password (if it exists) - if [ -f "/root/.cyberpanel_password" ]; then - admin_password=$(cat /root/.cyberpanel_password 2>/dev/null) - fi - - # If we have a password, show access details - if [ -n "$admin_password" ]; then - echo "" - echo "Access Details:" - echo " CyberPanel: https://$server_ip:8090" - echo " Username: admin" - echo " Password: $admin_password" - echo "" - echo " OpenLiteSpeed: https://$server_ip:7080" - echo " Username: admin" - echo " Password: $admin_password" - fi - - echo "" - echo "===============================================================================================================" - - if [ "$all_services_running" = true ]; then - echo "✓ Installation completed successfully! Ports 8090 and 7080 are accessible." - else - echo "⚠ Installation completed with warnings. Some services may need attention." - fi - echo "" -} - -# Function to show main menu -show_main_menu() { - show_banner - - echo "===============================================================================================================" - echo " SELECT INSTALLATION TYPE" - echo "===============================================================================================================" - echo "" - echo " 1. Fresh Installation (Recommended)" - echo " 2. Update Existing Installation" - echo " 3. Reinstall CyberPanel" - echo " 4. Force Reinstall (Clean & Install)" - echo " 5. Pre-Upgrade (Download latest upgrade script)" - echo " 6. Check System Status" - echo " 7. Advanced Options" - echo " 8. Exit" - echo "" - echo "===============================================================================================================" - echo "" - - while true; do - echo -n "Enter your choice [1-8]: " - read -r choice - - case $choice in - 1) - INSTALLATION_TYPE="fresh" - show_fresh_install_menu - return - ;; - 2) - INSTALLATION_TYPE="update" - show_update_menu - return - ;; - 3) - INSTALLATION_TYPE="reinstall" - show_reinstall_menu - return - ;; - 4) - INSTALLATION_TYPE="force_reinstall" - start_force_reinstall - return - ;; - 5) - start_preupgrade - return - ;; - 6) - show_system_status - return - ;; - 7) - show_advanced_menu - return - ;; - 8) - echo "Goodbye!" - exit 0 - ;; - *) - echo "" - echo "ERROR: Invalid choice. Please enter 1-7." - echo "" - ;; - esac - done -} - -# Function to show fresh installation menu -show_fresh_install_menu() { - echo "" - echo "===============================================================================================================" - echo " FRESH INSTALLATION SETUP" - echo "===============================================================================================================" - echo "" - - # Check if CyberPanel is already installed - if [ -d "/usr/local/CyberCP" ] && [ -f "/usr/local/CyberCP/manage.py" ]; then - echo "WARNING: CyberPanel appears to be already installed on this system." - echo " Consider using 'Update' or 'Reinstall' options instead." - echo "" - echo -n "Do you want to continue with fresh installation anyway? (y/n): " - read -r response - case $response in - [yY]|[yY][eE][sS]) - ;; - *) - show_main_menu - return - ;; - esac - fi - - echo "Select installation option:" - echo "" - echo " 1. Install Latest Stable Version" - echo " 2. Install Development Version (v2.5.5-dev)" - echo " 3. Install Specific Version/Branch" - echo " 4. Install from Commit Hash" - echo " 5. Quick Install (Auto-configure everything)" - echo " 6. Back to Main Menu" - echo "" - echo "===============================================================================================================" - echo "" - - while true; do - echo -n "Select installation option [1-6]: " - read -r choice - - case $choice in - 1) - BRANCH_NAME="" - show_installation_preferences - return - ;; - 2) - BRANCH_NAME="v2.5.5-dev" - show_installation_preferences - return - ;; - 3) - show_version_selection - return - ;; - 4) - show_commit_selection - return - ;; - 5) - BRANCH_NAME="" - AUTO_INSTALL=true - start_installation - return - ;; - 6) - show_main_menu - return - ;; - *) - echo "" - echo "ERROR: Invalid choice. Please enter 1-6." - echo "" - ;; -esac - done -} - -# Function to show commit selection -show_commit_selection() { - echo "" - echo "===============================================================================================================" - echo " COMMIT HASH SELECTION" - echo "===============================================================================================================" - echo "" - echo "Enter a specific commit hash to install from:" - echo "" - echo "Examples:" - echo " • Latest commit: Leave empty (press Enter)" - echo " • Specific commit: a1b2c3d4e5f6789012345678901234567890abcd" - echo " • Short commit: a1b2c3d (first 7 characters)" - echo "" - echo "You can find commit hashes at: https://github.com/usmannasir/cyberpanel/commits" - echo "" - echo "===============================================================================================================" - echo "" - - while true; do - echo -n "Enter commit hash (or press Enter for latest): " - read -r commit_hash - - if [ -z "$commit_hash" ]; then - echo "Using latest commit..." - BRANCH_NAME="" - show_installation_preferences - return - elif [[ "$commit_hash" =~ ^[a-f0-9]{7,40}$ ]]; then - echo "Using commit: $commit_hash" - BRANCH_NAME="$commit_hash" - show_installation_preferences - return - else - echo "" - echo "ERROR: Invalid commit hash format." - echo " Please enter a valid Git commit hash (7-40 hexadecimal characters)." - echo "" - fi - done -} - -# Function to show version selection -show_version_selection() { - echo "" - echo "===============================================================================================================" - echo " VERSION SELECTION" - echo "===============================================================================================================" - echo "" - echo "Available versions:" - echo "" - echo " 1. Latest Stable (Recommended)" - echo " 2. v2.5.5-dev (Development)" - echo " 3. v2.4.4 (Previous Stable)" - echo " 4. Custom Branch Name" - echo " 5. Custom Commit Hash" - echo "" - echo "===============================================================================================================" - echo "" - - while true; do - echo -n "Select version [1-5]: " - read -r choice - - case $choice in - 1) - BRANCH_NAME="" - break - ;; - 2) - BRANCH_NAME="v2.5.5-dev" - break - ;; - 3) - BRANCH_NAME="v2.4.4" - break - ;; - 4) - echo -n "Enter branch name (e.g., main, v2.5.5-dev): " - read -r BRANCH_NAME - if [ -z "$BRANCH_NAME" ]; then - echo "ERROR: Branch name cannot be empty." - continue - fi - # Add v prefix if it's a version number without v - if [[ "$BRANCH_NAME" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then - if [[ "$BRANCH_NAME" == *"-"* ]]; then - # Already has suffix like 2.5.5-dev, add v prefix - BRANCH_NAME="v$BRANCH_NAME" - else - # Add v prefix and dev suffix for development versions - BRANCH_NAME="v$BRANCH_NAME-dev" - fi - fi - break - ;; - 5) - echo -n "Enter commit hash (7-40 characters): " - read -r commit_hash - if [[ "$commit_hash" =~ ^[a-f0-9]{7,40}$ ]]; then - BRANCH_NAME="$commit_hash" - break - else - echo "ERROR: Invalid commit hash format." - continue - fi - ;; - *) - echo "" - echo "ERROR: Invalid choice. Please enter 1-5." - echo "" - ;; -esac - done - - show_installation_preferences -} - -# Function to show installation preferences -show_installation_preferences() { - echo "" - echo "===============================================================================================================" - echo " INSTALLATION PREFERENCES" - echo "===============================================================================================================" - echo "" - - # Debug mode - echo -n "Enable debug mode for detailed logging? (y/n) [n]: " - read -r response - case $response in - [yY]|[yY][eE][sS]) - DEBUG_MODE=true - ;; - *) - DEBUG_MODE=false - ;; - esac - - # Auto-install - echo -n "Auto-install without further prompts? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - AUTO_INSTALL=false - ;; - *) - AUTO_INSTALL=true - ;; - esac - - # Show summary - echo "" - echo "===============================================================================================================" - echo " INSTALLATION SUMMARY" - echo "===============================================================================================================" - echo "" - echo " Type: $INSTALLATION_TYPE" - echo " Version: ${BRANCH_NAME:-'Latest Stable'}" - echo " Debug Mode: $DEBUG_MODE" - echo " Auto Install: $AUTO_INSTALL" - echo "" - echo "===============================================================================================================" - echo "" - - echo -n "Proceed with installation? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - show_main_menu - ;; - *) - start_installation - ;; - esac -} - -# Function to show update menu -show_update_menu() { - echo "" - echo "===============================================================================================================" - echo " UPDATE INSTALLATION" - echo "===============================================================================================================" - echo "" - - if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then - echo "ERROR: CyberPanel is not installed on this system." - echo " Please use 'Fresh Installation' instead." - echo "" - read -p "Press Enter to return to main menu..." - show_main_menu - return - fi - - # Check current version - local current_version="unknown" - if [ -f "/usr/local/CyberCP/version.txt" ]; then - current_version=$(cat /usr/local/CyberCP/version.txt 2>/dev/null) - fi - - echo "Current Installation:" - echo "Version: $current_version" - echo "Path: /usr/local/CyberCP" - echo "" - - echo "Select update option:" - echo "" - echo " 1. Update to Latest Stable" - echo " 2. Update to Development Version" - echo " 3. Update to Specific Version/Branch" - echo " 4. Update from Commit Hash" - echo " 5. Back to Main Menu" - echo "" - echo "===============================================================================================================" - echo "" - - while true; do - echo -n "Select update option [1-5]: " - read -r choice - - case $choice in - 1) - BRANCH_NAME="" - break - ;; - 2) - BRANCH_NAME="v2.5.5-dev" - break - ;; - 3) - show_version_selection - return - ;; - 4) - show_commit_selection - return - ;; - 5) - show_main_menu - return - ;; - *) - echo "" - echo "ERROR: Invalid choice. Please enter 1-5." - echo "" - ;; - esac - done - - echo -n "Proceed with update? (This will backup your current installation) (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - show_main_menu - ;; - *) - start_upgrade - ;; - esac -} - -# Function to show reinstall menu -show_reinstall_menu() { - echo "" - echo "===============================================================================================================" - echo " REINSTALL CYBERPANEL" - echo "===============================================================================================================" - echo "" - - if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then - echo "ERROR: CyberPanel is not installed on this system." - echo " Please use 'Fresh Installation' instead." - echo "" - read -p "Press Enter to return to main menu..." - show_main_menu - return - fi - - echo "WARNING: This will completely remove the existing CyberPanel installation" - echo " and install a fresh copy. All data will be lost!" - echo "" - - echo -n "Are you sure you want to reinstall? (y/n) [n]: " - read -r response - case $response in - [yY]|[yY][eE][sS]) - ;; - *) - show_main_menu - return - ;; - esac - - echo "Select reinstall option:" - echo "" - echo " 1. Reinstall Latest Stable" - echo " 2. Reinstall Development Version" - echo " 3. Reinstall Specific Version/Branch" - echo " 4. Reinstall from Commit Hash" - echo " 5. Back to Main Menu" - echo "" - echo "===============================================================================================================" - echo "" - - while true; do - echo -n "Select reinstall option [1-5]: " - read -r choice - - case $choice in - 1) - BRANCH_NAME="" +# Parse -b/--branch for module download (when not running from repo) +BRANCH_FOR_MODULES="${CYBERPANEL_BRANCH:-stable}" +next="" +for arg in "$@"; do + if [[ "$arg" = "-b" ]] || [[ "$arg" = "--branch" ]]; then + next="1" + continue + fi + if [[ "$next" = "1" ]] && [[ -n "$arg" ]]; then + BRANCH_FOR_MODULES="$arg" break - ;; - 2) - BRANCH_NAME="v2.5.5-dev" - break - ;; - 3) - show_version_selection - return - ;; - 4) - show_commit_selection - return - ;; - 5) - show_main_menu - return - ;; - *) - echo "" - echo "ERROR: Invalid choice. Please enter 1-5." - echo "" - ;; - esac - done - - echo -n "Proceed with reinstall? (This will delete all existing data) (y/n) [n]: " - read -r response - case $response in - [yY]|[yY][eE][sS]) - start_reinstall - ;; - *) - show_main_menu - ;; - esac -} + fi +done -# Function to show system status -show_system_status() { - echo "" - echo "===============================================================================================================" - echo " SYSTEM STATUS CHECK" - echo "===============================================================================================================" - echo "" - - # Check OS - local os_info=$(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2 2>/dev/null || echo 'Unknown') - echo "Operating System: $os_info" - - # Check CyberPanel installation - if [ -d "/usr/local/CyberCP" ] && [ -f "/usr/local/CyberCP/manage.py" ]; then - local version="unknown" - if [ -f "/usr/local/CyberCP/version.txt" ]; then - version=$(cat /usr/local/CyberCP/version.txt 2>/dev/null) - fi - echo "CyberPanel: Installed (Version: $version)" - else - echo "CyberPanel: Not Installed" - fi - - # Check services - echo "" - echo "Services Status:" - if systemctl is-active --quiet mariadb; then - echo " SUCCESS: MariaDB - Running" - else - echo " ERROR: MariaDB - Not Running" - fi - - if systemctl is-active --quiet lsws; then - echo " SUCCESS: LiteSpeed - Running" - else - echo " ERROR: LiteSpeed - Not Running" - fi - - if systemctl is-active --quiet lscpd; then - echo " SUCCESS: CyberPanel - Running" - else - echo " ERROR: CyberPanel - Not Running" - fi - - # Check ports - echo "" - echo "Port Status:" - if netstat -tlnp | grep -q ":8090 "; then - echo " SUCCESS: Port 8090 (CyberPanel) - Listening" - else - echo " ERROR: Port 8090 (CyberPanel) - Not Listening" - fi - - if netstat -tlnp | grep -q ":80 "; then - echo " SUCCESS: Port 80 (HTTP) - Listening" - else - echo " ERROR: Port 80 (HTTP) - Not Listening" - fi - - echo "" - echo -n "Return to main menu? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - exit 0 - ;; - *) - show_main_menu - ;; - esac -} +# Resolve script directory +INSTALL_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" 2>/dev/null && pwd)" +[[ -z "$INSTALL_SCRIPT_DIR" ]] && INSTALL_SCRIPT_DIR="." -# Function to show advanced menu -show_advanced_menu() { - echo "" - echo "===============================================================================================================" - echo " ADVANCED OPTIONS" - echo "===============================================================================================================" - echo "" - echo " 1. Fix Installation Issues" - echo " 2. Clean Installation Files" - echo " 3. View Installation Logs" - echo " 4. System Diagnostics" - echo " 5. Show Error Help" - echo " 6. Back to Main Menu" - echo "" - echo "===============================================================================================================" - echo "" - - while true; do - echo -n "Select advanced option [1-6]: " - read -r choice - - case $choice in - 1) - show_fix_menu - return - ;; - 2) - show_clean_menu - return - ;; - 3) - show_logs_menu - return - ;; - 4) - show_diagnostics - return - ;; - 5) - show_error_help - return - ;; - 6) - show_main_menu - return - ;; - *) - echo "" - echo "ERROR: Invalid choice. Please enter 1-6." - echo "" - ;; - esac - done -} - -# Function to show error help -show_error_help() { - echo "" - echo "===============================================================================================================" - echo " ERROR TROUBLESHOOTING HELP" - echo "===============================================================================================================" - echo "" - echo "If your CyberPanel installation failed, here's how to troubleshoot:" - echo "" - echo "📋 LOG FILES LOCATION:" - echo " • Main installer log: /var/log/CyberPanel/install.log" - echo " • Installation output: /var/log/CyberPanel/install_output.log" - echo " • Upgrade output: /var/log/CyberPanel/upgrade_output.log" - echo " • System logs: /var/log/messages" - echo "" - echo "🔍 COMMON ISSUES & SOLUTIONS:" - echo "" - echo "1. DEPENDENCY INSTALLATION FAILED:" - echo " • Check internet connection: ping -c 3 google.com" - echo " • Update package lists: yum update -y (RHEL) or apt update (Debian)" - echo " • Check available disk space: df -h" - echo "" - echo "2. CYBERPANEL DOWNLOAD FAILED:" - echo " • Check internet connectivity" - echo " • Verify GitHub access: curl -I https://github.com" - echo " • Try different branch/version" - echo "" - echo "3. PERMISSION ERRORS:" - echo " • Ensure running as root: whoami" - echo " • Check file permissions: ls -la /var/log/CyberPanel/" - echo "" - echo "4. SYSTEM REQUIREMENTS:" - echo " • Minimum 1GB RAM: free -h" - echo " • Minimum 10GB disk space: df -h" - echo " • Supported OS: AlmaLinux 8/9, CentOS 7/8, Ubuntu 18.04+" - echo "" - echo "5. SERVICE CONFLICTS:" - echo " • Check running services: systemctl list-units --state=running" - echo " • Stop conflicting services: systemctl stop apache2 (if running)" - echo "" - echo "💡 QUICK DEBUG COMMANDS:" - echo " • View installation log: cat /var/log/CyberPanel/install_output.log" - echo " • Check system resources: free -h && df -h" - echo " • Test network: ping -c 3 google.com" - echo " • Check services: systemctl status lscpd" - echo " • View system logs: tail -50 /var/log/messages" - echo "" - echo "🆘 GETTING HELP:" - echo " • CyberPanel Documentation: https://docs.cyberpanel.net" - echo " • CyberPanel Community: https://forums.cyberpanel.net" - echo " • GitHub Issues: https://github.com/usmannasir/cyberpanel/issues" - echo " • Discord Support: https://discord.gg/cyberpanel" - echo "" - echo "🔄 RETRY INSTALLATION:" - echo " • Clean installation: Run installer with 'Clean Installation Files' option" - echo " • Different version: Try stable version instead of development" - echo " • Fresh system: Consider using a clean OS installation" - echo "" - echo "===============================================================================================================" - echo "" - read -p "Press Enter to return to main menu..." - show_main_menu -} - -# Function to show fix menu -show_fix_menu() { - echo "" - echo "===============================================================================================================" - echo " FIX INSTALLATION ISSUES" - echo "===============================================================================================================" - echo "" - echo "This will attempt to fix common CyberPanel installation issues:" - echo "• Database connection problems" - echo "• Service configuration issues" - echo "• SSL certificate problems" - echo "• File permission issues" - echo "" - - echo -n "Proceed with fixing installation issues? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - show_advanced_menu - ;; - *) - print_status "Applying fixes..." - apply_fixes - print_status "SUCCESS: Fixes applied successfully" - echo "" - read -p "Press Enter to return to advanced menu..." - show_advanced_menu - ;; - esac -} - -# Function to show clean menu -show_clean_menu() { - echo "" - echo "===============================================================================================================" - echo " CLEAN INSTALLATION FILES" - echo "===============================================================================================================" - echo "" - echo "WARNING: This will remove temporary installation files and logs." - echo " This action cannot be undone!" - echo "" - - echo -n "Proceed with cleaning? (y/n) [n]: " - read -r response - case $response in - [yY]|[yY][eE][sS]) - rm -rf /tmp/cyberpanel_* - rm -rf /var/log/cyberpanel_install.log - echo "SUCCESS: Cleanup complete! Temporary files and logs have been removed." - ;; - esac - - echo "" - echo -n "Return to advanced menu? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - show_main_menu - ;; - *) - show_advanced_menu - ;; - esac -} - -# Function to show logs menu -show_logs_menu() { - echo "" - echo "===============================================================================================================" - echo " VIEW INSTALLATION LOGS" - echo "===============================================================================================================" - echo "" - - local log_file="/var/log/cyberpanel_install.log" - - if [ -f "$log_file" ]; then - echo "Installation Log: $log_file" - echo "Log Size: $(du -h "$log_file" | cut -f1)" - echo "" - - echo -n "View recent log entries? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - ;; - *) - echo "" - echo "Recent log entries:" - tail -n 20 "$log_file" - ;; - esac - else - echo "No installation logs found at $log_file" - fi - - echo "" - echo -n "Return to advanced menu? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - show_main_menu - ;; - *) - show_advanced_menu - ;; - esac -} - -# Function to show diagnostics -show_diagnostics() { - echo "" - echo "===============================================================================================================" - echo " SYSTEM DIAGNOSTICS" - echo "===============================================================================================================" - echo "" - - echo "Running system diagnostics..." - echo "" - - # Disk space - echo "Disk Usage:" - df -h | grep -E '^/dev/' - - # Memory usage - echo "" - echo "Memory Usage:" - free -h - - # Load average - echo "" - echo "System Load:" - uptime - - # Network interfaces - echo "" - echo "Network Interfaces:" - ip addr show | grep -E '^[0-9]+:|inet ' - - echo "" - echo -n "Return to advanced menu? (y/n) [y]: " - read -r response - case $response in - [nN]|[nN][oO]) - show_main_menu - ;; - *) - show_advanced_menu - ;; - esac -} - -# Function to start upgrade -start_upgrade() { - echo "" - echo "===============================================================================================================" - echo " STARTING UPGRADE" - echo "===============================================================================================================" - echo "" - - # Detect OS - echo "Step 1/5: Detecting operating system..." - if ! detect_os; then - print_status "ERROR: Failed to detect operating system" - exit 1 - fi - echo " ✓ Operating system detected successfully" - echo "" - - # Install dependencies - echo "Step 2/5: Installing/updating dependencies..." - install_dependencies - echo "" - - # Download and run the upgrade script - echo "Step 3/5: Downloading CyberPanel upgrade script..." - local upgrade_url="" - if [ -n "$BRANCH_NAME" ]; then - if [[ "$BRANCH_NAME" =~ ^[a-f0-9]{40}$ ]]; then - # It's a commit hash - echo "Downloading from commit: $BRANCH_NAME" - upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" - else - # It's a branch name - echo "Downloading from branch: $BRANCH_NAME" - upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" - fi - else - echo "Downloading from: https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh" - upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh" - fi - - curl --silent -o cyberpanel_upgrade.sh "$upgrade_url" 2>/dev/null - - chmod +x cyberpanel_upgrade.sh - - echo " ✓ CyberPanel upgrade script downloaded" - echo " 🔄 Starting CyberPanel upgrade..." - echo "" - echo "IMPORTANT: The upgrade is now running in the background." - echo "You will see detailed output from the CyberPanel upgrade script below." - echo "This is normal and expected - the upgrade is proceeding!" - echo "" - echo "===============================================================================================================" - echo "" - - # Run the upgrade with live progress monitoring - echo "Starting CyberPanel upgrade process..." - echo "This may take several minutes. Please be patient." - echo "" - - # Create log directory - mkdir -p /var/log/CyberPanel - - # Run the upgrade with live output monitoring - echo "Starting CyberPanel upgrade with live progress monitoring..." - echo "" - echo "===============================================================================================================" - echo " LIVE UPGRADE PROGRESS" - echo "===============================================================================================================" - echo "" - - # Run upgrade and show live output - if [ "$DEBUG_MODE" = true ]; then - ./cyberpanel_upgrade.sh --debug 2>&1 | tee /var/log/CyberPanel/upgrade_output.log - else - ./cyberpanel_upgrade.sh 2>&1 | tee /var/log/CyberPanel/upgrade_output.log - fi - - local upgrade_exit_code=${PIPESTATUS[0]} - - echo "" - echo "===============================================================================================================" - echo " UPGRADE COMPLETED" - echo "===============================================================================================================" - echo "" - - # Clean up downloaded upgrade script - rm -f cyberpanel_upgrade.sh 2>/dev/null - - # Check if upgrade was successful - if [ $upgrade_exit_code -eq 0 ]; then - print_status "SUCCESS: CyberPanel upgraded successfully" - return 0 - else - print_status "ERROR: CyberPanel upgrade failed with exit code $upgrade_exit_code" - echo "" - echo "Upgrade log (last 50 lines):" - echo "===============================================================================================================" - tail -50 /var/log/CyberPanel/upgrade_output.log 2>/dev/null || echo "Could not read upgrade log" - echo "===============================================================================================================" - echo "" - echo "Full upgrade log available at: /var/log/CyberPanel/upgrade_output.log" - echo "" - return 1 - fi -} - -# Function to start force reinstall -start_force_reinstall() { - echo "" - echo "===============================================================================================================" - echo " FORCE REINSTALL CYBERPANEL" - echo "===============================================================================================================" - echo "" - echo "This will completely remove the existing CyberPanel installation and install a fresh copy." - echo "All data and configurations will be lost!" - echo "" - - while true; do - echo -n "Are you sure you want to proceed? (y/N): " - read -r confirm - case $confirm in - [Yy]*) - echo "" - echo "Starting force reinstall..." - echo "" - - # Clean up existing installation - cleanup_existing_cyberpanel - - # Start fresh installation - start_installation - break - ;; - [Nn]*|"") - echo "Force reinstall cancelled." - return - ;; - *) - echo "Please answer yes or no." - ;; - esac - done -} - -# Function to start preupgrade -start_preupgrade() { - echo "" - echo "===============================================================================================================" - echo " PRE-UPGRADE SETUP" - echo "===============================================================================================================" - echo "" - - echo "This will download the latest CyberPanel upgrade script to /usr/local/" - echo "and prepare it for execution." - echo "" - - # Get the latest version - echo "Step 1/3: Fetching latest version information..." - local latest_version=$(curl -s https://cyberpanel.net/version.txt | sed -e 's|{"version":"||g' -e 's|","build":|.|g' | sed 's:}*$::') - local branch_name="v$latest_version" - - echo " ✓ Latest version: $latest_version" - echo " ✓ Branch: $branch_name" - echo "" - - # Download the upgrade script - echo "Step 2/3: Downloading CyberPanel upgrade script..." - local upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$branch_name/cyberpanel_upgrade.sh" - echo "Downloading from: $upgrade_url" - - if curl --silent -o /usr/local/cyberpanel_upgrade.sh "$upgrade_url" 2>/dev/null; then - chmod 700 /usr/local/cyberpanel_upgrade.sh - echo " ✓ Upgrade script downloaded to /usr/local/cyberpanel_upgrade.sh" - else - print_status "ERROR: Failed to download upgrade script" - return 1 - fi - echo "" - - # Show instructions - echo "Step 3/3: Setup complete!" - echo "" - echo "The upgrade script is now ready at: /usr/local/cyberpanel_upgrade.sh" - echo "" - echo "To run the upgrade, you can either:" - echo " 1. Use this installer's 'Update Existing Installation' option" - echo " 2. Run directly: /usr/local/cyberpanel_upgrade.sh" - echo "" - echo "===============================================================================================================" - echo "" - - read -p "Press Enter to return to main menu..." - show_main_menu -} - -# Function to start reinstall -start_reinstall() { - echo "" - echo "===============================================================================================================" - echo " STARTING REINSTALL" - echo "===============================================================================================================" - echo "" - - echo "WARNING: This will completely remove the existing CyberPanel installation!" - echo "All data, websites, and configurations will be lost!" - echo "" - - # Detect OS - echo "Step 1/6: Detecting operating system..." - if ! detect_os; then - print_status "ERROR: Failed to detect operating system" - exit 1 - fi - echo " ✓ Operating system detected successfully" - echo "" - - # Stop services - echo "Step 2/6: Stopping CyberPanel services..." - systemctl stop lscpd 2>/dev/null || true - systemctl stop lsws 2>/dev/null || true - systemctl stop mariadb 2>/dev/null || true - systemctl stop postfix 2>/dev/null || true - systemctl stop dovecot 2>/dev/null || true - systemctl stop pure-ftpd 2>/dev/null || true - echo " ✓ Services stopped" - echo "" - - # Remove existing installation - echo "Step 3/6: Removing existing CyberPanel installation..." - rm -rf /usr/local/CyberCP 2>/dev/null || true - rm -rf /usr/local/lsws 2>/dev/null || true - rm -rf /home/cyberpanel 2>/dev/null || true - rm -rf /var/lib/mysql 2>/dev/null || true - rm -rf /var/log/cyberpanel 2>/dev/null || true - echo " ✓ Existing installation removed" - echo "" - - # Install dependencies - echo "Step 4/6: Installing dependencies..." - install_dependencies - echo "" - - # Install CyberPanel - echo "Step 5/6: Installing CyberPanel..." - if ! install_cyberpanel; then - print_status "ERROR: CyberPanel installation failed" - exit 1 +MOD_DIR="" +if [[ -d "$INSTALL_SCRIPT_DIR/install_modules" ]]; then + MOD_DIR="$INSTALL_SCRIPT_DIR/install_modules" +else + MOD_DIR="/tmp/cyberpanel_install_modules_$$" + mkdir -p "$MOD_DIR" + BASE_URL="https://raw.githubusercontent.com/master3395/cyberpanel/${BRANCH_FOR_MODULES}/install_modules" + for name in 00_common 01_verify_deps 02_install_core 03_install_direct 04_fixes_status 05_menus_main 06_menus_update 07_menus_advanced 08_actions 09_parse_main; do + curl -sL -H 'Cache-Control: no-cache' "$BASE_URL/${name}.sh" -o "$MOD_DIR/${name}.sh" 2>/dev/null || true + done fi - echo "" - - # Apply fixes - echo "Step 6/6: Applying installation fixes..." - apply_fixes - echo "" - - # Show status summary - show_status_summary - - print_status "SUCCESS: CyberPanel reinstalled successfully!" -} -# Function to start installation -start_installation() { - echo "" - echo "===============================================================================================================" - echo " STARTING INSTALLATION" - echo "===============================================================================================================" - echo "" - - # Detect OS - echo "Step 1/6: Detecting operating system..." - if ! detect_os; then - print_status "ERROR: Failed to detect operating system" - exit 1 - fi - echo " ✓ Operating system detected successfully" - echo "" - - # Install dependencies - echo "Step 2/6: Installing dependencies..." - install_dependencies - echo "" - - # Install CyberPanel - echo "Step 3/6: Installing CyberPanel..." - if ! install_cyberpanel; then - print_status "ERROR: CyberPanel installation failed" - echo "" - echo "Would you like to see troubleshooting help? (y/n) [y]: " - read -r show_help - case $show_help in - [nN]|[nN][oO]) - echo "Installation failed. Check logs at /var/log/CyberPanel/" - echo "Run the installer again and select 'Advanced Options' → 'Show Error Help' for detailed troubleshooting." - ;; - *) - show_error_help - ;; - esac - exit 1 - fi - echo "" - - # Apply post-installation fixes silently - apply_fixes +for f in "$MOD_DIR"/00_common.sh "$MOD_DIR"/01_verify_deps.sh "$MOD_DIR"/02_install_core.sh "$MOD_DIR"/03_install_direct.sh "$MOD_DIR"/04_fixes_status.sh "$MOD_DIR"/05_menus_main.sh "$MOD_DIR"/06_menus_update.sh "$MOD_DIR"/07_menus_advanced.sh "$MOD_DIR"/08_actions.sh "$MOD_DIR"/09_parse_main.sh; do + if [[ -f "$f" ]]; then + source "$f" + fi +done - # Create standard aliases (silently) - create_standard_aliases >/dev/null 2>&1 - - # Show final status summary - echo "" - show_status_summary -} - -# Function to parse command line arguments -parse_arguments() { - while [[ $# -gt 0 ]]; do - case $1 in - -b|--branch) - if [ -n "$2" ]; then - # Convert version number to branch name if needed - if [[ "$2" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then - if [[ "$2" == *"-"* ]]; then - # Already has suffix like 2.5.5-dev, add v prefix - BRANCH_NAME="v$2" - else - # Add v prefix and dev suffix for development versions - BRANCH_NAME="v$2-dev" - fi - elif [[ "$2" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then - # Already has v prefix, use as is - BRANCH_NAME="$2" - else - # Assume it's already a branch name or commit hash - BRANCH_NAME="$2" - fi - shift 2 - else - echo "ERROR: -b/--branch requires a version number or branch name" - echo "Example: -b 2.5.5-dev or -b v2.5.5-dev" - exit 1 - fi - ;; - -v|--version) - if [ -n "$2" ]; then - # Convert version number to branch name if needed - if [[ "$2" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then - if [[ "$2" == *"-"* ]]; then - # Already has suffix like 2.5.5-dev, add v prefix - BRANCH_NAME="v$2" - else - # Add v prefix and dev suffix for development versions - BRANCH_NAME="v$2-dev" - fi - elif [[ "$2" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then - # Already has v prefix, use as is - BRANCH_NAME="$2" - else - # Assume it's already a branch name or commit hash - BRANCH_NAME="$2" - fi - shift 2 - else - echo "ERROR: -v/--version requires a version number or branch name" - echo "Example: -v 2.5.5-dev or -v v2.5.5-dev" - exit 1 - fi - ;; - --debug) - DEBUG_MODE=true - set -x - shift - ;; - --mariadb-version) - if [ -n "$2" ] && [ "$2" = "10.11" ]; then - MARIADB_VER="10.11" - shift 2 - elif [ -n "$2" ] && [ "$2" = "11.8" ]; then - MARIADB_VER="11.8" - shift 2 - elif [ -n "$2" ] && [ "$2" = "12.1" ]; then - MARIADB_VER="12.1" - shift 2 - else - echo "ERROR: --mariadb-version requires 10.11, 11.8 or 12.1" - exit 1 - fi - ;; - --auto) - AUTO_INSTALL=true - shift - ;; - -h|--help) - echo "Usage: $0 [OPTIONS]" - echo "Options:" - echo " -b, --branch BRANCH Install from specific branch/commit" - echo " -v, --version VER Install specific version (auto-adds v prefix)" - echo " --mariadb-version VER MariaDB version: 10.11, 11.8 or 12.1 (asked after web server)" - echo " --debug Enable debug mode" - echo " --auto Auto mode: OpenLiteSpeed + MariaDB 11.8 unless --mariadb-version set" - echo " -h, --help Show this help message" - echo "" - echo "Examples:" - echo " $0 # Interactive installation" - echo " $0 --debug # Debug mode installation" - echo " $0 --auto # Auto installation" - echo " $0 -b v2.5.5-dev # Install development version" - echo " $0 -v 2.5.5-dev # Install version 2.5.5-dev" - echo " $0 -v 2.4.3 # Install version 2.4.3" - echo " $0 -b main # Install from main branch" - echo " $0 -b a1b2c3d4 # Install from specific commit" - echo " $0 --mariadb-version 10.11 # Use MariaDB 10.11 (same as v2.4.4 style)" - echo " $0 --mariadb-version 12.1 # Use MariaDB 12.1 (no prompt)" - echo " $0 --auto --mariadb-version 11.8 # Fully non-interactive with MariaDB 11.8" - echo "" - echo "Standard CyberPanel Installation Methods:" - echo " sh <(curl https://cyberpanel.net/install.sh)" - echo " bash <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh) -b 2.4.3" - echo " bash <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh) -b 2.5.5-dev" - exit 0 - ;; - *) - print_status "WARNING: Unknown option: $1" - shift - ;; - esac - done -} - -# Function to detect installation mode -detect_installation_mode() { - # Check if this is being called as an upgrade script - if [[ "$0" == *"cyberpanel_upgrade.sh"* ]] || [[ "$0" == *"upgrade"* ]]; then - INSTALLATION_TYPE="upgrade" - return 0 - fi - - # Check if this is being called as a pre-upgrade script - if [[ "$0" == *"preUpgrade.sh"* ]] || [[ "$0" == *"preupgrade"* ]]; then - INSTALLATION_TYPE="preupgrade" - return 0 - fi - - # Check if this is being called as a standard install script - if [[ "$0" == *"install.sh"* ]] || [[ "$0" == *"cyberpanel.sh"* ]]; then - INSTALLATION_TYPE="install" - return 0 - fi - - # Default to install mode - INSTALLATION_TYPE="install" - return 0 -} - -# Function to create standard CyberPanel aliases -create_standard_aliases() { - print_status "Creating standard CyberPanel installation aliases..." - - # Create symbolic links for standard installation methods - local script_dir="/usr/local/bin" - local script_name="cyberpanel_enhanced.sh" - - # Copy this script to /usr/local/bin - if cp "$0" "$script_dir/$script_name" 2>/dev/null; then - chmod +x "$script_dir/$script_name" - - # Create aliases for standard CyberPanel methods - ln -sf "$script_dir/$script_name" "$script_dir/cyberpanel_upgrade.sh" 2>/dev/null || true - ln -sf "$script_dir/$script_name" "$script_dir/preUpgrade.sh" 2>/dev/null || true - ln -sf "$script_dir/$script_name" "$script_dir/install.sh" 2>/dev/null || true - - print_status "✓ Standard CyberPanel aliases created" - print_status " - cyberpanel_upgrade.sh" - print_status " - preUpgrade.sh" - print_status " - install.sh" - else - print_status "WARNING: Could not create standard aliases (permission denied)" - fi -} - -# Main installation function -main() { - # Initialize log directory and file - mkdir -p "/var/log/CyberPanel" - touch "/var/log/CyberPanel/install.log" - - print_status "CyberPanel Enhanced Installer Starting..." - print_status "Log file: /var/log/CyberPanel/install.log" - - # Detect installation mode - detect_installation_mode - - # Parse command line arguments - parse_arguments "$@" - - # Handle different installation modes - case "$INSTALLATION_TYPE" in - "upgrade") - print_status "Running in upgrade mode..." - if [ -n "$BRANCH_NAME" ]; then - print_status "Upgrading to version: $BRANCH_NAME" - fi - start_upgrade - ;; - "preupgrade") - print_status "Running in pre-upgrade mode..." - start_preupgrade - ;; - "install"|*) - if [ "$AUTO_INSTALL" = true ]; then - # Run auto mode - print_status "Starting auto mode..." - - # Detect OS - if ! detect_os; then - print_status "ERROR: Failed to detect operating system" - exit 1 - fi - - # Install dependencies - install_dependencies - - # Install CyberPanel - if ! install_cyberpanel; then - print_status "ERROR: CyberPanel installation failed" - echo "" - echo "Would you like to see troubleshooting help? (y/n) [y]: " - read -r show_help - case $show_help in - [nN]|[nN][oO]) - echo "Installation failed. Check logs at /var/log/CyberPanel/" - ;; - *) - show_error_help - ;; - esac - exit 1 - fi - - # Apply fixes - apply_fixes - - # Create standard aliases - create_standard_aliases - - # Show status summary - show_status_summary - - print_status "SUCCESS: Installation completed successfully!" - else - # Run interactive mode - ensure stdin is the terminal for prompts (e.g. when script was piped from curl) - if [ ! -t 0 ]; then - exec 0/dev/null 2>&1 || MDB_CLI="mysql" + +# Logging function +log_message() { + # Ensure log directory exists + mkdir -p "/var/log/CyberPanel" + echo "[$(date '+%Y-%m-%d %H:%M:%S')] [CYBERPANEL] $1" | tee -a "/var/log/CyberPanel/install.log" 2>/dev/null || echo "[$(date '+%Y-%m-%d %H:%M:%S')] [CYBERPANEL] $1" +} + +# Print status +print_status() { + local message="$1" + echo "$message" + log_message "$message" +} + +# Function to show banner +show_banner() { + clear + echo "" + echo "===============================================================================================================" + echo " CYBERPANEL COMPLETE INSTALLER" + echo "===============================================================================================================" + echo "" + echo " The Ultimate Web Hosting Control Panel" + echo " Powered by OpenLiteSpeed • Fast • Secure • Scalable" + echo "" + echo " Interactive Menus • Version Selection • Advanced Options" + echo "" + echo "===============================================================================================================" + echo "" +} + +# Function to detect OS +detect_os() { + # Check if we're running from a file (not via curl) and modules are available + if [ -f "modules/os/detect.sh" ]; then + # Load the OS detection module for enhanced support + source "modules/os/detect.sh" + detect_os + return $? + fi + + print_status "Detecting operating system..." + + # Detect architecture + ARCHITECTURE=$(uname -m) + case $ARCHITECTURE in + x86_64) + print_status "Architecture: x86_64 (Supported)" + ;; + aarch64|arm64) + print_status "Architecture: $ARCHITECTURE (Limited support)" + ;; + *) + print_status "Architecture: $ARCHITECTURE (Not supported)" + return 1 + ;; + esac + + # Get OS release information + local OUTPUT=$(cat /etc/*release 2>/dev/null) + if [ -z "$OUTPUT" ]; then + print_status "ERROR: Cannot read OS release information" + return 1 + fi + + # Detect OS + if echo $OUTPUT | grep -q "AlmaLinux 10" ; then + SERVER_OS="AlmaLinux10" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: AlmaLinux 10" + elif echo $OUTPUT | grep -q "AlmaLinux 9" ; then + SERVER_OS="AlmaLinux9" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: AlmaLinux 9" + elif echo $OUTPUT | grep -q "AlmaLinux 8" ; then + SERVER_OS="AlmaLinux8" + OS_FAMILY="rhel" + PACKAGE_MANAGER="yum" + print_status "Detected: AlmaLinux 8" + elif echo $OUTPUT | grep -q "CentOS Linux 9" ; then + SERVER_OS="CentOS9" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: CentOS Linux 9" + elif echo $OUTPUT | grep -q "CentOS Linux 8" ; then + SERVER_OS="CentOS8" + OS_FAMILY="rhel" + PACKAGE_MANAGER="yum" + print_status "Detected: CentOS Linux 8" + elif echo $OUTPUT | grep -q "Rocky Linux 9" ; then + SERVER_OS="RockyLinux9" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: Rocky Linux 9" + elif echo $OUTPUT | grep -q "Rocky Linux 8" ; then + SERVER_OS="RockyLinux8" + OS_FAMILY="rhel" + PACKAGE_MANAGER="yum" + print_status "Detected: Rocky Linux 8" + elif echo $OUTPUT | grep -q "Ubuntu 24.04" ; then + SERVER_OS="Ubuntu2404" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Ubuntu 24.04" + elif echo $OUTPUT | grep -q "Ubuntu 22.04" ; then + SERVER_OS="Ubuntu2204" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Ubuntu 22.04" + elif echo $OUTPUT | grep -q "Ubuntu 20.04" ; then + SERVER_OS="Ubuntu2004" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Ubuntu 20.04" + elif echo $OUTPUT | grep -q "Debian GNU/Linux 13" ; then + SERVER_OS="Debian13" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Debian GNU/Linux 13" + elif echo $OUTPUT | grep -q "Debian GNU/Linux 12" ; then + SERVER_OS="Debian12" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Debian GNU/Linux 12" + elif echo $OUTPUT | grep -q "Debian GNU/Linux 11" ; then + SERVER_OS="Debian11" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Debian GNU/Linux 11" + else + print_status "ERROR: Unsupported OS detected" + print_status "Supported OS: AlmaLinux 8/9/10, CentOS 8/9, Rocky Linux 8/9, Ubuntu 20.04/22.04/24.04, Debian 11/12/13" + return 1 + fi + + return 0 +} + +# Function to fix static file permissions (critical for LiteSpeed) +fix_static_file_permissions() { + echo " 🔧 Fixing static file permissions for web server access..." + + # CRITICAL: Fix ownership and permissions for all public files + # LiteSpeed requires files to be owned by lscpd and NOT have execute permissions + + # Check if the public directory exists + if [ -d "/usr/local/CyberCP/public/" ]; then + echo " • Setting ownership to lscpd:lscpd for public directory..." + chown -R lscpd:lscpd /usr/local/CyberCP/public/ 2>/dev/null || true + + echo " • Setting directory permissions to 755..." + find /usr/local/CyberCP/public/ -type d -exec chmod 755 {} \; 2>/dev/null || true + + echo " • Setting file permissions to 644 (removing execute bit)..." + find /usr/local/CyberCP/public/ -type f -exec chmod 644 {} \; 2>/dev/null || true + + # Ensure parent directories have correct permissions + chmod 755 /usr/local/CyberCP/public/ 2>/dev/null || true + chmod 755 /usr/local/CyberCP/public/static/ 2>/dev/null || true + + echo " ✅ Static file permissions fixed successfully" + else + echo " ⚠️ Warning: /usr/local/CyberCP/public/ directory not found" + fi + + # Also check the alternative path + if [ -d "/usr/local/CyberPanel/public/" ]; then + echo " • Fixing permissions for /usr/local/CyberPanel/public/..." + chown -R lscpd:lscpd /usr/local/CyberPanel/public/ 2>/dev/null || true + find /usr/local/CyberPanel/public/ -type d -exec chmod 755 {} \; 2>/dev/null || true + find /usr/local/CyberPanel/public/ -type f -exec chmod 644 {} \; 2>/dev/null || true + fi +} + +# Function to fix post-installation issues +fix_post_install_issues() { + echo " 🔧 Fixing database connection issues..." + + # Wait for services to start + sleep 10 + + # Start and enable MariaDB if not running + if ! systemctl is-active --quiet mariadb; then + echo " Starting MariaDB service..." + systemctl start mariadb + systemctl enable mariadb + sleep 5 + fi + + # Start and enable LiteSpeed if not running + if ! systemctl is-active --quiet lsws; then + echo " Starting LiteSpeed service..." + systemctl start lsws + systemctl enable lsws + sleep 5 + fi + + # Fix database user permissions + echo " Fixing database user permissions..." + + # Wait for MariaDB to be ready + local retry_count=0 + while [ $retry_count -lt 10 ]; do + if $MDB_CLI -e "SELECT 1;" >/dev/null 2>&1; then + break + fi + echo " Waiting for MariaDB to be ready... ($((retry_count + 1))/10)" + sleep 2 + retry_count=$((retry_count + 1)) + done + + # Create database user with proper permissions + echo " Dropping existing cyberpanel user..." + $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'localhost';" 2>/dev/null || true + $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'%';" 2>/dev/null || true + + echo " Creating cyberpanel user with correct password..." + $MDB_CLI -e "CREATE USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + $MDB_CLI -e "CREATE USER 'cyberpanel'@'%' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + + echo " Granting privileges..." + $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'localhost' WITH GRANT OPTION;" 2>/dev/null || true + $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'%' WITH GRANT OPTION;" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + + # Verify the user was created correctly + echo " Verifying database user..." + if $MDB_CLI -u cyberpanel -pcyberpanel -e "SELECT 1;" >/dev/null 2>&1; then + echo " ✅ Database user verification successful" + else + echo " ⚠️ Database user verification failed, trying alternative approach..." + # Alternative: use root to create the user + $MDB_CLI -e "CREATE OR REPLACE USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'localhost' WITH GRANT OPTION;" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + fi + + # Create CyberPanel database if it doesn't exist + $MDB_CLI -e "CREATE DATABASE IF NOT EXISTS cyberpanel;" 2>/dev/null || true + $MDB_CLI -e "GRANT ALL PRIVILEGES ON cyberpanel.* TO 'cyberpanel'@'localhost';" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + + # Get or set unified password for both CyberPanel and OpenLiteSpeed + local unified_password="" + if [ -f "/root/.cyberpanel_password" ]; then + unified_password=$(cat /root/.cyberpanel_password 2>/dev/null) + fi + + # If no password was captured from installation, use default + if [ -z "$unified_password" ]; then + unified_password="1234567" + # Save password to file for later retrieval + echo "$unified_password" > /root/.cyberpanel_password 2>/dev/null || true + chmod 600 /root/.cyberpanel_password 2>/dev/null || true + fi + + echo " Setting unified password for CyberPanel and OpenLiteSpeed..." + echo " Password: $unified_password" + + # First, ensure the cyberpanel user exists and has correct password + $MDB_CLI -e "ALTER USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + + # Wait a moment for the database to be ready + sleep 2 + + # Reset CyberPanel admin password + echo " Setting CyberPanel admin password..." + /usr/local/CyberCP/bin/python3 /usr/local/CyberCP/plogical/adminPass.py 2>/dev/null || { + echo " Admin password reset failed, trying alternative method..." + # Alternative method: directly update the database + $MDB_CLI -u cyberpanel -pcyberpanel cyberpanel -e "UPDATE Administrator SET password = '$unified_password' WHERE id = 1;" 2>/dev/null || true + } + + # Set OpenLiteSpeed admin password + echo " Setting OpenLiteSpeed admin password..." + if [ -f "/usr/local/lsws/admin/htpasswd" ]; then + # Create OpenLiteSpeed admin user with the same password + /usr/local/lsws/admin/misc/admpass.sh -u admin -p "$unified_password" 2>/dev/null || { + echo " OpenLiteSpeed password set via alternative method..." + # Alternative method: directly create htpasswd entry + echo "admin:$(openssl passwd -apr1 '$unified_password')" > /usr/local/lsws/admin/htpasswd 2>/dev/null || true + } + fi + + # Fix PHP configuration files + echo " Fixing PHP configuration..." + + # Find the reference PHP version (usually lsphp82) + local reference_php="" + for php_version in lsphp82 lsphp81 lsphp80 lsphp84 lsphp83 lsphp74 lsphp73 lsphp72; do + if [ -d "/usr/local/lsws/$php_version" ] && [ -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then + reference_php="$php_version" + echo " Using $php_version as reference for PHP configuration" + break + fi + done + + if [ -n "$reference_php" ]; then + for php_version in lsphp72 lsphp73 lsphp74 lsphp80 lsphp81 lsphp82 lsphp83 lsphp84; do + if [ -d "/usr/local/lsws/$php_version" ]; then + # Create missing php.ini if it doesn't exist + if [ ! -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then + echo " Creating missing php.ini for $php_version..." + cp "/usr/local/lsws/$reference_php/etc/php.ini" "/usr/local/lsws/$php_version/etc/php.ini" 2>/dev/null || true + fi + + # Ensure the directory exists + mkdir -p "/usr/local/lsws/$php_version/etc" 2>/dev/null || true + fi + done + else + echo " ⚠️ No reference PHP configuration found, creating basic php.ini files..." + for php_version in lsphp72 lsphp73 lsphp74 lsphp80 lsphp81 lsphp82 lsphp83 lsphp84; do + if [ -d "/usr/local/lsws/$php_version" ]; then + mkdir -p "/usr/local/lsws/$php_version/etc" 2>/dev/null || true + if [ ! -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then + echo " Creating basic php.ini for $php_version..." + cat > "/usr/local/lsws/$php_version/etc/php.ini" << 'EOF' +[PHP] +engine = On +short_open_tag = Off +precision = 14 +output_buffering = 4096 +zlib.output_compression = Off +implicit_flush = Off +unserialize_callback_func = +serialize_precision = -1 +disable_functions = +disable_classes = +zend.enable_gc = On +expose_php = Off +max_execution_time = 30 +max_input_time = 60 +memory_limit = 128M +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT +display_errors = Off +display_startup_errors = Off +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +variables_order = "GPCS" +request_order = "GP" +register_argc_argv = Off +auto_globals_jit = On +post_max_size = 8M +auto_prepend_file = +auto_append_file = +default_mimetype = "text/html" +default_charset = "UTF-8" +file_uploads = On +upload_max_filesize = 2M +max_file_uploads = 20 +allow_url_fopen = On +allow_url_include = Off +default_socket_timeout = 60 +EOF + fi + fi + done + fi + + # Restart services + echo " Restarting services..." + systemctl restart mariadb + systemctl restart lsws + + # Wait for services to stabilize + sleep 10 + + # Verify services are running + if systemctl is-active --quiet mariadb && systemctl is-active --quiet lsws; then + echo " ✅ Post-installation fixes completed successfully" + + # Run final verification + verify_installation + else + echo " ⚠️ Some services may need manual attention" + echo " 🔧 Attempting additional fixes..." + + # Additional service fixes + systemctl daemon-reload + systemctl reset-failed mariadb lsws + systemctl start mariadb lsws + + sleep 5 + verify_installation + fi +} + +# Function to verify installation +verify_installation() { + echo "" + echo " 🔍 Verifying installation..." + + local issues=0 + + # Check MariaDB + if systemctl is-active --quiet mariadb; then + echo " ✅ MariaDB is running" + else + echo " ❌ MariaDB is not running" + issues=$((issues + 1)) + fi + + # Check LiteSpeed + if systemctl is-active --quiet lsws; then + echo " ✅ LiteSpeed is running" + else + echo " ❌ LiteSpeed is not running" + issues=$((issues + 1)) + fi + + # Check web interface + if curl -s -k --connect-timeout 5 https://localhost:8090 >/dev/null 2>&1; then + echo " ✅ Web interface is accessible" + else + echo " ⚠️ Web interface may not be accessible yet (this is normal)" + fi + + # Check database connection + if $MDB_CLI -e "SELECT 1;" >/dev/null 2>&1; then + echo " ✅ Database connection is working" + else + echo " ❌ Database connection failed" + issues=$((issues + 1)) + fi + + if [ $issues -eq 0 ]; then + echo "" + echo " 🎉 Installation verification completed successfully!" + echo " 🌐 CyberPanel: https://$(curl -s ifconfig.me):8090 (admin/1234567)" + echo " 🌐 OpenLiteSpeed: https://$(curl -s ifconfig.me):7080 (admin/1234567)" + echo " 🔑 Both services use the same password for convenience" + else + echo "" + echo " ⚠️ Installation completed with $issues issue(s)" + echo " 🔧 Some manual intervention may be required" + echo " 📋 Check the logs at: /var/log/CyberPanel/" + fi +} + +# Function to install dependencies +install_dependencies() { + # Check if we're running from a file (not via curl) and modules are available + if [ -f "modules/deps/manager.sh" ]; then + # Load the dependency manager module for enhanced support + source "modules/deps/manager.sh" + install_dependencies "$SERVER_OS" "$OS_FAMILY" "$PACKAGE_MANAGER" + return $? + fi + + print_status "Installing dependencies..." + echo "" + echo "Installing system dependencies for $SERVER_OS..." + echo "This may take a few minutes depending on your internet speed." + echo "" + + case $OS_FAMILY in + "rhel") + echo "Step 1/4: Installing EPEL repository..." + $PACKAGE_MANAGER install -y epel-release 2>/dev/null || true + echo " ✓ EPEL repository installed" + echo "" + + echo "Step 2/4: Installing development tools..." + $PACKAGE_MANAGER groupinstall -y 'Development Tools' 2>/dev/null || { + $PACKAGE_MANAGER install -y gcc gcc-c++ make kernel-devel 2>/dev/null || true + } + echo " ✓ Development tools installed" + echo "" + + echo "Step 3/4: Installing core packages..." + if [ "$SERVER_OS" = "AlmaLinux9" ] || [ "$SERVER_OS" = "AlmaLinux10" ] || [ "$SERVER_OS" = "CentOS9" ] || [ "$SERVER_OS" = "RockyLinux9" ]; then + # AlmaLinux 9/10 / CentOS 9 / Rocky Linux 9 + $PACKAGE_MANAGER install -y ImageMagick gd libicu oniguruma python3 python3-pip python3-devel 2>/dev/null || true + $PACKAGE_MANAGER install -y aspell 2>/dev/null || print_status "WARNING: aspell not available, skipping..." + $PACKAGE_MANAGER install -y libc-client-devel 2>/dev/null || print_status "WARNING: libc-client-devel not available, skipping..." + else + # AlmaLinux 8 / CentOS 8 / Rocky Linux 8 + $PACKAGE_MANAGER install -y ImageMagick gd libicu oniguruma aspell libc-client-devel python3 python3-pip python3-devel 2>/dev/null || true + fi + echo " ✓ Core packages installed" + echo "" + + echo "Step 4/4: Verifying installation..." + echo " ✓ All dependencies verified" + ;; + "debian") + echo "Step 1/4: Updating package lists..." + apt update -qq 2>/dev/null || true + echo " ✓ Package lists updated" + echo "" + + echo "Step 2/4: Installing essential packages..." + apt install -y -qq curl wget git unzip tar gzip bzip2 2>/dev/null || true + echo " ✓ Essential packages installed" + echo "" + + echo "Step 3/4: Installing development tools..." + apt install -y -qq build-essential gcc g++ make python3-dev python3-pip 2>/dev/null || true + echo " ✓ Development tools installed" + echo "" + + echo "Step 4/4: Installing core packages..." + apt install -y -qq imagemagick php-gd libicu-dev libonig-dev 2>/dev/null || true + apt install -y -qq aspell 2>/dev/null || print_status "WARNING: aspell not available, skipping..." + apt install -y -qq libc-client-dev 2>/dev/null || print_status "WARNING: libc-client-dev not available, skipping..." + echo " ✓ Core packages installed" + ;; + esac + + echo "" + print_status "SUCCESS: Dependencies installed successfully" +} + +# Function to install CyberPanel +install_cyberpanel() { + print_status "Installing CyberPanel..." + echo "" + echo "===============================================================================================================" + echo " CYBERPANEL INSTALLATION IN PROGRESS" + echo "===============================================================================================================" + echo "" + echo "This process may take 10-15 minutes depending on your internet speed." + echo "Please DO NOT close this terminal or interrupt the installation." + echo "" + echo "Current Status:" + echo " ✓ Dependencies installed" + echo " 🔄 Starting CyberPanel installation using working method..." + echo "" + + # Use the working CyberPanel installation method + install_cyberpanel_direct +} + +# Function to check if CyberPanel is already installed +check_cyberpanel_installed() { + if [ -d "/usr/local/CyberPanel" ] || [ -d "/usr/local/CyberCP" ] || [ -f "/usr/local/lsws/bin/lswsctrl" ]; then + return 0 # CyberPanel is installed + else + return 1 # CyberPanel is not installed + fi +} + +# Function to clean up existing CyberPanel installation +cleanup_existing_cyberpanel() { + echo " 🧹 Cleaning up existing CyberPanel installation..." + + # Stop services + systemctl stop lsws mariadb 2>/dev/null || true + + # Remove CyberPanel directories + rm -rf /usr/local/CyberPanel 2>/dev/null || true + rm -rf /usr/local/CyberCP 2>/dev/null || true + rm -rf /usr/local/lsws 2>/dev/null || true + + # Remove systemd services + systemctl disable lsws mariadb 2>/dev/null || true + rm -f /etc/systemd/system/lsws.service 2>/dev/null || true + + # Clean up databases + $MDB_CLI -e "DROP DATABASE IF EXISTS cyberpanel;" 2>/dev/null || true + $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'localhost';" 2>/dev/null || true + + echo " ✅ Cleanup completed" +} + +# Function to install CyberPanel directly using the working method +install_cyberpanel_direct() { + # Ask web server (OpenLiteSpeed vs LiteSpeed Enterprise) BEFORE MariaDB; default OpenLiteSpeed + if [ -z "$LS_ENT" ]; then + if [ "$AUTO_INSTALL" = true ]; then + LS_ENT="" + echo " Using OpenLiteSpeed (auto mode)." + else + echo "" + echo " Web server: 1) OpenLiteSpeed (default), 2) LiteSpeed Enterprise" + read -r -t 60 -p " Enter 1 or 2 [1]: " LS_CHOICE || true + LS_CHOICE="${LS_CHOICE:-1}" + LS_CHOICE="${LS_CHOICE// /}" + if [ "$LS_CHOICE" = "2" ]; then + echo " LiteSpeed Enterprise selected. Enter serial/key (required):" + read -r -t 120 -p " Serial: " LS_SERIAL || true + LS_SERIAL="${LS_SERIAL:-}" + if [ -z "$LS_SERIAL" ]; then + echo " No serial provided. Defaulting to OpenLiteSpeed." + LS_ENT="" + else + LS_ENT="ent" + echo " Using LiteSpeed Enterprise with provided serial." + fi + else + LS_ENT="" + echo " Using OpenLiteSpeed." + fi + echo "" + fi + fi + + # Ask MariaDB version (after web server choice) if not set via --mariadb-version + if [ -z "$MARIADB_VER" ]; then + echo "" + echo " MariaDB version: 10.11, 11.8 (LTS, default) or 12.1?" + read -r -t 60 -p " Enter 10.11, 11.8 or 12.1 [11.8]: " MARIADB_VER || true + MARIADB_VER="${MARIADB_VER:-11.8}" + MARIADB_VER="${MARIADB_VER// /}" + if [ "$MARIADB_VER" != "10.11" ] && [ "$MARIADB_VER" != "11.8" ] && [ "$MARIADB_VER" != "12.1" ]; then + MARIADB_VER="11.8" + fi + echo " Using MariaDB $MARIADB_VER" + echo "" + fi + + echo " 🔄 Downloading CyberPanel installation files..." + + # Check if CyberPanel is already installed + if check_cyberpanel_installed; then + echo " ⚠️ CyberPanel is already installed but may not be working properly" + echo " 🔧 Cleaning up existing installation and reinstalling..." + cleanup_existing_cyberpanel + fi + + # Pre-installation system checks + echo " 🔍 Running pre-installation checks..." + + # Ensure system is up to date + if command -v dnf >/dev/null 2>&1; then + echo " Updating system packages..." + dnf update -y >/dev/null 2>&1 || true + elif command -v yum >/dev/null 2>&1; then + echo " Updating system packages..." + yum update -y >/dev/null 2>&1 || true + elif command -v apt >/dev/null 2>&1; then + echo " Updating system packages..." + apt update -y >/dev/null 2>&1 || true + apt upgrade -y >/dev/null 2>&1 || true + fi + + # Ensure required services are available + echo " Checking system services..." + systemctl enable mariadb 2>/dev/null || true + systemctl enable lsws 2>/dev/null || true + + # Clear any previous install temp folders so we never use stale extracted files + rm -rf /tmp/cyberpanel_install_* 2>/dev/null || true + + # Create temporary directory for installation + local temp_dir="/tmp/cyberpanel_install_$$" + mkdir -p "$temp_dir" + cd "$temp_dir" || return 1 + + # Only add dnf exclude when we want to KEEP the current MariaDB (same version as user chose). + # If user chose 11.8 but 10.11 is installed, do NOT exclude — allow install.py to upgrade. + if command -v rpm >/dev/null 2>&1; then + if rpm -qa | grep -qiE "^(mariadb-server|mysql-server|MariaDB-server)" 2>/dev/null; then + local mariadb_version=$(mysql --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) + if [ -n "$mariadb_version" ]; then + local major_ver=$(echo "$mariadb_version" | cut -d. -f1) + local minor_ver=$(echo "$mariadb_version" | cut -d. -f2) + local installed_majmin="${major_ver}.${minor_ver}" + local chosen_ver="${MARIADB_VER:-11.8}" + # Only add exclude when installed version matches user's choice (preserve, no upgrade) + if [ "$installed_majmin" = "$chosen_ver" ]; then + print_status "MariaDB $mariadb_version matches chosen $chosen_ver, adding dnf exclude to preserve it" + + # Add MariaDB-server to dnf excludes (multiple formats for compatibility) + local dnf_conf="/etc/dnf/dnf.conf" + local exclude_added=false + + if [ -f "$dnf_conf" ]; then + # Check if [main] section exists + if grep -q "^\[main\]" "$dnf_conf" 2>/dev/null; then + # [main] section exists, add exclude there + if ! grep -q "exclude=.*MariaDB-server" "$dnf_conf" 2>/dev/null; then + if grep -q "^exclude=" "$dnf_conf" 2>/dev/null; then + # Append to existing exclude line in [main] section + sed -i '/^\[main\]/,/^\[/ { /^exclude=/ s/$/ MariaDB-server*/ }' "$dnf_conf" + else + # Add new exclude line after [main] + sed -i '/^\[main\]/a exclude=MariaDB-server*' "$dnf_conf" + fi + exclude_added=true + fi + else + # No [main] section, add it with exclude + if ! grep -q "exclude=.*MariaDB-server" "$dnf_conf" 2>/dev/null; then + echo "" >> "$dnf_conf" + echo "[main]" >> "$dnf_conf" + echo "exclude=MariaDB-server*" >> "$dnf_conf" + exclude_added=true + fi + fi + else + # Create dnf.conf with exclude + echo "[main]" > "$dnf_conf" + echo "exclude=MariaDB-server*" >> "$dnf_conf" + exclude_added=true + fi + + if [ "$exclude_added" = true ]; then + print_status "Added MariaDB-server* to dnf excludes in $dnf_conf" + fi + + # Also add to yum.conf for compatibility + local yum_conf="/etc/yum.conf" + if [ -f "$yum_conf" ]; then + if ! grep -q "exclude=.*MariaDB-server" "$yum_conf" 2>/dev/null; then + if grep -q "^exclude=" "$yum_conf" 2>/dev/null; then + sed -i 's/^exclude=\(.*\)/exclude=\1 MariaDB-server*/' "$yum_conf" + else + echo "exclude=MariaDB-server*" >> "$yum_conf" + fi + print_status "Added MariaDB-server* to yum excludes" + fi + fi + + # Create a function to disable MariaDB repositories (will be called after repository setup) + disable_mariadb_repos() { + local repo_files=( + "/etc/yum.repos.d/mariadb-main.repo" + "/etc/yum.repos.d/mariadb.repo" + "/etc/yum.repos.d/mariadb-12.1.repo" + ) + + # Also check for any mariadb repo files + while IFS= read -r repo_file; do + repo_files+=("$repo_file") + done < <(find /etc/yum.repos.d -name "*mariadb*.repo" 2>/dev/null) + + for repo_file in "${repo_files[@]}"; do + if [ -f "$repo_file" ] && [ -n "$repo_file" ]; then + # First, try to disable by setting enabled=0 + sed -i 's/^enabled\s*=\s*1/enabled=0/g' "$repo_file" 2>/dev/null + + # If file contains MariaDB 12.1 references, disable or remove it + if grep -qi "mariadb.*12\|12.*mariadb\|mariadb-main" "$repo_file" 2>/dev/null; then + # Try to add enabled=0 to each [mariadb...] section + python3 -c " +import re +import sys +try: + with open('$repo_file', 'r') as f: + content = f.read() + + # Replace enabled=1 with enabled=0 + content = re.sub(r'(enabled\s*=\s*)1', r'\g<1>0', content, flags=re.IGNORECASE) + + # Add enabled=0 after [mariadb...] sections if not present + lines = content.split('\n') + new_lines = [] + in_mariadb_section = False + has_enabled = False + + for i, line in enumerate(lines): + new_lines.append(line) + if re.match(r'^\s*\[.*mariadb.*\]', line, re.IGNORECASE): + in_mariadb_section = True + has_enabled = False + elif in_mariadb_section: + if re.match(r'^\s*enabled\s*=', line, re.IGNORECASE): + has_enabled = True + elif re.match(r'^\s*\[', line) and not re.match(r'^\s*\[.*mariadb.*\]', line, re.IGNORECASE): + if not has_enabled: + new_lines.insert(-1, 'enabled=0') + in_mariadb_section = False + has_enabled = False + + if in_mariadb_section and not has_enabled: + new_lines.append('enabled=0') + + with open('$repo_file', 'w') as f: + f.write('\n'.join(new_lines)) +except: + # Fallback: just rename the file + import os + os.rename('$repo_file', '${repo_file}.disabled') +" 2>/dev/null || \ + # Fallback: rename the file to disable it + mv "$repo_file" "${repo_file}.disabled" 2>/dev/null || true + fi + fi + done + } + + # Export function so it can be called from installer + export -f disable_mariadb_repos + export MARIADB_VERSION="$mariadb_version" + + # Also set up a background process to monitor and disable repos + ( + while [ ! -f /tmp/cyberpanel_install_complete ]; do + sleep 2 + if [ -f /etc/yum.repos.d/mariadb-main.repo ] || [ -f /etc/yum.repos.d/mariadb.repo ]; then + disable_mariadb_repos + fi + done + ) & + local monitor_pid=$! + echo "$monitor_pid" > /tmp/cyberpanel_repo_monitor.pid + print_status "Started background process to monitor and disable MariaDB repositories" + else + # User chose a different version (e.g. 11.8) than installed (e.g. 10.11) — allow upgrade + print_status "MariaDB $mariadb_version installed but you chose $chosen_ver; not adding dnf exclude (installer will upgrade)" + # Remove any existing MariaDB exclude from a previous run so install can proceed + for c in /etc/dnf/dnf.conf /etc/yum.conf; do + if [ -f "$c" ] && grep -q "exclude=.*MariaDB-server" "$c" 2>/dev/null; then + sed -i 's/ *MariaDB-server\* *//g; s/exclude= *$/exclude=/; s/exclude=\s*$/exclude=/' "$c" 2>/dev/null + if grep -q "^exclude=\s*$" "$c" 2>/dev/null; then + sed -i '/^exclude=\s*$/d' "$c" 2>/dev/null + fi + print_status "Removed MariaDB-server from excludes in $c to allow upgrade" + fi + done + fi + fi + fi + fi + + # Download the working CyberPanel installation files from upstream (usmannasir/cyberpanel) + echo "Downloading from: https://raw.githubusercontent.com/usmannasir/cyberpanel/v2.5.5-dev/cyberpanel.sh" + + # First, try to download the repository archive to get the correct installer + # GitHub: branch archives use refs/heads/BRANCH; GitHub returns 302 redirect to codeload, so we must use -L + local archive_url="" + local installer_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/v2.5.5-dev/cyberpanel.sh" + if curl -s -L --head "https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" | grep -q "200 OK"; then + archive_url="https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" + echo " Using development branch (v2.5.5-dev) from usmannasir/cyberpanel" + elif curl -s -L --head "https://github.com/usmannasir/cyberpanel/archive/v2.5.5-dev.tar.gz" | grep -q "200 OK"; then + archive_url="https://github.com/usmannasir/cyberpanel/archive/v2.5.5-dev.tar.gz" + echo " Using development branch (v2.5.5-dev) from usmannasir/cyberpanel" + else + echo " Development branch archive not available, trying installer script directly..." + if ! curl -s -L --head "$installer_url" | grep -q "200 OK"; then + echo " Development branch not available, falling back to stable" + installer_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" + archive_url="https://github.com/usmannasir/cyberpanel/archive/stable.tar.gz" + else + archive_url="https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" + fi + fi + + curl --silent -o cyberpanel_installer.sh "$installer_url" 2>/dev/null + if [ $? -ne 0 ] || [ ! -s "cyberpanel_installer.sh" ]; then + print_status "ERROR: Failed to download CyberPanel installer" + return 1 + fi + + # Do NOT patch installer to add --exclude=MariaDB-server*: it blocks initial MariaDB install + # and causes "MariaDB-server requires MariaDB-client but none of the providers can be installed". + + # Make script executable (use full path in case cwd has noexec) + chmod 755 cyberpanel_installer.sh 2>/dev/null || chmod +x cyberpanel_installer.sh 2>/dev/null || true + if [ ! -x "cyberpanel_installer.sh" ]; then + print_status "Note: Script will be run with bash (executable bit not set)" + fi + + # Download the install directory (use archive_url set above; may be branch or stable) + echo "Downloading installation files..." + if [ -z "$archive_url" ] || [ "$installer_url" = "https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" ]; then + archive_url="https://github.com/usmannasir/cyberpanel/archive/stable.tar.gz" + fi + # Append cache-bust so CDNs/proxies don't serve old installer (GitHub ignores query params) + archive_url="${archive_url}?nocache=$(date +%s 2>/dev/null || echo 0)" + + curl --silent -L -o install_files.tar.gz "$archive_url" 2>/dev/null + if [ $? -ne 0 ] || [ ! -s "install_files.tar.gz" ]; then + print_status "ERROR: Failed to download installation files" + return 1 + fi + + # Extract the installation files + tar -xzf install_files.tar.gz 2>/dev/null + if [ $? -ne 0 ]; then + print_status "ERROR: Failed to extract installation files" + return 1 + fi + + # Copy install directory to current location + if [ "$installer_url" = "https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" ]; then + if [ -d "cyberpanel-stable" ]; then + cp -r cyberpanel-stable/install . 2>/dev/null || true + cp -r cyberpanel-stable/install.sh . 2>/dev/null || true + fi + else + if [ -d "cyberpanel-v2.5.5-dev" ]; then + cp -r cyberpanel-v2.5.5-dev/install . 2>/dev/null || true + cp -r cyberpanel-v2.5.5-dev/install.sh . 2>/dev/null || true + fi + fi + + # Verify install directory was copied + if [ ! -d "install" ]; then + print_status "ERROR: install directory not found after extraction" + print_status "Archive contents:" + ls -la 2>/dev/null | head -20 + return 1 + fi + + print_status "Verified install directory exists" + install_cyberpanel_direct_cont +} + +# Continuation of install_cyberpanel_direct (split for module size) +install_cyberpanel_direct_cont() { + echo " ✓ CyberPanel installation files downloaded" + echo " 🔄 Starting CyberPanel installation..." + echo "" + echo "IMPORTANT: The installation is now running in the background." + echo "You will see detailed output from the CyberPanel installer below." + echo "This is normal and expected - the installation is proceeding!" + echo "" + echo "===============================================================================================================" + echo "" + + # Run the installer with live progress monitoring + echo "Starting CyberPanel installation process..." + echo "This may take several minutes. Please be patient." + echo "" + + # Create log directory (same as v2.4.4: installer logs go here) + mkdir -p /var/log/CyberPanel + echo " Installation logs:" + echo " • /var/log/CyberPanel/install.log (installer script messages)" + echo " • /var/log/CyberPanel/install_output.log (Python installer stdout/stderr)" + echo " • /var/log/installLogs.txt (install.py detailed log)" + echo "" + + # Run the installer with live output monitoring + echo "Starting CyberPanel installer with live progress monitoring..." + echo "" + echo "===============================================================================================================" + echo " LIVE INSTALLATION PROGRESS" + echo "===============================================================================================================" + echo "" + + # Set branch environment variable for the installer + if [ -n "$BRANCH_NAME" ]; then + export CYBERPANEL_BRANCH="$BRANCH_NAME" + echo "Setting installation branch to: $BRANCH_NAME" + else + export CYBERPANEL_BRANCH="stable" + echo "Using default stable branch" + fi + echo "" + + # CRITICAL: Use install/install.py directly instead of cyberpanel_installer.sh + # The cyberpanel_installer.sh is the old wrapper that doesn't support auto-install + # install/install.py is the actual installer that we can control + local installer_py="install/install.py" + if [ -f "$installer_py" ]; then + print_status "Using install/install.py directly for installation (non-interactive mode)" + + # NOTE: We do NOT patch install.py to add --exclude=MariaDB-server* to dnf install. + # That would block the initial MariaDB-server install. install.py now clears dnf exclude + # before installing MariaDB and uses official MariaDB-server packages. + + # Clear MariaDB-server from dnf/yum exclude so the installer can install or reinstall it + # (cyberpanel.sh may have added it earlier when 10.x was detected; partial installs leave exclude in place) + for conf in /etc/dnf/dnf.conf /etc/yum.conf; do + if [ -f "$conf" ] && grep -q "exclude=.*MariaDB-server" "$conf" 2>/dev/null; then + sed -i '/^exclude=/s/MariaDB-server\*\s*//g' "$conf" + sed -i '/^exclude=/s/\s*MariaDB-server\*//g' "$conf" + sed -i '/^exclude=/s/MariaDB-server\s*//g' "$conf" + sed -i '/^exclude=\s*$/d' "$conf" + sed -i '/^exclude=$/d' "$conf" + print_status "Cleared MariaDB-server from exclude in $conf for installation" + fi + done + + # If MariaDB 10.x is installed, disable repositories right before running installer + if [ -n "$MARIADB_VERSION" ] && [ -f /tmp/cyberpanel_repo_monitor.pid ]; then + # Call the disable function one more time before installer runs + if type disable_mariadb_repos >/dev/null 2>&1; then + disable_mariadb_repos + fi + fi + + # Get server IP address (required by install.py) + local server_ip + if command -v curl >/dev/null 2>&1; then + server_ip=$(curl -s --max-time 5 https://api.ipify.org 2>/dev/null || curl -s --max-time 5 https://icanhazip.com 2>/dev/null || echo "") + fi + + if [ -z "$server_ip" ]; then + # Fallback: try to get IP from network interfaces + server_ip=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $7; exit}' || \ + hostname -I 2>/dev/null | awk '{print $1}' || \ + echo "127.0.0.1") + fi + + if [ -z "$server_ip" ] || [ "$server_ip" = "127.0.0.1" ]; then + print_status "WARNING: Could not detect public IP, using 127.0.0.1" + server_ip="127.0.0.1" + fi + + print_status "Detected server IP: $server_ip" + + # CRITICAL: Install Python MySQL dependencies before running install.py + # installCyberPanel.py requires MySQLdb (mysqlclient) which needs development headers + echo "" + echo "===============================================================================================================" + echo "Installing Python MySQL dependencies (required for installCyberPanel.py)..." + echo "===============================================================================================================" + print_status "Installing Python MySQL dependencies..." + + # Detect OS for package installation + local os_family="" + if [ -f /etc/os-release ]; then + . /etc/os-release + case "$ID" in + almalinux|rocky|centos|rhel|fedora) + os_family="rhel" + print_status "Detected RHEL-based OS: $ID" + ;; + ubuntu|debian) + os_family="debian" + print_status "Detected Debian-based OS: $ID" + ;; + *) + print_status "Unknown OS ID: $ID, defaulting to RHEL-based" + os_family="rhel" + ;; + esac + else + print_status "WARNING: /etc/os-release not found, defaulting to RHEL-based" + os_family="rhel" + fi + + # Install MariaDB/MySQL development headers and Python mysqlclient + if [ "$os_family" = "rhel" ]; then + # RHEL-based (AlmaLinux, Rocky, CentOS, RHEL) + print_status "Installing MariaDB development headers for RHEL-based system..." + + # Try to install mariadb-devel (works with MariaDB 10.x and 12.x) + # NOTE: We need mariadb-devel even if we excluded MariaDB-server + # The exclude only applies to MariaDB-server, not development packages + if command -v dnf >/dev/null 2>&1; then + # For AlmaLinux 9/10 and newer - show output for debugging + print_status "Attempting to install mariadb-devel (development headers only, not server)..." + # Temporarily remove exclude for devel packages if needed + local dnf_exclude_backup="" + if [ -f /etc/dnf/dnf.conf ] && grep -q "exclude=.*MariaDB" /etc/dnf/dnf.conf; then + # Check if exclude is too broad + if grep -q "exclude=.*MariaDB-server.*MariaDB-devel" /etc/dnf/dnf.conf || \ + grep -q "exclude=.*MariaDB\*" /etc/dnf/dnf.conf; then + print_status "Temporarily adjusting dnf exclude to allow mariadb-devel installation..." + # We only want to exclude MariaDB-server, not devel packages + sed -i 's/exclude=\(.*\)MariaDB-server\(.*\)MariaDB-devel\(.*\)/exclude=\1MariaDB-server\2\3/' /etc/dnf/dnf.conf 2>/dev/null || true + sed -i 's/exclude=\(.*\)MariaDB\*\(.*\)/exclude=\1MariaDB-server*\2/' /etc/dnf/dnf.conf 2>/dev/null || true + fi + fi + + if dnf install -y --allowerasing --skip-broken --nobest \ + mariadb-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mariadb-devel" + elif dnf install -y --allowerasing --skip-broken --nobest \ + mysql-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mysql-devel" + elif dnf install -y --allowerasing --skip-broken --nobest \ + mariadb-connector-c-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mariadb-connector-c-devel" + else + print_status "⚠️ WARNING: Failed to install MariaDB development headers" + print_status "This may cause MySQLdb installation to fail" + fi + else + # For older systems with yum + print_status "Using yum to install mariadb-devel..." + if yum install -y mariadb-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mariadb-devel" + elif yum install -y mysql-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mysql-devel" + else + print_status "⚠️ WARNING: Failed to install MariaDB development headers" + fi + fi + + # Install mysqlclient Python package + print_status "Installing mysqlclient Python package..." + python3 -m pip install --upgrade pip setuptools wheel 2>&1 | grep -v "already satisfied" || true + if python3 -m pip install mysqlclient 2>&1; then + print_status "✓ Successfully installed mysqlclient" + else + # If pip install fails, try with build dependencies + print_status "Retrying mysqlclient installation with build dependencies..." + python3 -m pip install --no-cache-dir mysqlclient 2>&1 || { + print_status "⚠️ WARNING: Failed to install mysqlclient, trying alternative method..." + # Try installing from source + python3 -m pip install --no-binary mysqlclient mysqlclient 2>&1 || true + } + fi + + elif [ "$os_family" = "debian" ]; then + # Debian-based (Ubuntu, Debian) + print_status "Installing MariaDB development headers for Debian-based system..." + apt-get update -y + if apt-get install -y libmariadb-dev libmariadb-dev-compat pkg-config build-essential python3-dev python3-pip; then + print_status "✓ Successfully installed MariaDB development headers" + elif apt-get install -y default-libmysqlclient-dev pkg-config build-essential python3-dev python3-pip; then + print_status "✓ Successfully installed MySQL development headers" + else + print_status "⚠️ WARNING: Failed to install MariaDB/MySQL development headers" + fi + + # Install mysqlclient Python package + print_status "Installing mysqlclient Python package..." + python3 -m pip install --upgrade pip setuptools wheel 2>&1 | grep -v "already satisfied" || true + if python3 -m pip install mysqlclient 2>&1; then + print_status "✓ Successfully installed mysqlclient" + else + print_status "Retrying mysqlclient installation with build dependencies..." + python3 -m pip install --no-cache-dir mysqlclient 2>&1 || true + fi + fi + + # Verify MySQLdb is available (mysqlclient; some builds lack __version__) + print_status "Verifying MySQLdb module availability..." + if python3 -c "import MySQLdb; getattr(MySQLdb, '__version__', 'ok'); print('MySQLdb OK')" 2>/dev/null || \ + python3 -c "import MySQLdb; MySQLdb; print('MySQLdb OK')" 2>/dev/null; then + print_status "✓ MySQLdb module is available and working" + else + print_status "⚠️ WARNING: MySQLdb module not available" + print_status "Attempting to diagnose the issue..." + python3 -c "import sys; print('Python path:', sys.path)" 2>&1 || true + python3 -m pip list | grep -i mysql || print_status "No MySQL-related packages found in pip list" + print_status "Attempting to continue anyway, but installation may fail..." + fi + echo "" + + # Build installer arguments based on user preferences + # install.py requires publicip as first positional argument + local install_args=("$server_ip") + + # Web server: OpenLiteSpeed (default) or LiteSpeed Enterprise (--ent + --serial) + if [ -n "$LS_ENT" ] && [ -n "$LS_SERIAL" ]; then + install_args+=("--ent" "$LS_ENT" "--serial" "$LS_SERIAL") + fi + # Default: OpenLiteSpeed, Full installation (postfix, powerdns, ftp), Local MySQL + install_args+=("--postfix" "ON") + install_args+=("--powerdns" "ON") + install_args+=("--ftp" "ON") + install_args+=("--remotemysql" "OFF") + # Only pass --mariadb-version if this install.py supports it (avoids "unrecognized arguments" on older archives) + if grep -q "mariadb-version\|mariadb_version" "$installer_py" 2>/dev/null; then + install_args+=("--mariadb-version" "${MARIADB_VER:-11.8}") + fi + + if [ "$DEBUG_MODE" = true ]; then + # Note: install.py doesn't have --debug, but we can set it via environment + export DEBUG_MODE=true + fi + + # CRITICAL: If CyberPanel Python does not exist yet, patch installer to use system Python. + # Fixes FileNotFoundError when archive is cached/old and still references /usr/local/CyberPanel/bin/python. + if [ ! -f /usr/local/CyberPanel/bin/python ]; then + sys_python="/usr/bin/python3" + [ -x "$sys_python" ] || sys_python="/usr/local/bin/python3" + if [ -x "$sys_python" ]; then + for f in install/install_utils.py install/install.py; do + if [ -f "$f" ] && grep -q '/usr/local/CyberPanel/bin/python' "$f" 2>/dev/null; then + sed -i "s|/usr/local/CyberPanel/bin/python|$sys_python|g" "$f" + print_status "Patched $f to use $sys_python (CyberPanel python not yet installed)" + fi + done + fi + fi + + # Run the Python installer directly + if [ "$DEBUG_MODE" = true ]; then + python3 "$installer_py" "${install_args[@]}" 2>&1 | tee /var/log/CyberPanel/install_output.log + else + python3 "$installer_py" "${install_args[@]}" 2>&1 | tee /var/log/CyberPanel/install_output.log + fi + else + # Fallback to cyberpanel_installer.sh if install.py not found + print_status "WARNING: install/install.py not found, using cyberpanel_installer.sh (may be interactive)" + + local installer_script="cyberpanel_installer.sh" + if [ ! -f "$installer_script" ]; then + print_status "ERROR: cyberpanel_installer.sh not found in current directory: $(pwd)" + return 1 + fi + + # Get absolute path to installer script + local installer_path + if [[ "$installer_script" = /* ]]; then + installer_path="$installer_script" + else + installer_path="$(pwd)/$installer_script" + fi + + # If MariaDB 10.x is installed, disable repositories right before running installer + if [ -n "$MARIADB_VERSION" ] && [ -f /tmp/cyberpanel_repo_monitor.pid ]; then + # Call the disable function one more time before installer runs + if type disable_mariadb_repos >/dev/null 2>&1; then + disable_mariadb_repos + fi + fi + + if [ "$DEBUG_MODE" = true ]; then + bash "$installer_path" --debug 2>&1 | tee /var/log/CyberPanel/install_output.log + else + bash "$installer_path" 2>&1 | tee /var/log/CyberPanel/install_output.log + fi + fi + + local install_exit_code=${PIPESTATUS[0]} + + # Stop the repository monitor + if [ -f /tmp/cyberpanel_repo_monitor.pid ]; then + local monitor_pid=$(cat /tmp/cyberpanel_repo_monitor.pid 2>/dev/null) + if [ -n "$monitor_pid" ] && kill -0 "$monitor_pid" 2>/dev/null; then + kill "$monitor_pid" 2>/dev/null + fi + rm -f /tmp/cyberpanel_repo_monitor.pid + fi + touch /tmp/cyberpanel_install_complete 2>/dev/null || true + + local install_exit_code=${PIPESTATUS[0]} + + # Extract the generated password from the installation output + local generated_password=$(grep "Panel password:" /var/log/CyberPanel/install_output.log | awk '{print $NF}') + if [ -n "$generated_password" ]; then + echo "Captured CyberPanel password: $generated_password" + echo "$generated_password" > /root/.cyberpanel_password + chmod 600 /root/.cyberpanel_password + fi + + echo "" + echo "===============================================================================================================" + echo " INSTALLATION COMPLETED" + echo "===============================================================================================================" + echo "" + echo " Installation logs (for troubleshooting):" + echo " • /var/log/CyberPanel/install.log (installer script messages)" + echo " • /var/log/CyberPanel/install_output.log (Python installer stdout/stderr)" + echo " • /var/log/installLogs.txt (install.py detailed log)" + echo "" + + # Check if installation was successful + if [ $install_exit_code -ne 0 ]; then + print_status "ERROR: CyberPanel installation failed with exit code $install_exit_code" + echo "" + echo "Installation log (last 50 lines):" + echo "===============================================================================================================" + tail -50 /var/log/CyberPanel/install_output.log 2>/dev/null || echo "Could not read installation log" + echo "===============================================================================================================" + echo "" + echo "Full installation log available at: /var/log/CyberPanel/install_output.log" + echo "" + return 1 + fi + + # Clean up temporary directory + cd /tmp + rm -rf "$temp_dir" 2>/dev/null || true + + # Check if installation was successful + if [ $install_exit_code -eq 0 ]; then + # Installation succeeded, but don't print success message yet + # The CyberPanel installer has already shown its summary + + # Run static file permission fixes (critical for LiteSpeed) silently + fix_static_file_permissions >/dev/null 2>&1 + + return 0 + else + print_status "ERROR: CyberPanel installation failed (exit code: $install_exit_code)" + echo "" + echo "===============================================================================================================" + echo " INSTALLATION FAILED" + echo "===============================================================================================================" + echo "" + echo "The CyberPanel installation has failed. Here's how to troubleshoot:" + echo "" + echo "📋 LOG FILES LOCATION:" + echo " • Main installer log: /var/log/CyberPanel/install.log" + echo " • Installation output: /var/log/CyberPanel/install_output.log" + echo " • System logs: /var/log/messages" + echo "" + echo "🔍 TROUBLESHOOTING STEPS:" + echo " 1. Check the installation output log for specific errors" + echo " 2. Verify your system meets the requirements" + echo " 3. Ensure you have sufficient disk space and memory" + echo " 4. Check your internet connection" + echo " 5. Try running the installer again" + echo "" + echo "📄 LAST 30 LINES OF INSTALLATION LOG:" + echo "===============================================================================================================" + if [ -f "/var/log/CyberPanel/install_output.log" ]; then + tail -30 /var/log/CyberPanel/install_output.log 2>/dev/null || echo "Could not read installation log" + else + echo "Installation log not found at /var/log/CyberPanel/install_output.log" + fi + echo "===============================================================================================================" + echo "" + echo "💡 QUICK DEBUG COMMANDS:" + echo " • View full log: cat /var/log/CyberPanel/install_output.log" + echo " • Check system: free -h && df -h" + echo " • Check network: ping -c 3 google.com" + echo " • Retry installation: Run the installer again" + echo "" + echo "🆘 NEED HELP?" + echo " • CyberPanel Documentation: https://docs.cyberpanel.net" + echo " • CyberPanel Community: https://forums.cyberpanel.net" + echo " • GitHub Issues: https://github.com/usmannasir/cyberpanel/issues" + echo "" + return 1 + fi +} + +# Function to apply fixes +apply_fixes() { + echo "" + echo "Applying post-installation configurations..." + + # Get the actual password that was generated during installation + local admin_password="" + if [ -f "/root/.cyberpanel_password" ]; then + admin_password=$(cat /root/.cyberpanel_password 2>/dev/null) + fi + + # If no password was captured, use the default + if [ -z "$admin_password" ]; then + admin_password="1234567" + echo "$admin_password" > /root/.cyberpanel_password + chmod 600 /root/.cyberpanel_password + fi + + # Fix database issues + systemctl start mariadb 2>/dev/null || true + systemctl enable mariadb 2>/dev/null || true + + # Fix LiteSpeed service only if the web server was actually installed + if [ -x /usr/local/lsws/bin/lswsctrl ] || [ -x /usr/local/lsws/bin/lsctrl ] || [ -f /usr/local/lsws/bin/openlitespeed ]; then + cat > /etc/systemd/system/lsws.service << 'EOF' +[Unit] +Description=LiteSpeed Web Server +After=network.target + +[Service] +Type=forking +User=root +Group=root +ExecStart=/usr/local/lsws/bin/lswsctrl start +ExecStop=/usr/local/lsws/bin/lswsctrl stop +ExecReload=/usr/local/lsws/bin/lswsctrl restart +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + + systemctl daemon-reload + systemctl enable lsws + systemctl start lsws || true + else + echo " • LiteSpeed/OpenLiteSpeed not found at /usr/local/lsws - skipping lsws.service (install may have skipped web server)" + echo " • If the installer failed earlier (e.g. Python error), re-run the installer. Once it completes, open ports 8090 and 7080 in your cloud security group (e.g. AWS EC2 Security Group inbound rules)." + systemctl disable lsws 2>/dev/null || true + rm -f /etc/systemd/system/lsws.service + systemctl daemon-reload + fi + + # Set OpenLiteSpeed admin password to match CyberPanel + echo " • Configuring OpenLiteSpeed admin password..." + if [ -f "/usr/local/lsws/admin/misc/admpass.sh" ]; then + # Auto-answer the prompts for username and password + (echo "admin"; echo "$admin_password"; echo "$admin_password") | /usr/local/lsws/admin/misc/admpass.sh >/dev/null 2>&1 || { + # Alternative method: directly create htpasswd entry + echo "admin:$(openssl passwd -apr1 '$admin_password')" > /usr/local/lsws/admin/htpasswd 2>/dev/null || true + } + echo " ✓ OpenLiteSpeed configured" + fi + + # Ensure CyberPanel (lscpd) service is running + echo " • Starting CyberPanel service..." + systemctl enable lscpd 2>/dev/null || true + systemctl start lscpd 2>/dev/null || true + + # Give services a moment to start + sleep 3 + + # Ensure both 8090 (CyberPanel) and 7080 (LiteSpeed/OLS) are accessible + echo " • Ensuring ports 8090 and 7080 are accessible..." + port_check() { + local port=$1 + command -v ss >/dev/null 2>&1 && ss -tlnp 2>/dev/null | grep -q ":$port " && return 0 + command -v netstat >/dev/null 2>&1 && netstat -tlnp 2>/dev/null | grep -q ":$port " && return 0 + return 1 + } + max_attempts=18 + attempt=0 + while [ $attempt -lt $max_attempts ]; do + need_restart=false + systemctl is-active --quiet mariadb || { systemctl start mariadb 2>/dev/null; need_restart=true; } + systemctl is-active --quiet lsws 2>/dev/null || { [ -x /usr/local/lsws/bin/lswsctrl ] && systemctl start lsws 2>/dev/null; need_restart=true; } + systemctl is-active --quiet lscpd 2>/dev/null || { systemctl start lscpd 2>/dev/null; need_restart=true; } + [ "$need_restart" = true ] && sleep 5 + if port_check 8090 && port_check 7080; then + echo " ✓ Port 8090 (CyberPanel) and 7080 (OpenLiteSpeed) are listening" + break + fi + attempt=$((attempt + 1)) + [ $attempt -lt $max_attempts ] && sleep 5 + done + if ! port_check 8090 || ! port_check 7080; then + systemctl start lscpd 2>/dev/null + systemctl start lsws 2>/dev/null + sleep 10 + if port_check 8090 && port_check 7080; then + echo " ✓ Port 8090 and 7080 are now listening" + else + echo " ⚠ One or both ports not yet listening. Run: systemctl start mariadb lsws lscpd" + echo " ⚠ On AWS/cloud: add inbound rules for TCP 8090 and 7080 in the instance security group." + fi + fi + + echo " ✓ Post-installation configurations completed" +} + +# Helper: check if a port is listening +_port_listening() { + local port=$1 + command -v ss >/dev/null 2>&1 && ss -tlnp 2>/dev/null | grep -q ":$port " && return 0 + command -v netstat >/dev/null 2>&1 && netstat -tlnp 2>/dev/null | grep -q ":$port " && return 0 + return 1 +} + +# Function to show status summary +show_status_summary() { + # Last-chance: try to start services so 8090 and 7080 are accessible + if ! _port_listening 8090 || ! _port_listening 7080; then + systemctl start mariadb 2>/dev/null || true + systemctl start lsws 2>/dev/null || true + systemctl start lscpd 2>/dev/null || true + sleep 8 + fi + + echo "===============================================================================================================" + echo " FINAL STATUS CHECK" + echo "===============================================================================================================" + echo "" + + # Quick service check + local all_services_running=true + + echo "Service Status:" + if systemctl is-active --quiet mariadb; then + echo " ✓ MariaDB Database - Running" + else + echo " ✗ MariaDB Database - Not Running" + all_services_running=false + fi + + if systemctl is-active --quiet lsws; then + echo " ✓ LiteSpeed Web Server - Running" + else + echo " ✗ LiteSpeed Web Server - Not Running" + all_services_running=false + fi + + if systemctl is-active --quiet lscpd; then + echo " ✓ CyberPanel Application - Running" + else + echo " ✗ CyberPanel Application - Not Running (may take a moment to start)" + all_services_running=false + fi + + echo "" + echo "Port Accessibility:" + if _port_listening 8090; then + echo " ✓ Port 8090 (CyberPanel) - Accessible" + else + echo " ✗ Port 8090 (CyberPanel) - Not listening (run: systemctl start lscpd)" + all_services_running=false + fi + if _port_listening 7080; then + echo " ✓ Port 7080 (OpenLiteSpeed) - Accessible" + else + echo " ✗ Port 7080 (OpenLiteSpeed) - Not listening (run: systemctl start lsws)" + all_services_running=false + fi + + # Get the actual password that was set + local admin_password="" + local server_ip=$(curl -s ifconfig.me 2>/dev/null || echo "your-server-ip") + + # Check if password was set in /root/.cyberpanel_password (if it exists) + if [ -f "/root/.cyberpanel_password" ]; then + admin_password=$(cat /root/.cyberpanel_password 2>/dev/null) + fi + + # If we have a password, show access details + if [ -n "$admin_password" ]; then + echo "" + echo "Access Details:" + echo " CyberPanel: https://$server_ip:8090" + echo " Username: admin" + echo " Password: $admin_password" + echo "" + echo " OpenLiteSpeed: https://$server_ip:7080" + echo " Username: admin" + echo " Password: $admin_password" + fi + + echo "" + echo "===============================================================================================================" + + if [ "$all_services_running" = true ]; then + echo "✓ Installation completed successfully! Ports 8090 and 7080 are accessible." + else + echo "⚠ Installation completed with warnings. Some services may need attention." + fi + echo "" +} + +# Function to show main menu +show_main_menu() { + show_banner + + echo "===============================================================================================================" + echo " SELECT INSTALLATION TYPE" + echo "===============================================================================================================" + echo "" + echo " 1. Fresh Installation (Recommended)" + echo " 2. Update Existing Installation" + echo " 3. Reinstall CyberPanel" + echo " 4. Force Reinstall (Clean & Install)" + echo " 5. Pre-Upgrade (Download latest upgrade script)" + echo " 6. Check System Status" + echo " 7. Advanced Options" + echo " 8. Exit" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Enter your choice [1-8]: " + read -r choice + + case $choice in + 1) + INSTALLATION_TYPE="fresh" + show_fresh_install_menu + return + ;; + 2) + INSTALLATION_TYPE="update" + show_update_menu + return + ;; + 3) + INSTALLATION_TYPE="reinstall" + show_reinstall_menu + return + ;; + 4) + INSTALLATION_TYPE="force_reinstall" + start_force_reinstall + return + ;; + 5) + start_preupgrade + return + ;; + 6) + show_system_status + return + ;; + 7) + show_advanced_menu + return + ;; + 8) + echo "Goodbye!" + exit 0 + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-7." + echo "" + ;; + esac + done +} + +# Function to show fresh installation menu +show_fresh_install_menu() { + echo "" + echo "===============================================================================================================" + echo " FRESH INSTALLATION SETUP" + echo "===============================================================================================================" + echo "" + + # Check if CyberPanel is already installed + if [ -d "/usr/local/CyberCP" ] && [ -f "/usr/local/CyberCP/manage.py" ]; then + echo "WARNING: CyberPanel appears to be already installed on this system." + echo " Consider using 'Update' or 'Reinstall' options instead." + echo "" + echo -n "Do you want to continue with fresh installation anyway? (y/n): " + read -r response + case $response in + [yY]|[yY][eE][sS]) + ;; + *) + show_main_menu + return + ;; + esac + fi + + echo "Select installation option:" + echo "" + echo " 1. Install Latest Stable Version" + echo " 2. Install Development Version (v2.5.5-dev)" + echo " 3. Install Specific Version/Branch" + echo " 4. Install from Commit Hash" + echo " 5. Quick Install (Auto-configure everything)" + echo " 6. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select installation option [1-6]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + show_installation_preferences + return + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + show_installation_preferences + return + ;; + 3) + show_version_selection + return + ;; + 4) + show_commit_selection + return + ;; + 5) + BRANCH_NAME="" + AUTO_INSTALL=true + start_installation + return + ;; + 6) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-6." + echo "" + ;; +esac + done +} + +# Function to show commit selection +show_commit_selection() { + echo "" + echo "===============================================================================================================" + echo " COMMIT HASH SELECTION" + echo "===============================================================================================================" + echo "" + echo "Enter a specific commit hash to install from:" + echo "" + echo "Examples:" + echo " • Latest commit: Leave empty (press Enter)" + echo " • Specific commit: a1b2c3d4e5f6789012345678901234567890abcd" + echo " • Short commit: a1b2c3d (first 7 characters)" + echo "" + echo "You can find commit hashes at: https://github.com/usmannasir/cyberpanel/commits" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Enter commit hash (or press Enter for latest): " + read -r commit_hash + + if [ -z "$commit_hash" ]; then + echo "Using latest commit..." + BRANCH_NAME="" + show_installation_preferences + return + elif [[ "$commit_hash" =~ ^[a-f0-9]{7,40}$ ]]; then + echo "Using commit: $commit_hash" + BRANCH_NAME="$commit_hash" + show_installation_preferences + return + else + echo "" + echo "ERROR: Invalid commit hash format." + echo " Please enter a valid Git commit hash (7-40 hexadecimal characters)." + echo "" + fi + done +} + +# Function to show version selection +show_version_selection() { + echo "" + echo "===============================================================================================================" + echo " VERSION SELECTION" + echo "===============================================================================================================" + echo "" + echo "Available versions:" + echo "" + echo " 1. Latest Stable (Recommended)" + echo " 2. v2.5.5-dev (Development)" + echo " 3. v2.4.4 (Previous Stable)" + echo " 4. Custom Branch Name" + echo " 5. Custom Commit Hash" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select version [1-5]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + break + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + break + ;; + 3) + BRANCH_NAME="v2.4.4" + break + ;; + 4) + echo -n "Enter branch name (e.g., main, v2.5.5-dev): " + read -r BRANCH_NAME + if [ -z "$BRANCH_NAME" ]; then + echo "ERROR: Branch name cannot be empty." + continue + fi + # Add v prefix if it's a version number without v + if [[ "$BRANCH_NAME" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + if [[ "$BRANCH_NAME" == *"-"* ]]; then + # Already has suffix like 2.5.5-dev, add v prefix + BRANCH_NAME="v$BRANCH_NAME" + else + # Add v prefix and dev suffix for development versions + BRANCH_NAME="v$BRANCH_NAME-dev" + fi + fi + break + ;; + 5) + echo -n "Enter commit hash (7-40 characters): " + read -r commit_hash + if [[ "$commit_hash" =~ ^[a-f0-9]{7,40}$ ]]; then + BRANCH_NAME="$commit_hash" + break + else + echo "ERROR: Invalid commit hash format." + continue + fi + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-5." + echo "" + ;; +esac + done + + show_installation_preferences +} + +# Function to show installation preferences +show_installation_preferences() { + echo "" + echo "===============================================================================================================" + echo " INSTALLATION PREFERENCES" + echo "===============================================================================================================" + echo "" + + # Debug mode + echo -n "Enable debug mode for detailed logging? (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + DEBUG_MODE=true + ;; + *) + DEBUG_MODE=false + ;; + esac + + # Auto-install + echo -n "Auto-install without further prompts? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + AUTO_INSTALL=false + ;; + *) + AUTO_INSTALL=true + ;; + esac + + # Show summary + echo "" + echo "===============================================================================================================" + echo " INSTALLATION SUMMARY" + echo "===============================================================================================================" + echo "" + echo " Type: $INSTALLATION_TYPE" + echo " Version: ${BRANCH_NAME:-'Latest Stable'}" + echo " Debug Mode: $DEBUG_MODE" + echo " Auto Install: $AUTO_INSTALL" + echo "" + echo "===============================================================================================================" + echo "" + + echo -n "Proceed with installation? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + start_installation + ;; + esac +} + +# Function to show update menu +show_update_menu() { + echo "" + echo "===============================================================================================================" + echo " UPDATE INSTALLATION" + echo "===============================================================================================================" + echo "" + + if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then + echo "ERROR: CyberPanel is not installed on this system." + echo " Please use 'Fresh Installation' instead." + echo "" + read -p "Press Enter to return to main menu..." + show_main_menu + return + fi + + # Check current version + local current_version="unknown" + if [ -f "/usr/local/CyberCP/version.txt" ]; then + current_version=$(cat /usr/local/CyberCP/version.txt 2>/dev/null) + fi + + echo "Current Installation:" + echo "Version: $current_version" + echo "Path: /usr/local/CyberCP" + echo "" + + echo "Select update option:" + echo "" + echo " 1. Update to Latest Stable" + echo " 2. Update to Development Version" + echo " 3. Update to Specific Version/Branch" + echo " 4. Update from Commit Hash" + echo " 5. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select update option [1-5]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + break + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + break + ;; + 3) + show_version_selection + return + ;; + 4) + show_commit_selection + return + ;; + 5) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-5." + echo "" + ;; + esac + done + + echo -n "Proceed with update? (This will backup your current installation) (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + start_upgrade + ;; + esac +} + +# Function to show reinstall menu +show_reinstall_menu() { + echo "" + echo "===============================================================================================================" + echo " REINSTALL CYBERPANEL" + echo "===============================================================================================================" + echo "" + + if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then + echo "ERROR: CyberPanel is not installed on this system." + echo " Please use 'Fresh Installation' instead." + echo "" + read -p "Press Enter to return to main menu..." + show_main_menu + return + fi + + echo "WARNING: This will completely remove the existing CyberPanel installation" + echo " and install a fresh copy. All data will be lost!" + echo "" + + echo -n "Are you sure you want to reinstall? (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + ;; + *) + show_main_menu + return + ;; + esac + + echo "Select reinstall option:" + echo "" + echo " 1. Reinstall Latest Stable" + echo " 2. Reinstall Development Version" + echo " 3. Reinstall Specific Version/Branch" + echo " 4. Reinstall from Commit Hash" + echo " 5. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select reinstall option [1-5]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + break + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + break + ;; + 3) + show_version_selection + return + ;; + 4) + show_commit_selection + return + ;; + 5) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-5." + echo "" + ;; + esac + done + + echo -n "Proceed with reinstall? (This will delete all existing data) (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + start_reinstall + ;; + *) + show_main_menu + ;; + esac +} + +# Function to show system status +show_system_status() { + echo "" + echo "===============================================================================================================" + echo " SYSTEM STATUS CHECK" + echo "===============================================================================================================" + echo "" + + # Check OS + local os_info=$(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2 2>/dev/null || echo 'Unknown') + echo "Operating System: $os_info" + + # Check CyberPanel installation + if [ -d "/usr/local/CyberCP" ] && [ -f "/usr/local/CyberCP/manage.py" ]; then + local version="unknown" + if [ -f "/usr/local/CyberCP/version.txt" ]; then + version=$(cat /usr/local/CyberCP/version.txt 2>/dev/null) + fi + echo "CyberPanel: Installed (Version: $version)" + else + echo "CyberPanel: Not Installed" + fi + + # Check services + echo "" + echo "Services Status:" + if systemctl is-active --quiet mariadb; then + echo " SUCCESS: MariaDB - Running" + else + echo " ERROR: MariaDB - Not Running" + fi + + if systemctl is-active --quiet lsws; then + echo " SUCCESS: LiteSpeed - Running" + else + echo " ERROR: LiteSpeed - Not Running" + fi + + if systemctl is-active --quiet lscpd; then + echo " SUCCESS: CyberPanel - Running" + else + echo " ERROR: CyberPanel - Not Running" + fi + + # Check ports + echo "" + echo "Port Status:" + if netstat -tlnp | grep -q ":8090 "; then + echo " SUCCESS: Port 8090 (CyberPanel) - Listening" + else + echo " ERROR: Port 8090 (CyberPanel) - Not Listening" + fi + + if netstat -tlnp | grep -q ":80 "; then + echo " SUCCESS: Port 80 (HTTP) - Listening" + else + echo " ERROR: Port 80 (HTTP) - Not Listening" + fi + + echo "" + echo -n "Return to main menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + exit 0 + ;; + *) + show_main_menu + ;; + esac +} + +# Function to show advanced menu +show_advanced_menu() { + echo "" + echo "===============================================================================================================" + echo " ADVANCED OPTIONS" + echo "===============================================================================================================" + echo "" + echo " 1. Fix Installation Issues" + echo " 2. Clean Installation Files" + echo " 3. View Installation Logs" + echo " 4. System Diagnostics" + echo " 5. Show Error Help" + echo " 6. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select advanced option [1-6]: " + read -r choice + + case $choice in + 1) + show_fix_menu + return + ;; + 2) + show_clean_menu + return + ;; + 3) + show_logs_menu + return + ;; + 4) + show_diagnostics + return + ;; + 5) + show_error_help + return + ;; + 6) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-6." + echo "" + ;; + esac + done +} + +# Function to show error help +show_error_help() { + echo "" + echo "===============================================================================================================" + echo " ERROR TROUBLESHOOTING HELP" + echo "===============================================================================================================" + echo "" + echo "If your CyberPanel installation failed, here's how to troubleshoot:" + echo "" + echo "📋 LOG FILES LOCATION:" + echo " • Main installer log: /var/log/CyberPanel/install.log" + echo " • Installation output: /var/log/CyberPanel/install_output.log" + echo " • Upgrade output: /var/log/CyberPanel/upgrade_output.log" + echo " • System logs: /var/log/messages" + echo "" + echo "🔍 COMMON ISSUES & SOLUTIONS:" + echo "" + echo "1. DEPENDENCY INSTALLATION FAILED:" + echo " • Check internet connection: ping -c 3 google.com" + echo " • Update package lists: yum update -y (RHEL) or apt update (Debian)" + echo " • Check available disk space: df -h" + echo "" + echo "2. CYBERPANEL DOWNLOAD FAILED:" + echo " • Check internet connectivity" + echo " • Verify GitHub access: curl -I https://github.com" + echo " • Try different branch/version" + echo "" + echo "3. PERMISSION ERRORS:" + echo " • Ensure running as root: whoami" + echo " • Check file permissions: ls -la /var/log/CyberPanel/" + echo "" + echo "4. SYSTEM REQUIREMENTS:" + echo " • Minimum 1GB RAM: free -h" + echo " • Minimum 10GB disk space: df -h" + echo " • Supported OS: AlmaLinux 8/9, CentOS 7/8, Ubuntu 18.04+" + echo "" + echo "5. SERVICE CONFLICTS:" + echo " • Check running services: systemctl list-units --state=running" + echo " • Stop conflicting services: systemctl stop apache2 (if running)" + echo "" + echo "💡 QUICK DEBUG COMMANDS:" + echo " • View installation log: cat /var/log/CyberPanel/install_output.log" + echo " • Check system resources: free -h && df -h" + echo " • Test network: ping -c 3 google.com" + echo " • Check services: systemctl status lscpd" + echo " • View system logs: tail -50 /var/log/messages" + echo "" + echo "🆘 GETTING HELP:" + echo " • CyberPanel Documentation: https://docs.cyberpanel.net" + echo " • CyberPanel Community: https://forums.cyberpanel.net" + echo " • GitHub Issues: https://github.com/usmannasir/cyberpanel/issues" + echo " • Discord Support: https://discord.gg/cyberpanel" + echo "" + echo "🔄 RETRY INSTALLATION:" + echo " • Clean installation: Run installer with 'Clean Installation Files' option" + echo " • Different version: Try stable version instead of development" + echo " • Fresh system: Consider using a clean OS installation" + echo "" + echo "===============================================================================================================" + echo "" + read -p "Press Enter to return to main menu..." + show_main_menu +} + +# Function to show fix menu +show_fix_menu() { + echo "" + echo "===============================================================================================================" + echo " FIX INSTALLATION ISSUES" + echo "===============================================================================================================" + echo "" + echo "This will attempt to fix common CyberPanel installation issues:" + echo "• Database connection problems" + echo "• Service configuration issues" + echo "• SSL certificate problems" + echo "• File permission issues" + echo "" + + echo -n "Proceed with fixing installation issues? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_advanced_menu + ;; + *) + print_status "Applying fixes..." + apply_fixes + print_status "SUCCESS: Fixes applied successfully" + echo "" + read -p "Press Enter to return to advanced menu..." + show_advanced_menu + ;; + esac +} + +# Function to show clean menu +show_clean_menu() { + echo "" + echo "===============================================================================================================" + echo " CLEAN INSTALLATION FILES" + echo "===============================================================================================================" + echo "" + echo "WARNING: This will remove temporary installation files and logs." + echo " This action cannot be undone!" + echo "" + + echo -n "Proceed with cleaning? (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + rm -rf /tmp/cyberpanel_* + rm -rf /var/log/cyberpanel_install.log + echo "SUCCESS: Cleanup complete! Temporary files and logs have been removed." + ;; + esac + + echo "" + echo -n "Return to advanced menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + show_advanced_menu + ;; + esac +} + +# Function to show logs menu +show_logs_menu() { + echo "" + echo "===============================================================================================================" + echo " VIEW INSTALLATION LOGS" + echo "===============================================================================================================" + echo "" + + local log_file="/var/log/cyberpanel_install.log" + + if [ -f "$log_file" ]; then + echo "Installation Log: $log_file" + echo "Log Size: $(du -h "$log_file" | cut -f1)" + echo "" + + echo -n "View recent log entries? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + ;; + *) + echo "" + echo "Recent log entries:" + tail -n 20 "$log_file" + ;; + esac + else + echo "No installation logs found at $log_file" + fi + + echo "" + echo -n "Return to advanced menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + show_advanced_menu + ;; + esac +} + +# Function to show diagnostics +show_diagnostics() { + echo "" + echo "===============================================================================================================" + echo " SYSTEM DIAGNOSTICS" + echo "===============================================================================================================" + echo "" + + echo "Running system diagnostics..." + echo "" + + # Disk space + echo "Disk Usage:" + df -h | grep -E '^/dev/' + + # Memory usage + echo "" + echo "Memory Usage:" + free -h + + # Load average + echo "" + echo "System Load:" + uptime + + # Network interfaces + echo "" + echo "Network Interfaces:" + ip addr show | grep -E '^[0-9]+:|inet ' + + echo "" + echo -n "Return to advanced menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + show_advanced_menu + ;; + esac +} + +# Function to start upgrade +start_upgrade() { + echo "" + echo "===============================================================================================================" + echo " STARTING UPGRADE" + echo "===============================================================================================================" + echo "" + + # Detect OS + echo "Step 1/5: Detecting operating system..." + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + echo " ✓ Operating system detected successfully" + echo "" + + # Install dependencies + echo "Step 2/5: Installing/updating dependencies..." + install_dependencies + echo "" + + # Download and run the upgrade script + echo "Step 3/5: Downloading CyberPanel upgrade script..." + local upgrade_url="" + if [ -n "$BRANCH_NAME" ]; then + if [[ "$BRANCH_NAME" =~ ^[a-f0-9]{40}$ ]]; then + # It's a commit hash + echo "Downloading from commit: $BRANCH_NAME" + upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" + else + # It's a branch name + echo "Downloading from branch: $BRANCH_NAME" + upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" + fi + else + echo "Downloading from: https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh" + upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh" + fi + + curl --silent -o cyberpanel_upgrade.sh "$upgrade_url" 2>/dev/null + + chmod +x cyberpanel_upgrade.sh + + echo " ✓ CyberPanel upgrade script downloaded" + echo " 🔄 Starting CyberPanel upgrade..." + echo "" + echo "IMPORTANT: The upgrade is now running in the background." + echo "You will see detailed output from the CyberPanel upgrade script below." + echo "This is normal and expected - the upgrade is proceeding!" + echo "" + echo "===============================================================================================================" + echo "" + + # Run the upgrade with live progress monitoring + echo "Starting CyberPanel upgrade process..." + echo "This may take several minutes. Please be patient." + echo "" + + # Create log directory + mkdir -p /var/log/CyberPanel + + # Run the upgrade with live output monitoring + echo "Starting CyberPanel upgrade with live progress monitoring..." + echo "" + echo "===============================================================================================================" + echo " LIVE UPGRADE PROGRESS" + echo "===============================================================================================================" + echo "" + + # Run upgrade and show live output + if [ "$DEBUG_MODE" = true ]; then + ./cyberpanel_upgrade.sh --debug 2>&1 | tee /var/log/CyberPanel/upgrade_output.log + else + ./cyberpanel_upgrade.sh 2>&1 | tee /var/log/CyberPanel/upgrade_output.log + fi + + local upgrade_exit_code=${PIPESTATUS[0]} + + echo "" + echo "===============================================================================================================" + echo " UPGRADE COMPLETED" + echo "===============================================================================================================" + echo "" + + # Clean up downloaded upgrade script + rm -f cyberpanel_upgrade.sh 2>/dev/null + + # Check if upgrade was successful + if [ $upgrade_exit_code -eq 0 ]; then + print_status "SUCCESS: CyberPanel upgraded successfully" + return 0 + else + print_status "ERROR: CyberPanel upgrade failed with exit code $upgrade_exit_code" + echo "" + echo "Upgrade log (last 50 lines):" + echo "===============================================================================================================" + tail -50 /var/log/CyberPanel/upgrade_output.log 2>/dev/null || echo "Could not read upgrade log" + echo "===============================================================================================================" + echo "" + echo "Full upgrade log available at: /var/log/CyberPanel/upgrade_output.log" + echo "" + return 1 + fi +} + +# Function to start force reinstall +start_force_reinstall() { + echo "" + echo "===============================================================================================================" + echo " FORCE REINSTALL CYBERPANEL" + echo "===============================================================================================================" + echo "" + echo "This will completely remove the existing CyberPanel installation and install a fresh copy." + echo "All data and configurations will be lost!" + echo "" + + while true; do + echo -n "Are you sure you want to proceed? (y/N): " + read -r confirm + case $confirm in + [Yy]*) + echo "" + echo "Starting force reinstall..." + echo "" + + # Clean up existing installation + cleanup_existing_cyberpanel + + # Start fresh installation + start_installation + break + ;; + [Nn]*|"") + echo "Force reinstall cancelled." + return + ;; + *) + echo "Please answer yes or no." + ;; + esac + done +} + +# Function to start preupgrade +start_preupgrade() { + echo "" + echo "===============================================================================================================" + echo " PRE-UPGRADE SETUP" + echo "===============================================================================================================" + echo "" + + echo "This will download the latest CyberPanel upgrade script to /usr/local/" + echo "and prepare it for execution." + echo "" + + # Get the latest version + echo "Step 1/3: Fetching latest version information..." + local latest_version=$(curl -s https://cyberpanel.net/version.txt | sed -e 's|{"version":"||g' -e 's|","build":|.|g' | sed 's:}*$::') + local branch_name="v$latest_version" + + echo " ✓ Latest version: $latest_version" + echo " ✓ Branch: $branch_name" + echo "" + + # Download the upgrade script + echo "Step 2/3: Downloading CyberPanel upgrade script..." + local upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$branch_name/cyberpanel_upgrade.sh" + echo "Downloading from: $upgrade_url" + + if curl --silent -o /usr/local/cyberpanel_upgrade.sh "$upgrade_url" 2>/dev/null; then + chmod 700 /usr/local/cyberpanel_upgrade.sh + echo " ✓ Upgrade script downloaded to /usr/local/cyberpanel_upgrade.sh" + else + print_status "ERROR: Failed to download upgrade script" + return 1 + fi + echo "" + + # Show instructions + echo "Step 3/3: Setup complete!" + echo "" + echo "The upgrade script is now ready at: /usr/local/cyberpanel_upgrade.sh" + echo "" + echo "To run the upgrade, you can either:" + echo " 1. Use this installer's 'Update Existing Installation' option" + echo " 2. Run directly: /usr/local/cyberpanel_upgrade.sh" + echo "" + echo "===============================================================================================================" + echo "" + + read -p "Press Enter to return to main menu..." + show_main_menu +} + +# Function to start reinstall +start_reinstall() { + echo "" + echo "===============================================================================================================" + echo " STARTING REINSTALL" + echo "===============================================================================================================" + echo "" + + echo "WARNING: This will completely remove the existing CyberPanel installation!" + echo "All data, websites, and configurations will be lost!" + echo "" + + # Detect OS + echo "Step 1/6: Detecting operating system..." + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + echo " ✓ Operating system detected successfully" + echo "" + + # Stop services + echo "Step 2/6: Stopping CyberPanel services..." + systemctl stop lscpd 2>/dev/null || true + systemctl stop lsws 2>/dev/null || true + systemctl stop mariadb 2>/dev/null || true + systemctl stop postfix 2>/dev/null || true + systemctl stop dovecot 2>/dev/null || true + systemctl stop pure-ftpd 2>/dev/null || true + echo " ✓ Services stopped" + echo "" + + # Remove existing installation + echo "Step 3/6: Removing existing CyberPanel installation..." + rm -rf /usr/local/CyberCP 2>/dev/null || true + rm -rf /usr/local/lsws 2>/dev/null || true + rm -rf /home/cyberpanel 2>/dev/null || true + rm -rf /var/lib/mysql 2>/dev/null || true + rm -rf /var/log/cyberpanel 2>/dev/null || true + echo " ✓ Existing installation removed" + echo "" + + # Install dependencies + echo "Step 4/6: Installing dependencies..." + install_dependencies + echo "" + + # Install CyberPanel + echo "Step 5/6: Installing CyberPanel..." + if ! install_cyberpanel; then + print_status "ERROR: CyberPanel installation failed" + exit 1 +fi + echo "" + + # Apply fixes + echo "Step 6/6: Applying installation fixes..." + apply_fixes + echo "" + + # Show status summary + show_status_summary + + print_status "SUCCESS: CyberPanel reinstalled successfully!" +} + +# Function to start installation +start_installation() { + echo "" + echo "===============================================================================================================" + echo " STARTING INSTALLATION" + echo "===============================================================================================================" + echo "" + + # Detect OS + echo "Step 1/6: Detecting operating system..." + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + echo " ✓ Operating system detected successfully" + echo "" + + # Install dependencies + echo "Step 2/6: Installing dependencies..." + install_dependencies + echo "" + + # Install CyberPanel + echo "Step 3/6: Installing CyberPanel..." + if ! install_cyberpanel; then + print_status "ERROR: CyberPanel installation failed" + echo "" + echo "Would you like to see troubleshooting help? (y/n) [y]: " + read -r show_help + case $show_help in + [nN]|[nN][oO]) + echo "Installation failed. Check logs at /var/log/CyberPanel/" + echo "Run the installer again and select 'Advanced Options' → 'Show Error Help' for detailed troubleshooting." + ;; + *) + show_error_help + ;; + esac + exit 1 + fi + echo "" + + # Apply post-installation fixes silently + apply_fixes + + # Create standard aliases (silently) + create_standard_aliases >/dev/null 2>&1 + + # Show final status summary + echo "" + show_status_summary +} + +# Function to parse command line arguments +parse_arguments() { + while [[ $# -gt 0 ]]; do + case $1 in + -b|--branch) + if [ -n "$2" ]; then + # Convert version number to branch name if needed + if [[ "$2" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + if [[ "$2" == *"-"* ]]; then + # Already has suffix like 2.5.5-dev, add v prefix + BRANCH_NAME="v$2" + else + # Add v prefix and dev suffix for development versions + BRANCH_NAME="v$2-dev" + fi + elif [[ "$2" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + # Already has v prefix, use as is + BRANCH_NAME="$2" + else + # Assume it's already a branch name or commit hash + BRANCH_NAME="$2" + fi + shift 2 + else + echo "ERROR: -b/--branch requires a version number or branch name" + echo "Example: -b 2.5.5-dev or -b v2.5.5-dev" + exit 1 + fi + ;; + -v|--version) + if [ -n "$2" ]; then + # Convert version number to branch name if needed + if [[ "$2" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + if [[ "$2" == *"-"* ]]; then + # Already has suffix like 2.5.5-dev, add v prefix + BRANCH_NAME="v$2" + else + # Add v prefix and dev suffix for development versions + BRANCH_NAME="v$2-dev" + fi + elif [[ "$2" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + # Already has v prefix, use as is + BRANCH_NAME="$2" + else + # Assume it's already a branch name or commit hash + BRANCH_NAME="$2" + fi + shift 2 + else + echo "ERROR: -v/--version requires a version number or branch name" + echo "Example: -v 2.5.5-dev or -v v2.5.5-dev" + exit 1 + fi + ;; + --debug) + DEBUG_MODE=true + set -x + shift + ;; + --mariadb-version) + if [ -n "$2" ] && [ "$2" = "10.11" ]; then + MARIADB_VER="10.11" + shift 2 + elif [ -n "$2" ] && [ "$2" = "11.8" ]; then + MARIADB_VER="11.8" + shift 2 + elif [ -n "$2" ] && [ "$2" = "12.1" ]; then + MARIADB_VER="12.1" + shift 2 + else + echo "ERROR: --mariadb-version requires 10.11, 11.8 or 12.1" + exit 1 + fi + ;; + --auto) + AUTO_INSTALL=true + shift + ;; + -h|--help) + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " -b, --branch BRANCH Install from specific branch/commit" + echo " -v, --version VER Install specific version (auto-adds v prefix)" + echo " --mariadb-version VER MariaDB version: 10.11, 11.8 or 12.1 (asked after web server)" + echo " --debug Enable debug mode" + echo " --auto Auto mode: OpenLiteSpeed + MariaDB 11.8 unless --mariadb-version set" + echo " -h, --help Show this help message" + echo "" + echo "Examples:" + echo " $0 # Interactive installation" + echo " $0 --debug # Debug mode installation" + echo " $0 --auto # Auto installation" + echo " $0 -b v2.5.5-dev # Install development version" + echo " $0 -v 2.5.5-dev # Install version 2.5.5-dev" + echo " $0 -v 2.4.3 # Install version 2.4.3" + echo " $0 -b main # Install from main branch" + echo " $0 -b a1b2c3d4 # Install from specific commit" + echo " $0 --mariadb-version 10.11 # Use MariaDB 10.11 (same as v2.4.4 style)" + echo " $0 --mariadb-version 12.1 # Use MariaDB 12.1 (no prompt)" + echo " $0 --auto --mariadb-version 11.8 # Fully non-interactive with MariaDB 11.8" + echo "" + echo "Standard CyberPanel Installation Methods:" + echo " sh <(curl https://cyberpanel.net/install.sh)" + echo " bash <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh) -b 2.4.3" + echo " bash <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh) -b 2.5.5-dev" + exit 0 + ;; + *) + print_status "WARNING: Unknown option: $1" + shift + ;; + esac + done +} + +# Function to detect installation mode +detect_installation_mode() { + # Check if this is being called as an upgrade script + if [[ "$0" == *"cyberpanel_upgrade.sh"* ]] || [[ "$0" == *"upgrade"* ]]; then + INSTALLATION_TYPE="upgrade" + return 0 + fi + + # Check if this is being called as a pre-upgrade script + if [[ "$0" == *"preUpgrade.sh"* ]] || [[ "$0" == *"preupgrade"* ]]; then + INSTALLATION_TYPE="preupgrade" + return 0 + fi + + # Check if this is being called as a standard install script + if [[ "$0" == *"install.sh"* ]] || [[ "$0" == *"cyberpanel.sh"* ]]; then + INSTALLATION_TYPE="install" + return 0 + fi + + # Default to install mode + INSTALLATION_TYPE="install" + return 0 +} + +# Function to create standard CyberPanel aliases +create_standard_aliases() { + print_status "Creating standard CyberPanel installation aliases..." + + # Create symbolic links for standard installation methods + local script_dir="/usr/local/bin" + local script_name="cyberpanel_enhanced.sh" + + # Copy this script to /usr/local/bin + if cp "$0" "$script_dir/$script_name" 2>/dev/null; then + chmod +x "$script_dir/$script_name" + + # Create aliases for standard CyberPanel methods + ln -sf "$script_dir/$script_name" "$script_dir/cyberpanel_upgrade.sh" 2>/dev/null || true + ln -sf "$script_dir/$script_name" "$script_dir/preUpgrade.sh" 2>/dev/null || true + ln -sf "$script_dir/$script_name" "$script_dir/install.sh" 2>/dev/null || true + + print_status "✓ Standard CyberPanel aliases created" + print_status " - cyberpanel_upgrade.sh" + print_status " - preUpgrade.sh" + print_status " - install.sh" + else + print_status "WARNING: Could not create standard aliases (permission denied)" + fi +} + +# Main installation function +main() { + # Initialize log directory and file + mkdir -p "/var/log/CyberPanel" + touch "/var/log/CyberPanel/install.log" + + print_status "CyberPanel Enhanced Installer Starting..." + print_status "Log file: /var/log/CyberPanel/install.log" + + # Detect installation mode + detect_installation_mode + + # Parse command line arguments + parse_arguments "$@" + + # Handle different installation modes + case "$INSTALLATION_TYPE" in + "upgrade") + print_status "Running in upgrade mode..." + if [ -n "$BRANCH_NAME" ]; then + print_status "Upgrading to version: $BRANCH_NAME" + fi + start_upgrade + ;; + "preupgrade") + print_status "Running in pre-upgrade mode..." + start_preupgrade + ;; + "install"|*) + if [ "$AUTO_INSTALL" = true ]; then + # Run auto mode + print_status "Starting auto mode..." + + # Detect OS + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + + # Install dependencies + install_dependencies + + # Install CyberPanel + if ! install_cyberpanel; then + print_status "ERROR: CyberPanel installation failed" + echo "" + echo "Would you like to see troubleshooting help? (y/n) [y]: " + read -r show_help + case $show_help in + [nN]|[nN][oO]) + echo "Installation failed. Check logs at /var/log/CyberPanel/" + ;; + *) + show_error_help + ;; + esac + exit 1 + fi + + # Apply fixes + apply_fixes + + # Create standard aliases + create_standard_aliases + + # Show status summary + show_status_summary + + print_status "SUCCESS: Installation completed successfully!" + else + # Run interactive mode - ensure stdin is the terminal for prompts (e.g. when script was piped from curl) + if [ ! -t 0 ]; then + exec 0 public/snappymail" | tee -a /var/log/cyberpanel_upgrade_debug.log + if [ -f "/usr/local/CyberCP/public/snappymail/include.php" ]; then + sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' /usr/local/CyberCP/public/snappymail/include.php + fi + for inc in /usr/local/CyberCP/public/snappymail/snappymail/v/*/include.php /usr/local/CyberCP/public/snappymail/rainloop/v/*/include.php; do + [ -f "$inc" ] && sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' "$inc" && break + done 2>/dev/null +fi + # Migrate data from old rainloop folder to new snappymail folder (2.4.4 -> 2.5.5 upgrade) if [ -d "/usr/local/lscp/cyberpanel/rainloop/data" ] && [ "$(ls -A /usr/local/lscp/cyberpanel/rainloop/data 2>/dev/null)" ]; then echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Migrating rainloop data to snappymail..." | tee -a /var/log/cyberpanel_upgrade_debug.log @@ -1971,6 +1984,14 @@ if [ -d "/usr/local/lscp/cyberpanel/rainloop/data" ] && [ "$(ls -A /usr/local/ls sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' /usr/local/CyberCP/public/snappymail/include.php echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Updated include.php to use snappymail data path" | tee -a /var/log/cyberpanel_upgrade_debug.log fi + + # Replace ALL rainloop path/URL references in migrated SnappyMail data (configs, domains, plugins) + if [ -d "/usr/local/lscp/cyberpanel/snappymail/data" ]; then + find /usr/local/lscp/cyberpanel/snappymail/data -type f \( -name "*.ini" -o -name "*.json" -o -name "*.php" -o -name "*.cfg" \) -exec grep -l "rainloop" {} \; 2>/dev/null | while read -r f; do + sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g; s|/rainloop/|/snappymail/|g; s|rainloop/data|snappymail/data|g' "$f" + done + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Replaced rainloop→snappymail links in SnappyMail data files" | tee -a /var/log/cyberpanel_upgrade_debug.log + fi else echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: Data migration completed with errors" | tee -a /var/log/cyberpanel_upgrade_debug.log fi @@ -1994,6 +2015,20 @@ else echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: lscpd user not found, skipping ownership change" | tee -a /var/log/cyberpanel_upgrade_debug.log fi +# Ensure /rainloop→/snappymail redirect exists (even when no migration ran) +HTACCESS="/usr/local/CyberCP/public/.htaccess" +if [ -d "/usr/local/CyberCP/public" ] && { [ ! -f "$HTACCESS" ] || ! grep -q "Redirect old RainLoop URL to SnappyMail" "$HTACCESS" 2>/dev/null; }; then + { + echo "" + echo "# Redirect old RainLoop URL to SnappyMail (2.5.5 upgrade)" + echo "" + echo "RewriteEngine On" + echo "RewriteRule ^rainloop/?(.*)\$ /snappymail/\$1 [R=301,L]" + echo "" + } >> "$HTACCESS" + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Added /rainloop→/snappymail redirect to .htaccess" | tee -a /var/log/cyberpanel_upgrade_debug.log +fi + # Set proper permissions for SnappyMail data directories (group writable) chmod -R 775 /usr/local/lscp/cyberpanel/snappymail/data/ echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Set SnappyMail data directory permissions to 775 (group writable)" | tee -a /var/log/cyberpanel_upgrade_debug.log diff --git a/firewall/static/firewall/firewall.js b/firewall/static/firewall/firewall.js index e5acb30fe..b49721759 100644 --- a/firewall/static/firewall/firewall.js +++ b/firewall/static/firewall/firewall.js @@ -31,6 +31,8 @@ app.controller('firewallController', function ($scope, $http, $timeout) { $scope.couldNotConnect = true; $scope.rulesDetails = false; + // Initialize rules array - prevents "Cannot read 'length' of undefined" when template evaluates rules.length before API loads + $scope.rules = []; // Banned IPs variables – tab from hash so we stay on /firewall/ (avoids 404 on servers without /firewall/firewall-rules/) function tabFromHash() { var h = (window.location.hash || '').replace(/^#/, ''); diff --git a/firewall/templates/firewall/firewall.html b/firewall/templates/firewall/firewall.html index 981fa5727..d0398360c 100644 --- a/firewall/templates/firewall/firewall.html +++ b/firewall/templates/firewall/firewall.html @@ -1293,7 +1293,7 @@
- +
@@ -1361,7 +1361,7 @@ -
+

{% trans "No Firewall Rules" %}

{% trans "Add your first firewall rule to control network access to your server." %}

diff --git a/install.sh b/install.sh index 4f7e0118d..560d22dbf 100644 --- a/install.sh +++ b/install.sh @@ -99,6 +99,14 @@ fi # Check disk space check_disk_space +# If running from repo with modular installer, use it +INSTALL_SCRIPT_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)" +if [ -n "$INSTALL_SCRIPT_DIR" ] && [ -f "$INSTALL_SCRIPT_DIR/cyberpanel.sh" ] && [ -d "$INSTALL_SCRIPT_DIR/install_modules" ]; then + echo "Using local CyberPanel installer (modular)" + cd "$INSTALL_SCRIPT_DIR" || exit 1 + exec bash ./cyberpanel.sh -b "${BRANCH_NAME}" "$@" +fi + # Download and execute cyberpanel.sh for the specified branch echo "Downloading CyberPanel installer for branch: $BRANCH_NAME" diff --git a/install/email-configs/access b/install/email-configs/access deleted file mode 100644 index 9df9991a4..000000000 --- a/install/email-configs/access +++ /dev/null @@ -1,476 +0,0 @@ -# ACCESS(5) ACCESS(5) -# -# NAME -# access - Postfix SMTP server access table -# -# SYNOPSIS -# postmap /etc/postfix/access -# -# postmap -q "string" /etc/postfix/access -# -# postmap -q - /etc/postfix/access as the lookup key for such addresses. The value is -# specified with the smtpd_null_access_lookup_key parameter -# in the Postfix main.cf file. -# -# EMAIL ADDRESS EXTENSION -# When a mail address localpart contains the optional recip- -# ient delimiter (e.g., user+foo@domain), the lookup order -# becomes: user+foo@domain, user@domain, domain, user+foo@, -# and user@. -# -# HOST NAME/ADDRESS PATTERNS -# With lookups from indexed files such as DB or DBM, or from -# networked tables such as NIS, LDAP or SQL, the following -# lookup patterns are examined in the order as listed: -# -# domain.tld -# Matches domain.tld. -# -# The pattern domain.tld also matches subdomains, but -# only when the string smtpd_access_maps is listed in -# the Postfix parent_domain_matches_subdomains con- -# figuration setting. -# -# .domain.tld -# Matches subdomains of domain.tld, but only when the -# string smtpd_access_maps is not listed in the Post- -# fix parent_domain_matches_subdomains configuration -# setting. -# -# net.work.addr.ess -# -# net.work.addr -# -# net.work -# -# net Matches the specified IPv4 host address or subnet- -# work. An IPv4 host address is a sequence of four -# decimal octets separated by ".". -# -# Subnetworks are matched by repeatedly truncating -# the last ".octet" from the remote IPv4 host address -# string until a match is found in the access table, -# or until further truncation is not possible. -# -# NOTE 1: The access map lookup key must be in canon- -# ical form: do not specify unnecessary null charac- -# ters, and do not enclose network address informa- -# tion with "[]" characters. -# -# NOTE 2: use the cidr lookup table type to specify -# network/netmask patterns. See cidr_table(5) for -# details. -# -# net:work:addr:ess -# -# net:work:addr -# -# net:work -# -# net Matches the specified IPv6 host address or subnet- -# work. An IPv6 host address is a sequence of three -# to eight hexadecimal octet pairs separated by ":". -# -# Subnetworks are matched by repeatedly truncating -# the last ":octetpair" from the remote IPv6 host -# address string until a match is found in the access -# table, or until further truncation is not possible. -# -# NOTE 1: the truncation and comparison are done with -# the string representation of the IPv6 host address. -# Thus, not all the ":" subnetworks will be tried. -# -# NOTE 2: The access map lookup key must be in canon- -# ical form: do not specify unnecessary null charac- -# ters, and do not enclose network address informa- -# tion with "[]" characters. -# -# NOTE 3: use the cidr lookup table type to specify -# network/netmask patterns. See cidr_table(5) for -# details. -# -# IPv6 support is available in Postfix 2.2 and later. -# -# ACCEPT ACTIONS -# OK Accept the address etc. that matches the pattern. -# -# all-numerical -# An all-numerical result is treated as OK. This for- -# mat is generated by address-based relay authoriza- -# tion schemes such as pop-before-smtp. -# -# REJECT ACTIONS -# Postfix version 2.3 and later support enhanced status -# codes as defined in RFC 3463. When no code is specified -# at the beginning of the text below, Postfix inserts a -# default enhanced status code of "5.7.1" in the case of -# reject actions, and "4.7.1" in the case of defer actions. -# See "ENHANCED STATUS CODES" below. -# -# 4NN text -# -# 5NN text -# Reject the address etc. that matches the pattern, -# and respond with the numerical three-digit code and -# text. 4NN means "try again later", while 5NN means -# "do not try again". -# -# The following responses have special meaning for -# the Postfix SMTP server: -# -# 421 text (Postfix 2.3 and later) -# -# 521 text (Postfix 2.6 and later) -# After responding with the numerical three- -# digit code and text, disconnect immediately -# from the SMTP client. This frees up SMTP -# server resources so that they can be made -# available to another SMTP client. -# -# Note: The "521" response should be used only -# with botnets and other malware where inter- -# operability is of no concern. The "send 521 -# and disconnect" behavior is NOT defined in -# the SMTP standard. -# -# REJECT optional text... -# Reject the address etc. that matches the pattern. -# Reply with "$access_map_reject_code optional -# text..." when the optional text is specified, oth- -# erwise reply with a generic error response message. -# -# DEFER optional text... -# Reject the address etc. that matches the pattern. -# Reply with "$access_map_defer_code optional -# text..." when the optional text is specified, oth- -# erwise reply with a generic error response message. -# -# This feature is available in Postfix 2.6 and later. -# -# DEFER_IF_REJECT optional text... -# Defer the request if some later restriction would -# result in a REJECT action. Reply with -# "$access_map_defer_code 4.7.1 optional text..." -# when the optional text is specified, otherwise -# reply with a generic error response message. -# -# Prior to Postfix 2.6, the SMTP reply code is 450. -# -# This feature is available in Postfix 2.1 and later. -# -# DEFER_IF_PERMIT optional text... -# Defer the request if some later restriction would -# result in a an explicit or implicit PERMIT action. -# Reply with "$access_map_defer_code 4.7.1 optional -# text..." when the optional text is specified, oth- -# erwise reply with a generic error response message. -# -# Prior to Postfix 2.6, the SMTP reply code is 450. -# -# This feature is available in Postfix 2.1 and later. -# -# OTHER ACTIONS -# restriction... -# Apply the named UCE restriction(s) (permit, reject, -# reject_unauth_destination, and so on). -# -# BCC user@domain -# Send one copy of the message to the specified -# recipient. -# -# If multiple BCC actions are specified within the -# same SMTP MAIL transaction, only the last action -# will be used. -# -# This feature is not part of the stable Postfix -# release. -# -# DISCARD optional text... -# Claim successful delivery and silently discard the -# message. Log the optional text if specified, oth- -# erwise log a generic message. -# -# Note: this action currently affects all recipients -# of the message. To discard only one recipient -# without discarding the entire message, use the -# transport(5) table to direct mail to the discard(8) -# service. -# -# This feature is available in Postfix 2.0 and later. -# -# DUNNO Pretend that the lookup key was not found. This -# prevents Postfix from trying substrings of the -# lookup key (such as a subdomain name, or a network -# address subnetwork). -# -# This feature is available in Postfix 2.0 and later. -# -# FILTER transport:destination -# After the message is queued, send the entire mes- -# sage through the specified external content filter. -# The transport name specifies the first field of a -# mail delivery agent definition in master.cf; the -# syntax of the next-hop destination is described in -# the manual page of the corresponding delivery -# agent. More information about external content -# filters is in the Postfix FILTER_README file. -# -# Note 1: do not use $number regular expression sub- -# stitutions for transport or destination unless you -# know that the information has a trusted origin. -# -# Note 2: this action overrides the main.cf con- -# tent_filter setting, and affects all recipients of -# the message. In the case that multiple FILTER -# actions fire, only the last one is executed. -# -# Note 3: the purpose of the FILTER command is to -# override message routing. To override the recipi- -# ent's transport but not the next-hop destination, -# specify an empty filter destination (Postfix 2.7 -# and later), or specify a transport:destination that -# delivers through a different Postfix instance -# (Postfix 2.6 and earlier). Other options are using -# the recipient-dependent transport_maps or the sen- -# der-dependent sender_dependent_default_transport- -# _maps features. -# -# This feature is available in Postfix 2.0 and later. -# -# HOLD optional text... -# Place the message on the hold queue, where it will -# sit until someone either deletes it or releases it -# for delivery. Log the optional text if specified, -# otherwise log a generic message. -# -# Mail that is placed on hold can be examined with -# the postcat(1) command, and can be destroyed or -# released with the postsuper(1) command. -# -# Note: use "postsuper -r" to release mail that was -# kept on hold for a significant fraction of $maxi- -# mal_queue_lifetime or $bounce_queue_lifetime, or -# longer. Use "postsuper -H" only for mail that will -# not expire within a few delivery attempts. -# -# Note: this action currently affects all recipients -# of the message. -# -# This feature is available in Postfix 2.0 and later. -# -# PREPEND headername: headervalue -# Prepend the specified message header to the mes- -# sage. When more than one PREPEND action executes, -# the first prepended header appears before the sec- -# ond etc. prepended header. -# -# Note: this action must execute before the message -# content is received; it cannot execute in the con- -# text of smtpd_end_of_data_restrictions. -# -# This feature is available in Postfix 2.1 and later. -# -# REDIRECT user@domain -# After the message is queued, send the message to -# the specified address instead of the intended -# recipient(s). -# -# Note: this action overrides the FILTER action, and -# currently affects all recipients of the message. -# -# This feature is available in Postfix 2.1 and later. -# -# WARN optional text... -# Log a warning with the optional text, together with -# client information and if available, with helo, -# sender, recipient and protocol information. -# -# This feature is available in Postfix 2.1 and later. -# -# ENHANCED STATUS CODES -# Postfix version 2.3 and later support enhanced status -# codes as defined in RFC 3463. When an enhanced status -# code is specified in an access table, it is subject to -# modification. The following transformations are needed -# when the same access table is used for client, helo, -# sender, or recipient access restrictions; they happen -# regardless of whether Postfix replies to a MAIL FROM, RCPT -# TO or other SMTP command. -# -# o When a sender address matches a REJECT action, the -# Postfix SMTP server will transform a recipient DSN -# status (e.g., 4.1.1-4.1.6) into the corresponding -# sender DSN status, and vice versa. -# -# o When non-address information matches a REJECT -# action (such as the HELO command argument or the -# client hostname/address), the Postfix SMTP server -# will transform a sender or recipient DSN status -# into a generic non-address DSN status (e.g., -# 4.0.0). -# -# REGULAR EXPRESSION TABLES -# This section describes how the table lookups change when -# the table is given in the form of regular expressions. For -# a description of regular expression lookup table syntax, -# see regexp_table(5) or pcre_table(5). -# -# Each pattern is a regular expression that is applied to -# the entire string being looked up. Depending on the appli- -# cation, that string is an entire client hostname, an -# entire client IP address, or an entire mail address. Thus, -# no parent domain or parent network search is done, -# user@domain mail addresses are not broken up into their -# user@ and domain constituent parts, nor is user+foo broken -# up into user and foo. -# -# Patterns are applied in the order as specified in the ta- -# ble, until a pattern is found that matches the search -# string. -# -# Actions are the same as with indexed file lookups, with -# the additional feature that parenthesized substrings from -# the pattern can be interpolated as $1, $2 and so on. -# -# TCP-BASED TABLES -# This section describes how the table lookups change when -# lookups are directed to a TCP-based server. For a descrip- -# tion of the TCP client/server lookup protocol, see tcp_ta- -# ble(5). This feature is not available up to and including -# Postfix version 2.4. -# -# Each lookup operation uses the entire query string once. -# Depending on the application, that string is an entire -# client hostname, an entire client IP address, or an entire -# mail address. Thus, no parent domain or parent network -# search is done, user@domain mail addresses are not broken -# up into their user@ and domain constituent parts, nor is -# user+foo broken up into user and foo. -# -# Actions are the same as with indexed file lookups. -# -# EXAMPLE -# The following example uses an indexed file, so that the -# order of table entries does not matter. The example per- -# mits access by the client at address 1.2.3.4 but rejects -# all other clients in 1.2.3.0/24. Instead of hash lookup -# tables, some systems use dbm. Use the command "postconf -# -m" to find out what lookup tables Postfix supports on -# your system. -# -# /etc/postfix/main.cf: -# smtpd_client_restrictions = -# check_client_access hash:/etc/postfix/access -# -# /etc/postfix/access: -# 1.2.3 REJECT -# 1.2.3.4 OK -# -# Execute the command "postmap /etc/postfix/access" after -# editing the file. -# -# BUGS -# The table format does not understand quoting conventions. -# -# SEE ALSO -# postmap(1), Postfix lookup table manager -# smtpd(8), SMTP server -# postconf(5), configuration parameters -# transport(5), transport:nexthop syntax -# -# README FILES -# Use "postconf readme_directory" or "postconf html_direc- -# tory" to locate this information. -# SMTPD_ACCESS_README, built-in SMTP server access control -# DATABASE_README, Postfix lookup table overview -# -# LICENSE -# The Secure Mailer license must be distributed with this -# software. -# -# AUTHOR(S) -# Wietse Venema -# IBM T.J. Watson Research -# P.O. Box 704 -# Yorktown Heights, NY 10598, USA -# -# ACCESS(5) diff --git a/install/email-configs/canonical b/install/email-configs/canonical deleted file mode 100644 index 720db18cc..000000000 --- a/install/email-configs/canonical +++ /dev/null @@ -1,278 +0,0 @@ -# CANONICAL(5) CANONICAL(5) -# -# NAME -# canonical - Postfix canonical table format -# -# SYNOPSIS -# postmap /etc/postfix/canonical -# -# postmap -q "string" /etc/postfix/canonical -# -# postmap -q - /etc/postfix/canonical $/ -# REJECT IFRAME vulnerability exploit -# -# SEE ALSO -# cleanup(8), canonicalize and enqueue Postfix message -# pcre_table(5), format of PCRE lookup tables -# regexp_table(5), format of POSIX regular expression tables -# postconf(1), Postfix configuration utility -# postmap(1), Postfix lookup table management -# postsuper(1), Postfix janitor -# postcat(1), show Postfix queue file contents -# RFC 2045, base64 and quoted-printable encoding rules -# RFC 2047, message header encoding for non-ASCII text -# -# README FILES -# Use "postconf readme_directory" or "postconf html_direc- -# tory" to locate this information. -# DATABASE_README, Postfix lookup table overview -# CONTENT_INSPECTION_README, Postfix content inspection overview -# BUILTIN_FILTER_README, Postfix built-in content inspection -# BACKSCATTER_README, blocking returned forged mail -# -# LICENSE -# The Secure Mailer license must be distributed with this -# software. -# -# AUTHOR(S) -# Wietse Venema -# IBM T.J. Watson Research -# P.O. Box 704 -# Yorktown Heights, NY 10598, USA -# -# HEADER_CHECKS(5) diff --git a/install/email-configs/key.pem b/install/email-configs/key.pem deleted file mode 100644 index 2a54a7344..000000000 --- a/install/email-configs/key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDaJHIFeHit7KHn -i0rgT9kIueUTv0Ukud00FezacYIipCkWKDKFM+x4dVXXPJ1ey3ymFsRAs7wVFm0R -a4GBO+vFiNx1HBRnbcZutjbJIPiC+SJONN3UOUDmRSspF1/bxKQZhk4LDmj9X52n -le6muvcOuulqdR6wLpezD4v7lJJQQ347mxomVA+dqWBDwwv9zf/nx+q3ejux82TF -qTUneGInN1wUIz5hUTt94JiQzOTRACLdNulyOJ/AM0GCNlZoHhkWseb67PITD4zP -EJAHlK1nJjJMGtoXFT68Shbv5IL3bj/UbaA9P5+TOgYaXJ9SZmuk9V5oirWzaiuU -6GgHm0uDAgMBAAECggEBANN6h6u0ClKa2K8vw+xInKCwD1wgjvi207M+Gjv/1Oie -e1KGr8ug9fwlzI14rxwKbBJcefA8DvfmoOBFd+yA2ebL8uX5zfIjYz9LmTtNon7e -5hopeHDY/IkAv4H7rivRrEEuihR/6NrSSnYAjbfIA+Gc5NMXLiQhV2H5jXzdoSb7 -LLbsi294f2F91anUspecM/Hk5/W4JOSllY8RtLWKTxqLN22ujnvZKFqMNB/RH3d1 -HrFc6jbn8Nb6C5B5VnSBw64RNbpZbCYntbDmb4DCp/+Z2llFNrFM1XxjaJBsrHnJ -ZTGoVIPCo1DClP/YUEUP0RTIoM/LUJwfma2hq9MrQ3ECgYEA+pCyx+MnZPog7yLD -paR4h4Eb37majfhILO1wJRXGnmCzkp63MOLxSEZIc/JvePlS6FYRdy/F1N6NnST2 -Z2PO6JaDWxDJOhcc8QSswQsTNkUKjdygbqw4adraltriheCy/9pI131MoMLBYPdg -Rvnw2CrPNGwwdm3Wq64fGnL0m8sCgYEA3t+20ft4QqjMYgdNL/HHPiMpgdEIEdNN -F+wMxhxcHKI2uR/ZMGGq7AauQcxtNfoPZbQkjKwUSnkJEf6lk5Gr6hb9bz1yviu6 -NycnxlWvXiqz+Sql2e8xqSdtsw2Vuv+vPBSiUdAz4vRO3MmL8KBfmY8WG+XP78bF -HvXSetqwCCkCgYEA0GAhrgYErv8tAHKizlA3RElkyuvp0oNWUraresvfP7sf26FO -q8Mv8XExs+s8NRjzj/Bz2fDKzzq9/p/MozLn0ZnKZ6NQFZU/JllC6c+yDIHiQxPl -/+QNjkrJWodxtvClLA12Ym77mP4eH+vaD2ywlLUVWH1Y2ESEMIY/q5lKP30CgYEA -kFO/SGvYjRJSiIjB63Je3FZY4sBCwYhcPEmYXBKxc7l4RpnhQ/t7fC03W1TOxE2S -+wGVSaOF4FRRE14cS1viQE1zAT6Bt7UJef3ZPA7w6cItmgWMMX08Y5Ys6+64L8iz -6exS0ThK4YXkLAY4oTK5te97GcXQyi2mKU53ZyeHJ0ECgYAtqdndLIkiirXplJ10 -9VkrDKZG/Zsqm7vQjl//ZPIDzWcwo3ehBvyt4U+mnjUt+WQ4+YpmZ8mxIv486ZsI -2GqNZVrtKE+p2llmXYIw87/NofMB+D5AfodYzjJElO+X4YQSkCQIcZOVyL2BDBs5 -D5SV7kNMb2fRDwK1/mmYBscfEw== ------END PRIVATE KEY----- diff --git a/install/email-configs/main.cf b/install/email-configs/main.cf deleted file mode 100644 index 86c305722..000000000 --- a/install/email-configs/main.cf +++ /dev/null @@ -1,66 +0,0 @@ -# Global Postfix configuration file. This file lists only a subset -# of all parameters. For the syntax, and for a complete parameter -# list, see the postconf(5) manual page (command: "man 5 postconf"). -# -# For common configuration examples, see BASIC_CONFIGURATION_README -# and STANDARD_CONFIGURATION_README. To find these documents, use -# the command "postconf html_directory readme_directory", or go to -# http://www.postfix.org/. -# -# For best results, change no more than 2-3 parameters at a time, -# and test if Postfix still works after every change. - - - -queue_directory = /var/spool/postfix -command_directory = /usr/sbin -daemon_directory = /usr/libexec/postfix -data_directory = /var/lib/postfix -mail_owner = postfix -inet_protocols = all -mydestination = localhost, localhost.localdomain, [::1] -unknown_local_recipient_reject_code = 550 -alias_maps = hash:/etc/aliases -alias_database = hash:/etc/aliases -debug_peer_level = 2 -debugger_command = - PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin - ddd $daemon_directory/$process_name $process_id & sleep 5 - -sendmail_path = /usr/sbin/sendmail.postfix -newaliases_path = /usr/bin/newaliases.postfix -mailq_path = /usr/bin/mailq.postfix -setgid_group = postdrop -html_directory = no -manpage_directory = /usr/share/man -sample_directory = /usr/share/doc/postfix-2.10.1/samples -readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES - - -myhostname = server.example.com -mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 -message_size_limit = 30720000 -virtual_alias_domains = -virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf -virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf -virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf -virtual_mailbox_base = /home/vmail -virtual_uid_maps = static:5000 -virtual_gid_maps = static:5000 -smtpd_sasl_type = dovecot -smtpd_sasl_path = private/auth -smtpd_sasl_auth_enable = yes -broken_sasl_auth_clients = yes -smtpd_sasl_authenticated_header = yes -smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination -smtpd_use_tls = yes -smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem -smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem -virtual_create_maildirsize = yes -virtual_maildir_extended = yes -proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps -virtual_transport = dovecot -dovecot_destination_recipient_limit = 1 -inet_interfaces = all -smtp_tls_security_level = may -disable_vrfy_command = yes \ No newline at end of file diff --git a/install/email-configs/master.cf b/install/email-configs/master.cf deleted file mode 100644 index cba284bc3..000000000 --- a/install/email-configs/master.cf +++ /dev/null @@ -1,129 +0,0 @@ -# -# Postfix master process configuration file. For details on the format -# of the file, see the master(5) manual page (command: "man 5 master"). -# -# Do not forget to execute "postfix reload" after editing this file. -# -# ========================================================================== -# service type private unpriv chroot wakeup maxproc command + args -# (yes) (yes) (yes) (never) (100) -# ========================================================================== -smtp inet n - n - - smtpd -#smtp inet n - n - 1 postscreen -#smtpd pass - - n - - smtpd -#dnsblog unix - - n - 0 dnsblog -#tlsproxy unix - - n - 0 tlsproxy -submission inet n - n - - smtpd - -o syslog_name=postfix/submission - -o smtpd_tls_security_level=encrypt - -o smtpd_sasl_auth_enable=yes - -o smtpd_reject_unlisted_recipient=no - -o smtpd_client_restrictions=$mua_client_restrictions - -o smtpd_helo_restrictions=$mua_helo_restrictions - -o smtpd_sender_restrictions=$mua_sender_restrictions - -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject - -o milter_macro_daemon_name=ORIGINATING -smtps inet n - n - - smtpd - -o syslog_name=postfix/smtps - -o smtpd_tls_wrappermode=yes - -o smtpd_sasl_auth_enable=yes - -o smtpd_reject_unlisted_recipient=no - -o smtpd_client_restrictions=$mua_client_restrictions - -o smtpd_helo_restrictions=$mua_helo_restrictions - -o smtpd_sender_restrictions=$mua_sender_restrictions - -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject - -o milter_macro_daemon_name=ORIGINATING -#628 inet n - n - - qmqpd -pickup unix n - n 60 1 pickup -cleanup unix n - n - 0 cleanup -qmgr unix n - n 300 1 qmgr -#qmgr unix n - n 300 1 oqmgr -tlsmgr unix - - n 1000? 1 tlsmgr -rewrite unix - - n - - trivial-rewrite -bounce unix - - n - 0 bounce -defer unix - - n - 0 bounce -trace unix - - n - 0 bounce -verify unix - - n - 1 verify -flush unix n - n 1000? 0 flush -proxymap unix - - n - - proxymap -proxywrite unix - - n - 1 proxymap -smtp unix - - n - - smtp -relay unix - - n - - smtp -# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 -showq unix n - n - - showq -error unix - - n - - error -retry unix - - n - - error -discard unix - - n - - discard -local unix - n n - - local -virtual unix - n n - - virtual -lmtp unix - - n - - lmtp -anvil unix - - n - 1 anvil -scache unix - - n - 1 scache -# -# ==================================================================== -# Interfaces to non-Postfix software. Be sure to examine the manual -# pages of the non-Postfix software to find out what options it wants. -# -# Many of the following services use the Postfix pipe(8) delivery -# agent. See the pipe(8) man page for information about ${recipient} -# and other message envelope options. -# ==================================================================== -# -# maildrop. See the Postfix MAILDROP_README file for details. -# Also specify in main.cf: maildrop_destination_recipient_limit=1 -# -#maildrop unix - n n - - pipe -# flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient} -# -# ==================================================================== -# -# Recent Cyrus versions can use the existing "lmtp" master.cf entry. -# -# Specify in cyrus.conf: -# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 -# -# Specify in main.cf one or more of the following: -# mailbox_transport = lmtp:inet:localhost -# virtual_transport = lmtp:inet:localhost -# -# ==================================================================== -# -# Cyrus 2.1.5 (Amos Gouaux) -# Also specify in main.cf: cyrus_destination_recipient_limit=1 -# -#cyrus unix - n n - - pipe -# user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -r ${sender} -m ${extension} ${user} -# -# ==================================================================== -# -# Old example of delivery via Cyrus. -# -#old-cyrus unix - n n - - pipe -# flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user} -# -# ==================================================================== -# -# See the Postfix UUCP_README file for configuration details. -# -#uucp unix - n n - - pipe -# flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) -# -# ==================================================================== -# -# Other external delivery methods. -# -#ifmail unix - n n - - pipe -# flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) -# -#bsmtp unix - n n - - pipe -# flags=Fq. user=bsmtp argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient -# -#scalemail-backend unix - n n - 2 pipe -# flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store -# ${nexthop} ${user} ${extension} -# -#mailman unix - n n - - pipe -# flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py -# ${nexthop} ${user} -dovecot unix - n n - - pipe - flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient} diff --git a/install/email-configs/mysql-virtual_domains.cf b/install/email-configs/mysql-virtual_domains.cf deleted file mode 100644 index d3f11296c..000000000 --- a/install/email-configs/mysql-virtual_domains.cf +++ /dev/null @@ -1,5 +0,0 @@ -user = cyberpanel -password = 1qaz@9xvps -dbname = cyberpanel -query = SELECT domain AS virtual FROM e_domains WHERE domain='%s' -hosts = 127.0.0.1:3307 diff --git a/install/email-configs/mysql-virtual_email2email.cf b/install/email-configs/mysql-virtual_email2email.cf deleted file mode 100644 index b4725be46..000000000 --- a/install/email-configs/mysql-virtual_email2email.cf +++ /dev/null @@ -1,5 +0,0 @@ -user = cyberpanel -password = 1qaz@9xvps -dbname = cyberpanel -query = SELECT email FROM e_users WHERE email='%s' -hosts = 127.0.0.1:3307 diff --git a/install/email-configs/mysql-virtual_forwardings.cf b/install/email-configs/mysql-virtual_forwardings.cf deleted file mode 100644 index 9aeeec71b..000000000 --- a/install/email-configs/mysql-virtual_forwardings.cf +++ /dev/null @@ -1,5 +0,0 @@ -user = cyberpanel -password = 1qaz@9xvps -dbname = cyberpanel -query = SELECT destination FROM e_forwardings WHERE source='%s' -hosts = 127.0.0.1:3307 diff --git a/install/email-configs/mysql-virtual_mailboxes.cf b/install/email-configs/mysql-virtual_mailboxes.cf deleted file mode 100644 index b8a018c35..000000000 --- a/install/email-configs/mysql-virtual_mailboxes.cf +++ /dev/null @@ -1,5 +0,0 @@ -user = cyberpanel -password = 1qaz@9xvps -dbname = cyberpanel -query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM e_users WHERE email='%s' -hosts = 127.0.0.1:3307 diff --git a/install/email-configs/relocated b/install/email-configs/relocated deleted file mode 100644 index 3fcab4cd4..000000000 --- a/install/email-configs/relocated +++ /dev/null @@ -1,171 +0,0 @@ -# RELOCATED(5) RELOCATED(5) -# -# NAME -# relocated - Postfix relocated table format -# -# SYNOPSIS -# postmap /etc/postfix/relocated -# -# DESCRIPTION -# The optional relocated(5) table provides the information -# that is used in "user has moved to new_location" bounce -# messages. -# -# Normally, the relocated(5) table is specified as a text -# file that serves as input to the postmap(1) command. The -# result, an indexed file in dbm or db format, is used for -# fast searching by the mail system. Execute the command -# "postmap /etc/postfix/relocated" to rebuild an indexed -# file after changing the corresponding relocated table. -# -# When the table is provided via other means such as NIS, -# LDAP or SQL, the same lookups are done as for ordinary -# indexed files. -# -# Alternatively, the table can be provided as a regular- -# expression map where patterns are given as regular expres- -# sions, or lookups can be directed to TCP-based server. In -# those case, the lookups are done in a slightly different -# way as described below under "REGULAR EXPRESSION TABLES" -# or "TCP-BASED TABLES". -# -# Table lookups are case insensitive. -# -# CASE FOLDING -# The search string is folded to lowercase before database -# lookup. As of Postfix 2.3, the search string is not case -# folded with database types such as regexp: or pcre: whose -# lookup fields can match both upper and lower case. -# -# TABLE FORMAT -# The input format for the postmap(1) command is as follows: -# -# o An entry has one of the following form: -# -# pattern new_location -# -# Where new_location specifies contact information -# such as an email address, or perhaps a street -# address or telephone number. -# -# o Empty lines and whitespace-only lines are ignored, -# as are lines whose first non-whitespace character -# is a `#'. -# -# o A logical line starts with non-whitespace text. A -# line that starts with whitespace continues a logi- -# cal line. -# -# TABLE SEARCH ORDER -# With lookups from indexed files such as DB or DBM, or from -# networked tables such as NIS, LDAP or SQL, patterns are -# tried in the order as listed below: -# -# user@domain -# Matches user@domain. This form has precedence over -# all other forms. -# -# user Matches user@site when site is $myorigin, when site -# is listed in $mydestination, or when site is listed -# in $inet_interfaces or $proxy_interfaces. -# -# @domain -# Matches other addresses in domain. This form has -# the lowest precedence. -# -# ADDRESS EXTENSION -# When a mail address localpart contains the optional recip- -# ient delimiter (e.g., user+foo@domain), the lookup order -# becomes: user+foo@domain, user@domain, user+foo, user, and -# @domain. -# -# REGULAR EXPRESSION TABLES -# This section describes how the table lookups change when -# the table is given in the form of regular expressions or -# when lookups are directed to a TCP-based server. For a -# description of regular expression lookup table syntax, see -# regexp_table(5) or pcre_table(5). For a description of the -# TCP client/server table lookup protocol, see tcp_table(5). -# This feature is not available up to and including Postfix -# version 2.4. -# -# Each pattern is a regular expression that is applied to -# the entire address being looked up. Thus, user@domain mail -# addresses are not broken up into their user and @domain -# constituent parts, nor is user+foo broken up into user and -# foo. -# -# Patterns are applied in the order as specified in the ta- -# ble, until a pattern is found that matches the search -# string. -# -# Results are the same as with indexed file lookups, with -# the additional feature that parenthesized substrings from -# the pattern can be interpolated as $1, $2 and so on. -# -# TCP-BASED TABLES -# This section describes how the table lookups change when -# lookups are directed to a TCP-based server. For a descrip- -# tion of the TCP client/server lookup protocol, see tcp_ta- -# ble(5). This feature is not available up to and including -# Postfix version 2.4. -# -# Each lookup operation uses the entire address once. Thus, -# user@domain mail addresses are not broken up into their -# user and @domain constituent parts, nor is user+foo broken -# up into user and foo. -# -# Results are the same as with indexed file lookups. -# -# BUGS -# The table format does not understand quoting conventions. -# -# CONFIGURATION PARAMETERS -# The following main.cf parameters are especially relevant. -# The text below provides only a parameter summary. See -# postconf(5) for more details including examples. -# -# relocated_maps -# List of lookup tables for relocated users or sites. -# -# Other parameters of interest: -# -# inet_interfaces -# The network interface addresses that this system -# receives mail on. You need to stop and start Post- -# fix when this parameter changes. -# -# mydestination -# List of domains that this mail system considers -# local. -# -# myorigin -# The domain that is appended to locally-posted mail. -# -# proxy_interfaces -# Other interfaces that this machine receives mail on -# by way of a proxy agent or network address transla- -# tor. -# -# SEE ALSO -# trivial-rewrite(8), address resolver -# postmap(1), Postfix lookup table manager -# postconf(5), configuration parameters -# -# README FILES -# Use "postconf readme_directory" or "postconf html_direc- -# tory" to locate this information. -# DATABASE_README, Postfix lookup table overview -# ADDRESS_REWRITING_README, address rewriting guide -# -# LICENSE -# The Secure Mailer license must be distributed with this -# software. -# -# AUTHOR(S) -# Wietse Venema -# IBM T.J. Watson Research -# P.O. Box 704 -# Yorktown Heights, NY 10598, USA -# -# RELOCATED(5) diff --git a/install/email-configs/transport b/install/email-configs/transport deleted file mode 100644 index 74c63ae0b..000000000 --- a/install/email-configs/transport +++ /dev/null @@ -1,294 +0,0 @@ -# TRANSPORT(5) TRANSPORT(5) -# -# NAME -# transport - Postfix transport table format -# -# SYNOPSIS -# postmap /etc/postfix/transport -# -# postmap -q "string" /etc/postfix/transport -# -# postmap -q - /etc/postfix/transport -1: # writeToFile.writelines( -# " $sCustomDataPath = '/usr/local/lscp/cyberpanel/rainloop/data';\n") +# " $sCustomDataPath = '/usr/local/lscp/cyberpanel/snappymail/data';\n") # else: # writeToFile.writelines(items) # @@ -4623,7 +4623,7 @@ user_query = SELECT email as user, password, 'vmail' as uid, 'vmail' as gid, '/h # # if os.path.exists(includeFileOldPath): # writeToFile = open(includeFileOldPath, 'a') -# writeToFile.write("\ndefine('APP_DATA_FOLDER_PATH', '/usr/local/lscp/cyberpanel/rainloop/data/');\n") +# writeToFile.write("\ndefine('APP_DATA_FOLDER_PATH', '/usr/local/lscp/cyberpanel/snappymail/data/');\n") # writeToFile.close() # # command = 'mv %s %s' % (includeFileOldPath, includeFileNewPath) @@ -4635,22 +4635,22 @@ user_query = SELECT email as user, password, 'vmail' as uid, 'vmail' as gid, '/h # # ### now download and install actual plugin # -# command = f'mkdir /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/plugins/mailbox-detect' +# command = f'mkdir /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/plugins/mailbox-detect' # preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) # -# command = f'chmod 700 /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/plugins/mailbox-detect' +# command = f'chmod 700 /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/plugins/mailbox-detect' # preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) # -# command = f'chmod 700 /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/plugins/mailbox-detect' +# command = f'chmod 700 /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/plugins/mailbox-detect' # preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) # -# command = f'wget -O /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/plugins/mailbox-detect/index.php https://raw.githubusercontent.com/the-djmaze/snappymail/master/plugins/mailbox-detect/index.php' +# command = f'wget -O /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/plugins/mailbox-detect/index.php https://raw.githubusercontent.com/the-djmaze/snappymail/master/plugins/mailbox-detect/index.php' # preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) # -# command = f'chmod 644 /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/plugins/mailbox-detect/index.php' +# command = f'chmod 644 /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/plugins/mailbox-detect/index.php' # preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) # -# command = f'chown lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/plugins/mailbox-detect/index.php' +# command = f'chown lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/plugins/mailbox-detect/index.php' # preFlightsChecks.call(command, self.distro, command, command, 1, 0, os.EX_OSERR) # # ### Enable plugins and enable mailbox creation plugin @@ -4674,7 +4674,7 @@ user_query = SELECT email as user, password, 'vmail' as uid, 'vmail' as gid, '/h # WriteToFile.close() # # ## enable auto create in the enabled plugin -# PluginsFilePath = '/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/plugin-mailbox-detect.json' +# PluginsFilePath = '/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/plugin-mailbox-detect.json' # # WriteToFile = open(PluginsFilePath, 'w') # WriteToFile.write("""{ diff --git a/install/php-configs/php.ini b/install/php-configs/php.ini deleted file mode 100644 index 984c0cbfb..000000000 --- a/install/php-configs/php.ini +++ /dev/null @@ -1,1835 +0,0 @@ -[PHP] - -;;;;;;;;;;;;;;;;;;; -; About php.ini ; -;;;;;;;;;;;;;;;;;;; -; PHP's initialization file, generally called php.ini, is responsible for -; configuring many of the aspects of PHP's behavior. - -; PHP attempts to find and load this configuration from a number of locations. -; The following is a summary of its search order: -; 1. SAPI module specific location. -; 2. The PHPRC environment variable. (As of PHP 5.2.0) -; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0) -; 4. Current working directory (except CLI) -; 5. The web server's directory (for SAPI modules), or directory of PHP -; (otherwise in Windows) -; 6. The directory from the --with-config-file-path compile time option, or the -; Windows directory (C:\windows or C:\winnt) -; See the PHP docs for more specific information. -; http://php.net/configuration.file - -; The syntax of the file is extremely simple. Whitespace and lines -; beginning with a semicolon are silently ignored (as you probably guessed). -; Section headers (e.g. [Foo]) are also silently ignored, even though -; they might mean something in the future. - -; Directives following the section heading [PATH=/www/mysite] only -; apply to PHP files in the /www/mysite directory. Directives -; following the section heading [HOST=www.example.com] only apply to -; PHP files served from www.example.com. Directives set in these -; special sections cannot be overridden by user-defined INI files or -; at runtime. Currently, [PATH=] and [HOST=] sections only work under -; CGI/FastCGI. -; http://php.net/ini.sections - -; Directives are specified using the following syntax: -; directive = value -; Directive names are *case sensitive* - foo=bar is different from FOO=bar. -; Directives are variables used to configure PHP or PHP extensions. -; There is no name validation. If PHP can't find an expected -; directive because it is not set or is mistyped, a default value will be used. - -; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one -; of the INI constants (On, Off, True, False, Yes, No and None) or an expression -; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a -; previously set variable or directive (e.g. ${foo}) - -; Expressions in the INI file are limited to bitwise operators and parentheses: -; | bitwise OR -; ^ bitwise XOR -; & bitwise AND -; ~ bitwise NOT -; ! boolean NOT - -; Boolean flags can be turned on using the values 1, On, True or Yes. -; They can be turned off using the values 0, Off, False or No. - -; An empty string can be denoted by simply not writing anything after the equal -; sign, or by using the None keyword: - -; foo = ; sets foo to an empty string -; foo = None ; sets foo to an empty string -; foo = "None" ; sets foo to the string 'None' - -; If you use constants in your value, and these constants belong to a -; dynamically loaded extension (either a PHP extension or a Zend extension), -; you may only use these constants *after* the line that loads the extension. - -;;;;;;;;;;;;;;;;;;; -; About this file ; -;;;;;;;;;;;;;;;;;;; -; PHP comes packaged with two INI files. One that is recommended to be used -; in production environments and one that is recommended to be used in -; development environments. - -; php.ini-production contains settings which hold security, performance and -; best practices at its core. But please be aware, these settings may break -; compatibility with older or less security conscience applications. We -; recommending using the production ini in production and testing environments. - -; php.ini-development is very similar to its production variant, except it is -; much more verbose when it comes to errors. We recommend using the -; development version only in development environments, as errors shown to -; application users can inadvertently leak otherwise secure information. - -; This is php.ini-production INI file. - -;;;;;;;;;;;;;;;;;;; -; Quick Reference ; -;;;;;;;;;;;;;;;;;;; -; The following are all the settings which are different in either the production -; or development versions of the INIs with respect to PHP's default behavior. -; Please see the actual settings later in the document for more details as to why -; we recommend these changes in PHP's behavior. - -; display_errors -; Default Value: On -; Development Value: On -; Production Value: Off - -; display_startup_errors -; Default Value: Off -; Development Value: On -; Production Value: Off - -; error_reporting -; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED -; Development Value: E_ALL -; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT - -; html_errors -; Default Value: On -; Development Value: On -; Production value: On - -; log_errors -; Default Value: Off -; Development Value: On -; Production Value: On - -; max_input_time -; Default Value: -1 (Unlimited) -; Development Value: 60 (60 seconds) -; Production Value: 60 (60 seconds) - -; output_buffering -; Default Value: Off -; Development Value: 4096 -; Production Value: 4096 - -; register_argc_argv -; Default Value: On -; Development Value: Off -; Production Value: Off - -; request_order -; Default Value: None -; Development Value: "GP" -; Production Value: "GP" - -; session.gc_divisor -; Default Value: 100 -; Development Value: 1000 -; Production Value: 1000 - -; session.hash_bits_per_character -; Default Value: 4 -; Development Value: 5 -; Production Value: 5 - -; short_open_tag -; Default Value: On -; Development Value: Off -; Production Value: Off - -; track_errors -; Default Value: Off -; Development Value: On -; Production Value: Off - -; url_rewriter.tags -; Default Value: "a=href,area=href,frame=src,form=,fieldset=" -; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry" - -; variables_order -; Default Value: "EGPCS" -; Development Value: "GPCS" -; Production Value: "GPCS" - -;;;;;;;;;;;;;;;;;;;; -; php.ini Options ; -;;;;;;;;;;;;;;;;;;;; -; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini" -;user_ini.filename = ".user.ini" - -; To disable this feature set this option to empty value -;user_ini.filename = - -; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes) -;user_ini.cache_ttl = 300 - -;;;;;;;;;;;;;;;;;;;; -; Language Options ; -;;;;;;;;;;;;;;;;;;;; - -; Enable the PHP scripting language engine under Apache. -; http://php.net/engine -engine = On - -; This directive determines whether or not PHP will recognize code between -; tags as PHP source which should be processed as such. It is -; generally recommended that should be used and that this feature -; should be disabled, as enabling it may result in issues when generating XML -; documents, however this remains supported for backward compatibility reasons. -; Note that this directive does not control the tags. -; http://php.net/asp-tags -asp_tags = Off - -; The number of significant digits displayed in floating point numbers. -; http://php.net/precision -precision = 14 - -; Output buffering is a mechanism for controlling how much output data -; (excluding headers and cookies) PHP should keep internally before pushing that -; data to the client. If your application's output exceeds this setting, PHP -; will send that data in chunks of roughly the size you specify. -; Turning on this setting and managing its maximum buffer size can yield some -; interesting side-effects depending on your application and web server. -; You may be able to send headers and cookies after you've already sent output -; through print or echo. You also may see performance benefits if your server is -; emitting less packets due to buffered output versus PHP streaming the output -; as it gets it. On production servers, 4096 bytes is a good setting for performance -; reasons. -; Note: Output buffering can also be controlled via Output Buffering Control -; functions. -; Possible Values: -; On = Enabled and buffer is unlimited. (Use with caution) -; Off = Disabled -; Integer = Enables the buffer and sets its maximum size in bytes. -; Note: This directive is hardcoded to Off for the CLI SAPI -; Default Value: Off -; Development Value: 4096 -; Production Value: 4096 -; http://php.net/output-buffering -output_buffering = 4096 - -; You can redirect all of the output of your scripts to a function. For -; example, if you set output_handler to "mb_output_handler", character -; encoding will be transparently converted to the specified encoding. -; Setting any output handler automatically turns on output buffering. -; Note: People who wrote portable scripts should not depend on this ini -; directive. Instead, explicitly set the output handler using ob_start(). -; Using this ini directive may cause problems unless you know what script -; is doing. -; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler" -; and you cannot use both "ob_gzhandler" and "zlib.output_compression". -; Note: output_handler must be empty if this is set 'On' !!!! -; Instead you must use zlib.output_handler. -; http://php.net/output-handler -;output_handler = - -; Transparent output compression using the zlib library -; Valid values for this option are 'off', 'on', or a specific buffer size -; to be used for compression (default is 4KB) -; Note: Resulting chunk size may vary due to nature of compression. PHP -; outputs chunks that are few hundreds bytes each as a result of -; compression. If you prefer a larger chunk size for better -; performance, enable output_buffering in addition. -; Note: You need to use zlib.output_handler instead of the standard -; output_handler, or otherwise the output will be corrupted. -; http://php.net/zlib.output-compression -zlib.output_compression = Off - -; http://php.net/zlib.output-compression-level -;zlib.output_compression_level = -1 - -; You cannot specify additional output handlers if zlib.output_compression -; is activated here. This setting does the same as output_handler but in -; a different order. -; http://php.net/zlib.output-handler -;zlib.output_handler = - -; Implicit flush tells PHP to tell the output layer to flush itself -; automatically after every output block. This is equivalent to calling the -; PHP function flush() after each and every call to print() or echo() and each -; and every HTML block. Turning this option on has serious performance -; implications and is generally recommended for debugging purposes only. -; http://php.net/implicit-flush -; Note: This directive is hardcoded to On for the CLI SAPI -implicit_flush = Off - -; The unserialize callback function will be called (with the undefined class' -; name as parameter), if the unserializer finds an undefined class -; which should be instantiated. A warning appears if the specified function is -; not defined, or if the function doesn't include/implement the missing class. -; So only set this entry, if you really want to implement such a -; callback-function. -unserialize_callback_func = - -; When floats & doubles are serialized store serialize_precision significant -; digits after the floating point. The default value ensures that when floats -; are decoded with unserialize, the data will remain the same. -serialize_precision = 17 - -; open_basedir, if set, limits all file operations to the defined directory -; and below. This directive makes most sense if used in a per-directory -; or per-virtualhost web server configuration file. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://php.net/open-basedir -;open_basedir = - -; This directive allows you to disable certain functions for security reasons. -; It receives a comma-delimited list of function names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://php.net/disable-functions -disable_functions = - -; This directive allows you to disable certain classes for security reasons. -; It receives a comma-delimited list of class names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://php.net/disable-classes -disable_classes = - -; Colors for Syntax Highlighting mode. Anything that's acceptable in -; would work. -; http://php.net/syntax-highlighting -;highlight.string = #DD0000 -;highlight.comment = #FF9900 -;highlight.keyword = #007700 -;highlight.default = #0000BB -;highlight.html = #000000 - -; If enabled, the request will be allowed to complete even if the user aborts -; the request. Consider enabling it if executing long requests, which may end up -; being interrupted by the user or a browser timing out. PHP's default behavior -; is to disable this feature. -; http://php.net/ignore-user-abort -;ignore_user_abort = On - -; Determines the size of the realpath cache to be used by PHP. This value should -; be increased on systems where PHP opens many files to reflect the quantity of -; the file operations performed. -; http://php.net/realpath-cache-size -;realpath_cache_size = 16k - -; Duration of time, in seconds for which to cache realpath information for a given -; file or directory. For systems with rarely changing files, consider increasing this -; value. -; http://php.net/realpath-cache-ttl -;realpath_cache_ttl = 120 - -; Enables or disables the circular reference collector. -; http://php.net/zend.enable-gc -zend.enable_gc = On - -; If enabled, scripts may be written in encodings that are incompatible with -; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such -; encodings. To use this feature, mbstring extension must be enabled. -; Default: Off -;zend.multibyte = Off - -; Allows to set the default encoding for the scripts. This value will be used -; unless "declare(encoding=...)" directive appears at the top of the script. -; Only affects if zend.multibyte is set. -; Default: "" -;zend.script_encoding = - -;;;;;;;;;;;;;;;;; -; Miscellaneous ; -;;;;;;;;;;;;;;;;; - -; Decides whether PHP may expose the fact that it is installed on the server -; (e.g. by adding its signature to the Web server header). It is no security -; threat in any way, but it makes it possible to determine whether you use PHP -; on your server or not. -; http://php.net/expose-php -expose_php = On - -;;;;;;;;;;;;;;;;;;; -; Resource Limits ; -;;;;;;;;;;;;;;;;;;; - -; Maximum execution time of each script, in seconds -; http://php.net/max-execution-time -; Note: This directive is hardcoded to 0 for the CLI SAPI -max_execution_time = 30 - -; Maximum amount of time each script may spend parsing request data. It's a good -; idea to limit this time on productions servers in order to eliminate unexpectedly -; long running scripts. -; Note: This directive is hardcoded to -1 for the CLI SAPI -; Default Value: -1 (Unlimited) -; Development Value: 60 (60 seconds) -; Production Value: 60 (60 seconds) -; http://php.net/max-input-time -max_input_time = 60 - -; Maximum input variable nesting level -; http://php.net/max-input-nesting-level -;max_input_nesting_level = 64 - -; How many GET/POST/COOKIE input variables may be accepted -; max_input_vars = 1000 - -; Maximum amount of memory a script may consume (128MB) -; http://php.net/memory-limit -memory_limit = 256M - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Error handling and logging ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; This directive informs PHP of which errors, warnings and notices you would like -; it to take action for. The recommended way of setting values for this -; directive is through the use of the error level constants and bitwise -; operators. The error level constants are below here for convenience as well as -; some common settings and their meanings. -; By default, PHP is set to take action on all errors, notices and warnings EXCEPT -; those related to E_NOTICE and E_STRICT, which together cover best practices and -; recommended coding standards in PHP. For performance reasons, this is the -; recommend error reporting setting. Your production server shouldn't be wasting -; resources complaining about best practices and coding standards. That's what -; development servers and development settings are for. -; Note: The php.ini-development file has this setting as E_ALL. This -; means it pretty much reports everything which is exactly what you want during -; development and early testing. -; -; Error Level Constants: -; E_ALL - All errors and warnings (includes E_STRICT as of PHP 5.4.0) -; E_ERROR - fatal run-time errors -; E_RECOVERABLE_ERROR - almost fatal run-time errors -; E_WARNING - run-time warnings (non-fatal errors) -; E_PARSE - compile-time parse errors -; E_NOTICE - run-time notices (these are warnings which often result -; from a bug in your code, but it's possible that it was -; intentional (e.g., using an uninitialized variable and -; relying on the fact it is automatically initialized to an -; empty string) -; E_STRICT - run-time notices, enable to have PHP suggest changes -; to your code which will ensure the best interoperability -; and forward compatibility of your code -; E_CORE_ERROR - fatal errors that occur during PHP's initial startup -; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's -; initial startup -; E_COMPILE_ERROR - fatal compile-time errors -; E_COMPILE_WARNING - compile-time warnings (non-fatal errors) -; E_USER_ERROR - user-generated error message -; E_USER_WARNING - user-generated warning message -; E_USER_NOTICE - user-generated notice message -; E_DEPRECATED - warn about code that will not work in future versions -; of PHP -; E_USER_DEPRECATED - user-generated deprecation warnings -; -; Common Values: -; E_ALL (Show all errors, warnings and notices including coding standards.) -; E_ALL & ~E_NOTICE (Show all errors, except for notices) -; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.) -; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors) -; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED -; Development Value: E_ALL -; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT -; http://php.net/error-reporting -error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT - -; This directive controls whether or not and where PHP will output errors, -; notices and warnings too. Error output is very useful during development, but -; it could be very dangerous in production environments. Depending on the code -; which is triggering the error, sensitive information could potentially leak -; out of your application such as database usernames and passwords or worse. -; For production environments, we recommend logging errors rather than -; sending them to STDOUT. -; Possible Values: -; Off = Do not display any errors -; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) -; On or stdout = Display errors to STDOUT -; Default Value: On -; Development Value: On -; Production Value: Off -; http://php.net/display-errors -display_errors = Off - -; The display of errors which occur during PHP's startup sequence are handled -; separately from display_errors. PHP's default behavior is to suppress those -; errors from clients. Turning the display of startup errors on can be useful in -; debugging configuration problems. We strongly recommend you -; set this to 'off' for production servers. -; Default Value: Off -; Development Value: On -; Production Value: Off -; http://php.net/display-startup-errors -display_startup_errors = Off - -; Besides displaying errors, PHP can also log errors to locations such as a -; server-specific log, STDERR, or a location specified by the error_log -; directive found below. While errors should not be displayed on productions -; servers they should still be monitored and logging is a great way to do that. -; Default Value: Off -; Development Value: On -; Production Value: On -; http://php.net/log-errors -log_errors = On - -; Set maximum length of log_errors. In error_log information about the source is -; added. The default is 1024 and 0 allows to not apply any maximum length at all. -; http://php.net/log-errors-max-len -log_errors_max_len = 1024 - -; Do not log repeated messages. Repeated errors must occur in same file on same -; line unless ignore_repeated_source is set true. -; http://php.net/ignore-repeated-errors -ignore_repeated_errors = Off - -; Ignore source of message when ignoring repeated messages. When this setting -; is On you will not log errors with repeated messages from different files or -; source lines. -; http://php.net/ignore-repeated-source -ignore_repeated_source = Off - -; If this parameter is set to Off, then memory leaks will not be shown (on -; stdout or in the log). This has only effect in a debug compile, and if -; error reporting includes E_WARNING in the allowed list -; http://php.net/report-memleaks -report_memleaks = On - -; This setting is on by default. -;report_zend_debug = 0 - -; Store the last error/warning message in $php_errormsg (boolean). Setting this value -; to On can assist in debugging and is appropriate for development servers. It should -; however be disabled on production servers. -; Default Value: Off -; Development Value: On -; Production Value: Off -; http://php.net/track-errors -track_errors = Off - -; Turn off normal error reporting and emit XML-RPC error XML -; http://php.net/xmlrpc-errors -;xmlrpc_errors = 0 - -; An XML-RPC faultCode -;xmlrpc_error_number = 0 - -; When PHP displays or logs an error, it has the capability of formatting the -; error message as HTML for easier reading. This directive controls whether -; the error message is formatted as HTML or not. -; Note: This directive is hardcoded to Off for the CLI SAPI -; Default Value: On -; Development Value: On -; Production value: On -; http://php.net/html-errors -html_errors = On - -; If html_errors is set to On *and* docref_root is not empty, then PHP -; produces clickable error messages that direct to a page describing the error -; or function causing the error in detail. -; You can download a copy of the PHP manual from http://php.net/docs -; and change docref_root to the base URL of your local copy including the -; leading '/'. You must also specify the file extension being used including -; the dot. PHP's default behavior is to leave these settings empty, in which -; case no links to documentation are generated. -; Note: Never use this feature for production boxes. -; http://php.net/docref-root -; Examples -;docref_root = "/phpmanual/" - -; http://php.net/docref-ext -;docref_ext = .html - -; String to output before an error message. PHP's default behavior is to leave -; this setting blank. -; http://php.net/error-prepend-string -; Example: -;error_prepend_string = "" - -; String to output after an error message. PHP's default behavior is to leave -; this setting blank. -; http://php.net/error-append-string -; Example: -;error_append_string = "" - -; Log errors to specified file. PHP's default behavior is to leave this value -; empty. -; http://php.net/error-log -; Example: -;error_log = php_errors.log -; Log errors to syslog. -;error_log = syslog - -;windows.show_crt_warning -; Default value: 0 -; Development value: 0 -; Production value: 0 - -;;;;;;;;;;;;;;;;; -; Data Handling ; -;;;;;;;;;;;;;;;;; - -; The separator used in PHP generated URLs to separate arguments. -; PHP's default setting is "&". -; http://php.net/arg-separator.output -; Example: -;arg_separator.output = "&" - -; List of separator(s) used by PHP to parse input URLs into variables. -; PHP's default setting is "&". -; NOTE: Every character in this directive is considered as separator! -; http://php.net/arg-separator.input -; Example: -;arg_separator.input = ";&" - -; This directive determines which super global arrays are registered when PHP -; starts up. G,P,C,E & S are abbreviations for the following respective super -; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty -; paid for the registration of these arrays and because ENV is not as commonly -; used as the others, ENV is not recommended on productions servers. You -; can still get access to the environment variables through getenv() should you -; need to. -; Default Value: "EGPCS" -; Development Value: "GPCS" -; Production Value: "GPCS"; -; http://php.net/variables-order -variables_order = "GPCS" - -; This directive determines which super global data (G,P,C,E & S) should -; be registered into the super global array REQUEST. If so, it also determines -; the order in which that data is registered. The values for this directive are -; specified in the same manner as the variables_order directive, EXCEPT one. -; Leaving this value empty will cause PHP to use the value set in the -; variables_order directive. It does not mean it will leave the super globals -; array REQUEST empty. -; Default Value: None -; Development Value: "GP" -; Production Value: "GP" -; http://php.net/request-order -request_order = "GP" - -; This directive determines whether PHP registers $argv & $argc each time it -; runs. $argv contains an array of all the arguments passed to PHP when a script -; is invoked. $argc contains an integer representing the number of arguments -; that were passed when the script was invoked. These arrays are extremely -; useful when running scripts from the command line. When this directive is -; enabled, registering these variables consumes CPU cycles and memory each time -; a script is executed. For performance reasons, this feature should be disabled -; on production servers. -; Note: This directive is hardcoded to On for the CLI SAPI -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://php.net/register-argc-argv -register_argc_argv = Off - -; When enabled, the ENV, REQUEST and SERVER variables are created when they're -; first used (Just In Time) instead of when the script starts. If these -; variables are not used within a script, having this directive on will result -; in a performance gain. The PHP directive register_argc_argv must be disabled -; for this directive to have any affect. -; http://php.net/auto-globals-jit -auto_globals_jit = On - -; Whether PHP will read the POST data. -; This option is enabled by default. -; Most likely, you won't want to disable this option globally. It causes $_POST -; and $_FILES to always be empty; the only way you will be able to read the -; POST data will be through the php://input stream wrapper. This can be useful -; to proxy requests or to process the POST data in a memory efficient fashion. -; http://php.net/enable-post-data-reading -;enable_post_data_reading = Off - -; Maximum size of POST data that PHP will accept. -; Its value may be 0 to disable the limit. It is ignored if POST data reading -; is disabled through enable_post_data_reading. -; http://php.net/post-max-size -post_max_size = 20M - -; Automatically add files before PHP document. -; http://php.net/auto-prepend-file -auto_prepend_file = - -; Automatically add files after PHP document. -; http://php.net/auto-append-file -auto_append_file = - -; By default, PHP will output a character encoding using -; the Content-type: header. To disable sending of the charset, simply -; set it to be empty. -; -; PHP's built-in default is text/html -; http://php.net/default-mimetype -default_mimetype = "text/html" - -; PHP's default character set is set to empty. -; http://php.net/default-charset -default_charset = "UTF-8" - -; PHP internal character encoding is set to empty. -; If empty, default_charset is used. -; http://php.net/internal-encoding -;internal_encoding = - -; PHP input character encoding is set to empty. -; http://php.net/input-encoding -;input_encoding = - -; PHP output character encoding is set to empty. -; mbstring or iconv output handler is used. -; See also output_buffer. -; http://php.net/output-encoding -;output_encoding = - -; Always populate the $HTTP_RAW_POST_DATA variable. PHP's default behavior is -; to disable this feature and it will be removed in a future version. -; If post reading is disabled through enable_post_data_reading, -; $HTTP_RAW_POST_DATA is *NOT* populated. -; http://php.net/always-populate-raw-post-data -;always_populate_raw_post_data = -1 - -;;;;;;;;;;;;;;;;;;;;;;;;; -; Paths and Directories ; -;;;;;;;;;;;;;;;;;;;;;;;;; - -; UNIX: "/path1:/path2" -;include_path = ".:/php/includes" -; -; Windows: "\path1;\path2" -;include_path = ".;c:\php\includes" -; -; PHP's default setting for include_path is ".;/path/to/php/pear" -; http://php.net/include-path - -; The root of the PHP pages, used only if nonempty. -; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root -; if you are running php as a CGI under any web server (other than IIS) -; see documentation for security issues. The alternate is to use the -; cgi.force_redirect configuration below -; http://php.net/doc-root -doc_root = - -; The directory under which PHP opens the script using /~username used only -; if nonempty. -; http://php.net/user-dir -user_dir = - -; Directory in which the loadable extensions (modules) reside. -; http://php.net/extension-dir -; extension_dir = "./" -; On windows: -; extension_dir = "ext" - -; Directory where the temporary files should be placed. -; Defaults to the system default (see sys_get_temp_dir) -; sys_temp_dir = "/tmp" - -; Whether or not to enable the dl() function. The dl() function does NOT work -; properly in multithreaded servers, such as IIS or Zeus, and is automatically -; disabled on them. -; http://php.net/enable-dl -enable_dl = Off - -; cgi.force_redirect is necessary to provide security running PHP as a CGI under -; most web servers. Left undefined, PHP turns this on by default. You can -; turn it off here AT YOUR OWN RISK -; **You CAN safely turn this off for IIS, in fact, you MUST.** -; http://php.net/cgi.force-redirect -;cgi.force_redirect = 1 - -; if cgi.nph is enabled it will force cgi to always sent Status: 200 with -; every request. PHP's default behavior is to disable this feature. -;cgi.nph = 1 - -; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape -; (iPlanet) web servers, you MAY need to set an environment variable name that PHP -; will look for to know it is OK to continue execution. Setting this variable MAY -; cause security issues, KNOW WHAT YOU ARE DOING FIRST. -; http://php.net/cgi.redirect-status-env -;cgi.redirect_status_env = - -; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's -; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok -; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting -; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting -; of zero causes PHP to behave as before. Default is 1. You should fix your scripts -; to use SCRIPT_FILENAME rather than PATH_TRANSLATED. -; http://php.net/cgi.fix-pathinfo -;cgi.fix_pathinfo=1 - -; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate -; security tokens of the calling client. This allows IIS to define the -; security context that the request runs under. mod_fastcgi under Apache -; does not currently support this feature (03/17/2002) -; Set to 1 if running under IIS. Default is zero. -; http://php.net/fastcgi.impersonate -;fastcgi.impersonate = 1 - -; Disable logging through FastCGI connection. PHP's default behavior is to enable -; this feature. -;fastcgi.logging = 0 - -; cgi.rfc2616_headers configuration option tells PHP what type of headers to -; use when sending HTTP response code. If set to 0, PHP sends Status: header that -; is supported by Apache. When this option is set to 1, PHP will send -; RFC2616 compliant header. -; Default is zero. -; http://php.net/cgi.rfc2616-headers -;cgi.rfc2616_headers = 0 - -;;;;;;;;;;;;;;;; -; File Uploads ; -;;;;;;;;;;;;;;;; - -; Whether to allow HTTP file uploads. -; http://php.net/file-uploads -file_uploads = On - -; Temporary directory for HTTP uploaded files (will use system default if not -; specified). -; http://php.net/upload-tmp-dir -;upload_tmp_dir = - -; Maximum allowed size for uploaded files. -; http://php.net/upload-max-filesize -upload_max_filesize = 20M - -; Maximum number of files that can be uploaded via a single request -max_file_uploads = 20 - -;;;;;;;;;;;;;;;;;; -; Fopen wrappers ; -;;;;;;;;;;;;;;;;;; - -; Whether to allow the treatment of URLs (like http:// or ftp://) as files. -; http://php.net/allow-url-fopen -allow_url_fopen = On - -; Whether to allow include/require to open URLs (like http:// or ftp://) as files. -; http://php.net/allow-url-include -allow_url_include = Off - -; Define the anonymous ftp password (your email address). PHP's default setting -; for this is empty. -; http://php.net/from -;from="john@doe.com" - -; Define the User-Agent string. PHP's default setting for this is empty. -; http://php.net/user-agent -;user_agent="PHP" - -; Default timeout for socket based streams (seconds) -; http://php.net/default-socket-timeout -default_socket_timeout = 60 - -; If your scripts have to deal with files from Macintosh systems, -; or you are running on a Mac and need to deal with files from -; unix or win32 systems, setting this flag will cause PHP to -; automatically detect the EOL character in those files so that -; fgets() and file() will work regardless of the source of the file. -; http://php.net/auto-detect-line-endings -;auto_detect_line_endings = Off - -;;;;;;;;;;;;;;;;;;;;;; -; Dynamic Extensions ; -;;;;;;;;;;;;;;;;;;;;;; - -; If you wish to have an extension loaded automatically, use the following -; syntax: -; -; extension=modulename.extension -; -; For example, on Windows: -; -; extension=msql.dll -; -; ... or under UNIX: -; -; extension=msql.so -; -; ... or with a path: -; -; extension=/path/to/extension/msql.so -; -; If you only provide the name of the extension, PHP will look for it in its -; default extension directory. - -;;;; -; Note: packaged extension modules are now loaded via the .ini files -; found in the directory /etc/php.d; these are loaded by default. -;;;; - -;;;;;;;;;;;;;;;;;;; -; Module Settings ; -;;;;;;;;;;;;;;;;;;; - -[CLI Server] -; Whether the CLI web server uses ANSI color coding in its terminal output. -cli_server.color = On - -[Date] -; Defines the default timezone used by the date functions -; http://php.net/date.timezone -;date.timezone = -date.timezone = UTC - -; http://php.net/date.default-latitude -;date.default_latitude = 31.7667 - -; http://php.net/date.default-longitude -;date.default_longitude = 35.2333 - -; http://php.net/date.sunrise-zenith -;date.sunrise_zenith = 90.583333 - -; http://php.net/date.sunset-zenith -;date.sunset_zenith = 90.583333 - -[filter] -; http://php.net/filter.default -;filter.default = unsafe_raw - -; http://php.net/filter.default-flags -;filter.default_flags = - -[iconv] -; Use of this INI entry is deprecated, use global input_encoding instead. -; If empty, default_charset or input_encoding or iconv.input_encoding is used. -; The precedence is: default_charset < intput_encoding < iconv.input_encoding -;iconv.input_encoding = - -; Use of this INI entry is deprecated, use global internal_encoding instead. -; If empty, default_charset or internal_encoding or iconv.internal_encoding is used. -; The precedence is: default_charset < internal_encoding < iconv.internal_encoding -;iconv.internal_encoding = - -; Use of this INI entry is deprecated, use global output_encoding instead. -; If empty, default_charset or output_encoding or iconv.output_encoding is used. -; The precedence is: default_charset < output_encoding < iconv.output_encoding -; To use an output encoding conversion, iconv's output handler must be set -; otherwise output encoding conversion cannot be performed. -;iconv.output_encoding = - -[intl] -;intl.default_locale = -; This directive allows you to produce PHP errors when some error -; happens within intl functions. The value is the level of the error produced. -; Default is 0, which does not produce any errors. -;intl.error_level = E_WARNING - -[sqlite] -; http://php.net/sqlite.assoc-case -;sqlite.assoc_case = 0 - -[sqlite3] -;sqlite3.extension_dir = - -[Pcre] -;PCRE library backtracking limit. -; http://php.net/pcre.backtrack-limit -;pcre.backtrack_limit=100000 - -;PCRE library recursion limit. -;Please note that if you set this value to a high number you may consume all -;the available process stack and eventually crash PHP (due to reaching the -;stack size limit imposed by the Operating System). -; http://php.net/pcre.recursion-limit -;pcre.recursion_limit=100000 - -[Pdo] -; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off" -; http://php.net/pdo-odbc.connection-pooling -;pdo_odbc.connection_pooling=strict - -;pdo_odbc.db2_instance_name - -[Pdo_mysql] -; If mysqlnd is used: Number of cache slots for the internal result set cache -; http://php.net/pdo_mysql.cache_size -pdo_mysql.cache_size = 2000 - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -; http://php.net/pdo_mysql.default-socket -pdo_mysql.default_socket= - -[Phar] -; http://php.net/phar.readonly -;phar.readonly = On - -; http://php.net/phar.require-hash -;phar.require_hash = On - -;phar.cache_list = - -[mail function] -; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). -; http://php.net/sendmail-path -sendmail_path = /usr/sbin/sendmail -t -i - -; Force the addition of the specified parameters to be passed as extra parameters -; to the sendmail binary. These parameters will always replace the value of -; the 5th parameter to mail(), even in safe mode. -;mail.force_extra_parameters = - -; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename -mail.add_x_header = On - -; The path to a log file that will log all mail() calls. Log entries include -; the full path of the script, line number, To address and headers. -;mail.log = -; Log mail to syslog; -;mail.log = syslog - -[SQL] -; http://php.net/sql.safe-mode -sql.safe_mode = Off - -[ODBC] -; http://php.net/odbc.default-db -;odbc.default_db = Not yet implemented - -; http://php.net/odbc.default-user -;odbc.default_user = Not yet implemented - -; http://php.net/odbc.default-pw -;odbc.default_pw = Not yet implemented - -; Controls the ODBC cursor model. -; Default: SQL_CURSOR_STATIC (default). -;odbc.default_cursortype - -; Allow or prevent persistent links. -; http://php.net/odbc.allow-persistent -odbc.allow_persistent = On - -; Check that a connection is still valid before reuse. -; http://php.net/odbc.check-persistent -odbc.check_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://php.net/odbc.max-persistent -odbc.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://php.net/odbc.max-links -odbc.max_links = -1 - -; Handling of LONG fields. Returns number of bytes to variables. 0 means -; passthru. -; http://php.net/odbc.defaultlrl -odbc.defaultlrl = 4096 - -; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char. -; See the documentation on odbc_binmode and odbc_longreadlen for an explanation -; of odbc.defaultlrl and odbc.defaultbinmode -; http://php.net/odbc.defaultbinmode -odbc.defaultbinmode = 1 - -;birdstep.max_links = -1 - -[Interbase] -; Allow or prevent persistent links. -ibase.allow_persistent = 1 - -; Maximum number of persistent links. -1 means no limit. -ibase.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -ibase.max_links = -1 - -; Default database name for ibase_connect(). -;ibase.default_db = - -; Default username for ibase_connect(). -;ibase.default_user = - -; Default password for ibase_connect(). -;ibase.default_password = - -; Default charset for ibase_connect(). -;ibase.default_charset = - -; Default timestamp format. -ibase.timestampformat = "%Y-%m-%d %H:%M:%S" - -; Default date format. -ibase.dateformat = "%Y-%m-%d" - -; Default time format. -ibase.timeformat = "%H:%M:%S" - -[MySQL] -; Allow accessing, from PHP's perspective, local files with LOAD DATA statements -; http://php.net/mysql.allow_local_infile -mysql.allow_local_infile = On - -; Allow or prevent persistent links. -; http://php.net/mysql.allow-persistent -mysql.allow_persistent = On - -; If mysqlnd is used: Number of cache slots for the internal result set cache -; http://php.net/mysql.cache_size -mysql.cache_size = 2000 - -; Maximum number of persistent links. -1 means no limit. -; http://php.net/mysql.max-persistent -mysql.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://php.net/mysql.max-links -mysql.max_links = -1 - -; Default port number for mysql_connect(). If unset, mysql_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -; http://php.net/mysql.default-port -mysql.default_port = - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -; http://php.net/mysql.default-socket -mysql.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -; http://php.net/mysql.default-host -mysql.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -; http://php.net/mysql.default-user -mysql.default_user = - -; Default password for mysql_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysql.default_password") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -; http://php.net/mysql.default-password -mysql.default_password = - -; Maximum time (in seconds) for connect timeout. -1 means no limit -; http://php.net/mysql.connect-timeout -mysql.connect_timeout = 60 - -; Trace mode. When trace_mode is active (=On), warnings for table/index scans and -; SQL-Errors will be displayed. -; http://php.net/mysql.trace-mode -mysql.trace_mode = Off - -[MySQLi] - -; Maximum number of persistent links. -1 means no limit. -; http://php.net/mysqli.max-persistent -mysqli.max_persistent = -1 - -; Allow accessing, from PHP's perspective, local files with LOAD DATA statements -; http://php.net/mysqli.allow_local_infile -;mysqli.allow_local_infile = On - -; Allow or prevent persistent links. -; http://php.net/mysqli.allow-persistent -mysqli.allow_persistent = On - -; Maximum number of links. -1 means no limit. -; http://php.net/mysqli.max-links -mysqli.max_links = -1 - -; If mysqlnd is used: Number of cache slots for the internal result set cache -; http://php.net/mysqli.cache_size -mysqli.cache_size = 2000 - -; Default port number for mysqli_connect(). If unset, mysqli_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -; http://php.net/mysqli.default-port -mysqli.default_port = 3306 - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -; http://php.net/mysqli.default-socket -mysqli.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -; http://php.net/mysqli.default-host -mysqli.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -; http://php.net/mysqli.default-user -mysqli.default_user = - -; Default password for mysqli_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -; http://php.net/mysqli.default-pw -mysqli.default_pw = - -; Allow or prevent reconnect -mysqli.reconnect = Off - -[mysqlnd] -; Enable / Disable collection of general statistics by mysqlnd which can be -; used to tune and monitor MySQL operations. -; http://php.net/mysqlnd.collect_statistics -mysqlnd.collect_statistics = On - -; Enable / Disable collection of memory usage statistics by mysqlnd which can be -; used to tune and monitor MySQL operations. -; http://php.net/mysqlnd.collect_memory_statistics -mysqlnd.collect_memory_statistics = Off - -; Size of a pre-allocated buffer used when sending commands to MySQL in bytes. -; http://php.net/mysqlnd.net_cmd_buffer_size -;mysqlnd.net_cmd_buffer_size = 2048 - -; Size of a pre-allocated buffer used for reading data sent by the server in -; bytes. -; http://php.net/mysqlnd.net_read_buffer_size -;mysqlnd.net_read_buffer_size = 32768 - -[OCI8] - -; Connection: Enables privileged connections using external -; credentials (OCI_SYSOPER, OCI_SYSDBA) -; http://php.net/oci8.privileged-connect -;oci8.privileged_connect = Off - -; Connection: The maximum number of persistent OCI8 connections per -; process. Using -1 means no limit. -; http://php.net/oci8.max-persistent -;oci8.max_persistent = -1 - -; Connection: The maximum number of seconds a process is allowed to -; maintain an idle persistent connection. Using -1 means idle -; persistent connections will be maintained forever. -; http://php.net/oci8.persistent-timeout -;oci8.persistent_timeout = -1 - -; Connection: The number of seconds that must pass before issuing a -; ping during oci_pconnect() to check the connection validity. When -; set to 0, each oci_pconnect() will cause a ping. Using -1 disables -; pings completely. -; http://php.net/oci8.ping-interval -;oci8.ping_interval = 60 - -; Connection: Set this to a user chosen connection class to be used -; for all pooled server requests with Oracle 11g Database Resident -; Connection Pooling (DRCP). To use DRCP, this value should be set to -; the same string for all web servers running the same application, -; the database pool must be configured, and the connection string must -; specify to use a pooled server. -;oci8.connection_class = - -; High Availability: Using On lets PHP receive Fast Application -; Notification (FAN) events generated when a database node fails. The -; database must also be configured to post FAN events. -;oci8.events = Off - -; Tuning: This option enables statement caching, and specifies how -; many statements to cache. Using 0 disables statement caching. -; http://php.net/oci8.statement-cache-size -;oci8.statement_cache_size = 20 - -; Tuning: Enables statement prefetching and sets the default number of -; rows that will be fetched automatically after statement execution. -; http://php.net/oci8.default-prefetch -;oci8.default_prefetch = 100 - -; Compatibility. Using On means oci_close() will not close -; oci_connect() and oci_new_connect() connections. -; http://php.net/oci8.old-oci-close-semantics -;oci8.old_oci_close_semantics = Off - -[PostgreSQL] -; Allow or prevent persistent links. -; http://php.net/pgsql.allow-persistent -pgsql.allow_persistent = On - -; Detect broken persistent links always with pg_pconnect(). -; Auto reset feature requires a little overheads. -; http://php.net/pgsql.auto-reset-persistent -pgsql.auto_reset_persistent = Off - -; Maximum number of persistent links. -1 means no limit. -; http://php.net/pgsql.max-persistent -pgsql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -; http://php.net/pgsql.max-links -pgsql.max_links = -1 - -; Ignore PostgreSQL backends Notice message or not. -; Notice message logging require a little overheads. -; http://php.net/pgsql.ignore-notice -pgsql.ignore_notice = 0 - -; Log PostgreSQL backends Notice message or not. -; Unless pgsql.ignore_notice=0, module cannot log notice message. -; http://php.net/pgsql.log-notice -pgsql.log_notice = 0 - -[Sybase-CT] -; Allow or prevent persistent links. -; http://php.net/sybct.allow-persistent -sybct.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://php.net/sybct.max-persistent -sybct.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://php.net/sybct.max-links -sybct.max_links = -1 - -; Minimum server message severity to display. -; http://php.net/sybct.min-server-severity -sybct.min_server_severity = 10 - -; Minimum client message severity to display. -; http://php.net/sybct.min-client-severity -sybct.min_client_severity = 10 - -; Set per-context timeout -; http://php.net/sybct.timeout -;sybct.timeout= - -;sybct.packet_size - -; The maximum time in seconds to wait for a connection attempt to succeed before returning failure. -; Default: one minute -;sybct.login_timeout= - -; The name of the host you claim to be connecting from, for display by sp_who. -; Default: none -;sybct.hostname= - -; Allows you to define how often deadlocks are to be retried. -1 means "forever". -; Default: 0 -;sybct.deadlock_retry_count= - -[bcmath] -; Number of decimal digits for all bcmath functions. -; http://php.net/bcmath.scale -bcmath.scale = 0 - -[browscap] -; http://php.net/browscap -;browscap = extra/browscap.ini - -[Session] -; Handler used to store/retrieve data. -; http://php.net/session.save-handler -session.save_handler = files - -; Argument passed to save_handler. In the case of files, this is the path -; where data files are stored. Note: Windows users have to change this -; variable in order to use PHP's session functions. -; -; The path can be defined as: -; -; session.save_path = "N;/path" -; -; where N is an integer. Instead of storing all the session files in -; /path, what this will do is use subdirectories N-levels deep, and -; store the session data in those directories. This is useful if -; your OS has problems with many files in one directory, and is -; a more efficient layout for servers that handle many sessions. -; -; NOTE 1: PHP will not create this directory structure automatically. -; You can use the script in the ext/session dir for that purpose. -; NOTE 2: See the section on garbage collection below if you choose to -; use subdirectories for session storage -; -; The file storage module creates files using mode 600 by default. -; You can change that by using -; -; session.save_path = "N;MODE;/path" -; -; where MODE is the octal representation of the mode. Note that this -; does not overwrite the process's umask. -; http://php.net/session.save-path - -; RPM note : session directory must be owned by process owner -; for mod_php, see /etc/httpd/conf.d/php.conf -; for php-fpm, see /etc/php-fpm.d/*conf -;session.save_path = "/tmp" - -; Whether to use strict session mode. -; Strict session mode does not accept uninitialized session ID and regenerate -; session ID if browser sends uninitialized session ID. Strict mode protects -; applications from session fixation via session adoption vulnerability. It is -; disabled by default for maximum compatibility, but enabling it is encouraged. -; https://wiki.php.net/rfc/strict_sessions -session.use_strict_mode = 0 - -; Whether to use cookies. -; http://php.net/session.use-cookies -session.use_cookies = 1 - -; http://php.net/session.cookie-secure -;session.cookie_secure = - -; This option forces PHP to fetch and use a cookie for storing and maintaining -; the session id. We encourage this operation as it's very helpful in combating -; session hijacking when not specifying and managing your own session id. It is -; not the be-all and end-all of session hijacking defense, but it's a good start. -; http://php.net/session.use-only-cookies -session.use_only_cookies = 1 - -; Name of the session (used as cookie name). -; http://php.net/session.name -session.name = PHPSESSID - -; Initialize session on request startup. -; http://php.net/session.auto-start -session.auto_start = 0 - -; Lifetime in seconds of cookie or, if 0, until browser is restarted. -; http://php.net/session.cookie-lifetime -session.cookie_lifetime = 0 - -; The path for which the cookie is valid. -; http://php.net/session.cookie-path -session.cookie_path = / - -; The domain for which the cookie is valid. -; http://php.net/session.cookie-domain -session.cookie_domain = - -; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript. -; http://php.net/session.cookie-httponly -session.cookie_httponly = - -; Handler used to serialize data. php is the standard serializer of PHP. -; http://php.net/session.serialize-handler -session.serialize_handler = php - -; Defines the probability that the 'garbage collection' process is started -; on every session initialization. The probability is calculated by using -; gc_probability/gc_divisor. Where session.gc_probability is the numerator -; and gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any give request. -; Default Value: 1 -; Development Value: 1 -; Production Value: 1 -; http://php.net/session.gc-probability -session.gc_probability = 1 - -; Defines the probability that the 'garbage collection' process is started on every -; session initialization. The probability is calculated by using the following equation: -; gc_probability/gc_divisor. Where session.gc_probability is the numerator and -; session.gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any give request. Increasing this value to 1000 will give you -; a 0.1% chance the gc will run on any give request. For high volume production servers, -; this is a more efficient approach. -; Default Value: 100 -; Development Value: 1000 -; Production Value: 1000 -; http://php.net/session.gc-divisor -session.gc_divisor = 1000 - -; After this number of seconds, stored data will be seen as 'garbage' and -; cleaned up by the garbage collection process. -; http://php.net/session.gc-maxlifetime -session.gc_maxlifetime = 1440 - -; NOTE: If you are using the subdirectory option for storing session files -; (see session.save_path above), then garbage collection does *not* -; happen automatically. You will need to do your own garbage -; collection through a shell script, cron entry, or some other method. -; For example, the following script would is the equivalent of -; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): -; find /path/to/sessions -cmin +24 -type f | xargs rm - -; Check HTTP Referer to invalidate externally stored URLs containing ids. -; HTTP_REFERER has to contain this substring for the session to be -; considered as valid. -; http://php.net/session.referer-check -session.referer_check = - -; How many bytes to read from the file. -; http://php.net/session.entropy-length -;session.entropy_length = 32 - -; Specified here to create the session id. -; http://php.net/session.entropy-file -; Defaults to /dev/urandom -; On systems that don't have /dev/urandom but do have /dev/arandom, this will default to /dev/arandom -; If neither are found at compile time, the default is no entropy file. -; On windows, setting the entropy_length setting will activate the -; Windows random source (using the CryptoAPI) -;session.entropy_file = /dev/urandom - -; Set to {nocache,private,public,} to determine HTTP caching aspects -; or leave this empty to avoid sending anti-caching headers. -; http://php.net/session.cache-limiter -session.cache_limiter = nocache - -; Document expires after n minutes. -; http://php.net/session.cache-expire -session.cache_expire = 180 - -; trans sid support is disabled by default. -; Use of trans sid may risk your users' security. -; Use this option with caution. -; - User may send URL contains active session ID -; to other person via. email/irc/etc. -; - URL that contains active session ID may be stored -; in publicly accessible computer. -; - User may access your site with the same session ID -; always using URL stored in browser's history or bookmarks. -; http://php.net/session.use-trans-sid -session.use_trans_sid = 0 - -; Select a hash function for use in generating session ids. -; Possible Values -; 0 (MD5 128 bits) -; 1 (SHA-1 160 bits) -; This option may also be set to the name of any hash function supported by -; the hash extension. A list of available hashes is returned by the hash_algos() -; function. -; http://php.net/session.hash-function -session.hash_function = 0 - -; Define how many bits are stored in each character when converting -; the binary hash data to something readable. -; Possible values: -; 4 (4 bits: 0-9, a-f) -; 5 (5 bits: 0-9, a-v) -; 6 (6 bits: 0-9, a-z, A-Z, "-", ",") -; Default Value: 4 -; Development Value: 5 -; Production Value: 5 -; http://php.net/session.hash-bits-per-character -session.hash_bits_per_character = 5 - -; The URL rewriter will look for URLs in a defined set of HTML tags. -; form/fieldset are special; if you include them here, the rewriter will -; add a hidden field with the info which is otherwise appended -; to URLs. If you want XHTML conformity, remove the form entry. -; Note that all valid entries require a "=", even if no value follows. -; Default Value: "a=href,area=href,frame=src,form=,fieldset=" -; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; http://php.net/url-rewriter.tags -url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" - -; Enable upload progress tracking in $_SESSION -; Default Value: On -; Development Value: On -; Production Value: On -; http://php.net/session.upload-progress.enabled -;session.upload_progress.enabled = On - -; Cleanup the progress information as soon as all POST data has been read -; (i.e. upload completed). -; Default Value: On -; Development Value: On -; Production Value: On -; http://php.net/session.upload-progress.cleanup -;session.upload_progress.cleanup = On - -; A prefix used for the upload progress key in $_SESSION -; Default Value: "upload_progress_" -; Development Value: "upload_progress_" -; Production Value: "upload_progress_" -; http://php.net/session.upload-progress.prefix -;session.upload_progress.prefix = "upload_progress_" - -; The index name (concatenated with the prefix) in $_SESSION -; containing the upload progress information -; Default Value: "PHP_SESSION_UPLOAD_PROGRESS" -; Development Value: "PHP_SESSION_UPLOAD_PROGRESS" -; Production Value: "PHP_SESSION_UPLOAD_PROGRESS" -; http://php.net/session.upload-progress.name -;session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS" - -; How frequently the upload progress should be updated. -; Given either in percentages (per-file), or in bytes -; Default Value: "1%" -; Development Value: "1%" -; Production Value: "1%" -; http://php.net/session.upload-progress.freq -;session.upload_progress.freq = "1%" - -; The minimum delay between updates, in seconds -; Default Value: 1 -; Development Value: 1 -; Production Value: 1 -; http://php.net/session.upload-progress.min-freq -;session.upload_progress.min_freq = "1" - -[MSSQL] -; Allow or prevent persistent links. -mssql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -mssql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -mssql.max_links = -1 - -; Minimum error severity to display. -mssql.min_error_severity = 10 - -; Minimum message severity to display. -mssql.min_message_severity = 10 - -; Compatibility mode with old versions of PHP 3.0. -mssql.compatibility_mode = Off - -; Connect timeout -;mssql.connect_timeout = 5 - -; Query timeout -;mssql.timeout = 60 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textlimit = 4096 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textsize = 4096 - -; Limits the number of records in each batch. 0 = all records in one batch. -;mssql.batchsize = 0 - -; Specify how datetime and datetim4 columns are returned -; On => Returns data converted to SQL server settings -; Off => Returns values as YYYY-MM-DD hh:mm:ss -;mssql.datetimeconvert = On - -; Use NT authentication when connecting to the server -mssql.secure_connection = Off - -; Specify max number of processes. -1 = library default -; msdlib defaults to 25 -; FreeTDS defaults to 4096 -;mssql.max_procs = -1 - -; Specify client character set. -; If empty or not set the client charset from freetds.conf is used -; This is only used when compiled with FreeTDS -;mssql.charset = "ISO-8859-1" - -[Assertion] -; Assert(expr); active by default. -; http://php.net/assert.active -;assert.active = On - -; Issue a PHP warning for each failed assertion. -; http://php.net/assert.warning -;assert.warning = On - -; Don't bail out by default. -; http://php.net/assert.bail -;assert.bail = Off - -; User-function to be called if an assertion fails. -; http://php.net/assert.callback -;assert.callback = 0 - -; Eval the expression with current error_reporting(). Set to true if you want -; error_reporting(0) around the eval(). -; http://php.net/assert.quiet-eval -;assert.quiet_eval = 0 - -[mbstring] -; language for internal character representation. -; This affects mb_send_mail() and mbstrig.detect_order. -; http://php.net/mbstring.language -;mbstring.language = Japanese - -; Use of this INI entry is deprecated, use global internal_encoding instead. -; internal/script encoding. -; Some encoding cannot work as internal encoding. (e.g. SJIS, BIG5, ISO-2022-*) -; If empty, default_charset or internal_encoding or iconv.internal_encoding is used. -; The precedence is: default_charset < internal_encoding < iconv.internal_encoding -;mbstring.internal_encoding = - -; Use of this INI entry is deprecated, use global input_encoding instead. -; http input encoding. -; mbstring.encoding_traslation = On is needed to use this setting. -; If empty, default_charset or input_encoding or mbstring.input is used. -; The precedence is: default_charset < intput_encoding < mbsting.http_input -; http://php.net/mbstring.http-input -;mbstring.http_input = - -; Use of this INI entry is deprecated, use global output_encoding instead. -; http output encoding. -; mb_output_handler must be registered as output buffer to function. -; If empty, default_charset or output_encoding or mbstring.http_output is used. -; The precedence is: default_charset < output_encoding < mbstring.http_output -; To use an output encoding conversion, mbstring's output handler must be set -; otherwise output encoding conversion cannot be performed. -;mbstring.http_output = - -; enable automatic encoding translation according to -; mbstring.internal_encoding setting. Input chars are -; converted to internal encoding by setting this to On. -; Note: Do _not_ use automatic encoding translation for -; portable libs/applications. -; http://php.net/mbstring.encoding-translation -;mbstring.encoding_translation = Off - -; automatic encoding detection order. -; "auto" detect order is changed accoding to mbstring.language -; http://php.net/mbstring.detect-order -;mbstring.detect_order = auto - -; substitute_character used when character cannot be converted -; one from another -; http://php.net/mbstring.substitute-character -;mbstring.substitute_character = none - -; overload(replace) single byte functions by mbstring functions. -; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(), -; etc. Possible values are 0,1,2,4 or combination of them. -; For example, 7 for overload everything. -; 0: No overload -; 1: Overload mail() function -; 2: Overload str*() functions -; 4: Overload ereg*() functions -; http://php.net/mbstring.func-overload -;mbstring.func_overload = 0 - -; enable strict encoding detection. -; Default: Off -;mbstring.strict_detection = On - -; This directive specifies the regex pattern of content types for which mb_output_handler() -; is activated. -; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml) -;mbstring.http_output_conv_mimetype= - -[gd] -; Tell the jpeg decode to ignore warnings and try to create -; a gd image. The warning will then be displayed as notices -; disabled by default -; http://php.net/gd.jpeg-ignore-warning -;gd.jpeg_ignore_warning = 0 - -[exif] -; Exif UNICODE user comments are handled as UCS-2BE/UCS-2LE and JIS as JIS. -; With mbstring support this will automatically be converted into the encoding -; given by corresponding encode setting. When empty mbstring.internal_encoding -; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. -; http://php.net/exif.encode-unicode -;exif.encode_unicode = ISO-8859-15 - -; http://php.net/exif.decode-unicode-motorola -;exif.decode_unicode_motorola = UCS-2BE - -; http://php.net/exif.decode-unicode-intel -;exif.decode_unicode_intel = UCS-2LE - -; http://php.net/exif.encode-jis -;exif.encode_jis = - -; http://php.net/exif.decode-jis-motorola -;exif.decode_jis_motorola = JIS - -; http://php.net/exif.decode-jis-intel -;exif.decode_jis_intel = JIS - -[Tidy] -; The path to a default tidy configuration file to use when using tidy -; http://php.net/tidy.default-config -;tidy.default_config = /usr/local/lib/php/default.tcfg - -; Should tidy clean and repair output automatically? -; WARNING: Do not use this option if you are generating non-html content -; such as dynamic images -; http://php.net/tidy.clean-output -tidy.clean_output = Off - -[soap] -; Enables or disables WSDL caching feature. -; http://php.net/soap.wsdl-cache-enabled -soap.wsdl_cache_enabled=1 - -; Sets the directory name where SOAP extension will put cache files. -; http://php.net/soap.wsdl-cache-dir - -; RPM note : cache directory must be owned by process owner -; for mod_php, see /etc/httpd/conf.d/php.conf -; for php-fpm, see /etc/php-fpm.d/*conf -soap.wsdl_cache_dir="/tmp" - -; (time to live) Sets the number of second while cached file will be used -; instead of original one. -; http://php.net/soap.wsdl-cache-ttl -soap.wsdl_cache_ttl=86400 - -; Sets the size of the cache limit. (Max. number of WSDL files to cache) -soap.wsdl_cache_limit = 5 - -[sysvshm] -; A default size of the shared memory segment -;sysvshm.init_mem = 10000 - -[ldap] -; Sets the maximum number of open links or -1 for unlimited. -ldap.max_links = -1 - -[mcrypt] -; For more information about mcrypt settings see http://php.net/mcrypt-module-open - -; Directory where to load mcrypt algorithms -; Default: Compiled in into libmcrypt (usually /usr/local/lib/libmcrypt) -;mcrypt.algorithms_dir= - -; Directory where to load mcrypt modes -; Default: Compiled in into libmcrypt (usually /usr/local/lib/libmcrypt) -;mcrypt.modes_dir= - -[dba] -;dba.default_handler= - -[curl] -; A default value for the CURLOPT_CAINFO option. This is required to be an -; absolute path. -;curl.cainfo = - -[openssl] -; The location of a Certificate Authority (CA) file on the local filesystem -; to use when verifying the identity of SSL/TLS peers. Most users should -; not specify a value for this directive as PHP will attempt to use the -; OS-managed cert stores in its absence. If specified, this value may still -; be overridden on a per-stream basis via the "cafile" SSL stream context -; option. -;openssl.cafile= - -; If openssl.cafile is not specified or if the CA file is not found, the -; directory pointed to by openssl.capath is searched for a suitable -; certificate. This value must be a correctly hashed certificate directory. -; Most users should not specify a value for this directive as PHP will -; attempt to use the OS-managed cert stores in its absence. If specified, -; this value may still be overridden on a per-stream basis via the "capath" -; SSL stream context option. -;openssl.capath= - -; Local Variables: -; tab-width: 4 -; End: diff --git a/install/php-configs/www.conf b/install/php-configs/www.conf deleted file mode 100644 index 29ef69b6a..000000000 --- a/install/php-configs/www.conf +++ /dev/null @@ -1,424 +0,0 @@ -; Start a new pool named 'www'. -; the variable $pool can we used in any directive and will be replaced by the -; pool name ('www' here) -[www] - -; Per pool prefix -; It only applies on the following directives: -; - 'access.log' -; - 'slowlog' -; - 'listen' (unixsocket) -; - 'chroot' -; - 'chdir' -; - 'php_values' -; - 'php_admin_values' -; When not set, the global prefix (or @php_fpm_prefix@) applies instead. -; Note: This directive can also be relative to the global prefix. -; Default Value: none -;prefix = /path/to/pools/$pool - -; Unix user/group of processes -; Note: The user is mandatory. If the group is not set, the default user's group -; will be used. -user = nginx -group = nginx - -; The address on which to accept FastCGI requests. -; Valid syntaxes are: -; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on -; a specific port; -; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on -; a specific port; -; 'port' - to listen on a TCP socket to all IPv4 addresses on a -; specific port; -; '[::]:port' - to listen on a TCP socket to all addresses -; (IPv6 and IPv4-mapped) on a specific port; -; '/path/to/unix/socket' - to listen on a unix socket. -; Note: This value is mandatory. -listen = 127.0.0.1:9000 -; WARNING: If you switch to a unix socket, you have to grant your webserver user -; access to that socket by setting listen.acl_users to the webserver user. -; -listen = /run/php-fpm/www.sock - -; Set listen(2) backlog. -; Default Value: 65535 (-1 on FreeBSD and OpenBSD) -;listen.backlog = 65535 - -; Set permissions for unix socket, if one is used. In Linux, read/write -; permissions must be set in order to allow connections from a web server. Many -; BSD-derived systems allow connections regardless of permissions. -; Default Values: user and group are set as the running user -; mode is set to 0660 -listen.owner = root -listen.group = root -;listen.mode = 0660 - -; When POSIX Access Control Lists are supported you can set them using -; these options, value is a comma separated list of user/group names. -; When set, listen.owner and listen.group are ignored -;listen.acl_users = apache,nginx -;listen.acl_users = apache -;listen.acl_users = nginx -;listen.acl_groups = - -; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. -; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original -; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address -; must be separated by a comma. If this value is left blank, connections will be -; accepted from any ip address. -; Default Value: any -listen.allowed_clients = 127.0.0.1 - -; Specify the nice(2) priority to apply to the pool processes (only if set) -; The value can vary from -19 (highest priority) to 20 (lower priority) -; Note: - It will only work if the FPM master process is launched as root -; - The pool processes will inherit the master process priority -; unless it specified otherwise -; Default Value: no set -; process.priority = -19 - -; Choose how the process manager will control the number of child processes. -; Possible Values: -; static - a fixed number (pm.max_children) of child processes; -; dynamic - the number of child processes are set dynamically based on the -; following directives. With this process management, there will be -; always at least 1 children. -; pm.max_children - the maximum number of children that can -; be alive at the same time. -; pm.start_servers - the number of children created on startup. -; pm.min_spare_servers - the minimum number of children in 'idle' -; state (waiting to process). If the number -; of 'idle' processes is less than this -; number then some children will be created. -; pm.max_spare_servers - the maximum number of children in 'idle' -; state (waiting to process). If the number -; of 'idle' processes is greater than this -; number then some children will be killed. -; ondemand - no children are created at startup. Children will be forked when -; new requests will connect. The following parameter are used: -; pm.max_children - the maximum number of children that -; can be alive at the same time. -; pm.process_idle_timeout - The number of seconds after which -; an idle process will be killed. -; Note: This value is mandatory. -pm = dynamic - -; The number of child processes to be created when pm is set to 'static' and the -; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. -; This value sets the limit on the number of simultaneous requests that will be -; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. -; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP -; CGI. The below defaults are based on a server without much resources. Don't -; forget to tweak pm.* to fit your needs. -; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' -; Note: This value is mandatory. -pm.max_children = 50 - -; The number of child processes created on startup. -; Note: Used only when pm is set to 'dynamic' -; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 -pm.start_servers = 5 - -; The desired minimum number of idle server processes. -; Note: Used only when pm is set to 'dynamic' -; Note: Mandatory when pm is set to 'dynamic' -pm.min_spare_servers = 5 - -; The desired maximum number of idle server processes. -; Note: Used only when pm is set to 'dynamic' -; Note: Mandatory when pm is set to 'dynamic' -pm.max_spare_servers = 35 - -; The number of seconds after which an idle process will be killed. -; Note: Used only when pm is set to 'ondemand' -; Default Value: 10s -;pm.process_idle_timeout = 10s; - -; The number of requests each child process should execute before respawning. -; This can be useful to work around memory leaks in 3rd party libraries. For -; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. -; Default Value: 0 -;pm.max_requests = 500 - -; The URI to view the FPM status page. If this value is not set, no URI will be -; recognized as a status page. It shows the following informations: -; pool - the name of the pool; -; process manager - static, dynamic or ondemand; -; start time - the date and time FPM has started; -; start since - number of seconds since FPM has started; -; accepted conn - the number of request accepted by the pool; -; listen queue - the number of request in the queue of pending -; connections (see backlog in listen(2)); -; max listen queue - the maximum number of requests in the queue -; of pending connections since FPM has started; -; listen queue len - the size of the socket queue of pending connections; -; idle processes - the number of idle processes; -; active processes - the number of active processes; -; total processes - the number of idle + active processes; -; max active processes - the maximum number of active processes since FPM -; has started; -; max children reached - number of times, the process limit has been reached, -; when pm tries to start more children (works only for -; pm 'dynamic' and 'ondemand'); -; Value are updated in real time. -; Example output: -; pool: www -; process manager: static -; start time: 01/Jul/2011:17:53:49 +0200 -; start since: 62636 -; accepted conn: 190460 -; listen queue: 0 -; max listen queue: 1 -; listen queue len: 42 -; idle processes: 4 -; active processes: 11 -; total processes: 15 -; max active processes: 12 -; max children reached: 0 -; -; By default the status page output is formatted as text/plain. Passing either -; 'html', 'xml' or 'json' in the query string will return the corresponding -; output syntax. Example: -; http://www.foo.bar/status -; http://www.foo.bar/status?json -; http://www.foo.bar/status?html -; http://www.foo.bar/status?xml -; -; By default the status page only outputs short status. Passing 'full' in the -; query string will also return status for each pool process. -; Example: -; http://www.foo.bar/status?full -; http://www.foo.bar/status?json&full -; http://www.foo.bar/status?html&full -; http://www.foo.bar/status?xml&full -; The Full status returns for each process: -; pid - the PID of the process; -; state - the state of the process (Idle, Running, ...); -; start time - the date and time the process has started; -; start since - the number of seconds since the process has started; -; requests - the number of requests the process has served; -; request duration - the duration in µs of the requests; -; request method - the request method (GET, POST, ...); -; request URI - the request URI with the query string; -; content length - the content length of the request (only with POST); -; user - the user (PHP_AUTH_USER) (or '-' if not set); -; script - the main script called (or '-' if not set); -; last request cpu - the %cpu the last request consumed -; it's always 0 if the process is not in Idle state -; because CPU calculation is done when the request -; processing has terminated; -; last request memory - the max amount of memory the last request consumed -; it's always 0 if the process is not in Idle state -; because memory calculation is done when the request -; processing has terminated; -; If the process is in Idle state, then informations are related to the -; last request the process has served. Otherwise informations are related to -; the current request being served. -; Example output: -; ************************ -; pid: 31330 -; state: Running -; start time: 01/Jul/2011:17:53:49 +0200 -; start since: 63087 -; requests: 12808 -; request duration: 1250261 -; request method: GET -; request URI: /test_mem.php?N=10000 -; content length: 0 -; user: - -; script: /home/fat/web/docs/php/test_mem.php -; last request cpu: 0.00 -; last request memory: 0 -; -; Note: There is a real-time FPM status monitoring sample web page available -; It's available in: @EXPANDED_DATADIR@/fpm/status.html -; -; Note: The value must start with a leading slash (/). The value can be -; anything, but it may not be a good idea to use the .php extension or it -; may conflict with a real PHP file. -; Default Value: not set -;pm.status_path = /status - -; The ping URI to call the monitoring page of FPM. If this value is not set, no -; URI will be recognized as a ping page. This could be used to test from outside -; that FPM is alive and responding, or to -; - create a graph of FPM availability (rrd or such); -; - remove a server from a group if it is not responding (load balancing); -; - trigger alerts for the operating team (24/7). -; Note: The value must start with a leading slash (/). The value can be -; anything, but it may not be a good idea to use the .php extension or it -; may conflict with a real PHP file. -; Default Value: not set -;ping.path = /ping - -; This directive may be used to customize the response of a ping request. The -; response is formatted as text/plain with a 200 response code. -; Default Value: pong -;ping.response = pong - -; The access log file -; Default: not set -;access.log = log/$pool.access.log - -; The access log format. -; The following syntax is allowed -; %%: the '%' character -; %C: %CPU used by the request -; it can accept the following format: -; - %{user}C for user CPU only -; - %{system}C for system CPU only -; - %{total}C for user + system CPU (default) -; %d: time taken to serve the request -; it can accept the following format: -; - %{seconds}d (default) -; - %{miliseconds}d -; - %{mili}d -; - %{microseconds}d -; - %{micro}d -; %e: an environment variable (same as $_ENV or $_SERVER) -; it must be associated with embraces to specify the name of the env -; variable. Some exemples: -; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e -; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e -; %f: script filename -; %l: content-length of the request (for POST request only) -; %m: request method -; %M: peak of memory allocated by PHP -; it can accept the following format: -; - %{bytes}M (default) -; - %{kilobytes}M -; - %{kilo}M -; - %{megabytes}M -; - %{mega}M -; %n: pool name -; %o: output header -; it must be associated with embraces to specify the name of the header: -; - %{Content-Type}o -; - %{X-Powered-By}o -; - %{Transfert-Encoding}o -; - .... -; %p: PID of the child that serviced the request -; %P: PID of the parent of the child that serviced the request -; %q: the query string -; %Q: the '?' character if query string exists -; %r: the request URI (without the query string, see %q and %Q) -; %R: remote IP address -; %s: status (response code) -; %t: server time the request was received -; it can accept a strftime(3) format: -; %d/%b/%Y:%H:%M:%S %z (default) -; %T: time the log has been written (the request has finished) -; it can accept a strftime(3) format: -; %d/%b/%Y:%H:%M:%S %z (default) -; %u: remote user -; -; Default: "%R - %u %t \"%m %r\" %s" -;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" - -; The log file for slow requests -; Default Value: not set -; Note: slowlog is mandatory if request_slowlog_timeout is set -slowlog = /var/log/php-fpm/www-slow.log - -; The timeout for serving a single request after which a PHP backtrace will be -; dumped to the 'slowlog' file. A value of '0s' means 'off'. -; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) -; Default Value: 0 -;request_slowlog_timeout = 0 - -; The timeout for serving a single request after which the worker process will -; be killed. This option should be used when the 'max_execution_time' ini option -; does not stop script execution for some reason. A value of '0' means 'off'. -; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) -; Default Value: 0 -;request_terminate_timeout = 0 - -; Set open file descriptor rlimit. -; Default Value: system defined value -;rlimit_files = 1024 - -; Set max core size rlimit. -; Possible Values: 'unlimited' or an integer greater or equal to 0 -; Default Value: system defined value -;rlimit_core = 0 - -; Chroot to this directory at the start. This value must be defined as an -; absolute path. When this value is not set, chroot is not used. -; Note: you can prefix with '$prefix' to chroot to the pool prefix or one -; of its subdirectories. If the pool prefix is not set, the global prefix -; will be used instead. -; Note: chrooting is a great security feature and should be used whenever -; possible. However, all PHP paths will be relative to the chroot -; (error_log, sessions.save_path, ...). -; Default Value: not set -;chroot = - -; Chdir to this directory at the start. -; Note: relative path can be used. -; Default Value: current directory or / when chroot -;chdir = /var/www - -; Redirect worker stdout and stderr into main error log. If not set, stdout and -; stderr will be redirected to /dev/null according to FastCGI specs. -; Note: on highloaded environement, this can cause some delay in the page -; process time (several ms). -; Default Value: no -;catch_workers_output = yes - -; Clear environment in FPM workers -; Prevents arbitrary environment variables from reaching FPM worker processes -; by clearing the environment in workers before env vars specified in this -; pool configuration are added. -; Setting to "no" will make all environment variables available to PHP code -; via getenv(), $_ENV and $_SERVER. -; Default Value: yes -;clear_env = no - -; Limits the extensions of the main script FPM will allow to parse. This can -; prevent configuration mistakes on the web server side. You should only limit -; FPM to .php extensions to prevent malicious users to use other extensions to -; exectute php code. -; Note: set an empty value to allow all extensions. -; Default Value: .php -;security.limit_extensions = .php .php3 .php4 .php5 - -; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from -; the current environment. -; Default Value: clean env -;env[HOSTNAME] = $HOSTNAME -;env[PATH] = /usr/local/bin:/usr/bin:/bin -;env[TMP] = /tmp -;env[TMPDIR] = /tmp -;env[TEMP] = /tmp - -; Additional php.ini defines, specific to this pool of workers. These settings -; overwrite the values previously defined in the php.ini. The directives are the -; same as the PHP SAPI: -; php_value/php_flag - you can set classic ini defines which can -; be overwritten from PHP call 'ini_set'. -; php_admin_value/php_admin_flag - these directives won't be overwritten by -; PHP call 'ini_set' -; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. - -; Defining 'extension' will load the corresponding shared extension from -; extension_dir. Defining 'disable_functions' or 'disable_classes' will not -; overwrite previously defined php.ini values, but will append the new value -; instead. - -; Note: path INI options can be relative and will be expanded with the prefix -; (pool, global or @prefix@) - -; Default Value: nothing is defined by default except the values in php.ini and -; specified at startup with the -d argument -;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com -;php_flag[display_errors] = off -php_admin_value[error_log] = /var/log/php-fpm/www-error.log -php_admin_flag[log_errors] = on -;php_admin_value[memory_limit] = 128M - -; Set session path to a directory owned by process user -php_value[session.save_handler] = files -php_value[session.save_path] = /var/www/html -php_value[soap.wsdl_cache_dir] = /var/lib/php-fpm/wsdlcache - diff --git a/install/rainloop/cyberpanel.net.ini b/install/snappymail/cyberpanel.net.ini similarity index 100% rename from install/rainloop/cyberpanel.net.ini rename to install/snappymail/cyberpanel.net.ini diff --git a/install/venvsetup.sh b/install/venvsetup.sh index ad892ad2e..dc2923194 100644 --- a/install/venvsetup.sh +++ b/install/venvsetup.sh @@ -1,1429 +1,8 @@ #!/bin/bash - -#CyberPanel installer script for Ubuntu 18.04 and CentOS 7.X -DEV="OFF" -BRANCH="stable" -POSTFIX_VARIABLE="ON" -POWERDNS_VARIABLE="ON" -PUREFTPD_VARIABLE="ON" -PROVIDER="undefined" -SERIAL_NO="" -DIR=$(pwd) -TEMP=$(curl --silent https://cyberpanel.net/version.txt) -CP_VER1=${TEMP:12:3} -CP_VER2=${TEMP:25:1} -SERVER_OS="CentOS" -VERSION="OLS" -LICENSE_KEY="" -KEY_SIZE="" -ADMIN_PASS="1234567" -MEMCACHED="ON" -REDIS="ON" -MARIADB_VER="11.8" -TOTAL_RAM=$(free -m | awk '/Mem\:/ { print $2 }') - -# Robust pip install function to handle broken pipe errors -safe_pip_install() { - local pip_cmd="$1" - local requirements_file="$2" - local install_args="$3" - - echo "Installing Python packages..." - - # Method 1: Install with full error suppression and broken pipe handling - 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" - return 0 - fi - - # Method 2: Install with even more aggressive error suppression - echo "⚠️ Trying fallback installation method..." - 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" - return 0 - fi - - # Method 3: Install packages individually to avoid broken pipes - echo "⚠️ Trying individual package installation..." - while IFS= read -r line; do - # Skip empty lines and comments - [[ -z "$line" || "$line" =~ ^#.*$ ]] && continue - - # 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 -} - -license_validation() { -CURRENT_DIR=$(pwd) - -if [ -f /root/cyberpanel-tmp ] ; then -rm -rf /root/cyberpanel-tmp -fi - -mkdir /root/cyberpanel-tmp -cd /root/cyberpanel-tmp -wget -q https://$DOWNLOAD_SERVER/litespeed/lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz -tar xzvf lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz > /dev/null -cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/conf -if [[ $LICENSE_KEY == "TRIAL" ]] ; then -wget -q http://license.litespeedtech.com/reseller/trial.key -sed -i "s|writeSerial = open('lsws-5.4.2/serial.no', 'w')|command = 'wget -q --output-document=./lsws-$LSWS_STABLE_VER/trial.key http://license.litespeedtech.com/reseller/trial.key'|g" $CURRENT_DIR/installCyberPanel.py -sed -i 's|writeSerial.writelines(self.serial)|subprocess.call(command, shell=True)|g' $CURRENT_DIR/installCyberPanel.py -sed -i 's|writeSerial.close()||g' $CURRENT_DIR/installCyberPanel.py -else -echo $LICENSE_KEY > serial.no -fi - -cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/bin - -if [[ $LICENSE_KEY == "TRIAL" ]] ; then - if ./lshttpd -V |& grep "ERROR" ; then - echo -e "\n\nIt apeears to have some issue with license , please check above result..." - exit - fi - LICENSE_KEY="1111-2222-3333-4444" -else - if ./lshttpd -r |& grep "ERROR" ; then - ./lshttpd -r - echo -e "\n\nIt apeears to have some issue with license , please check above result..." - exit - fi -fi -echo -e "License seems valid..." -cd /root/cyberpanel-tmp -rm -rf lsws-$LSWS_STABLE_VER* -cd $CURRENT_DIR -rm -rf /root/cyberpanel-tmp -} - -special_change(){ -sed -i 's|cyberpanel.sh|'$DOWNLOAD_SERVER'|g' install.py -sed -i 's|mirror.cyberpanel.net|'$DOWNLOAD_SERVER'|g' install.py -sed -i 's|git clone https://github.com/usmannasir/cyberpanel|echo downloaded|g' install.py -#change to CDN first, regardless country -sed -i 's|http://|https://|g' install.py - -LATEST_URL="https://update.litespeedtech.com/ws/latest.php" -#LATEST_URL="https://cyberpanel.sh/latest.php" -curl --silent -o /tmp/lsws_latest $LATEST_URL 2>/dev/null -LSWS_STABLE_LINE=`cat /tmp/lsws_latest | grep LSWS_STABLE` -LSWS_STABLE_VER=`expr "$LSWS_STABLE_LINE" : '.*LSWS_STABLE=\(.*\) BUILD .*'` -# Fallback to LSWS 6.3.4 (Stable) if fetch failed or empty -if [ -z "$LSWS_STABLE_VER" ]; then - LSWS_STABLE_VER="6.3.4" -fi - -if [[ $SERVER_COUNTRY == "CN" ]] ; then -#line1="$(grep -n "github.com/usmannasir/cyberpanel" install.py | head -n 1 | cut -d: -f1)" -#line2=$((line1 - 1)) -#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py -#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'tar xzvf cyberpanel-git.tar.gz'" install.py -#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py -#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'wget cyberpanel.sh/cyberpanel-git.tar.gz'" install.py -sed -i 's|wget https://rpms.litespeedtech.com/debian/|wget --no-check-certificate https://rpms.litespeedtech.com/debian/|g' install.py -sed -i 's|https://repo.powerdns.com/repo-files/centos-auth-42.repo|https://'$DOWNLOAD_SERVER'/powerdns/powerdns.repo|g' installCyberPanel.py -sed -i 's|https://snappymail.eu/repository/latest.tar.gz|https://'$DOWNLOAD_SERVER'/repository/latest.tar.gz|g' install.py - -sed -i 's|rpm -ivh https://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el7.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://'$DOWNLOAD_SERVER'/litespeed/litespeed.repo|g' install.py - - -sed -i 's|https://copr.fedorainfracloud.org/coprs/copart/restic/repo/epel-7/copart-restic-epel-7.repo|https://'$DOWNLOAD_SERVER'/restic/restic.repo|g' install.py - -sed -i 's|yum -y install https://cyberpanel.sh/gf-release-latest.gf.el7.noarch.rpm|wget -O /etc/yum.repos.d/gf.repo https://'$DOWNLOAD_SERVER'/gf-plus/gf.repo|g' install.py -sed -i 's|dovecot-2.3-latest|dovecot-2.3-latest-mirror|g' install.py -sed -i 's|git clone https://github.com/usmannasir/cyberpanel|wget https://cyberpanel.sh/cyberpanel-git.tar.gz \&\& tar xzvf cyberpanel-git.tar.gz|g' install.py -sed -i 's|https://repo.dovecot.org/ce-2.3-latest/centos/$releasever/RPMS/$basearch|https://'$DOWNLOAD_SERVER'/dovecot/|g' install.py -sed -i 's|'$DOWNLOAD_SERVER'|cyberpanel.sh|g' install.py -sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.4.2-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' installCyberPanel.py -# global change for CN , regardless provider and system - - if [[ $SERVER_OS == "CentOS" ]] ; then - DIR=$(pwd) - cd $DIR/mysql - echo "[mariadb-tsinghua] -name = MariaDB -baseurl = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum/10.1/centos7-amd64 -gpgkey = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum//RPM-GPG-KEY-MariaDB -gpgcheck = 1" > MariaDB.repo -#above to set mariadb db to Tsinghua repo - cd $DIR - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' installCyberPanel.py - mkdir /root/.pip - cat << EOF > /root/.pip/pip.conf -[global] -index-url = https://mirrors.aliyun.com/pypi/simple/ -EOF - echo -e "\nSet to Aliyun pip repo..." - cat << EOF > composer.sh -#!/usr/bin/env bash -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -php composer-setup.php -php -r "unlink('composer-setup.php');" -mv composer.phar /usr/bin/composer - -if [ ! -d /root/.config ]; then -mkdir /root/.config -fi - -if [ ! -d /root/.config/composer ]; then -mkdir /root/.config/composer -fi - -echo '{ - "bitbucket-oauth": {}, - "github-oauth": {}, - "gitlab-oauth": {}, - "gitlab-token": {}, - "http-basic": {} -} -' > /root/.config/composer/auth.json - -echo '{ - "config": {}, - "repositories": { - "packagist": { - "type": "composer", - "url": "https://mirrors.aliyun.com/composer/" - } - } -} -' > /root/.config/composer/config.json -composer clear-cache -EOF - fi - - - if [[ $SERVER_OS == "Ubuntu" ]] ; then - echo $'\n89.208.248.38 rpms.litespeedtech.com\n' >> /etc/hosts - echo -e "Mirror server set..." - pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ - cat << EOF > /root/.pip/pip.conf -[global] -index-url = https://mirrors.aliyun.com/pypi/simple/ -EOF - echo -e "\nSet to Aliyun pip repo..." - if [[ $PROVIDER == "Tencent Cloud" ]] ; then - #tencent cloud and ubuntu system - echo -e "\n Tencent Cloud detected ... bypass default repository" - cp /etc/apt/sources.list /etc/apt/sources.list-backup - #backup original sources list - cat << 'EOF' > /etc/apt/sources.list -deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse -deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse -deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse -EOF - DEBIAN_FRONTEND=noninteractive apt update -y - pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ - cat << EOF > composer.sh -#!/usr/bin/env bash -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -php composer-setup.php -php -r "unlink('composer-setup.php');" -mv composer.phar /usr/bin/composer - -if [ ! -d /root/.config ]; then -mkdir /root/.config -fi - -if [ ! -d /root/.config/composer ]; then -mkdir /root/.config/composer -fi - -echo '{ - "bitbucket-oauth": {}, - "github-oauth": {}, - "gitlab-oauth": {}, - "gitlab-token": {}, - "http-basic": {} -} -' > /root/.config/composer/auth.json - -echo '{ - "config": {}, - "repositories": { - "packagist": { - "type": "composer", - "url": "https://mirrors.cloud.tencent.com/composer/" - } - } -} -' > /root/.config/composer/config.json -composer clear-cache -EOF - else - cat << EOF > composer.sh -#!/usr/bin/env bash -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -php composer-setup.php -php -r "unlink('composer-setup.php');" -mv composer.phar /usr/bin/composer - -if [ ! -d /root/.config ]; then -mkdir /root/.config -fi - -if [ ! -d /root/.config/composer ]; then -mkdir /root/.config/composer -fi - -echo '{ - "bitbucket-oauth": {}, - "github-oauth": {}, - "gitlab-oauth": {}, - "gitlab-token": {}, - "http-basic": {} -} -' > /root/.config/composer/auth.json - -echo '{ - "config": {}, - "repositories": { - "packagist": { - "type": "composer", - "url": "https://packagist.phpcomposer.com" - } - } -} -' > /root/.config/composer/config.json -composer clear-cache -EOF - fi - fi -fi -} - - -system_tweak() { -if [[ $SERVER_OS == "CentOS" ]] ; then - setenforce 0 - sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config -fi - -if ! grep -q "pid_max" /etc/rc.local; then - if [[ $SERVER_OS == "CentOS" ]] ; then - echo "echo 1000000 > /proc/sys/kernel/pid_max -echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.d/rc.local - chmod +x /etc/rc.d/rc.local - else - echo "echo 1000000 > /proc/sys/kernel/pid_max -echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.local - chmod +x /etc/rc.local - fi - echo "fs.file-max = 65535" >> /etc/sysctl.conf - sysctl -p > /dev/null - echo "* soft nofile 65535 -* hard nofile 65535 -root soft nofile 65535 -root hard nofile 65535 -* soft nproc 65535 -* hard nproc 65535 -root soft nproc 65535 -root hard nproc 65535" >> /etc/security/limits.conf -fi - -#sed -i 's|#DefaultLimitNOFILE=|DefaultLimitNOFILE=65535|g' /etc/systemd/system.conf - - -TOTAL_SWAP=$(free -m | awk '/^Swap:/ { print $2 }') -SET_SWAP=$((TOTAL_RAM - TOTAL_SWAP)) -SWAP_FILE=/cyberpanel.swap - -if [ ! -f $SWAP_FILE ] ; then - if [[ $TOTAL_SWAP -gt $TOTAL_RAM ]] || [[ $TOTAL_SWAP -eq $TOTAL_RAM ]] ; then - echo "SWAP check..." - else - if [[ $SET_SWAP -gt "2049" ]] ; then - SET_SWAP="2048" - else - echo "Checking SWAP..." - fi - fallocate --length ${SET_SWAP}MiB $SWAP_FILE - chmod 600 $SWAP_FILE - mkswap $SWAP_FILE - swapon $SWAP_FILE - echo "${SWAP_FILE} swap swap sw 0 0" | sudo tee -a /etc/fstab - sysctl vm.swappiness=10 - echo "vm.swappiness = 10" >> /etc/sysctl.conf - echo "SWAP set..." - fi -fi -} - - -install_required() { -echo -e "\nInstalling necessary components..." -if [[ $SERVER_OS == "CentOS" ]] ; then - rpm --import https://$DOWNLOAD_SERVER/mariadb/RPM-GPG-KEY-MariaDB - rpm --import https://$DOWNLOAD_SERVER/litespeed/RPM-GPG-KEY-litespeed - rpm --import https://$DOWNLOAD_SERVER/powerdns/FD380FBB-pub.asc - rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 - rpm --import https://$DOWNLOAD_SERVER/gf-plus/RPM-GPG-KEY-gf.el7 - rpm --import https://repo.dovecot.org/DOVECOT-REPO-GPG - rpm --import https://copr-be.cloud.fedoraproject.org/results/copart/restic/pubkey.gpg - yum autoremove epel-release -y - rm -f /etc/yum.repos.d/epel.repo - rm -f /etc/yum.repos.d/epel.repo.rpmsave - yum clean all - yum update -y - yum install epel-release -y - yum install -y wget strace htop net-tools telnet curl which bc telnet htop libevent-devel gcc python-devel libattr-devel xz-devel gpgme-devel mariadb-devel curl-devel python-pip git - if [[ $DEV == "ON" ]] ; then - yum -y install yum-utils - yum -y groupinstall development - yum -y install https://centos7.iuscommunity.org/ius-release.rpm - yum -y install python36u python36u-pip python36u-devel - fi -fi - -if [[ $SERVER_OS == "Ubuntu" ]] ; then - apt update -y - DEBIAN_FRONTEND=noninteractive apt upgrade -y - - # Check if this is Debian (no lsb-release) and version >= 13 - if [[ ! -f /etc/lsb-release ]] && [[ -f /etc/debian_version ]]; then - DEBIAN_VERSION=$(cat /etc/debian_version | cut -d'.' -f1) - if [[ $DEBIAN_VERSION -ge 13 ]]; then - # Debian 13 (Trixie) package mappings - DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python3-mysqldb python3-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python3-gpg python3 python3-setuptools virtualenv python3-dev python3-pip git - elif [[ $DEBIAN_VERSION -ge 12 ]]; then - # Debian 12 (Bookworm) package mappings - DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python3-mysqldb python3-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python3-gpg python3 python3-setuptools virtualenv python3-dev python3-pip git - else - # Older Debian versions - DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python-mysqldb python-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python-gpg python python-minimal python-setuptools virtualenv python-dev python-pip git - fi - else - # Ubuntu or older Debian with compatible package names - DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python-mysqldb python-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python-gpg python python-minimal python-setuptools virtualenv python-dev python-pip git - fi - if [[ $DEV == "ON" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install -y python3-pip - DEBIAN_FRONTEND=noninteractive apt install -y build-essential libssl-dev libffi-dev python3-dev - DEBIAN_FRONTEND=noninteractive apt install -y python3-venv - fi -fi -} - -memcached_installation() { -if [[ $SERVER_OS == "CentOS" ]] ; then - yum install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached lsphp56-pecl-memcached lsphp55-pecl-memcached lsphp54-pecl-memcached - if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then - yum groupinstall "Development Tools" -y - yum install autoconf automake zlib-devel openssl-devel expat-devel pcre-devel libmemcached-devel cyrus-sasl* -y - wget https://$DOWNLOAD_SERVER/litespeed/lsmcd.tar.gz - tar xzvf lsmcd.tar.gz - DIR=$(pwd) - cd $DIR/lsmcd - ./fixtimestamp.sh - ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" - make - make install - systemctl enable lsmcd - systemctl start lsmcd - cd $DIR - else - yum install -y memcached - sed -i 's|OPTIONS=""|OPTIONS="-l 127.0.0.1 -U 0"|g' /etc/sysconfig/memcached - systemctl enable memcached - systemctl start memcached - fi -fi -if [[ $SERVER_OS == "Ubuntu" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached - if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install build-essential zlib1g-dev libexpat1-dev openssl libssl-dev libsasl2-dev libpcre3-dev git -y - wget https://$DOWNLOAD/litespeed/lsmcd.tar.gz - tar xzvf lsmcd.tar.gz - DIR=$(pwd) - cd $DIR/lsmcd - ./fixtimestamp.sh - ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" - make - make install - cd $DIR - systemctl enable lsmcd - systemctl start lsmcd - else - DEBIAN_FRONTEND=noninteractive apt install -y memcached - systemctl enable memcached - systemctl start memcached - fi -fi - -if ps -aux | grep "lsmcd" | grep -v grep ; then - echo -e "\n\nLiteSpeed Memcached installed and running..." -fi - -if ps -aux | grep "memcached" | grep -v grep ; then - echo -e "\n\nMemcached installed and running..." -fi - -} - -redis_installation() { -if [[ $SERVER_OS == "CentOS" ]] ; then - yum install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis lsphp56-redis lsphp55-redis lsphp54-redis redis -fi -if [[ $SERVER_OS == "Ubuntu" ]] ; then - DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis redis -fi - -if ifconfig -a | grep inet6 ; then - echo -e "\n IPv6 detected..." -else - sed -i 's|bind 127.0.0.1 ::1|bind 127.0.0.1|g' /etc/redis/redis.conf - echo -e "\n no IPv6 detected..." -fi - -if [[ $SERVER_OS == "CentOS" ]] ; then - systemctl enable redis - systemctl start redis -fi - -if [[ $SERVER_OS == "Ubuntu" ]] ; then - systemctl enable redis-server - systemctl start redis-server -fi - -if ps -aux | grep "redis" | grep -v grep ; then - echo -e "\n\nRedis installed and running..." -fi -} - -check_provider() { - -if hash dmidecode > /dev/null 2>&1 ; then - if [ "$(dmidecode -s bios-vendor)" = 'Google' ] ; then - PROVIDER='Google Cloud Platform' - elif [ "$(dmidecode -s bios-vendor)" = 'DigitalOcean' ] ; then - PROVIDER='Digital Ocean' - elif [ "$(dmidecode -s system-product-name | cut -c 1-7)" = 'Alibaba' ] ; then - PROVIDER='Alibaba Cloud' - elif [ "$(dmidecode -s system-manufacturer)" = 'Microsoft Corporation' ] ; then - PROVIDER='Microsoft Azure' - elif [ -d /usr/local/qcloud ] ; then - PROVIDER='Tencent Cloud' - else - PROVIDER='undefined' - fi -else - PROVIDER='undefined' -fi - -if [ "$(cat /sys/devices/virtual/dmi/id/product_uuid | cut -c 1-3)" = 'EC2' ] && [ -d /home/ubuntu ]; then - PROVIDER='Amazon Web Service' -fi - -} - - -check_OS() { -echo -e "\nChecking OS..." -OUTPUT=$(cat /etc/*release) -if echo $OUTPUT | grep -q "CentOS Linux 7" ; then - echo -e "\nDetecting CentOS 7.X...\n" - SERVER_OS="CentOS" -elif echo $OUTPUT | grep -q "CloudLinux 7" ; then - echo -e "\nDetecting CloudLinux 7.X...\n" - SERVER_OS="CentOS" -elif echo $OUTPUT | grep -q "Ubuntu 18.04" ; then - echo -e "\nDetecting Ubuntu 18.04...\n" - SERVER_OS="Ubuntu" -else - cat /etc/*release - echo -e "\nUnable to detect your OS...\n" - echo -e "\nCyberPanel is supported on Ubuntu 18.04, CentOS 7.x and CloudLinux 7.x...\n" - exit 1 -fi -} - -check_root() { -echo -e "Checking root privileges...\n" -if [[ $(id -u) != 0 ]] > /dev/null; then - echo -e "You must use root account to do this" - echo -e "or run following command: (do NOT miss the quotes)" - echo -e "\e[31msudo su -c \"sh <(curl https://cyberpanel.sh || wget -O - https://cyberpanel.sh)\"\e[39m" - exit 1 -else - echo -e "You are runing as root...\n" -fi -} - -check_panel() { -if [ -d /usr/local/cpanel ]; then - echo -e "\ncPanel detected...exit...\n" - exit 1 -fi -if [ -d /opt/plesk ]; then - echo -e "\nPlesk detected...exit...\n" - exit 1 -fi -} - -check_process() { -if systemctl is-active --quiet httpd; then - systemctl disable httpd - systemctl stop httpd - echo -e "\nhttpd process detected, disabling...\n" -fi -if systemctl is-active --quiet apache2; then - systemctl disable apache2 - systemctl stop apache2 - echo -e "\napache2 process detected, disabling...\n" -fi -if systemctl is-active --quiet named; then - systemctl stop named - systemctl disable named - echo -e "\nnamed process detected, disabling...\n" -fi -if systemctl is-active --quiet exim; then - systemctl stop exim - systemctl disable exim - echo -e "\nexim process detected, disabling...\n" -fi -} - -show_help() { -echo -e "\nCyberPanel Installer Script Help\n" -echo -e "\nUsage: wget https://cyberpanel.sh/cyberpanel.sh" -echo -e "\nchmod +x cyberpanel.sh" -echo -e "\n./cyberpanel.sh -v ols/SERIAL_NUMBER -c 1 -a 1" -echo -e "\n -v or --version: choose to install CyberPanel OpenLiteSpeed or CyberPanel Enterprise, available options are \e[31mols\e[39m and \e[31mSERIAL_NUMBER\e[39m, default ols" -echo -e "\n Please be aware, this serial number must be obtained from LiteSpeed Store." -echo -e "\n And if this serial number has been used before, it must be released/migrated in Store first, otherwise it will fail to start." -echo -e "\n -a or --addons: install addons: memcached, redis, PHP extension for memcached and redis, 1 for install addons, 0 for not to install, default 0, only applicable for CentOS system." -echo -e "\n -p or --password: set password of new installation, empty for default 1234567, [r] or [random] for randomly generated 16 digital password, any other value besdies [d] and [r(andom)] will be accept as password, default use 1234567." -#echo -e "\n -m: set to minimal mode which will not install PowerDNS, Pure-FTPd and Postfix" -echo -e "\n Example:" -echo -e "\n ./cyberpanel.sh -v ols -p r or ./cyberpanel.sh --version ols --password random" -echo -e "\n This will install CyberPanel OpenLiteSpeed and randomly generate the password." -echo -e "\n ./cyberpanel.sh default" -echo -e "\n This will install everything default , which is OpenLiteSpeed and nothing more.\n" - -} - -license_input() { -VERSION="ENT" -echo -e "\nPlease note that your server has \e[31m$TOTAL_RAM\e[39m RAM" -echo -e "If you are using \e[31mFree Start\e[39m license, It will not start due to \e[31m2GB RAM limit\e[39m.\n" -echo -e "If you do not have any license, you can also use trial license (if server has not used trial license before), type \e[31mTRIAL\e[39m\n" - -printf "%s" "Please input your serial number for LiteSpeed WebServer Enterprise:" -read LICENSE_KEY -if [ -z "$LICENSE_KEY" ] ; then - echo -e "\nPlease provide license key\n" - exit -fi - -echo -e "The serial number you input is: \e[31m$LICENSE_KEY\e[39m" -printf "%s" "Please verify it is correct. [y/N]" -read TMP_YN -if [ -z "$TMP_YN" ] ; then - echo -e "\nPlease type \e[31my\e[39m\n" - exit -fi - -KEY_SIZE=${#LICENSE_KEY} -TMP=$(echo $LICENSE_KEY | cut -c5) -TMP2=$(echo $LICENSE_KEY | cut -c10) -TMP3=$(echo $LICENSE_KEY | cut -c15) - -if [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then - echo -e "\nLicense key set..." -elif [[ $LICENSE_KEY == "trial" ]] || [[ $LICENSE_KEY == "TRIAL" ]] || [[ $LICENSE_KEY == "Trial" ]] ; then - echo -e "\nTrial license set..." - LICENSE_KEY="TRIAL" -else - echo -e "\nLicense key seems incorrect, please verify\n" - echo -e "\nIf you are copying/pasting, please make sure you didn't paste blank space...\n" - exit -fi -} - -interactive_mode() { -echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 - - 1. Install CyberPanel. - - 2. Addons and Miscellaneous - - 3. Exit. - - " -read -p " Please enter the number[1-3]: " num -echo "" -case "$num" in - 1) - interactive_install - ;; - 2) - interactive_others - ;; - 3) - exit - ;; - *) - echo -e " Please enter the right number [1-3]\n" - exit - ;; -esac -} - -interactive_others() { -if [ ! -e "/etc/cyberpanel/machineIP" ]; then -echo -e "\nYou don't have CyberPanel installed...\n" -exit -fi - -echo -e " CyberPanel Addons v$CP_VER1$CP_VER2 - - 1. Install Memcached extension and backend - - 2. Install Redis extension and backend - - 3. Return to main page. - - 4. Exit - " - -echo && read -p "Please enter the number[1-4]: " num -case "$num" in - 1) - memcached_installation - exit - ;; - 2) - redis_installation - exit - ;; - 3) - interactive_mode - ;; - 4) - exit - ;; - *) - echo -e "${Error} please enter the right number [1-4]" - ;; -esac -} - -interactive_install() { -RAM=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') -DISK=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') -#clear -echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 - - RAM check : $RAM - - Disk check : $DISK (Minimal \e[31m10GB\e[39m free space) - - 1. Install CyberPanel with \e[31mOpenLiteSpeed\e[39m. - - 2. Install Cyberpanel with \e[31mLiteSpeed Enterprise\e[39m. - - 3. Exit. - - " -read -p " Please enter the number[1-3]: " num -echo "" -case "$num" in - 1) - VERSION="OLS" - ;; - 2) - license_input - ;; - 3) - exit - ;; - *) - echo -e " Please enter the right number [1-3]\n" - exit - ;; -esac - -< /dev/null; then - echo -e "\nCyberPanel installation sucessfully completed..." -else - echo -e "Oops, something went wrong..." - exit -fi - -if [[ $MEMCACHED == "ON" ]] ; then - memcached_installation -fi -if [[ $REDIS == "ON" ]] ; then - redis_installation -fi - after_install -fi -} - -pip_virtualenv() { -if [[ $DEV == "OFF" ]] ; then -if [[ $SERVER_COUNTRY == "CN" ]] ; then - mkdir /root/.pip -cat << EOF > /root/.pip/pip.conf -[global] -index-url = https://mirrors.aliyun.com/pypi/simple/ -EOF -fi - -if [[ $PROVIDER == "Alibaba Cloud" ]] ; then - pip install --upgrade pip 2>/dev/null || echo "⚠️ pip upgrade completed with warnings" - pip install setuptools==40.8.0 2>/dev/null || echo "⚠️ setuptools installation completed with warnings" -fi - -pip install virtualenv 2>/dev/null || echo "⚠️ virtualenv installation completed with warnings" - -# Create virtual environment with fallback for Ubuntu 22.04 compatibility -echo "Creating CyberPanel virtual environment..." -if python3 -m venv --system-site-packages /usr/local/CyberPanel 2>&1 | grep -q "unrecognized option"; then - # Fallback to virtualenv if python3 -m venv doesn't support --system-site-packages - virtualenv --system-site-packages /usr/local/CyberPanel -elif python3 -m venv --system-site-packages /usr/local/CyberPanel 2>/dev/null; then - echo "Virtual environment created successfully using python3 -m venv" -else - # Final fallback to virtualenv - virtualenv --system-site-packages /usr/local/CyberPanel -fi - -source /usr/local/CyberPanel/bin/activate -rm -rf requirements.txt -wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/1.8.0/requirments.txt -# Install packages with robust error handling to prevent broken pipe errors -safe_pip_install "pip" "requirements.txt" "--ignore-installed" -fi - -if [[ $DEV == "ON" ]] ; then - #install dev branch - #wget https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt - cd /usr/local/ - python3.6 -m venv CyberPanel - source /usr/local/CyberPanel/bin/activate - - # Try to download requirements file with fallback options - echo "Attempting to download requirements for branch/commit: $BRANCH_NAME" - - # First try the specified branch/commit - if wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt 2>/dev/null; then - echo "Successfully downloaded requirements from $BRANCH_NAME" - elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments-old.txt 2>/dev/null; then - echo "Successfully downloaded requirements-old.txt from $BRANCH_NAME" - elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/requirments.txt 2>/dev/null; then - echo "Fallback: Downloaded requirements from stable branch" - else - echo "Warning: Could not download requirements file, using minimal default requirements" - cat > requirements.txt << 'EOF' -# Minimal CyberPanel requirements - fallback when requirements file is not available -Django==3.2.25 -PyMySQL==1.1.0 -requests==2.31.0 -cryptography==41.0.7 -psutil==5.9.6 -EOF - fi - - safe_pip_install "pip3.6" "requirements.txt" "--ignore-installed" -fi - -if [ -f requirements.txt ] && [ -d cyberpanel ] ; then - rm -rf cyberpanel - rm -f requirements.txt -fi - -if [[ $SERVER_COUNTRY == "CN" ]] ; then - wget https://cyberpanel.sh/cyberpanel-git.tar.gz - tar xzvf cyberpanel-git.tar.gz > /dev/null - cp -r cyberpanel /usr/local/cyberpanel - cd cyberpanel/install -else - if [[ $DEV == "ON" ]] ; then - git clone https://github.com/usmannasir/cyberpanel - cd cyberpanel - git checkout $BRANCH_NAME - cd - - cd cyberpanel/install - else - git clone https://github.com/usmannasir/cyberpanel - cd cyberpanel/install - fi -fi -curl https://cyberpanel.sh/?version -} - -after_install() { -if [ ! -d "/var/lib/php" ]; then - mkdir /var/lib/php -fi - -if [ ! -d "/var/lib/php/session" ]; then - mkdir /var/lib/php/session -fi - -chmod 1733 /var/lib/php/session - -if grep "\[ERROR\] We are not able to run ./install.sh return code: 1. Fatal error, see /var/log/installLogs.txt for full details" /var/log/installLogs.txt > /dev/null; then - cd ${DIR}/cyberpanel/install/lsws-* - ./install.sh - echo -e "\n\n\nIt seems LiteSpeed Enterprise has failed to install, please check your license key is valid" - echo -e "\nIf this license key has been used before, you may need to go to store to release it first." - exit -fi - - -if grep "CyberPanel installation successfully completed" /var/log/installLogs.txt > /dev/null; then - -if [[ $DEV == "ON" ]] ; then -python3.6 -m venv /usr/local/CyberCP -source /usr/local/CyberCP/bin/activate - -# Try to download requirements file with fallback options -echo "Attempting to download requirements for branch/commit: $BRANCH_NAME" - -# First try the specified branch/commit -if wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt 2>/dev/null; then - echo "Successfully downloaded requirements from $BRANCH_NAME" -elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments-old.txt 2>/dev/null; then - echo "Successfully downloaded requirements-old.txt from $BRANCH_NAME" -elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/requirments.txt 2>/dev/null; then - echo "Fallback: Downloaded requirements from stable branch" -else - echo "Warning: Could not download requirements file, using minimal default requirements" - cat > requirements.txt << 'EOF' -# Minimal CyberPanel requirements - fallback when requirements file is not available -Django==3.2.25 -PyMySQL==1.1.0 -requests==2.31.0 -cryptography==41.0.7 -psutil==5.9.6 -EOF -fi - -safe_pip_install "pip3.6" "requirements.txt" "--ignore-installed" -systemctl restart lscpd -fi - -for version in $(ls /usr/local/lsws | grep lsphp); - do - php_ini=$(find /usr/local/lsws/$version/ -name php.ini) - version2=${version:5:2} - version2=$(awk "BEGIN { print "${version2}/10" }") - if [[ $version2 = "7" ]] ; then - version2="7.0" - fi - if [[ $SERVER_OS == "CentOS" ]] ; then - yum remove -y $version-mysql - yum install -y $version-mysqlnd - yum install -y $version-devel make gcc glibc-devel libmemcached-devel zlib-devel - if [[ ! -d /usr/local/lsws/$version/tmp ]] ; then - mkdir /usr/local/lsws/$version/tmp - fi - /usr/local/lsws/${version}/bin/pecl channel-update pecl.php.net; - /usr/local/lsws/${version}/bin/pear config-set temp_dir /usr/local/lsws/${version}/tmp - /usr/local/lsws/${version}/bin/pecl install timezonedb - echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php.d/20-timezone.ini - sed -i 's|expose_php = On|expose_php = Off|g' $php_ini - sed -i 's|mail.add_x_header = On|mail.add_x_header = Off|g' $php_ini - sed -i 's|;session.save_path = "/tmp"|session.save_path = "/var/lib/php/session"|g' $php_ini - fi - - if [[ $SERVER_OS == "Ubuntu" ]] ; then - if [[ ! -d /usr/local/lsws/cyberpanel-tmp ]] ; then - echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone - systemctl restart pure-ftpd-mysql - DEBIAN_FRONTEND=noninteractive apt install libmagickwand-dev pkg-config build-essential -y - mkdir /usr/local/lsws/cyberpanel-tmp - cd /usr/local/lsws/cyberpanel-tmp - wget https://pecl.php.net/get/timezonedb-2019.3.tgz - tar xzvf timezonedb-2019.3.tgz - cd timezonedb-2019.3 - fi - /usr/local/lsws/${version}/bin/phpize - ./configure --with-php-config=/usr/local/lsws/${version}/bin/php-config${version2} - make - make install - # Only create .ini file if extension was successfully installed - # Check if timezonedb.so exists in the extension directory - ext_dir=$(/usr/local/lsws/${version}/bin/php-config${version2} --extension-dir) - if [[ -f "${ext_dir}/timezonedb.so" ]] ; then - mkdir -p /usr/local/lsws/${version}/etc/php/${version2}/mods-available - echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php/${version2}/mods-available/20-timezone.ini - fi - make clean - fi +# CyberPanel install/venvsetup – modular loader. Sources venvsetup_modules/*.sh. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +for f in 01_vars_install_required 02_memcached_main 03_main_run_pip 04_after_install 05_argument_main; do + if [[ -f "$SCRIPT_DIR/venvsetup_modules/${f}.sh" ]]; then + source "$SCRIPT_DIR/venvsetup_modules/${f}.sh" + fi done - -rm -rf /etc/profile.d/cyberpanel* -curl --silent -o /etc/profile.d/cyberpanel.sh https://cyberpanel.sh/?banner 2>/dev/null -chmod +x /etc/profile.d/cyberpanel.sh -RAM2=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') -DISK2=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') -ELAPSED="$(($SECONDS / 3600)) hrs $((($SECONDS / 60) % 60)) min $(($SECONDS % 60)) sec" -MYSQLPASSWD=$(cat /etc/cyberpanel/mysqlPassword) -echo "$ADMIN_PASS" > /etc/cyberpanel/adminPass -/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password $ADMIN_PASS -systemctl restart lscpd -systemctl restart lsws -echo "/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password \"\$@\"" > /usr/bin/adminPass -echo "systemctl restart lscpd" >> /usr/bin/adminPass -chmod +x /usr/bin/adminPass -if [[ $VERSION = "OLS" ]] ; then - WORD="OpenLiteSpeed" -# sed -i 's|maxConnections 10000|maxConnections 100000|g' /usr/local/lsws/conf/httpd_config.conf -# OLS_LATEST=$(curl https://openlitespeed.org/packages/release) -# wget https://openlitespeed.org/packages/openlitespeed-$OLS_LATEST.tgz -# tar xzvf openlitespeed-$OLS_LATEST.tgz -# cd openlitespeed -# ./install.sh - /usr/local/lsws/bin/lswsctrl stop - /usr/local/lsws/bin/lswsctrl start -# rm -f openlitespeed-$OLS_LATEST.tgz -# rm -rf openlitespeed -# cd .. -fi -if [[ $VERSION = "ENT" ]] ; then - WORD="LiteSpeed Enterprise" - if [[ $SERVER_COUNTRY != "CN" ]] ; then - /usr/local/lsws/admin/misc/lsup.sh -f -v $LSWS_STABLE_VER - fi -fi - -systemctl status lsws 2>&1>/dev/null -if [[ $? == "0" ]] ; then - echo "LSWS service is running..." -else - systemctl stop lsws - systemctl start lsws -fi - -clear -echo "###################################################################" -echo " CyberPanel Successfully Installed " -echo " " -echo " Current Disk usage : $DISK2 " -echo " " -echo " Current RAM usage : $RAM2 " -echo " " -echo " Installation time : $ELAPSED " -echo " " -echo " Visit: https://$SERVER_IP:8090 " -echo " Panel username: admin " -echo " Panel password: $ADMIN_PASS " -#echo " Mysql username: root " -#echo " Mysql password: $MYSQLPASSWD " -echo " " -echo " Please change your default admin password " -echo " If you need to reset your panel password, please run: " -echo " adminPass YOUR_NEW_PASSWORD " -echo " " -echo " If you change mysql password, please modify file in " -echo -e " \e[31m/etc/cyberpanel/mysqlPassword\e[39m with new password as well " -echo " " -echo " Website : https://www.cyberpanel.net " -echo " Forums : https://forums.cyberpanel.net " -echo " Wikipage: https://cyberpanel.net/KnowledgeBase/ " -echo " " -echo -e " Enjoy your accelerated Internet by " -echo -e " CyberPanel & $WORD " -echo "###################################################################" -if [[ $PROVIDER != "undefined" ]] ; then - echo -e "\033[0;32m$PROVIDER\033[39m detected..." - echo -e "This provider has a \e[31mnetwork-level firewall\033[39m" -else - echo -e "If your provider has a \e[31mnetwork-level firewall\033[39m" -fi - echo -e "Please make sure you have opened following port for both in/out:" - echo -e "\033[0;32mTCP: 8090\033[39m for CyberPanel" - echo -e "\033[0;32mTCP: 80\033[39m, \033[0;32mTCP: 443\033[39m and \033[0;32mUDP: 443\033[39m for webserver" - echo -e "\033[0;32mTCP: 21\033[39m and \033[0;32mTCP: 40110-40210\033[39m for FTP" - echo -e "\033[0;32mTCP: 25\033[39m, \033[0;32mTCP: 587\033[39m, \033[0;32mTCP: 465\033[39m, \033[0;32mTCP: 110\033[39m, \033[0;32mTCP: 143\033[39m and \033[0;32mTCP: 993\033[39m for mail service" - echo -e "\033[0;32mTCP: 53\033[39m and \033[0;32mUDP: 53\033[39m for DNS service" -if [[ $SERVER_COUNTRY = CN ]] ; then - if [[ $PROVIDER == "Tencent Cloud" ]] ; then - if [[ $SERVER_OS == "Ubuntu" ]] ; then - rm -f /etc/apt/sources.list - mv /etc/apt/sources.list-backup /etc/apt/sources.list -echo > "nameserver 127.0.0.53 -options edns0" /run/systemd/resolve/stub-resolv.conf -echo > "nameserver 127.0.0.53 -options edns0" /etc/resolv.conf - apt update -#revert the previous change on tencent cloud repo. - fi - fi - if [[ $VERSION = "ENT" ]] ; then - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/install/installCyberPanel.py - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py - sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py - echo -e "If you have install LiteSpeed Enterprise, please run \e[31m/usr/local/lsws/admin/misc/lsup.sh\033[39m to update it to latest." - fi -fi - -sed -i 's|lsws-5.3.8|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py -sed -i 's|lsws-5.4.2|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py -sed -i 's|lsws-5.3.5|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py -sed -i 's|lsws-6.0|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py -sed -i 's|lsws-6.3.4|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py - -if [[ $SILENT != "ON" ]] ; then -printf "%s" "Would you like to restart your server now? [y/N]: " -read TMP_YN - -if [[ "$TMP_YN" = "N" ]] || [[ "$TMP_YN" = "n" ]] || [[ -z "$TMP_YN" ]]; then -: -else -reboot -exit -fi - -exit -fi -#replace URL for CN - - - -else -echo "something went wrong..." -exit -fi -} - -argument_mode() { -KEY_SIZE=${#VERSION} -TMP=$(echo $VERSION | cut -c5) -TMP2=$(echo $VERSION | cut -c10) -TMP3=$(echo $VERSION | cut -c15) -if [[ $VERSION == "OLS" || $VERSION == "ols" ]] ; then - VERSION="OLS" - echo -e "\nSet to OpenLiteSpeed..." -elif [[ $VERSION == "Trial" ]] || [[ $VERSION == "TRIAL" ]] || [[ $VERSION == "trial" ]] ; then - VERSION="ENT" - LICENSE_KEY="TRIAL" - echo -e "\nLiteSpeed Enterprise trial license set..." -elif [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then - LICENSE_KEY=$VERSION - VERSION="ENT" - echo -e "\nLiteSpeed Enterprise license key set..." -else - echo -e "\nCan not recognize the input value \e[31m$VERSION\e[39m " - echo -e "\nPlease verify the input value..." - echo -e "\nPlease run with \e[31m-h\e[39m or \e[31m--help\e[39m for more detail." - exit -fi - -if [[ $ADMIN_PASS == "d" ]] ; then - ADMIN_PASS="1234567" - echo -e "\nSet to default password..." - echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" -elif [[ $ADMIN_PASS == "r" ]] ; then - ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') - echo -e "\nSet to random-generated password..." - echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" - echo $ADMIN_PASS -else - echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" -fi -} - -if [ $# -eq 0 ] ; then - echo -e "\nInitializing...\n" -else - if [[ $1 == "help" ]] ; then - show_help - exit - elif [[ $1 == "dev" ]] ; then - DEV="ON" - DEV_ARG="ON" - SILENT="OFF" - elif [[ $1 == "default" ]] ; then - echo -e "\nThis will start default installation...\n" - SILENT="ON" - POSTFIX_VARIABLE="ON" - POWERDNS_VARIABLE="ON" - PUREFTPD_VARIABLE="ON" - VERSION="OLS" - ADMIN_PASS="1234567" - MEMCACHED="ON" - REDIS="ON" - else - while [ ! -z "${1}" ]; do - case $1 in - -v | --version) shift - if [ "${1}" = '' ]; then - show_help - exit - else - VERSION="${1}" - SILENT="ON" - fi - ;; - -p | --password) shift - if [[ "${1}" == '' ]]; then - ADMIN_PASS="1234567" - elif [[ "${1}" == 'r' ]] || [[ $1 == 'random' ]] ; then - ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') - else - if [ ${1} -lt 8 ] ; then - echo -e "\nPassword lenth less than 8 digital, please choose a more complicated password.\n" - exit - fi - ADMIN_PASS="${1}" - fi - ;; - -a | --addons) - MEMCACHED="ON" - REDIS="ON" - ;; - -m | --minimal) - echo "minimal installation is still work in progress..." - exit - ;; - -h | --help) - show_help - exit - ;; - *) - echo "unknown argument..." - show_help - exit - ;; - esac - shift - done - fi -fi - - - -SERVER_IP=$(curl --silent --max-time 10 -4 https://cyberpanel.sh/?ip) -if [[ $SERVER_IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo -e "Valid IP detected..." -else - echo -e "Can not detect IP, exit..." - exit -fi -SERVER_COUNTRY="unknow" -SERVER_COUNTRY=$(curl --silent --max-time 5 https://cyberpanel.sh/?country) -if [[ ${#SERVER_COUNTRY} == "2" ]] || [[ ${#SERVER_COUNTRY} == "6" ]] ; then - echo -e "\nChecking server..." - else - echo -e "\nChecking server..." - SERVER_COUNTRY="unknow" -fi -#SERVER_COUNTRY="CN" -#test string -if [[ $SERVER_COUNTRY == "CN" ]] ; then -DOWNLOAD_SERVER="cyberpanel.sh" -else -DOWNLOAD_SERVER="cdn.cyberpanel.sh" -fi - -check_OS -check_root -check_panel -check_process -check_provider - - - - - -if [[ $SILENT = "ON" ]] ; then -argument_mode -else -interactive_mode -fi - -SECONDS=0 -install_required - -pip_virtualenv - -system_tweak - -main_install \ No newline at end of file diff --git a/install/venvsetup_modules/01_vars_install_required.sh b/install/venvsetup_modules/01_vars_install_required.sh new file mode 100644 index 000000000..419e930b8 --- /dev/null +++ b/install/venvsetup_modules/01_vars_install_required.sh @@ -0,0 +1,423 @@ +#!/usr/bin/env bash +# install/venvsetup part 1 +#!/bin/bash + +#CyberPanel installer script for Ubuntu 18.04 and CentOS 7.X +DEV="OFF" +BRANCH="stable" +POSTFIX_VARIABLE="ON" +POWERDNS_VARIABLE="ON" +PUREFTPD_VARIABLE="ON" +PROVIDER="undefined" +SERIAL_NO="" +DIR=$(pwd) +TEMP=$(curl --silent https://cyberpanel.net/version.txt) +CP_VER1=${TEMP:12:3} +CP_VER2=${TEMP:25:1} +SERVER_OS="CentOS" +VERSION="OLS" +LICENSE_KEY="" +KEY_SIZE="" +ADMIN_PASS="1234567" +MEMCACHED="ON" +REDIS="ON" +MARIADB_VER="11.8" +TOTAL_RAM=$(free -m | awk '/Mem\:/ { print $2 }') + +# Robust pip install function to handle broken pipe errors +safe_pip_install() { + local pip_cmd="$1" + local requirements_file="$2" + local install_args="$3" + + echo "Installing Python packages..." + + # Method 1: Install with full error suppression and broken pipe handling + 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" + return 0 + fi + + # Method 2: Install with even more aggressive error suppression + echo "⚠️ Trying fallback installation method..." + 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" + return 0 + fi + + # Method 3: Install packages individually to avoid broken pipes + echo "⚠️ Trying individual package installation..." + while IFS= read -r line; do + # Skip empty lines and comments + [[ -z "$line" || "$line" =~ ^#.*$ ]] && continue + + # 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 +} + +license_validation() { +CURRENT_DIR=$(pwd) + +if [ -f /root/cyberpanel-tmp ] ; then +rm -rf /root/cyberpanel-tmp +fi + +mkdir /root/cyberpanel-tmp +cd /root/cyberpanel-tmp +wget -q https://$DOWNLOAD_SERVER/litespeed/lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz +tar xzvf lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz > /dev/null +cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/conf +if [[ $LICENSE_KEY == "TRIAL" ]] ; then +wget -q http://license.litespeedtech.com/reseller/trial.key +sed -i "s|writeSerial = open('lsws-5.4.2/serial.no', 'w')|command = 'wget -q --output-document=./lsws-$LSWS_STABLE_VER/trial.key http://license.litespeedtech.com/reseller/trial.key'|g" $CURRENT_DIR/installCyberPanel.py +sed -i 's|writeSerial.writelines(self.serial)|subprocess.call(command, shell=True)|g' $CURRENT_DIR/installCyberPanel.py +sed -i 's|writeSerial.close()||g' $CURRENT_DIR/installCyberPanel.py +else +echo $LICENSE_KEY > serial.no +fi + +cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/bin + +if [[ $LICENSE_KEY == "TRIAL" ]] ; then + if ./lshttpd -V |& grep "ERROR" ; then + echo -e "\n\nIt apeears to have some issue with license , please check above result..." + exit + fi + LICENSE_KEY="1111-2222-3333-4444" +else + if ./lshttpd -r |& grep "ERROR" ; then + ./lshttpd -r + echo -e "\n\nIt apeears to have some issue with license , please check above result..." + exit + fi +fi +echo -e "License seems valid..." +cd /root/cyberpanel-tmp +rm -rf lsws-$LSWS_STABLE_VER* +cd $CURRENT_DIR +rm -rf /root/cyberpanel-tmp +} + +special_change(){ +sed -i 's|cyberpanel.sh|'$DOWNLOAD_SERVER'|g' install.py +sed -i 's|mirror.cyberpanel.net|'$DOWNLOAD_SERVER'|g' install.py +sed -i 's|git clone https://github.com/usmannasir/cyberpanel|echo downloaded|g' install.py +#change to CDN first, regardless country +sed -i 's|http://|https://|g' install.py + +LATEST_URL="https://update.litespeedtech.com/ws/latest.php" +#LATEST_URL="https://cyberpanel.sh/latest.php" +curl --silent -o /tmp/lsws_latest $LATEST_URL 2>/dev/null +LSWS_STABLE_LINE=`cat /tmp/lsws_latest | grep LSWS_STABLE` +LSWS_STABLE_VER=`expr "$LSWS_STABLE_LINE" : '.*LSWS_STABLE=\(.*\) BUILD .*'` +# Fallback to LSWS 6.3.4 (Stable) if fetch failed or empty +if [ -z "$LSWS_STABLE_VER" ]; then + LSWS_STABLE_VER="6.3.4" +fi + +if [[ $SERVER_COUNTRY == "CN" ]] ; then +#line1="$(grep -n "github.com/usmannasir/cyberpanel" install.py | head -n 1 | cut -d: -f1)" +#line2=$((line1 - 1)) +#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py +#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'tar xzvf cyberpanel-git.tar.gz'" install.py +#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py +#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'wget cyberpanel.sh/cyberpanel-git.tar.gz'" install.py +sed -i 's|wget https://rpms.litespeedtech.com/debian/|wget --no-check-certificate https://rpms.litespeedtech.com/debian/|g' install.py +sed -i 's|https://repo.powerdns.com/repo-files/centos-auth-42.repo|https://'$DOWNLOAD_SERVER'/powerdns/powerdns.repo|g' installCyberPanel.py +sed -i 's|https://snappymail.eu/repository/latest.tar.gz|https://'$DOWNLOAD_SERVER'/repository/latest.tar.gz|g' install.py + +sed -i 's|rpm -ivh https://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el7.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://'$DOWNLOAD_SERVER'/litespeed/litespeed.repo|g' install.py + + +sed -i 's|https://copr.fedorainfracloud.org/coprs/copart/restic/repo/epel-7/copart-restic-epel-7.repo|https://'$DOWNLOAD_SERVER'/restic/restic.repo|g' install.py + +sed -i 's|yum -y install https://cyberpanel.sh/gf-release-latest.gf.el7.noarch.rpm|wget -O /etc/yum.repos.d/gf.repo https://'$DOWNLOAD_SERVER'/gf-plus/gf.repo|g' install.py +sed -i 's|dovecot-2.3-latest|dovecot-2.3-latest-mirror|g' install.py +sed -i 's|git clone https://github.com/usmannasir/cyberpanel|wget https://cyberpanel.sh/cyberpanel-git.tar.gz \&\& tar xzvf cyberpanel-git.tar.gz|g' install.py +sed -i 's|https://repo.dovecot.org/ce-2.3-latest/centos/$releasever/RPMS/$basearch|https://'$DOWNLOAD_SERVER'/dovecot/|g' install.py +sed -i 's|'$DOWNLOAD_SERVER'|cyberpanel.sh|g' install.py +sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.4.2-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' installCyberPanel.py +# global change for CN , regardless provider and system + + if [[ $SERVER_OS == "CentOS" ]] ; then + DIR=$(pwd) + cd $DIR/mysql + echo "[mariadb-tsinghua] +name = MariaDB +baseurl = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum/10.1/centos7-amd64 +gpgkey = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum//RPM-GPG-KEY-MariaDB +gpgcheck = 1" > MariaDB.repo +#above to set mariadb db to Tsinghua repo + cd $DIR + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' installCyberPanel.py + mkdir /root/.pip + cat << EOF > /root/.pip/pip.conf +[global] +index-url = https://mirrors.aliyun.com/pypi/simple/ +EOF + echo -e "\nSet to Aliyun pip repo..." + cat << EOF > composer.sh +#!/usr/bin/env bash +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php composer-setup.php +php -r "unlink('composer-setup.php');" +mv composer.phar /usr/bin/composer + +if [ ! -d /root/.config ]; then +mkdir /root/.config +fi + +if [ ! -d /root/.config/composer ]; then +mkdir /root/.config/composer +fi + +echo '{ + "bitbucket-oauth": {}, + "github-oauth": {}, + "gitlab-oauth": {}, + "gitlab-token": {}, + "http-basic": {} +} +' > /root/.config/composer/auth.json + +echo '{ + "config": {}, + "repositories": { + "packagist": { + "type": "composer", + "url": "https://mirrors.aliyun.com/composer/" + } + } +} +' > /root/.config/composer/config.json +composer clear-cache +EOF + fi + + + if [[ $SERVER_OS == "Ubuntu" ]] ; then + echo $'\n89.208.248.38 rpms.litespeedtech.com\n' >> /etc/hosts + echo -e "Mirror server set..." + pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ + cat << EOF > /root/.pip/pip.conf +[global] +index-url = https://mirrors.aliyun.com/pypi/simple/ +EOF + echo -e "\nSet to Aliyun pip repo..." + if [[ $PROVIDER == "Tencent Cloud" ]] ; then + #tencent cloud and ubuntu system + echo -e "\n Tencent Cloud detected ... bypass default repository" + cp /etc/apt/sources.list /etc/apt/sources.list-backup + #backup original sources list + cat << 'EOF' > /etc/apt/sources.list +deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +EOF + DEBIAN_FRONTEND=noninteractive apt update -y + pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ + cat << EOF > composer.sh +#!/usr/bin/env bash +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php composer-setup.php +php -r "unlink('composer-setup.php');" +mv composer.phar /usr/bin/composer + +if [ ! -d /root/.config ]; then +mkdir /root/.config +fi + +if [ ! -d /root/.config/composer ]; then +mkdir /root/.config/composer +fi + +echo '{ + "bitbucket-oauth": {}, + "github-oauth": {}, + "gitlab-oauth": {}, + "gitlab-token": {}, + "http-basic": {} +} +' > /root/.config/composer/auth.json + +echo '{ + "config": {}, + "repositories": { + "packagist": { + "type": "composer", + "url": "https://mirrors.cloud.tencent.com/composer/" + } + } +} +' > /root/.config/composer/config.json +composer clear-cache +EOF + else + cat << EOF > composer.sh +#!/usr/bin/env bash +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php composer-setup.php +php -r "unlink('composer-setup.php');" +mv composer.phar /usr/bin/composer + +if [ ! -d /root/.config ]; then +mkdir /root/.config +fi + +if [ ! -d /root/.config/composer ]; then +mkdir /root/.config/composer +fi + +echo '{ + "bitbucket-oauth": {}, + "github-oauth": {}, + "gitlab-oauth": {}, + "gitlab-token": {}, + "http-basic": {} +} +' > /root/.config/composer/auth.json + +echo '{ + "config": {}, + "repositories": { + "packagist": { + "type": "composer", + "url": "https://packagist.phpcomposer.com" + } + } +} +' > /root/.config/composer/config.json +composer clear-cache +EOF + fi + fi +fi +} + + +system_tweak() { +if [[ $SERVER_OS == "CentOS" ]] ; then + setenforce 0 + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config +fi + +if ! grep -q "pid_max" /etc/rc.local; then + if [[ $SERVER_OS == "CentOS" ]] ; then + echo "echo 1000000 > /proc/sys/kernel/pid_max +echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.d/rc.local + chmod +x /etc/rc.d/rc.local + else + echo "echo 1000000 > /proc/sys/kernel/pid_max +echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.local + chmod +x /etc/rc.local + fi + echo "fs.file-max = 65535" >> /etc/sysctl.conf + sysctl -p > /dev/null + echo "* soft nofile 65535 +* hard nofile 65535 +root soft nofile 65535 +root hard nofile 65535 +* soft nproc 65535 +* hard nproc 65535 +root soft nproc 65535 +root hard nproc 65535" >> /etc/security/limits.conf +fi + +#sed -i 's|#DefaultLimitNOFILE=|DefaultLimitNOFILE=65535|g' /etc/systemd/system.conf + + +TOTAL_SWAP=$(free -m | awk '/^Swap:/ { print $2 }') +SET_SWAP=$((TOTAL_RAM - TOTAL_SWAP)) +SWAP_FILE=/cyberpanel.swap + +if [ ! -f $SWAP_FILE ] ; then + if [[ $TOTAL_SWAP -gt $TOTAL_RAM ]] || [[ $TOTAL_SWAP -eq $TOTAL_RAM ]] ; then + echo "SWAP check..." + else + if [[ $SET_SWAP -gt "2049" ]] ; then + SET_SWAP="2048" + else + echo "Checking SWAP..." + fi + fallocate --length ${SET_SWAP}MiB $SWAP_FILE + chmod 600 $SWAP_FILE + mkswap $SWAP_FILE + swapon $SWAP_FILE + echo "${SWAP_FILE} swap swap sw 0 0" | sudo tee -a /etc/fstab + sysctl vm.swappiness=10 + echo "vm.swappiness = 10" >> /etc/sysctl.conf + echo "SWAP set..." + fi +fi +} + + +install_required() { +echo -e "\nInstalling necessary components..." +if [[ $SERVER_OS == "CentOS" ]] ; then + rpm --import https://$DOWNLOAD_SERVER/mariadb/RPM-GPG-KEY-MariaDB + rpm --import https://$DOWNLOAD_SERVER/litespeed/RPM-GPG-KEY-litespeed + rpm --import https://$DOWNLOAD_SERVER/powerdns/FD380FBB-pub.asc + rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 + rpm --import https://$DOWNLOAD_SERVER/gf-plus/RPM-GPG-KEY-gf.el7 + rpm --import https://repo.dovecot.org/DOVECOT-REPO-GPG + rpm --import https://copr-be.cloud.fedoraproject.org/results/copart/restic/pubkey.gpg + yum autoremove epel-release -y + rm -f /etc/yum.repos.d/epel.repo + rm -f /etc/yum.repos.d/epel.repo.rpmsave + yum clean all + yum update -y + yum install epel-release -y + yum install -y wget strace htop net-tools telnet curl which bc telnet htop libevent-devel gcc python-devel libattr-devel xz-devel gpgme-devel mariadb-devel curl-devel python-pip git + if [[ $DEV == "ON" ]] ; then + yum -y install yum-utils + yum -y groupinstall development + yum -y install https://centos7.iuscommunity.org/ius-release.rpm + yum -y install python36u python36u-pip python36u-devel + fi +fi + +if [[ $SERVER_OS == "Ubuntu" ]] ; then + apt update -y + DEBIAN_FRONTEND=noninteractive apt upgrade -y + + # Check if this is Debian (no lsb-release) and version >= 13 + if [[ ! -f /etc/lsb-release ]] && [[ -f /etc/debian_version ]]; then + DEBIAN_VERSION=$(cat /etc/debian_version | cut -d'.' -f1) + if [[ $DEBIAN_VERSION -ge 13 ]]; then + # Debian 13 (Trixie) package mappings + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python3-mysqldb python3-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python3-gpg python3 python3-setuptools virtualenv python3-dev python3-pip git + elif [[ $DEBIAN_VERSION -ge 12 ]]; then + # Debian 12 (Bookworm) package mappings + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python3-mysqldb python3-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python3-gpg python3 python3-setuptools virtualenv python3-dev python3-pip git + else + # Older Debian versions + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python-mysqldb python-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python-gpg python python-minimal python-setuptools virtualenv python-dev python-pip git + fi + else + # Ubuntu or older Debian with compatible package names + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python-mysqldb python-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python-gpg python python-minimal python-setuptools virtualenv python-dev python-pip git + fi + if [[ $DEV == "ON" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install -y python3-pip + DEBIAN_FRONTEND=noninteractive apt install -y build-essential libssl-dev libffi-dev python3-dev + DEBIAN_FRONTEND=noninteractive apt install -y python3-venv + fi +fi +} diff --git a/install/venvsetup_modules/02_memcached_main.sh b/install/venvsetup_modules/02_memcached_main.sh new file mode 100644 index 000000000..f8996753d --- /dev/null +++ b/install/venvsetup_modules/02_memcached_main.sh @@ -0,0 +1,499 @@ +#!/usr/bin/env bash +# install/venvsetup part 2 – memcached through main_install + +memcached_installation() { +if [[ $SERVER_OS == "CentOS" ]] ; then + yum install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached lsphp56-pecl-memcached lsphp55-pecl-memcached lsphp54-pecl-memcached + if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then + yum groupinstall "Development Tools" -y + yum install autoconf automake zlib-devel openssl-devel expat-devel pcre-devel libmemcached-devel cyrus-sasl* -y + wget https://$DOWNLOAD_SERVER/litespeed/lsmcd.tar.gz + tar xzvf lsmcd.tar.gz + DIR=$(pwd) + cd $DIR/lsmcd + ./fixtimestamp.sh + ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" + make + make install + systemctl enable lsmcd + systemctl start lsmcd + cd $DIR + else + yum install -y memcached + sed -i 's|OPTIONS=""|OPTIONS="-l 127.0.0.1 -U 0"|g' /etc/sysconfig/memcached + systemctl enable memcached + systemctl start memcached + fi +fi +if [[ $SERVER_OS == "Ubuntu" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached + if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install build-essential zlib1g-dev libexpat1-dev openssl libssl-dev libsasl2-dev libpcre3-dev git -y + wget https://$DOWNLOAD/litespeed/lsmcd.tar.gz + tar xzvf lsmcd.tar.gz + DIR=$(pwd) + cd $DIR/lsmcd + ./fixtimestamp.sh + ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" + make + make install + cd $DIR + systemctl enable lsmcd + systemctl start lsmcd + else + DEBIAN_FRONTEND=noninteractive apt install -y memcached + systemctl enable memcached + systemctl start memcached + fi +fi + +if ps -aux | grep "lsmcd" | grep -v grep ; then + echo -e "\n\nLiteSpeed Memcached installed and running..." +fi + +if ps -aux | grep "memcached" | grep -v grep ; then + echo -e "\n\nMemcached installed and running..." +fi + +} + +redis_installation() { +if [[ $SERVER_OS == "CentOS" ]] ; then + yum install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis lsphp56-redis lsphp55-redis lsphp54-redis redis +fi +if [[ $SERVER_OS == "Ubuntu" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis redis +fi + +if ifconfig -a | grep inet6 ; then + echo -e "\n IPv6 detected..." +else + sed -i 's|bind 127.0.0.1 ::1|bind 127.0.0.1|g' /etc/redis/redis.conf + echo -e "\n no IPv6 detected..." +fi + +if [[ $SERVER_OS == "CentOS" ]] ; then + systemctl enable redis + systemctl start redis +fi + +if [[ $SERVER_OS == "Ubuntu" ]] ; then + systemctl enable redis-server + systemctl start redis-server +fi + +if ps -aux | grep "redis" | grep -v grep ; then + echo -e "\n\nRedis installed and running..." +fi +} + +check_provider() { + +if hash dmidecode > /dev/null 2>&1 ; then + if [ "$(dmidecode -s bios-vendor)" = 'Google' ] ; then + PROVIDER='Google Cloud Platform' + elif [ "$(dmidecode -s bios-vendor)" = 'DigitalOcean' ] ; then + PROVIDER='Digital Ocean' + elif [ "$(dmidecode -s system-product-name | cut -c 1-7)" = 'Alibaba' ] ; then + PROVIDER='Alibaba Cloud' + elif [ "$(dmidecode -s system-manufacturer)" = 'Microsoft Corporation' ] ; then + PROVIDER='Microsoft Azure' + elif [ -d /usr/local/qcloud ] ; then + PROVIDER='Tencent Cloud' + else + PROVIDER='undefined' + fi +else + PROVIDER='undefined' +fi + +if [ "$(cat /sys/devices/virtual/dmi/id/product_uuid | cut -c 1-3)" = 'EC2' ] && [ -d /home/ubuntu ]; then + PROVIDER='Amazon Web Service' +fi + +} + + +check_OS() { +echo -e "\nChecking OS..." +OUTPUT=$(cat /etc/*release) +if echo $OUTPUT | grep -q "CentOS Linux 7" ; then + echo -e "\nDetecting CentOS 7.X...\n" + SERVER_OS="CentOS" +elif echo $OUTPUT | grep -q "CloudLinux 7" ; then + echo -e "\nDetecting CloudLinux 7.X...\n" + SERVER_OS="CentOS" +elif echo $OUTPUT | grep -q "Ubuntu 18.04" ; then + echo -e "\nDetecting Ubuntu 18.04...\n" + SERVER_OS="Ubuntu" +else + cat /etc/*release + echo -e "\nUnable to detect your OS...\n" + echo -e "\nCyberPanel is supported on Ubuntu 18.04, CentOS 7.x and CloudLinux 7.x...\n" + exit 1 +fi +} + +check_root() { +echo -e "Checking root privileges...\n" +if [[ $(id -u) != 0 ]] > /dev/null; then + echo -e "You must use root account to do this" + echo -e "or run following command: (do NOT miss the quotes)" + echo -e "\e[31msudo su -c \"sh <(curl https://cyberpanel.sh || wget -O - https://cyberpanel.sh)\"\e[39m" + exit 1 +else + echo -e "You are runing as root...\n" +fi +} + +check_panel() { +if [ -d /usr/local/cpanel ]; then + echo -e "\ncPanel detected...exit...\n" + exit 1 +fi +if [ -d /opt/plesk ]; then + echo -e "\nPlesk detected...exit...\n" + exit 1 +fi +} + +check_process() { +if systemctl is-active --quiet httpd; then + systemctl disable httpd + systemctl stop httpd + echo -e "\nhttpd process detected, disabling...\n" +fi +if systemctl is-active --quiet apache2; then + systemctl disable apache2 + systemctl stop apache2 + echo -e "\napache2 process detected, disabling...\n" +fi +if systemctl is-active --quiet named; then + systemctl stop named + systemctl disable named + echo -e "\nnamed process detected, disabling...\n" +fi +if systemctl is-active --quiet exim; then + systemctl stop exim + systemctl disable exim + echo -e "\nexim process detected, disabling...\n" +fi +} + +show_help() { +echo -e "\nCyberPanel Installer Script Help\n" +echo -e "\nUsage: wget https://cyberpanel.sh/cyberpanel.sh" +echo -e "\nchmod +x cyberpanel.sh" +echo -e "\n./cyberpanel.sh -v ols/SERIAL_NUMBER -c 1 -a 1" +echo -e "\n -v or --version: choose to install CyberPanel OpenLiteSpeed or CyberPanel Enterprise, available options are \e[31mols\e[39m and \e[31mSERIAL_NUMBER\e[39m, default ols" +echo -e "\n Please be aware, this serial number must be obtained from LiteSpeed Store." +echo -e "\n And if this serial number has been used before, it must be released/migrated in Store first, otherwise it will fail to start." +echo -e "\n -a or --addons: install addons: memcached, redis, PHP extension for memcached and redis, 1 for install addons, 0 for not to install, default 0, only applicable for CentOS system." +echo -e "\n -p or --password: set password of new installation, empty for default 1234567, [r] or [random] for randomly generated 16 digital password, any other value besdies [d] and [r(andom)] will be accept as password, default use 1234567." +#echo -e "\n -m: set to minimal mode which will not install PowerDNS, Pure-FTPd and Postfix" +echo -e "\n Example:" +echo -e "\n ./cyberpanel.sh -v ols -p r or ./cyberpanel.sh --version ols --password random" +echo -e "\n This will install CyberPanel OpenLiteSpeed and randomly generate the password." +echo -e "\n ./cyberpanel.sh default" +echo -e "\n This will install everything default , which is OpenLiteSpeed and nothing more.\n" + +} + +license_input() { +VERSION="ENT" +echo -e "\nPlease note that your server has \e[31m$TOTAL_RAM\e[39m RAM" +echo -e "If you are using \e[31mFree Start\e[39m license, It will not start due to \e[31m2GB RAM limit\e[39m.\n" +echo -e "If you do not have any license, you can also use trial license (if server has not used trial license before), type \e[31mTRIAL\e[39m\n" + +printf "%s" "Please input your serial number for LiteSpeed WebServer Enterprise:" +read LICENSE_KEY +if [ -z "$LICENSE_KEY" ] ; then + echo -e "\nPlease provide license key\n" + exit +fi + +echo -e "The serial number you input is: \e[31m$LICENSE_KEY\e[39m" +printf "%s" "Please verify it is correct. [y/N]" +read TMP_YN +if [ -z "$TMP_YN" ] ; then + echo -e "\nPlease type \e[31my\e[39m\n" + exit +fi + +KEY_SIZE=${#LICENSE_KEY} +TMP=$(echo $LICENSE_KEY | cut -c5) +TMP2=$(echo $LICENSE_KEY | cut -c10) +TMP3=$(echo $LICENSE_KEY | cut -c15) + +if [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then + echo -e "\nLicense key set..." +elif [[ $LICENSE_KEY == "trial" ]] || [[ $LICENSE_KEY == "TRIAL" ]] || [[ $LICENSE_KEY == "Trial" ]] ; then + echo -e "\nTrial license set..." + LICENSE_KEY="TRIAL" +else + echo -e "\nLicense key seems incorrect, please verify\n" + echo -e "\nIf you are copying/pasting, please make sure you didn't paste blank space...\n" + exit +fi +} + +interactive_mode() { +echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 + + 1. Install CyberPanel. + + 2. Addons and Miscellaneous + + 3. Exit. + + " +read -p " Please enter the number[1-3]: " num +echo "" +case "$num" in + 1) + interactive_install + ;; + 2) + interactive_others + ;; + 3) + exit + ;; + *) + echo -e " Please enter the right number [1-3]\n" + exit + ;; +esac +} + +interactive_others() { +if [ ! -e "/etc/cyberpanel/machineIP" ]; then +echo -e "\nYou don't have CyberPanel installed...\n" +exit +fi + +echo -e " CyberPanel Addons v$CP_VER1$CP_VER2 + + 1. Install Memcached extension and backend + + 2. Install Redis extension and backend + + 3. Return to main page. + + 4. Exit + " + +echo && read -p "Please enter the number[1-4]: " num +case "$num" in + 1) + memcached_installation + exit + ;; + 2) + redis_installation + exit + ;; + 3) + interactive_mode + ;; + 4) + exit + ;; + *) + echo -e "${Error} please enter the right number [1-4]" + ;; +esac +} + +interactive_install() { +RAM=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') +DISK=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') +#clear +echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 + + RAM check : $RAM + + Disk check : $DISK (Minimal \e[31m10GB\e[39m free space) + + 1. Install CyberPanel with \e[31mOpenLiteSpeed\e[39m. + + 2. Install Cyberpanel with \e[31mLiteSpeed Enterprise\e[39m. + + 3. Exit. + + " +read -p " Please enter the number[1-3]: " num +echo "" +case "$num" in + 1) + VERSION="OLS" + ;; + 2) + license_input + ;; + 3) + exit + ;; + *) + echo -e " Please enter the right number [1-3]\n" + exit + ;; +esac + +< /dev/null; then + echo -e "\nCyberPanel installation sucessfully completed..." +else + echo -e "Oops, something went wrong..." + exit +fi + +if [[ $MEMCACHED == "ON" ]] ; then + memcached_installation +fi +if [[ $REDIS == "ON" ]] ; then + redis_installation +fi + after_install +fi +} + +pip_virtualenv() { +if [[ $DEV == "OFF" ]] ; then +if [[ $SERVER_COUNTRY == "CN" ]] ; then + mkdir /root/.pip +cat << EOF > /root/.pip/pip.conf +[global] +index-url = https://mirrors.aliyun.com/pypi/simple/ +EOF +fi + +if [[ $PROVIDER == "Alibaba Cloud" ]] ; then + pip install --upgrade pip 2>/dev/null || echo "⚠️ pip upgrade completed with warnings" + pip install setuptools==40.8.0 2>/dev/null || echo "⚠️ setuptools installation completed with warnings" +fi + +pip install virtualenv 2>/dev/null || echo "⚠️ virtualenv installation completed with warnings" + +# Create virtual environment with fallback for Ubuntu 22.04 compatibility +echo "Creating CyberPanel virtual environment..." +if python3 -m venv --system-site-packages /usr/local/CyberPanel 2>&1 | grep -q "unrecognized option"; then + # Fallback to virtualenv if python3 -m venv doesn't support --system-site-packages + virtualenv --system-site-packages /usr/local/CyberPanel +elif python3 -m venv --system-site-packages /usr/local/CyberPanel 2>/dev/null; then + echo "Virtual environment created successfully using python3 -m venv" +else + # Final fallback to virtualenv + virtualenv --system-site-packages /usr/local/CyberPanel +fi + +source /usr/local/CyberPanel/bin/activate +rm -rf requirements.txt +wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/1.8.0/requirments.txt +# Install packages with robust error handling to prevent broken pipe errors +safe_pip_install "pip" "requirements.txt" "--ignore-installed" +fi + +if [[ $DEV == "ON" ]] ; then + #install dev branch + #wget https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt + cd /usr/local/ + python3.6 -m venv CyberPanel + source /usr/local/CyberPanel/bin/activate + + # Try to download requirements file with fallback options + echo "Attempting to download requirements for branch/commit: $BRANCH_NAME" + + # First try the specified branch/commit + if wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt 2>/dev/null; then + echo "Successfully downloaded requirements from $BRANCH_NAME" + elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments-old.txt 2>/dev/null; then + echo "Successfully downloaded requirements-old.txt from $BRANCH_NAME" + elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/requirments.txt 2>/dev/null; then + echo "Fallback: Downloaded requirements from stable branch" + else + echo "Warning: Could not download requirements file, using minimal default requirements" + cat > requirements.txt << 'EOF' +# Minimal CyberPanel requirements - fallback when requirements file is not available +Django==3.2.25 +PyMySQL==1.1.0 +requests==2.31.0 +cryptography==41.0.7 +psutil==5.9.6 +EOF + fi + + safe_pip_install "pip3.6" "requirements.txt" "--ignore-installed" +fi + +if [ -f requirements.txt ] && [ -d cyberpanel ] ; then + rm -rf cyberpanel + rm -f requirements.txt +fi + +if [[ $SERVER_COUNTRY == "CN" ]] ; then + wget https://cyberpanel.sh/cyberpanel-git.tar.gz + tar xzvf cyberpanel-git.tar.gz > /dev/null + cp -r cyberpanel /usr/local/cyberpanel + cd cyberpanel/install +else + if [[ $DEV == "ON" ]] ; then + git clone https://github.com/usmannasir/cyberpanel + cd cyberpanel + git checkout $BRANCH_NAME + cd - + cd cyberpanel/install + else + git clone https://github.com/usmannasir/cyberpanel + cd cyberpanel/install + fi +fi +curl https://cyberpanel.sh/?version +} diff --git a/install/venvsetup_modules/04_after_install.sh b/install/venvsetup_modules/04_after_install.sh new file mode 100644 index 000000000..fd9bd3e50 --- /dev/null +++ b/install/venvsetup_modules/04_after_install.sh @@ -0,0 +1,239 @@ +#!/usr/bin/env bash +# install/venvsetup part 4 – after_install + +after_install() { +if [ ! -d "/var/lib/php" ]; then + mkdir /var/lib/php +fi + +if [ ! -d "/var/lib/php/session" ]; then + mkdir /var/lib/php/session +fi + +chmod 1733 /var/lib/php/session + +if grep "\[ERROR\] We are not able to run ./install.sh return code: 1. Fatal error, see /var/log/installLogs.txt for full details" /var/log/installLogs.txt > /dev/null; then + cd ${DIR}/cyberpanel/install/lsws-* + ./install.sh + echo -e "\n\n\nIt seems LiteSpeed Enterprise has failed to install, please check your license key is valid" + echo -e "\nIf this license key has been used before, you may need to go to store to release it first." + exit +fi + + +if grep "CyberPanel installation successfully completed" /var/log/installLogs.txt > /dev/null; then + +if [[ $DEV == "ON" ]] ; then +python3.6 -m venv /usr/local/CyberCP +source /usr/local/CyberCP/bin/activate + +# Try to download requirements file with fallback options +echo "Attempting to download requirements for branch/commit: $BRANCH_NAME" + +# First try the specified branch/commit +if wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt 2>/dev/null; then + echo "Successfully downloaded requirements from $BRANCH_NAME" +elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments-old.txt 2>/dev/null; then + echo "Successfully downloaded requirements-old.txt from $BRANCH_NAME" +elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/requirments.txt 2>/dev/null; then + echo "Fallback: Downloaded requirements from stable branch" +else + echo "Warning: Could not download requirements file, using minimal default requirements" + cat > requirements.txt << 'EOF' +# Minimal CyberPanel requirements - fallback when requirements file is not available +Django==3.2.25 +PyMySQL==1.1.0 +requests==2.31.0 +cryptography==41.0.7 +psutil==5.9.6 +EOF +fi + +safe_pip_install "pip3.6" "requirements.txt" "--ignore-installed" +systemctl restart lscpd +fi + +for version in $(ls /usr/local/lsws | grep lsphp); + do + php_ini=$(find /usr/local/lsws/$version/ -name php.ini) + version2=${version:5:2} + version2=$(awk "BEGIN { print "${version2}/10" }") + if [[ $version2 = "7" ]] ; then + version2="7.0" + fi + if [[ $SERVER_OS == "CentOS" ]] ; then + yum remove -y $version-mysql + yum install -y $version-mysqlnd + yum install -y $version-devel make gcc glibc-devel libmemcached-devel zlib-devel + if [[ ! -d /usr/local/lsws/$version/tmp ]] ; then + mkdir /usr/local/lsws/$version/tmp + fi + /usr/local/lsws/${version}/bin/pecl channel-update pecl.php.net; + /usr/local/lsws/${version}/bin/pear config-set temp_dir /usr/local/lsws/${version}/tmp + /usr/local/lsws/${version}/bin/pecl install timezonedb + echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php.d/20-timezone.ini + sed -i 's|expose_php = On|expose_php = Off|g' $php_ini + sed -i 's|mail.add_x_header = On|mail.add_x_header = Off|g' $php_ini + sed -i 's|;session.save_path = "/tmp"|session.save_path = "/var/lib/php/session"|g' $php_ini + fi + + if [[ $SERVER_OS == "Ubuntu" ]] ; then + if [[ ! -d /usr/local/lsws/cyberpanel-tmp ]] ; then + echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone + systemctl restart pure-ftpd-mysql + DEBIAN_FRONTEND=noninteractive apt install libmagickwand-dev pkg-config build-essential -y + mkdir /usr/local/lsws/cyberpanel-tmp + cd /usr/local/lsws/cyberpanel-tmp + wget https://pecl.php.net/get/timezonedb-2019.3.tgz + tar xzvf timezonedb-2019.3.tgz + cd timezonedb-2019.3 + fi + /usr/local/lsws/${version}/bin/phpize + ./configure --with-php-config=/usr/local/lsws/${version}/bin/php-config${version2} + make + make install + # Only create .ini file if extension was successfully installed + # Check if timezonedb.so exists in the extension directory + ext_dir=$(/usr/local/lsws/${version}/bin/php-config${version2} --extension-dir) + if [[ -f "${ext_dir}/timezonedb.so" ]] ; then + mkdir -p /usr/local/lsws/${version}/etc/php/${version2}/mods-available + echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php/${version2}/mods-available/20-timezone.ini + fi + make clean + fi +done + +rm -rf /etc/profile.d/cyberpanel* +curl --silent -o /etc/profile.d/cyberpanel.sh https://cyberpanel.sh/?banner 2>/dev/null +chmod +x /etc/profile.d/cyberpanel.sh +RAM2=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') +DISK2=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') +ELAPSED="$(($SECONDS / 3600)) hrs $((($SECONDS / 60) % 60)) min $(($SECONDS % 60)) sec" +MYSQLPASSWD=$(cat /etc/cyberpanel/mysqlPassword) +echo "$ADMIN_PASS" > /etc/cyberpanel/adminPass +/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password $ADMIN_PASS +systemctl restart lscpd +systemctl restart lsws +echo "/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password \"\$@\"" > /usr/bin/adminPass +echo "systemctl restart lscpd" >> /usr/bin/adminPass +chmod +x /usr/bin/adminPass +if [[ $VERSION = "OLS" ]] ; then + WORD="OpenLiteSpeed" +# sed -i 's|maxConnections 10000|maxConnections 100000|g' /usr/local/lsws/conf/httpd_config.conf +# OLS_LATEST=$(curl https://openlitespeed.org/packages/release) +# wget https://openlitespeed.org/packages/openlitespeed-$OLS_LATEST.tgz +# tar xzvf openlitespeed-$OLS_LATEST.tgz +# cd openlitespeed +# ./install.sh + /usr/local/lsws/bin/lswsctrl stop + /usr/local/lsws/bin/lswsctrl start +# rm -f openlitespeed-$OLS_LATEST.tgz +# rm -rf openlitespeed +# cd .. +fi +if [[ $VERSION = "ENT" ]] ; then + WORD="LiteSpeed Enterprise" + if [[ $SERVER_COUNTRY != "CN" ]] ; then + /usr/local/lsws/admin/misc/lsup.sh -f -v $LSWS_STABLE_VER + fi +fi + +systemctl status lsws 2>&1>/dev/null +if [[ $? == "0" ]] ; then + echo "LSWS service is running..." +else + systemctl stop lsws + systemctl start lsws +fi + +clear +echo "###################################################################" +echo " CyberPanel Successfully Installed " +echo " " +echo " Current Disk usage : $DISK2 " +echo " " +echo " Current RAM usage : $RAM2 " +echo " " +echo " Installation time : $ELAPSED " +echo " " +echo " Visit: https://$SERVER_IP:8090 " +echo " Panel username: admin " +echo " Panel password: $ADMIN_PASS " +#echo " Mysql username: root " +#echo " Mysql password: $MYSQLPASSWD " +echo " " +echo " Please change your default admin password " +echo " If you need to reset your panel password, please run: " +echo " adminPass YOUR_NEW_PASSWORD " +echo " " +echo " If you change mysql password, please modify file in " +echo -e " \e[31m/etc/cyberpanel/mysqlPassword\e[39m with new password as well " +echo " " +echo " Website : https://www.cyberpanel.net " +echo " Forums : https://forums.cyberpanel.net " +echo " Wikipage: https://cyberpanel.net/KnowledgeBase/ " +echo " " +echo -e " Enjoy your accelerated Internet by " +echo -e " CyberPanel & $WORD " +echo "###################################################################" +if [[ $PROVIDER != "undefined" ]] ; then + echo -e "\033[0;32m$PROVIDER\033[39m detected..." + echo -e "This provider has a \e[31mnetwork-level firewall\033[39m" +else + echo -e "If your provider has a \e[31mnetwork-level firewall\033[39m" +fi + echo -e "Please make sure you have opened following port for both in/out:" + echo -e "\033[0;32mTCP: 8090\033[39m for CyberPanel" + echo -e "\033[0;32mTCP: 80\033[39m, \033[0;32mTCP: 443\033[39m and \033[0;32mUDP: 443\033[39m for webserver" + echo -e "\033[0;32mTCP: 21\033[39m and \033[0;32mTCP: 40110-40210\033[39m for FTP" + echo -e "\033[0;32mTCP: 25\033[39m, \033[0;32mTCP: 587\033[39m, \033[0;32mTCP: 465\033[39m, \033[0;32mTCP: 110\033[39m, \033[0;32mTCP: 143\033[39m and \033[0;32mTCP: 993\033[39m for mail service" + echo -e "\033[0;32mTCP: 53\033[39m and \033[0;32mUDP: 53\033[39m for DNS service" +if [[ $SERVER_COUNTRY = CN ]] ; then + if [[ $PROVIDER == "Tencent Cloud" ]] ; then + if [[ $SERVER_OS == "Ubuntu" ]] ; then + rm -f /etc/apt/sources.list + mv /etc/apt/sources.list-backup /etc/apt/sources.list +echo > "nameserver 127.0.0.53 +options edns0" /run/systemd/resolve/stub-resolv.conf +echo > "nameserver 127.0.0.53 +options edns0" /etc/resolv.conf + apt update +#revert the previous change on tencent cloud repo. + fi + fi + if [[ $VERSION = "ENT" ]] ; then + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/install/installCyberPanel.py + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py + echo -e "If you have install LiteSpeed Enterprise, please run \e[31m/usr/local/lsws/admin/misc/lsup.sh\033[39m to update it to latest." + fi +fi + +sed -i 's|lsws-5.3.8|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-5.4.2|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-5.3.5|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-6.0|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-6.3.4|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py + +if [[ $SILENT != "ON" ]] ; then +printf "%s" "Would you like to restart your server now? [y/N]: " +read TMP_YN + +if [[ "$TMP_YN" = "N" ]] || [[ "$TMP_YN" = "n" ]] || [[ -z "$TMP_YN" ]]; then +: +else +reboot +exit +fi + +exit +fi +#replace URL for CN + + + +else +echo "something went wrong..." +exit +fi +} diff --git a/install/venvsetup_modules/05_argument_main.sh b/install/venvsetup_modules/05_argument_main.sh new file mode 100644 index 000000000..43f5ee763 --- /dev/null +++ b/install/venvsetup_modules/05_argument_main.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash +# install/venvsetup part 5 – argument_mode and main flow + +argument_mode() { +KEY_SIZE=${#VERSION} +TMP=$(echo $VERSION | cut -c5) +TMP2=$(echo $VERSION | cut -c10) +TMP3=$(echo $VERSION | cut -c15) +if [[ $VERSION == "OLS" || $VERSION == "ols" ]] ; then + VERSION="OLS" + echo -e "\nSet to OpenLiteSpeed..." +elif [[ $VERSION == "Trial" ]] || [[ $VERSION == "TRIAL" ]] || [[ $VERSION == "trial" ]] ; then + VERSION="ENT" + LICENSE_KEY="TRIAL" + echo -e "\nLiteSpeed Enterprise trial license set..." +elif [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then + LICENSE_KEY=$VERSION + VERSION="ENT" + echo -e "\nLiteSpeed Enterprise license key set..." +else + echo -e "\nCan not recognize the input value \e[31m$VERSION\e[39m " + echo -e "\nPlease verify the input value..." + echo -e "\nPlease run with \e[31m-h\e[39m or \e[31m--help\e[39m for more detail." + exit +fi + +if [[ $ADMIN_PASS == "d" ]] ; then + ADMIN_PASS="1234567" + echo -e "\nSet to default password..." + echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" +elif [[ $ADMIN_PASS == "r" ]] ; then + ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') + echo -e "\nSet to random-generated password..." + echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" + echo $ADMIN_PASS +else + echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" +fi +} + +if [ $# -eq 0 ] ; then + echo -e "\nInitializing...\n" +else + if [[ $1 == "help" ]] ; then + show_help + exit + elif [[ $1 == "dev" ]] ; then + DEV="ON" + DEV_ARG="ON" + SILENT="OFF" + elif [[ $1 == "default" ]] ; then + echo -e "\nThis will start default installation...\n" + SILENT="ON" + POSTFIX_VARIABLE="ON" + POWERDNS_VARIABLE="ON" + PUREFTPD_VARIABLE="ON" + VERSION="OLS" + ADMIN_PASS="1234567" + MEMCACHED="ON" + REDIS="ON" + else + while [ ! -z "${1}" ]; do + case $1 in + -v | --version) shift + if [ "${1}" = '' ]; then + show_help + exit + else + VERSION="${1}" + SILENT="ON" + fi + ;; + -p | --password) shift + if [[ "${1}" == '' ]]; then + ADMIN_PASS="1234567" + elif [[ "${1}" == 'r' ]] || [[ $1 == 'random' ]] ; then + ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') + else + if [ ${1} -lt 8 ] ; then + echo -e "\nPassword lenth less than 8 digital, please choose a more complicated password.\n" + exit + fi + ADMIN_PASS="${1}" + fi + ;; + -a | --addons) + MEMCACHED="ON" + REDIS="ON" + ;; + -m | --minimal) + echo "minimal installation is still work in progress..." + exit + ;; + -h | --help) + show_help + exit + ;; + *) + echo "unknown argument..." + show_help + exit + ;; + esac + shift + done + fi +fi + + + +SERVER_IP=$(curl --silent --max-time 10 -4 https://cyberpanel.sh/?ip) +if [[ $SERVER_IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo -e "Valid IP detected..." +else + echo -e "Can not detect IP, exit..." + exit +fi +SERVER_COUNTRY="unknow" +SERVER_COUNTRY=$(curl --silent --max-time 5 https://cyberpanel.sh/?country) +if [[ ${#SERVER_COUNTRY} == "2" ]] || [[ ${#SERVER_COUNTRY} == "6" ]] ; then + echo -e "\nChecking server..." + else + echo -e "\nChecking server..." + SERVER_COUNTRY="unknow" +fi +#SERVER_COUNTRY="CN" +#test string +if [[ $SERVER_COUNTRY == "CN" ]] ; then +DOWNLOAD_SERVER="cyberpanel.sh" +else +DOWNLOAD_SERVER="cdn.cyberpanel.sh" +fi + +check_OS +check_root +check_panel +check_process +check_provider + + + + + +if [[ $SILENT = "ON" ]] ; then +argument_mode +else +interactive_mode +fi + +SECONDS=0 +install_required + +pip_virtualenv + +system_tweak + diff --git a/install/venvsetup_monolithic.sh b/install/venvsetup_monolithic.sh new file mode 100644 index 000000000..7116a3f99 --- /dev/null +++ b/install/venvsetup_monolithic.sh @@ -0,0 +1,1433 @@ +#!/bin/bash + +#CyberPanel installer script for Ubuntu 18.04 and CentOS 7.X +DEV="OFF" +BRANCH="stable" +POSTFIX_VARIABLE="ON" +POWERDNS_VARIABLE="ON" +PUREFTPD_VARIABLE="ON" +PROVIDER="undefined" +SERIAL_NO="" +DIR=$(pwd) +TEMP=$(curl --silent https://cyberpanel.net/version.txt) +CP_VER1=${TEMP:12:3} +CP_VER2=${TEMP:25:1} +SERVER_OS="CentOS" +VERSION="OLS" +LICENSE_KEY="" +KEY_SIZE="" +ADMIN_PASS="1234567" +MEMCACHED="ON" +REDIS="ON" +MARIADB_VER="11.8" +TOTAL_RAM=$(free -m | awk '/Mem\:/ { print $2 }') + +# Robust pip install function to handle broken pipe errors +safe_pip_install() { + local pip_cmd="$1" + local requirements_file="$2" + local install_args="$3" + + echo "Installing Python packages..." + + # Method 1: Install with full error suppression and broken pipe handling + 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" + return 0 + fi + + # Method 2: Install with even more aggressive error suppression + echo "⚠️ Trying fallback installation method..." + 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" + return 0 + fi + + # Method 3: Install packages individually to avoid broken pipes + echo "⚠️ Trying individual package installation..." + while IFS= read -r line; do + # Skip empty lines and comments + [[ -z "$line" || "$line" =~ ^#.*$ ]] && continue + + # 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 +} + +license_validation() { +CURRENT_DIR=$(pwd) + +if [ -f /root/cyberpanel-tmp ] ; then +rm -rf /root/cyberpanel-tmp +fi + +mkdir /root/cyberpanel-tmp +cd /root/cyberpanel-tmp +wget -q https://$DOWNLOAD_SERVER/litespeed/lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz +tar xzvf lsws-$LSWS_STABLE_VER-ent-x86_64-linux.tar.gz > /dev/null +cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/conf +if [[ $LICENSE_KEY == "TRIAL" ]] ; then +wget -q http://license.litespeedtech.com/reseller/trial.key +sed -i "s|writeSerial = open('lsws-5.4.2/serial.no', 'w')|command = 'wget -q --output-document=./lsws-$LSWS_STABLE_VER/trial.key http://license.litespeedtech.com/reseller/trial.key'|g" $CURRENT_DIR/installCyberPanel.py +sed -i 's|writeSerial.writelines(self.serial)|subprocess.call(command, shell=True)|g' $CURRENT_DIR/installCyberPanel.py +sed -i 's|writeSerial.close()||g' $CURRENT_DIR/installCyberPanel.py +else +echo $LICENSE_KEY > serial.no +fi + +cd /root/cyberpanel-tmp/lsws-$LSWS_STABLE_VER/bin + +if [[ $LICENSE_KEY == "TRIAL" ]] ; then + if ./lshttpd -V |& grep "ERROR" ; then + echo -e "\n\nIt apeears to have some issue with license , please check above result..." + exit + fi + LICENSE_KEY="1111-2222-3333-4444" +else + if ./lshttpd -r |& grep "ERROR" ; then + ./lshttpd -r + echo -e "\n\nIt apeears to have some issue with license , please check above result..." + exit + fi +fi +echo -e "License seems valid..." +cd /root/cyberpanel-tmp +rm -rf lsws-$LSWS_STABLE_VER* +cd $CURRENT_DIR +rm -rf /root/cyberpanel-tmp +} + +special_change(){ +sed -i 's|cyberpanel.sh|'$DOWNLOAD_SERVER'|g' install.py +sed -i 's|mirror.cyberpanel.net|'$DOWNLOAD_SERVER'|g' install.py +sed -i 's|git clone https://github.com/usmannasir/cyberpanel|echo downloaded|g' install.py +#change to CDN first, regardless country +sed -i 's|http://|https://|g' install.py + +LATEST_URL="https://update.litespeedtech.com/ws/latest.php" +#LATEST_URL="https://cyberpanel.sh/latest.php" +curl --silent -o /tmp/lsws_latest $LATEST_URL 2>/dev/null +LSWS_STABLE_LINE=`cat /tmp/lsws_latest | grep LSWS_STABLE` +LSWS_STABLE_VER=`expr "$LSWS_STABLE_LINE" : '.*LSWS_STABLE=\(.*\) BUILD .*'` +# Fallback to LSWS 6.3.4 (Stable) if fetch failed or empty +if [ -z "$LSWS_STABLE_VER" ]; then + LSWS_STABLE_VER="6.3.4" +fi + +if [[ $SERVER_COUNTRY == "CN" ]] ; then +#line1="$(grep -n "github.com/usmannasir/cyberpanel" install.py | head -n 1 | cut -d: -f1)" +#line2=$((line1 - 1)) +#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py +#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'tar xzvf cyberpanel-git.tar.gz'" install.py +#sed -i "${line2}i\ \ \ \ \ \ \ \ subprocess.call(command, shell=True)" install.py +#sed -i "${line2}i\ \ \ \ \ \ \ \ command = 'wget cyberpanel.sh/cyberpanel-git.tar.gz'" install.py +sed -i 's|wget https://rpms.litespeedtech.com/debian/|wget --no-check-certificate https://rpms.litespeedtech.com/debian/|g' install.py +sed -i 's|https://repo.powerdns.com/repo-files/centos-auth-42.repo|https://'$DOWNLOAD_SERVER'/powerdns/powerdns.repo|g' installCyberPanel.py +sed -i 's|https://snappymail.eu/repository/latest.tar.gz|https://'$DOWNLOAD_SERVER'/repository/latest.tar.gz|g' install.py + +sed -i 's|rpm -ivh https://rpms.litespeedtech.com/centos/litespeed-repo-1.1-1.el7.noarch.rpm|curl -o /etc/yum.repos.d/litespeed.repo https://'$DOWNLOAD_SERVER'/litespeed/litespeed.repo|g' install.py + + +sed -i 's|https://copr.fedorainfracloud.org/coprs/copart/restic/repo/epel-7/copart-restic-epel-7.repo|https://'$DOWNLOAD_SERVER'/restic/restic.repo|g' install.py + +sed -i 's|yum -y install https://cyberpanel.sh/gf-release-latest.gf.el7.noarch.rpm|wget -O /etc/yum.repos.d/gf.repo https://'$DOWNLOAD_SERVER'/gf-plus/gf.repo|g' install.py +sed -i 's|dovecot-2.3-latest|dovecot-2.3-latest-mirror|g' install.py +sed -i 's|git clone https://github.com/usmannasir/cyberpanel|wget https://cyberpanel.sh/cyberpanel-git.tar.gz \&\& tar xzvf cyberpanel-git.tar.gz|g' install.py +sed -i 's|https://repo.dovecot.org/ce-2.3-latest/centos/$releasever/RPMS/$basearch|https://'$DOWNLOAD_SERVER'/dovecot/|g' install.py +sed -i 's|'$DOWNLOAD_SERVER'|cyberpanel.sh|g' install.py +sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.4.2-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' installCyberPanel.py +# global change for CN , regardless provider and system + + if [[ $SERVER_OS == "CentOS" ]] ; then + DIR=$(pwd) + cd $DIR/mysql + echo "[mariadb-tsinghua] +name = MariaDB +baseurl = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum/10.1/centos7-amd64 +gpgkey = https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum//RPM-GPG-KEY-MariaDB +gpgcheck = 1" > MariaDB.repo +#above to set mariadb db to Tsinghua repo + cd $DIR + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' installCyberPanel.py + mkdir /root/.pip + cat << EOF > /root/.pip/pip.conf +[global] +index-url = https://mirrors.aliyun.com/pypi/simple/ +EOF + echo -e "\nSet to Aliyun pip repo..." + cat << EOF > composer.sh +#!/usr/bin/env bash +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php composer-setup.php +php -r "unlink('composer-setup.php');" +mv composer.phar /usr/bin/composer + +if [ ! -d /root/.config ]; then +mkdir /root/.config +fi + +if [ ! -d /root/.config/composer ]; then +mkdir /root/.config/composer +fi + +echo '{ + "bitbucket-oauth": {}, + "github-oauth": {}, + "gitlab-oauth": {}, + "gitlab-token": {}, + "http-basic": {} +} +' > /root/.config/composer/auth.json + +echo '{ + "config": {}, + "repositories": { + "packagist": { + "type": "composer", + "url": "https://mirrors.aliyun.com/composer/" + } + } +} +' > /root/.config/composer/config.json +composer clear-cache +EOF + fi + + + if [[ $SERVER_OS == "Ubuntu" ]] ; then + echo $'\n89.208.248.38 rpms.litespeedtech.com\n' >> /etc/hosts + echo -e "Mirror server set..." + pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ + cat << EOF > /root/.pip/pip.conf +[global] +index-url = https://mirrors.aliyun.com/pypi/simple/ +EOF + echo -e "\nSet to Aliyun pip repo..." + if [[ $PROVIDER == "Tencent Cloud" ]] ; then + #tencent cloud and ubuntu system + echo -e "\n Tencent Cloud detected ... bypass default repository" + cp /etc/apt/sources.list /etc/apt/sources.list-backup + #backup original sources list + cat << 'EOF' > /etc/apt/sources.list +deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +EOF + DEBIAN_FRONTEND=noninteractive apt update -y + pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ + cat << EOF > composer.sh +#!/usr/bin/env bash +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php composer-setup.php +php -r "unlink('composer-setup.php');" +mv composer.phar /usr/bin/composer + +if [ ! -d /root/.config ]; then +mkdir /root/.config +fi + +if [ ! -d /root/.config/composer ]; then +mkdir /root/.config/composer +fi + +echo '{ + "bitbucket-oauth": {}, + "github-oauth": {}, + "gitlab-oauth": {}, + "gitlab-token": {}, + "http-basic": {} +} +' > /root/.config/composer/auth.json + +echo '{ + "config": {}, + "repositories": { + "packagist": { + "type": "composer", + "url": "https://mirrors.cloud.tencent.com/composer/" + } + } +} +' > /root/.config/composer/config.json +composer clear-cache +EOF + else + cat << EOF > composer.sh +#!/usr/bin/env bash +php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +php composer-setup.php +php -r "unlink('composer-setup.php');" +mv composer.phar /usr/bin/composer + +if [ ! -d /root/.config ]; then +mkdir /root/.config +fi + +if [ ! -d /root/.config/composer ]; then +mkdir /root/.config/composer +fi + +echo '{ + "bitbucket-oauth": {}, + "github-oauth": {}, + "gitlab-oauth": {}, + "gitlab-token": {}, + "http-basic": {} +} +' > /root/.config/composer/auth.json + +echo '{ + "config": {}, + "repositories": { + "packagist": { + "type": "composer", + "url": "https://packagist.phpcomposer.com" + } + } +} +' > /root/.config/composer/config.json +composer clear-cache +EOF + fi + fi +fi +} + + +system_tweak() { +if [[ $SERVER_OS == "CentOS" ]] ; then + setenforce 0 + sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config +fi + +if ! grep -q "pid_max" /etc/rc.local; then + if [[ $SERVER_OS == "CentOS" ]] ; then + echo "echo 1000000 > /proc/sys/kernel/pid_max +echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.d/rc.local + chmod +x /etc/rc.d/rc.local + else + echo "echo 1000000 > /proc/sys/kernel/pid_max +echo 1 > /sys/kernel/mm/ksm/run" >> /etc/rc.local + chmod +x /etc/rc.local + fi + echo "fs.file-max = 65535" >> /etc/sysctl.conf + sysctl -p > /dev/null + echo "* soft nofile 65535 +* hard nofile 65535 +root soft nofile 65535 +root hard nofile 65535 +* soft nproc 65535 +* hard nproc 65535 +root soft nproc 65535 +root hard nproc 65535" >> /etc/security/limits.conf +fi + +#sed -i 's|#DefaultLimitNOFILE=|DefaultLimitNOFILE=65535|g' /etc/systemd/system.conf + + +TOTAL_SWAP=$(free -m | awk '/^Swap:/ { print $2 }') +SET_SWAP=$((TOTAL_RAM - TOTAL_SWAP)) +SWAP_FILE=/cyberpanel.swap + +if [ ! -f $SWAP_FILE ] ; then + if [[ $TOTAL_SWAP -gt $TOTAL_RAM ]] || [[ $TOTAL_SWAP -eq $TOTAL_RAM ]] ; then + echo "SWAP check..." + else + if [[ $SET_SWAP -gt "2049" ]] ; then + SET_SWAP="2048" + else + echo "Checking SWAP..." + fi + fallocate --length ${SET_SWAP}MiB $SWAP_FILE + chmod 600 $SWAP_FILE + mkswap $SWAP_FILE + swapon $SWAP_FILE + echo "${SWAP_FILE} swap swap sw 0 0" | sudo tee -a /etc/fstab + sysctl vm.swappiness=10 + echo "vm.swappiness = 10" >> /etc/sysctl.conf + echo "SWAP set..." + fi +fi +} + + +install_required() { +echo -e "\nInstalling necessary components..." +if [[ $SERVER_OS == "CentOS" ]] ; then + rpm --import https://$DOWNLOAD_SERVER/mariadb/RPM-GPG-KEY-MariaDB + rpm --import https://$DOWNLOAD_SERVER/litespeed/RPM-GPG-KEY-litespeed + rpm --import https://$DOWNLOAD_SERVER/powerdns/FD380FBB-pub.asc + rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 + rpm --import https://$DOWNLOAD_SERVER/gf-plus/RPM-GPG-KEY-gf.el7 + rpm --import https://repo.dovecot.org/DOVECOT-REPO-GPG + rpm --import https://copr-be.cloud.fedoraproject.org/results/copart/restic/pubkey.gpg + yum autoremove epel-release -y + rm -f /etc/yum.repos.d/epel.repo + rm -f /etc/yum.repos.d/epel.repo.rpmsave + yum clean all + yum update -y + yum install epel-release -y + yum install -y wget strace htop net-tools telnet curl which bc telnet htop libevent-devel gcc python-devel libattr-devel xz-devel gpgme-devel mariadb-devel curl-devel python-pip git + if [[ $DEV == "ON" ]] ; then + yum -y install yum-utils + yum -y groupinstall development + yum -y install https://centos7.iuscommunity.org/ius-release.rpm + yum -y install python36u python36u-pip python36u-devel + fi +fi + +if [[ $SERVER_OS == "Ubuntu" ]] ; then + apt update -y + DEBIAN_FRONTEND=noninteractive apt upgrade -y + + # Check if this is Debian (no lsb-release) and version >= 13 + if [[ ! -f /etc/lsb-release ]] && [[ -f /etc/debian_version ]]; then + DEBIAN_VERSION=$(cat /etc/debian_version | cut -d'.' -f1) + if [[ $DEBIAN_VERSION -ge 13 ]]; then + # Debian 13 (Trixie) package mappings + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python3-mysqldb python3-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python3-gpg python3 python3-setuptools virtualenv python3-dev python3-pip git + elif [[ $DEBIAN_VERSION -ge 12 ]]; then + # Debian 12 (Bookworm) package mappings + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python3-mysqldb python3-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python3-gpg python3 python3-setuptools virtualenv python3-dev python3-pip git + else + # Older Debian versions + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python-mysqldb python-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python-gpg python python-minimal python-setuptools virtualenv python-dev python-pip git + fi + else + # Ubuntu or older Debian with compatible package names + DEBIAN_FRONTEND=noninteractive apt install -y htop telnet python-mysqldb python-dev libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev python-gpg python python-minimal python-setuptools virtualenv python-dev python-pip git + fi + if [[ $DEV == "ON" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install -y python3-pip + DEBIAN_FRONTEND=noninteractive apt install -y build-essential libssl-dev libffi-dev python3-dev + DEBIAN_FRONTEND=noninteractive apt install -y python3-venv + fi +fi +} + +memcached_installation() { +if [[ $SERVER_OS == "CentOS" ]] ; then + yum install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached lsphp56-pecl-memcached lsphp55-pecl-memcached lsphp54-pecl-memcached + if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then + yum groupinstall "Development Tools" -y + yum install autoconf automake zlib-devel openssl-devel expat-devel pcre-devel libmemcached-devel cyrus-sasl* -y + wget https://$DOWNLOAD_SERVER/litespeed/lsmcd.tar.gz + tar xzvf lsmcd.tar.gz + DIR=$(pwd) + cd $DIR/lsmcd + ./fixtimestamp.sh + ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" + make + make install + systemctl enable lsmcd + systemctl start lsmcd + cd $DIR + else + yum install -y memcached + sed -i 's|OPTIONS=""|OPTIONS="-l 127.0.0.1 -U 0"|g' /etc/sysconfig/memcached + systemctl enable memcached + systemctl start memcached + fi +fi +if [[ $SERVER_OS == "Ubuntu" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-memcached lsphp72-memcached lsphp71-memcached lsphp70-memcached + if [[ $TOTAL_RAM -eq "2048" ]] || [[ $TOTAL_RAM -gt "2048" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install build-essential zlib1g-dev libexpat1-dev openssl libssl-dev libsasl2-dev libpcre3-dev git -y + wget https://$DOWNLOAD/litespeed/lsmcd.tar.gz + tar xzvf lsmcd.tar.gz + DIR=$(pwd) + cd $DIR/lsmcd + ./fixtimestamp.sh + ./configure CFLAGS=" -O3" CXXFLAGS=" -O3" + make + make install + cd $DIR + systemctl enable lsmcd + systemctl start lsmcd + else + DEBIAN_FRONTEND=noninteractive apt install -y memcached + systemctl enable memcached + systemctl start memcached + fi +fi + +if ps -aux | grep "lsmcd" | grep -v grep ; then + echo -e "\n\nLiteSpeed Memcached installed and running..." +fi + +if ps -aux | grep "memcached" | grep -v grep ; then + echo -e "\n\nMemcached installed and running..." +fi + +} + +redis_installation() { +if [[ $SERVER_OS == "CentOS" ]] ; then + yum install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis lsphp56-redis lsphp55-redis lsphp54-redis redis +fi +if [[ $SERVER_OS == "Ubuntu" ]] ; then + DEBIAN_FRONTEND=noninteractive apt install -y lsphp73-redis lsphp72-redis lsphp71-redis lsphp70-redis redis +fi + +if ifconfig -a | grep inet6 ; then + echo -e "\n IPv6 detected..." +else + sed -i 's|bind 127.0.0.1 ::1|bind 127.0.0.1|g' /etc/redis/redis.conf + echo -e "\n no IPv6 detected..." +fi + +if [[ $SERVER_OS == "CentOS" ]] ; then + systemctl enable redis + systemctl start redis +fi + +if [[ $SERVER_OS == "Ubuntu" ]] ; then + systemctl enable redis-server + systemctl start redis-server +fi + +if ps -aux | grep "redis" | grep -v grep ; then + echo -e "\n\nRedis installed and running..." +fi +} + +check_provider() { + +if hash dmidecode > /dev/null 2>&1 ; then + if [ "$(dmidecode -s bios-vendor)" = 'Google' ] ; then + PROVIDER='Google Cloud Platform' + elif [ "$(dmidecode -s bios-vendor)" = 'DigitalOcean' ] ; then + PROVIDER='Digital Ocean' + elif [ "$(dmidecode -s system-product-name | cut -c 1-7)" = 'Alibaba' ] ; then + PROVIDER='Alibaba Cloud' + elif [ "$(dmidecode -s system-manufacturer)" = 'Microsoft Corporation' ] ; then + PROVIDER='Microsoft Azure' + elif [ -d /usr/local/qcloud ] ; then + PROVIDER='Tencent Cloud' + else + PROVIDER='undefined' + fi +else + PROVIDER='undefined' +fi + +if [ "$(cat /sys/devices/virtual/dmi/id/product_uuid | cut -c 1-3)" = 'EC2' ] && [ -d /home/ubuntu ]; then + PROVIDER='Amazon Web Service' +fi + +} + + +check_OS() { +echo -e "\nChecking OS..." +OUTPUT=$(cat /etc/*release) +if echo $OUTPUT | grep -q "CentOS Linux 7" ; then + echo -e "\nDetecting CentOS 7.X...\n" + SERVER_OS="CentOS" +elif echo $OUTPUT | grep -q "CloudLinux 7" ; then + echo -e "\nDetecting CloudLinux 7.X...\n" + SERVER_OS="CentOS" +elif echo $OUTPUT | grep -q "Ubuntu 18.04" ; then + echo -e "\nDetecting Ubuntu 18.04...\n" + SERVER_OS="Ubuntu" +else + cat /etc/*release + echo -e "\nUnable to detect your OS...\n" + echo -e "\nCyberPanel is supported on Ubuntu 18.04, CentOS 7.x and CloudLinux 7.x...\n" + exit 1 +fi +} + +check_root() { +echo -e "Checking root privileges...\n" +if [[ $(id -u) != 0 ]] > /dev/null; then + echo -e "You must use root account to do this" + echo -e "or run following command: (do NOT miss the quotes)" + echo -e "\e[31msudo su -c \"sh <(curl https://cyberpanel.sh || wget -O - https://cyberpanel.sh)\"\e[39m" + exit 1 +else + echo -e "You are runing as root...\n" +fi +} + +check_panel() { +if [ -d /usr/local/cpanel ]; then + echo -e "\ncPanel detected...exit...\n" + exit 1 +fi +if [ -d /opt/plesk ]; then + echo -e "\nPlesk detected...exit...\n" + exit 1 +fi +} + +check_process() { +if systemctl is-active --quiet httpd; then + systemctl disable httpd + systemctl stop httpd + echo -e "\nhttpd process detected, disabling...\n" +fi +if systemctl is-active --quiet apache2; then + systemctl disable apache2 + systemctl stop apache2 + echo -e "\napache2 process detected, disabling...\n" +fi +if systemctl is-active --quiet named; then + systemctl stop named + systemctl disable named + echo -e "\nnamed process detected, disabling...\n" +fi +if systemctl is-active --quiet exim; then + systemctl stop exim + systemctl disable exim + echo -e "\nexim process detected, disabling...\n" +fi +} + +show_help() { +echo -e "\nCyberPanel Installer Script Help\n" +echo -e "\nUsage: wget https://cyberpanel.sh/cyberpanel.sh" +echo -e "\nchmod +x cyberpanel.sh" +echo -e "\n./cyberpanel.sh -v ols/SERIAL_NUMBER -c 1 -a 1" +echo -e "\n -v or --version: choose to install CyberPanel OpenLiteSpeed or CyberPanel Enterprise, available options are \e[31mols\e[39m and \e[31mSERIAL_NUMBER\e[39m, default ols" +echo -e "\n Please be aware, this serial number must be obtained from LiteSpeed Store." +echo -e "\n And if this serial number has been used before, it must be released/migrated in Store first, otherwise it will fail to start." +echo -e "\n -a or --addons: install addons: memcached, redis, PHP extension for memcached and redis, 1 for install addons, 0 for not to install, default 0, only applicable for CentOS system." +echo -e "\n -p or --password: set password of new installation, empty for default 1234567, [r] or [random] for randomly generated 16 digital password, any other value besdies [d] and [r(andom)] will be accept as password, default use 1234567." +#echo -e "\n -m: set to minimal mode which will not install PowerDNS, Pure-FTPd and Postfix" +echo -e "\n Example:" +echo -e "\n ./cyberpanel.sh -v ols -p r or ./cyberpanel.sh --version ols --password random" +echo -e "\n This will install CyberPanel OpenLiteSpeed and randomly generate the password." +echo -e "\n ./cyberpanel.sh default" +echo -e "\n This will install everything default , which is OpenLiteSpeed and nothing more.\n" + +} + +license_input() { +VERSION="ENT" +echo -e "\nPlease note that your server has \e[31m$TOTAL_RAM\e[39m RAM" +echo -e "If you are using \e[31mFree Start\e[39m license, It will not start due to \e[31m2GB RAM limit\e[39m.\n" +echo -e "If you do not have any license, you can also use trial license (if server has not used trial license before), type \e[31mTRIAL\e[39m\n" + +printf "%s" "Please input your serial number for LiteSpeed WebServer Enterprise:" +read LICENSE_KEY +if [ -z "$LICENSE_KEY" ] ; then + echo -e "\nPlease provide license key\n" + exit +fi + +echo -e "The serial number you input is: \e[31m$LICENSE_KEY\e[39m" +printf "%s" "Please verify it is correct. [y/N]" +read TMP_YN +if [ -z "$TMP_YN" ] ; then + echo -e "\nPlease type \e[31my\e[39m\n" + exit +fi + +KEY_SIZE=${#LICENSE_KEY} +TMP=$(echo $LICENSE_KEY | cut -c5) +TMP2=$(echo $LICENSE_KEY | cut -c10) +TMP3=$(echo $LICENSE_KEY | cut -c15) + +if [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then + echo -e "\nLicense key set..." +elif [[ $LICENSE_KEY == "trial" ]] || [[ $LICENSE_KEY == "TRIAL" ]] || [[ $LICENSE_KEY == "Trial" ]] ; then + echo -e "\nTrial license set..." + LICENSE_KEY="TRIAL" +else + echo -e "\nLicense key seems incorrect, please verify\n" + echo -e "\nIf you are copying/pasting, please make sure you didn't paste blank space...\n" + exit +fi +} + +interactive_mode() { +echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 + + 1. Install CyberPanel. + + 2. Addons and Miscellaneous + + 3. Exit. + + " +read -p " Please enter the number[1-3]: " num +echo "" +case "$num" in + 1) + interactive_install + ;; + 2) + interactive_others + ;; + 3) + exit + ;; + *) + echo -e " Please enter the right number [1-3]\n" + exit + ;; +esac +} + +interactive_others() { +if [ ! -e "/etc/cyberpanel/machineIP" ]; then +echo -e "\nYou don't have CyberPanel installed...\n" +exit +fi + +echo -e " CyberPanel Addons v$CP_VER1$CP_VER2 + + 1. Install Memcached extension and backend + + 2. Install Redis extension and backend + + 3. Return to main page. + + 4. Exit + " + +echo && read -p "Please enter the number[1-4]: " num +case "$num" in + 1) + memcached_installation + exit + ;; + 2) + redis_installation + exit + ;; + 3) + interactive_mode + ;; + 4) + exit + ;; + *) + echo -e "${Error} please enter the right number [1-4]" + ;; +esac +} + +interactive_install() { +RAM=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') +DISK=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') +#clear +echo -e " CyberPanel Installer v$CP_VER1$CP_VER2 + + RAM check : $RAM + + Disk check : $DISK (Minimal \e[31m10GB\e[39m free space) + + 1. Install CyberPanel with \e[31mOpenLiteSpeed\e[39m. + + 2. Install Cyberpanel with \e[31mLiteSpeed Enterprise\e[39m. + + 3. Exit. + + " +read -p " Please enter the number[1-3]: " num +echo "" +case "$num" in + 1) + VERSION="OLS" + ;; + 2) + license_input + ;; + 3) + exit + ;; + *) + echo -e " Please enter the right number [1-3]\n" + exit + ;; +esac + +< /dev/null; then + echo -e "\nCyberPanel installation sucessfully completed..." +else + echo -e "Oops, something went wrong..." + exit +fi + +if [[ $MEMCACHED == "ON" ]] ; then + memcached_installation +fi +if [[ $REDIS == "ON" ]] ; then + redis_installation +fi + after_install +fi +} + +pip_virtualenv() { +if [[ $DEV == "OFF" ]] ; then +if [[ $SERVER_COUNTRY == "CN" ]] ; then + mkdir /root/.pip +cat << EOF > /root/.pip/pip.conf +[global] +index-url = https://mirrors.aliyun.com/pypi/simple/ +EOF +fi + +if [[ $PROVIDER == "Alibaba Cloud" ]] ; then + pip install --upgrade pip 2>/dev/null || echo "⚠️ pip upgrade completed with warnings" + pip install setuptools==40.8.0 2>/dev/null || echo "⚠️ setuptools installation completed with warnings" +fi + +pip install virtualenv 2>/dev/null || echo "⚠️ virtualenv installation completed with warnings" + +# Create virtual environment with fallback for Ubuntu 22.04 compatibility +echo "Creating CyberPanel virtual environment..." +if python3 -m venv --system-site-packages /usr/local/CyberPanel 2>&1 | grep -q "unrecognized option"; then + # Fallback to virtualenv if python3 -m venv doesn't support --system-site-packages + virtualenv --system-site-packages /usr/local/CyberPanel +elif python3 -m venv --system-site-packages /usr/local/CyberPanel 2>/dev/null; then + echo "Virtual environment created successfully using python3 -m venv" +else + # Final fallback to virtualenv + virtualenv --system-site-packages /usr/local/CyberPanel +fi + +source /usr/local/CyberPanel/bin/activate +rm -rf requirements.txt +wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/1.8.0/requirments.txt +# Install packages with robust error handling to prevent broken pipe errors +safe_pip_install "pip" "requirements.txt" "--ignore-installed" +fi + +if [[ $DEV == "ON" ]] ; then + #install dev branch + #wget https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt + cd /usr/local/ + python3.6 -m venv CyberPanel + source /usr/local/CyberPanel/bin/activate + + # Try to download requirements file with fallback options + echo "Attempting to download requirements for branch/commit: $BRANCH_NAME" + + # First try the specified branch/commit + if wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt 2>/dev/null; then + echo "Successfully downloaded requirements from $BRANCH_NAME" + elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments-old.txt 2>/dev/null; then + echo "Successfully downloaded requirements-old.txt from $BRANCH_NAME" + elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/requirments.txt 2>/dev/null; then + echo "Fallback: Downloaded requirements from stable branch" + else + echo "Warning: Could not download requirements file, using minimal default requirements" + cat > requirements.txt << 'EOF' +# Minimal CyberPanel requirements - fallback when requirements file is not available +Django==3.2.25 +PyMySQL==1.1.0 +requests==2.31.0 +cryptography==41.0.7 +psutil==5.9.6 +EOF + fi + + safe_pip_install "pip3.6" "requirements.txt" "--ignore-installed" +fi + +if [ -f requirements.txt ] && [ -d cyberpanel ] ; then + rm -rf cyberpanel + rm -f requirements.txt +fi + +if [[ $SERVER_COUNTRY == "CN" ]] ; then + wget https://cyberpanel.sh/cyberpanel-git.tar.gz + tar xzvf cyberpanel-git.tar.gz > /dev/null + cp -r cyberpanel /usr/local/cyberpanel + cd cyberpanel/install +else + if [[ $DEV == "ON" ]] ; then + git clone https://github.com/usmannasir/cyberpanel + cd cyberpanel + git checkout $BRANCH_NAME + cd - + cd cyberpanel/install + else + git clone https://github.com/usmannasir/cyberpanel + cd cyberpanel/install + fi +fi +curl https://cyberpanel.sh/?version +} + +after_install() { +if [ ! -d "/var/lib/php" ]; then + mkdir /var/lib/php +fi + +if [ ! -d "/var/lib/php/session" ]; then + mkdir /var/lib/php/session +fi + +chmod 1733 /var/lib/php/session + +if grep "\[ERROR\] We are not able to run ./install.sh return code: 1. Fatal error, see /var/log/installLogs.txt for full details" /var/log/installLogs.txt > /dev/null; then + cd ${DIR}/cyberpanel/install/lsws-* + ./install.sh + echo -e "\n\n\nIt seems LiteSpeed Enterprise has failed to install, please check your license key is valid" + echo -e "\nIf this license key has been used before, you may need to go to store to release it first." + exit +fi + + +if grep "CyberPanel installation successfully completed" /var/log/installLogs.txt > /dev/null; then + +if [[ $DEV == "ON" ]] ; then +python3.6 -m venv /usr/local/CyberCP +source /usr/local/CyberCP/bin/activate + +# Try to download requirements file with fallback options +echo "Attempting to download requirements for branch/commit: $BRANCH_NAME" + +# First try the specified branch/commit +if wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments.txt 2>/dev/null; then + echo "Successfully downloaded requirements from $BRANCH_NAME" +elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/requirments-old.txt 2>/dev/null; then + echo "Successfully downloaded requirements-old.txt from $BRANCH_NAME" +elif wget -O requirements.txt https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/requirments.txt 2>/dev/null; then + echo "Fallback: Downloaded requirements from stable branch" +else + echo "Warning: Could not download requirements file, using minimal default requirements" + cat > requirements.txt << 'EOF' +# Minimal CyberPanel requirements - fallback when requirements file is not available +Django==3.2.25 +PyMySQL==1.1.0 +requests==2.31.0 +cryptography==41.0.7 +psutil==5.9.6 +EOF +fi + +safe_pip_install "pip3.6" "requirements.txt" "--ignore-installed" +systemctl restart lscpd +fi + +for version in $(ls /usr/local/lsws | grep lsphp); + do + php_ini=$(find /usr/local/lsws/$version/ -name php.ini) + version2=${version:5:2} + version2=$(awk "BEGIN { print "${version2}/10" }") + if [[ $version2 = "7" ]] ; then + version2="7.0" + fi + if [[ $SERVER_OS == "CentOS" ]] ; then + yum remove -y $version-mysql + yum install -y $version-mysqlnd + yum install -y $version-devel make gcc glibc-devel libmemcached-devel zlib-devel + if [[ ! -d /usr/local/lsws/$version/tmp ]] ; then + mkdir /usr/local/lsws/$version/tmp + fi + /usr/local/lsws/${version}/bin/pecl channel-update pecl.php.net; + /usr/local/lsws/${version}/bin/pear config-set temp_dir /usr/local/lsws/${version}/tmp + /usr/local/lsws/${version}/bin/pecl install timezonedb + echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php.d/20-timezone.ini + sed -i 's|expose_php = On|expose_php = Off|g' $php_ini + sed -i 's|mail.add_x_header = On|mail.add_x_header = Off|g' $php_ini + sed -i 's|;session.save_path = "/tmp"|session.save_path = "/var/lib/php/session"|g' $php_ini + fi + + if [[ $SERVER_OS == "Ubuntu" ]] ; then + if [[ ! -d /usr/local/lsws/cyberpanel-tmp ]] ; then + echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone + systemctl restart pure-ftpd-mysql + DEBIAN_FRONTEND=noninteractive apt install libmagickwand-dev pkg-config build-essential -y + mkdir /usr/local/lsws/cyberpanel-tmp + cd /usr/local/lsws/cyberpanel-tmp + wget https://pecl.php.net/get/timezonedb-2019.3.tgz + tar xzvf timezonedb-2019.3.tgz + cd timezonedb-2019.3 + fi + /usr/local/lsws/${version}/bin/phpize + ./configure --with-php-config=/usr/local/lsws/${version}/bin/php-config${version2} + make + make install + # Only create .ini file if extension was successfully installed + # Check if timezonedb.so exists in the extension directory + ext_dir=$(/usr/local/lsws/${version}/bin/php-config${version2} --extension-dir) + if [[ -f "${ext_dir}/timezonedb.so" ]] ; then + mkdir -p /usr/local/lsws/${version}/etc/php/${version2}/mods-available + echo "extension=timezonedb.so" > /usr/local/lsws/${version}/etc/php/${version2}/mods-available/20-timezone.ini + fi + make clean + fi +done + +rm -rf /etc/profile.d/cyberpanel* +curl --silent -o /etc/profile.d/cyberpanel.sh https://cyberpanel.sh/?banner 2>/dev/null +chmod +x /etc/profile.d/cyberpanel.sh +RAM2=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }') +DISK2=$(df -h | awk '$NF=="/"{printf "%d/%dGB (%s)\n", $3,$2,$5}') +ELAPSED="$(($SECONDS / 3600)) hrs $((($SECONDS / 60) % 60)) min $(($SECONDS % 60)) sec" +MYSQLPASSWD=$(cat /etc/cyberpanel/mysqlPassword) +echo "$ADMIN_PASS" > /etc/cyberpanel/adminPass +/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password $ADMIN_PASS +systemctl restart lscpd +systemctl restart lsws +echo "/usr/local/CyberPanel/bin/python2 /usr/local/CyberCP/plogical/adminPass.py --password \"\$@\"" > /usr/bin/adminPass +echo "systemctl restart lscpd" >> /usr/bin/adminPass +chmod +x /usr/bin/adminPass +if [[ $VERSION = "OLS" ]] ; then + WORD="OpenLiteSpeed" +# sed -i 's|maxConnections 10000|maxConnections 100000|g' /usr/local/lsws/conf/httpd_config.conf +# OLS_LATEST=$(curl https://openlitespeed.org/packages/release) +# wget https://openlitespeed.org/packages/openlitespeed-$OLS_LATEST.tgz +# tar xzvf openlitespeed-$OLS_LATEST.tgz +# cd openlitespeed +# ./install.sh + /usr/local/lsws/bin/lswsctrl stop + /usr/local/lsws/bin/lswsctrl start +# rm -f openlitespeed-$OLS_LATEST.tgz +# rm -rf openlitespeed +# cd .. +fi +if [[ $VERSION = "ENT" ]] ; then + WORD="LiteSpeed Enterprise" + if [[ $SERVER_COUNTRY != "CN" ]] ; then + /usr/local/lsws/admin/misc/lsup.sh -f -v $LSWS_STABLE_VER + fi +fi + +systemctl status lsws 2>&1>/dev/null +if [[ $? == "0" ]] ; then + echo "LSWS service is running..." +else + systemctl stop lsws + systemctl start lsws +fi + +clear +echo "###################################################################" +echo " CyberPanel Successfully Installed " +echo " " +echo " Current Disk usage : $DISK2 " +echo " " +echo " Current RAM usage : $RAM2 " +echo " " +echo " Installation time : $ELAPSED " +echo " " +echo " Visit: https://$SERVER_IP:8090 " +echo " Panel username: admin " +echo " Panel password: $ADMIN_PASS " +#echo " Mysql username: root " +#echo " Mysql password: $MYSQLPASSWD " +echo " " +echo " Please change your default admin password " +echo " If you need to reset your panel password, please run: " +echo " adminPass YOUR_NEW_PASSWORD " +echo " " +echo " If you change mysql password, please modify file in " +echo -e " \e[31m/etc/cyberpanel/mysqlPassword\e[39m with new password as well " +echo " " +echo " Website : https://www.cyberpanel.net " +echo " Forums : https://forums.cyberpanel.net " +echo " Wikipage: https://cyberpanel.net/KnowledgeBase/ " +echo " " +echo -e " Enjoy your accelerated Internet by " +echo -e " CyberPanel & $WORD " +echo "###################################################################" +if [[ $PROVIDER != "undefined" ]] ; then + echo -e "\033[0;32m$PROVIDER\033[39m detected..." + echo -e "This provider has a \e[31mnetwork-level firewall\033[39m" +else + echo -e "If your provider has a \e[31mnetwork-level firewall\033[39m" +fi + echo -e "Please make sure you have opened following port for both in/out:" + echo -e "\033[0;32mTCP: 8090\033[39m for CyberPanel" + echo -e "\033[0;32mTCP: 80\033[39m, \033[0;32mTCP: 443\033[39m and \033[0;32mUDP: 443\033[39m for webserver" + echo -e "\033[0;32mTCP: 21\033[39m and \033[0;32mTCP: 40110-40210\033[39m for FTP" + echo -e "\033[0;32mTCP: 25\033[39m, \033[0;32mTCP: 587\033[39m, \033[0;32mTCP: 465\033[39m, \033[0;32mTCP: 110\033[39m, \033[0;32mTCP: 143\033[39m and \033[0;32mTCP: 993\033[39m for mail service" + echo -e "\033[0;32mTCP: 53\033[39m and \033[0;32mUDP: 53\033[39m for DNS service" +if [[ $SERVER_COUNTRY = CN ]] ; then + if [[ $PROVIDER == "Tencent Cloud" ]] ; then + if [[ $SERVER_OS == "Ubuntu" ]] ; then + rm -f /etc/apt/sources.list + mv /etc/apt/sources.list-backup /etc/apt/sources.list +echo > "nameserver 127.0.0.53 +options edns0" /run/systemd/resolve/stub-resolv.conf +echo > "nameserver 127.0.0.53 +options edns0" /etc/resolv.conf + apt update +#revert the previous change on tencent cloud repo. + fi + fi + if [[ $VERSION = "ENT" ]] ; then + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.5-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/install/installCyberPanel.py + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://cyberpanel.sh/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py + sed -i 's|https://www.litespeedtech.com/packages/5.0/lsws-5.3.8-ent-x86_64-linux.tar.gz|https://'$DOWNLOAD_SERVER'/litespeed/lsws-'$LSWS_STABLE_VER'-ent-x86_64-linux.tar.gz|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py + echo -e "If you have install LiteSpeed Enterprise, please run \e[31m/usr/local/lsws/admin/misc/lsup.sh\033[39m to update it to latest." + fi +fi + +sed -i 's|lsws-5.3.8|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-5.4.2|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-5.3.5|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-6.0|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py +sed -i 's|lsws-6.3.4|lsws-'$LSWS_STABLE_VER'|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py + +if [[ $SILENT != "ON" ]] ; then +printf "%s" "Would you like to restart your server now? [y/N]: " +read TMP_YN + +if [[ "$TMP_YN" = "N" ]] || [[ "$TMP_YN" = "n" ]] || [[ -z "$TMP_YN" ]]; then +: +else +reboot +exit +fi + +exit +fi +#replace URL for CN + + + +else +echo "something went wrong..." +exit +fi +} + +argument_mode() { +KEY_SIZE=${#VERSION} +TMP=$(echo $VERSION | cut -c5) +TMP2=$(echo $VERSION | cut -c10) +TMP3=$(echo $VERSION | cut -c15) +if [[ $VERSION == "OLS" || $VERSION == "ols" ]] ; then + VERSION="OLS" + echo -e "\nSet to OpenLiteSpeed..." +elif [[ $VERSION == "Trial" ]] || [[ $VERSION == "TRIAL" ]] || [[ $VERSION == "trial" ]] ; then + VERSION="ENT" + LICENSE_KEY="TRIAL" + echo -e "\nLiteSpeed Enterprise trial license set..." +elif [[ $TMP == "-" ]] && [[ $TMP2 == "-" ]] && [[ $TMP3 == "-" ]] && [[ $KEY_SIZE == "19" ]] ; then + LICENSE_KEY=$VERSION + VERSION="ENT" + echo -e "\nLiteSpeed Enterprise license key set..." +else + echo -e "\nCan not recognize the input value \e[31m$VERSION\e[39m " + echo -e "\nPlease verify the input value..." + echo -e "\nPlease run with \e[31m-h\e[39m or \e[31m--help\e[39m for more detail." + exit +fi + +if [[ $ADMIN_PASS == "d" ]] ; then + ADMIN_PASS="1234567" + echo -e "\nSet to default password..." + echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" +elif [[ $ADMIN_PASS == "r" ]] ; then + ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') + echo -e "\nSet to random-generated password..." + echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" + echo $ADMIN_PASS +else + echo -e "\nAdmin password will be set to \e[31m$ADMIN_PASS\e[39m" +fi +} + +if [ $# -eq 0 ] ; then + echo -e "\nInitializing...\n" +else + if [[ $1 == "help" ]] ; then + show_help + exit + elif [[ $1 == "dev" ]] ; then + DEV="ON" + DEV_ARG="ON" + SILENT="OFF" + elif [[ $1 == "default" ]] ; then + echo -e "\nThis will start default installation...\n" + SILENT="ON" + POSTFIX_VARIABLE="ON" + POWERDNS_VARIABLE="ON" + PUREFTPD_VARIABLE="ON" + VERSION="OLS" + ADMIN_PASS="1234567" + MEMCACHED="ON" + REDIS="ON" + else + while [ ! -z "${1}" ]; do + case $1 in + -v | --version) shift + if [ "${1}" = '' ]; then + show_help + exit + else + VERSION="${1}" + SILENT="ON" + fi + ;; + -p | --password) shift + if [[ "${1}" == '' ]]; then + ADMIN_PASS="1234567" + elif [[ "${1}" == 'r' ]] || [[ $1 == 'random' ]] ; then + ADMIN_PASS=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16 ; echo '') + else + if [ ${1} -lt 8 ] ; then + echo -e "\nPassword lenth less than 8 digital, please choose a more complicated password.\n" + exit + fi + ADMIN_PASS="${1}" + fi + ;; + -a | --addons) + MEMCACHED="ON" + REDIS="ON" + ;; + -m | --minimal) + echo "minimal installation is still work in progress..." + exit + ;; + -h | --help) + show_help + exit + ;; + *) + echo "unknown argument..." + show_help + exit + ;; + esac + shift + done + fi +fi + + + +SERVER_IP=$(curl --silent --max-time 10 -4 https://cyberpanel.sh/?ip) +if [[ $SERVER_IP =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo -e "Valid IP detected..." +else + echo -e "Can not detect IP, exit..." + exit +fi +SERVER_COUNTRY="unknow" +SERVER_COUNTRY=$(curl --silent --max-time 5 https://cyberpanel.sh/?country) +if [[ ${#SERVER_COUNTRY} == "2" ]] || [[ ${#SERVER_COUNTRY} == "6" ]] ; then + echo -e "\nChecking server..." + else + echo -e "\nChecking server..." + SERVER_COUNTRY="unknow" +fi +#SERVER_COUNTRY="CN" +#test string +if [[ $SERVER_COUNTRY == "CN" ]] ; then +DOWNLOAD_SERVER="cyberpanel.sh" +else +DOWNLOAD_SERVER="cdn.cyberpanel.sh" +fi + +check_OS +check_root +check_panel +check_process +check_provider + + + + + +if [[ $SILENT = "ON" ]] ; then +argument_mode +else +interactive_mode +fi + +SECONDS=0 +install_required + +pip_virtualenv + +system_tweak + +main_install \ No newline at end of file diff --git a/install_modules/00_common.sh b/install_modules/00_common.sh new file mode 100644 index 000000000..d650e3b32 --- /dev/null +++ b/install_modules/00_common.sh @@ -0,0 +1,418 @@ +#!/usr/bin/env bash +# CyberPanel install – common (globals, log, banner, detect_os, fix_*). Sourced by cyberpanel.sh. + +#!/bin/bash + +# CyberPanel Simple Installer +# Ultra-simple version that works reliably in all terminals + +set -e + +# Global variables +SERVER_OS="" +OS_FAMILY="" +PACKAGE_MANAGER="" +ARCHITECTURE="" +BRANCH_NAME="" +MARIADB_VER="" +DEBUG_MODE=false +AUTO_INSTALL=false +INSTALLATION_TYPE="" +# Prefer mariadb CLI (mysql is deprecated) +MDB_CLI="mariadb"; command -v mariadb >/dev/null 2>&1 || MDB_CLI="mysql" + +# Logging function +log_message() { + # Ensure log directory exists + mkdir -p "/var/log/CyberPanel" + echo "[$(date '+%Y-%m-%d %H:%M:%S')] [CYBERPANEL] $1" | tee -a "/var/log/CyberPanel/install.log" 2>/dev/null || echo "[$(date '+%Y-%m-%d %H:%M:%S')] [CYBERPANEL] $1" +} + +# Print status +print_status() { + local message="$1" + echo "$message" + log_message "$message" +} + +# Function to show banner +show_banner() { + clear + echo "" + echo "===============================================================================================================" + echo " CYBERPANEL COMPLETE INSTALLER" + echo "===============================================================================================================" + echo "" + echo " The Ultimate Web Hosting Control Panel" + echo " Powered by OpenLiteSpeed • Fast • Secure • Scalable" + echo "" + echo " Interactive Menus • Version Selection • Advanced Options" + echo "" + echo "===============================================================================================================" + echo "" +} + +# Function to detect OS +detect_os() { + # Check if we're running from a file (not via curl) and modules are available + if [ -f "modules/os/detect.sh" ]; then + # Load the OS detection module for enhanced support + source "modules/os/detect.sh" + detect_os + return $? + fi + + print_status "Detecting operating system..." + + # Detect architecture + ARCHITECTURE=$(uname -m) + case $ARCHITECTURE in + x86_64) + print_status "Architecture: x86_64 (Supported)" + ;; + aarch64|arm64) + print_status "Architecture: $ARCHITECTURE (Limited support)" + ;; + *) + print_status "Architecture: $ARCHITECTURE (Not supported)" + return 1 + ;; + esac + + # Get OS release information + local OUTPUT=$(cat /etc/*release 2>/dev/null) + if [ -z "$OUTPUT" ]; then + print_status "ERROR: Cannot read OS release information" + return 1 + fi + + # Detect OS + if echo $OUTPUT | grep -q "AlmaLinux 10" ; then + SERVER_OS="AlmaLinux10" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: AlmaLinux 10" + elif echo $OUTPUT | grep -q "AlmaLinux 9" ; then + SERVER_OS="AlmaLinux9" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: AlmaLinux 9" + elif echo $OUTPUT | grep -q "AlmaLinux 8" ; then + SERVER_OS="AlmaLinux8" + OS_FAMILY="rhel" + PACKAGE_MANAGER="yum" + print_status "Detected: AlmaLinux 8" + elif echo $OUTPUT | grep -q "CentOS Linux 9" ; then + SERVER_OS="CentOS9" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: CentOS Linux 9" + elif echo $OUTPUT | grep -q "CentOS Linux 8" ; then + SERVER_OS="CentOS8" + OS_FAMILY="rhel" + PACKAGE_MANAGER="yum" + print_status "Detected: CentOS Linux 8" + elif echo $OUTPUT | grep -q "Rocky Linux 9" ; then + SERVER_OS="RockyLinux9" + OS_FAMILY="rhel" + PACKAGE_MANAGER="dnf" + print_status "Detected: Rocky Linux 9" + elif echo $OUTPUT | grep -q "Rocky Linux 8" ; then + SERVER_OS="RockyLinux8" + OS_FAMILY="rhel" + PACKAGE_MANAGER="yum" + print_status "Detected: Rocky Linux 8" + elif echo $OUTPUT | grep -q "Ubuntu 24.04" ; then + SERVER_OS="Ubuntu2404" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Ubuntu 24.04" + elif echo $OUTPUT | grep -q "Ubuntu 22.04" ; then + SERVER_OS="Ubuntu2204" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Ubuntu 22.04" + elif echo $OUTPUT | grep -q "Ubuntu 20.04" ; then + SERVER_OS="Ubuntu2004" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Ubuntu 20.04" + elif echo $OUTPUT | grep -q "Debian GNU/Linux 13" ; then + SERVER_OS="Debian13" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Debian GNU/Linux 13" + elif echo $OUTPUT | grep -q "Debian GNU/Linux 12" ; then + SERVER_OS="Debian12" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Debian GNU/Linux 12" + elif echo $OUTPUT | grep -q "Debian GNU/Linux 11" ; then + SERVER_OS="Debian11" + OS_FAMILY="debian" + PACKAGE_MANAGER="apt" + print_status "Detected: Debian GNU/Linux 11" + else + print_status "ERROR: Unsupported OS detected" + print_status "Supported OS: AlmaLinux 8/9/10, CentOS 8/9, Rocky Linux 8/9, Ubuntu 20.04/22.04/24.04, Debian 11/12/13" + return 1 + fi + + return 0 +} + +# Function to fix static file permissions (critical for LiteSpeed) +fix_static_file_permissions() { + echo " 🔧 Fixing static file permissions for web server access..." + + # CRITICAL: Fix ownership and permissions for all public files + # LiteSpeed requires files to be owned by lscpd and NOT have execute permissions + + # Check if the public directory exists + if [ -d "/usr/local/CyberCP/public/" ]; then + echo " • Setting ownership to lscpd:lscpd for public directory..." + chown -R lscpd:lscpd /usr/local/CyberCP/public/ 2>/dev/null || true + + echo " • Setting directory permissions to 755..." + find /usr/local/CyberCP/public/ -type d -exec chmod 755 {} \; 2>/dev/null || true + + echo " • Setting file permissions to 644 (removing execute bit)..." + find /usr/local/CyberCP/public/ -type f -exec chmod 644 {} \; 2>/dev/null || true + + # Ensure parent directories have correct permissions + chmod 755 /usr/local/CyberCP/public/ 2>/dev/null || true + chmod 755 /usr/local/CyberCP/public/static/ 2>/dev/null || true + + echo " ✅ Static file permissions fixed successfully" + else + echo " ⚠️ Warning: /usr/local/CyberCP/public/ directory not found" + fi + + # Also check the alternative path + if [ -d "/usr/local/CyberPanel/public/" ]; then + echo " • Fixing permissions for /usr/local/CyberPanel/public/..." + chown -R lscpd:lscpd /usr/local/CyberPanel/public/ 2>/dev/null || true + find /usr/local/CyberPanel/public/ -type d -exec chmod 755 {} \; 2>/dev/null || true + find /usr/local/CyberPanel/public/ -type f -exec chmod 644 {} \; 2>/dev/null || true + fi +} + +# Function to fix post-installation issues +fix_post_install_issues() { + echo " 🔧 Fixing database connection issues..." + + # Wait for services to start + sleep 10 + + # Start and enable MariaDB if not running + if ! systemctl is-active --quiet mariadb; then + echo " Starting MariaDB service..." + systemctl start mariadb + systemctl enable mariadb + sleep 5 + fi + + # Start and enable LiteSpeed if not running + if ! systemctl is-active --quiet lsws; then + echo " Starting LiteSpeed service..." + systemctl start lsws + systemctl enable lsws + sleep 5 + fi + + # Fix database user permissions + echo " Fixing database user permissions..." + + # Wait for MariaDB to be ready + local retry_count=0 + while [ $retry_count -lt 10 ]; do + if $MDB_CLI -e "SELECT 1;" >/dev/null 2>&1; then + break + fi + echo " Waiting for MariaDB to be ready... ($((retry_count + 1))/10)" + sleep 2 + retry_count=$((retry_count + 1)) + done + + # Create database user with proper permissions + echo " Dropping existing cyberpanel user..." + $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'localhost';" 2>/dev/null || true + $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'%';" 2>/dev/null || true + + echo " Creating cyberpanel user with correct password..." + $MDB_CLI -e "CREATE USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + $MDB_CLI -e "CREATE USER 'cyberpanel'@'%' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + + echo " Granting privileges..." + $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'localhost' WITH GRANT OPTION;" 2>/dev/null || true + $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'%' WITH GRANT OPTION;" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + + # Verify the user was created correctly + echo " Verifying database user..." + if $MDB_CLI -u cyberpanel -pcyberpanel -e "SELECT 1;" >/dev/null 2>&1; then + echo " ✅ Database user verification successful" + else + echo " ⚠️ Database user verification failed, trying alternative approach..." + # Alternative: use root to create the user + $MDB_CLI -e "CREATE OR REPLACE USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + $MDB_CLI -e "GRANT ALL PRIVILEGES ON *.* TO 'cyberpanel'@'localhost' WITH GRANT OPTION;" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + fi + + # Create CyberPanel database if it doesn't exist + $MDB_CLI -e "CREATE DATABASE IF NOT EXISTS cyberpanel;" 2>/dev/null || true + $MDB_CLI -e "GRANT ALL PRIVILEGES ON cyberpanel.* TO 'cyberpanel'@'localhost';" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + + # Get or set unified password for both CyberPanel and OpenLiteSpeed + local unified_password="" + if [ -f "/root/.cyberpanel_password" ]; then + unified_password=$(cat /root/.cyberpanel_password 2>/dev/null) + fi + + # If no password was captured from installation, use default + if [ -z "$unified_password" ]; then + unified_password="1234567" + # Save password to file for later retrieval + echo "$unified_password" > /root/.cyberpanel_password 2>/dev/null || true + chmod 600 /root/.cyberpanel_password 2>/dev/null || true + fi + + echo " Setting unified password for CyberPanel and OpenLiteSpeed..." + echo " Password: $unified_password" + + # First, ensure the cyberpanel user exists and has correct password + $MDB_CLI -e "ALTER USER 'cyberpanel'@'localhost' IDENTIFIED BY 'cyberpanel';" 2>/dev/null || true + $MDB_CLI -e "FLUSH PRIVILEGES;" 2>/dev/null || true + + # Wait a moment for the database to be ready + sleep 2 + + # Reset CyberPanel admin password + echo " Setting CyberPanel admin password..." + /usr/local/CyberCP/bin/python3 /usr/local/CyberCP/plogical/adminPass.py 2>/dev/null || { + echo " Admin password reset failed, trying alternative method..." + # Alternative method: directly update the database + $MDB_CLI -u cyberpanel -pcyberpanel cyberpanel -e "UPDATE Administrator SET password = '$unified_password' WHERE id = 1;" 2>/dev/null || true + } + + # Set OpenLiteSpeed admin password + echo " Setting OpenLiteSpeed admin password..." + if [ -f "/usr/local/lsws/admin/htpasswd" ]; then + # Create OpenLiteSpeed admin user with the same password + /usr/local/lsws/admin/misc/admpass.sh -u admin -p "$unified_password" 2>/dev/null || { + echo " OpenLiteSpeed password set via alternative method..." + # Alternative method: directly create htpasswd entry + echo "admin:$(openssl passwd -apr1 '$unified_password')" > /usr/local/lsws/admin/htpasswd 2>/dev/null || true + } + fi + + # Fix PHP configuration files + echo " Fixing PHP configuration..." + + # Find the reference PHP version (usually lsphp82) + local reference_php="" + for php_version in lsphp82 lsphp81 lsphp80 lsphp84 lsphp83 lsphp74 lsphp73 lsphp72; do + if [ -d "/usr/local/lsws/$php_version" ] && [ -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then + reference_php="$php_version" + echo " Using $php_version as reference for PHP configuration" + break + fi + done + + if [ -n "$reference_php" ]; then + for php_version in lsphp72 lsphp73 lsphp74 lsphp80 lsphp81 lsphp82 lsphp83 lsphp84; do + if [ -d "/usr/local/lsws/$php_version" ]; then + # Create missing php.ini if it doesn't exist + if [ ! -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then + echo " Creating missing php.ini for $php_version..." + cp "/usr/local/lsws/$reference_php/etc/php.ini" "/usr/local/lsws/$php_version/etc/php.ini" 2>/dev/null || true + fi + + # Ensure the directory exists + mkdir -p "/usr/local/lsws/$php_version/etc" 2>/dev/null || true + fi + done + else + echo " ⚠️ No reference PHP configuration found, creating basic php.ini files..." + for php_version in lsphp72 lsphp73 lsphp74 lsphp80 lsphp81 lsphp82 lsphp83 lsphp84; do + if [ -d "/usr/local/lsws/$php_version" ]; then + mkdir -p "/usr/local/lsws/$php_version/etc" 2>/dev/null || true + if [ ! -f "/usr/local/lsws/$php_version/etc/php.ini" ]; then + echo " Creating basic php.ini for $php_version..." + cat > "/usr/local/lsws/$php_version/etc/php.ini" << 'EOF' +[PHP] +engine = On +short_open_tag = Off +precision = 14 +output_buffering = 4096 +zlib.output_compression = Off +implicit_flush = Off +unserialize_callback_func = +serialize_precision = -1 +disable_functions = +disable_classes = +zend.enable_gc = On +expose_php = Off +max_execution_time = 30 +max_input_time = 60 +memory_limit = 128M +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT +display_errors = Off +display_startup_errors = Off +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +variables_order = "GPCS" +request_order = "GP" +register_argc_argv = Off +auto_globals_jit = On +post_max_size = 8M +auto_prepend_file = +auto_append_file = +default_mimetype = "text/html" +default_charset = "UTF-8" +file_uploads = On +upload_max_filesize = 2M +max_file_uploads = 20 +allow_url_fopen = On +allow_url_include = Off +default_socket_timeout = 60 +EOF + fi + fi + done + fi + + # Restart services + echo " Restarting services..." + systemctl restart mariadb + systemctl restart lsws + + # Wait for services to stabilize + sleep 10 + + # Verify services are running + if systemctl is-active --quiet mariadb && systemctl is-active --quiet lsws; then + echo " ✅ Post-installation fixes completed successfully" + + # Run final verification + verify_installation + else + echo " ⚠️ Some services may need manual attention" + echo " 🔧 Attempting additional fixes..." + + # Additional service fixes + systemctl daemon-reload + systemctl reset-failed mariadb lsws + systemctl start mariadb lsws + + sleep 5 + verify_installation + fi +} + +# Function to verify installation diff --git a/install_modules/01_verify_deps.sh b/install_modules/01_verify_deps.sh new file mode 100644 index 000000000..c33cbb682 --- /dev/null +++ b/install_modules/01_verify_deps.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash +# CyberPanel install – verify_installation, install_dependencies. Sourced by cyberpanel.sh. + +verify_installation() { + echo "" + echo " 🔍 Verifying installation..." + + local issues=0 + + # Check MariaDB + if systemctl is-active --quiet mariadb; then + echo " ✅ MariaDB is running" + else + echo " ❌ MariaDB is not running" + issues=$((issues + 1)) + fi + + # Check LiteSpeed + if systemctl is-active --quiet lsws; then + echo " ✅ LiteSpeed is running" + else + echo " ❌ LiteSpeed is not running" + issues=$((issues + 1)) + fi + + # Check web interface + if curl -s -k --connect-timeout 5 https://localhost:8090 >/dev/null 2>&1; then + echo " ✅ Web interface is accessible" + else + echo " ⚠️ Web interface may not be accessible yet (this is normal)" + fi + + # Check database connection + if $MDB_CLI -e "SELECT 1;" >/dev/null 2>&1; then + echo " ✅ Database connection is working" + else + echo " ❌ Database connection failed" + issues=$((issues + 1)) + fi + + if [ $issues -eq 0 ]; then + echo "" + echo " 🎉 Installation verification completed successfully!" + echo " 🌐 CyberPanel: https://$(curl -s ifconfig.me):8090 (admin/1234567)" + echo " 🌐 OpenLiteSpeed: https://$(curl -s ifconfig.me):7080 (admin/1234567)" + echo " 🔑 Both services use the same password for convenience" + else + echo "" + echo " ⚠️ Installation completed with $issues issue(s)" + echo " 🔧 Some manual intervention may be required" + echo " 📋 Check the logs at: /var/log/CyberPanel/" + fi +} + +# Function to install dependencies +install_dependencies() { + # Check if we're running from a file (not via curl) and modules are available + if [ -f "modules/deps/manager.sh" ]; then + # Load the dependency manager module for enhanced support + source "modules/deps/manager.sh" + install_dependencies "$SERVER_OS" "$OS_FAMILY" "$PACKAGE_MANAGER" + return $? + fi + + print_status "Installing dependencies..." + echo "" + echo "Installing system dependencies for $SERVER_OS..." + echo "This may take a few minutes depending on your internet speed." + echo "" + + case $OS_FAMILY in + "rhel") + echo "Step 1/4: Installing EPEL repository..." + $PACKAGE_MANAGER install -y epel-release 2>/dev/null || true + echo " ✓ EPEL repository installed" + echo "" + + echo "Step 2/4: Installing development tools..." + $PACKAGE_MANAGER groupinstall -y 'Development Tools' 2>/dev/null || { + $PACKAGE_MANAGER install -y gcc gcc-c++ make kernel-devel 2>/dev/null || true + } + echo " ✓ Development tools installed" + echo "" + + echo "Step 3/4: Installing core packages..." + if [ "$SERVER_OS" = "AlmaLinux9" ] || [ "$SERVER_OS" = "AlmaLinux10" ] || [ "$SERVER_OS" = "CentOS9" ] || [ "$SERVER_OS" = "RockyLinux9" ]; then + # AlmaLinux 9/10 / CentOS 9 / Rocky Linux 9 + $PACKAGE_MANAGER install -y ImageMagick gd libicu oniguruma python3 python3-pip python3-devel 2>/dev/null || true + $PACKAGE_MANAGER install -y aspell 2>/dev/null || print_status "WARNING: aspell not available, skipping..." + $PACKAGE_MANAGER install -y libc-client-devel 2>/dev/null || print_status "WARNING: libc-client-devel not available, skipping..." + else + # AlmaLinux 8 / CentOS 8 / Rocky Linux 8 + $PACKAGE_MANAGER install -y ImageMagick gd libicu oniguruma aspell libc-client-devel python3 python3-pip python3-devel 2>/dev/null || true + fi + echo " ✓ Core packages installed" + echo "" + + echo "Step 4/4: Verifying installation..." + echo " ✓ All dependencies verified" + ;; + "debian") + echo "Step 1/4: Updating package lists..." + apt update -qq 2>/dev/null || true + echo " ✓ Package lists updated" + echo "" + + echo "Step 2/4: Installing essential packages..." + apt install -y -qq curl wget git unzip tar gzip bzip2 2>/dev/null || true + echo " ✓ Essential packages installed" + echo "" + + echo "Step 3/4: Installing development tools..." + apt install -y -qq build-essential gcc g++ make python3-dev python3-pip 2>/dev/null || true + echo " ✓ Development tools installed" + echo "" + + echo "Step 4/4: Installing core packages..." + apt install -y -qq imagemagick php-gd libicu-dev libonig-dev 2>/dev/null || true + apt install -y -qq aspell 2>/dev/null || print_status "WARNING: aspell not available, skipping..." + apt install -y -qq libc-client-dev 2>/dev/null || print_status "WARNING: libc-client-dev not available, skipping..." + echo " ✓ Core packages installed" + ;; + esac + + echo "" + print_status "SUCCESS: Dependencies installed successfully" +} + +# Function to install CyberPanel diff --git a/install_modules/02_install_core.sh b/install_modules/02_install_core.sh new file mode 100644 index 000000000..facc24d89 --- /dev/null +++ b/install_modules/02_install_core.sh @@ -0,0 +1,390 @@ +#!/usr/bin/env bash +# CyberPanel install – install_cyberpanel, install_cyberpanel_direct (part 1). Sourced by cyberpanel.sh. + +install_cyberpanel() { + print_status "Installing CyberPanel..." + echo "" + echo "===============================================================================================================" + echo " CYBERPANEL INSTALLATION IN PROGRESS" + echo "===============================================================================================================" + echo "" + echo "This process may take 10-15 minutes depending on your internet speed." + echo "Please DO NOT close this terminal or interrupt the installation." + echo "" + echo "Current Status:" + echo " ✓ Dependencies installed" + echo " 🔄 Starting CyberPanel installation using working method..." + echo "" + + # Use the working CyberPanel installation method + install_cyberpanel_direct +} + +# Function to check if CyberPanel is already installed +check_cyberpanel_installed() { + if [ -d "/usr/local/CyberPanel" ] || [ -d "/usr/local/CyberCP" ] || [ -f "/usr/local/lsws/bin/lswsctrl" ]; then + return 0 # CyberPanel is installed + else + return 1 # CyberPanel is not installed + fi +} + +# Function to clean up existing CyberPanel installation +cleanup_existing_cyberpanel() { + echo " 🧹 Cleaning up existing CyberPanel installation..." + + # Stop services + systemctl stop lsws mariadb 2>/dev/null || true + + # Remove CyberPanel directories + rm -rf /usr/local/CyberPanel 2>/dev/null || true + rm -rf /usr/local/CyberCP 2>/dev/null || true + rm -rf /usr/local/lsws 2>/dev/null || true + + # Remove systemd services + systemctl disable lsws mariadb 2>/dev/null || true + rm -f /etc/systemd/system/lsws.service 2>/dev/null || true + + # Clean up databases + $MDB_CLI -e "DROP DATABASE IF EXISTS cyberpanel;" 2>/dev/null || true + $MDB_CLI -e "DROP USER IF EXISTS 'cyberpanel'@'localhost';" 2>/dev/null || true + + echo " ✅ Cleanup completed" +} + +# Function to install CyberPanel directly using the working method +install_cyberpanel_direct() { + # Ask web server (OpenLiteSpeed vs LiteSpeed Enterprise) BEFORE MariaDB; default OpenLiteSpeed + if [ -z "$LS_ENT" ]; then + if [ "$AUTO_INSTALL" = true ]; then + LS_ENT="" + echo " Using OpenLiteSpeed (auto mode)." + else + echo "" + echo " Web server: 1) OpenLiteSpeed (default), 2) LiteSpeed Enterprise" + read -r -t 60 -p " Enter 1 or 2 [1]: " LS_CHOICE || true + LS_CHOICE="${LS_CHOICE:-1}" + LS_CHOICE="${LS_CHOICE// /}" + if [ "$LS_CHOICE" = "2" ]; then + echo " LiteSpeed Enterprise selected. Enter serial/key (required):" + read -r -t 120 -p " Serial: " LS_SERIAL || true + LS_SERIAL="${LS_SERIAL:-}" + if [ -z "$LS_SERIAL" ]; then + echo " No serial provided. Defaulting to OpenLiteSpeed." + LS_ENT="" + else + LS_ENT="ent" + echo " Using LiteSpeed Enterprise with provided serial." + fi + else + LS_ENT="" + echo " Using OpenLiteSpeed." + fi + echo "" + fi + fi + + # Ask MariaDB version (after web server choice) if not set via --mariadb-version + if [ -z "$MARIADB_VER" ]; then + echo "" + echo " MariaDB version: 10.11, 11.8 (LTS, default) or 12.1?" + read -r -t 60 -p " Enter 10.11, 11.8 or 12.1 [11.8]: " MARIADB_VER || true + MARIADB_VER="${MARIADB_VER:-11.8}" + MARIADB_VER="${MARIADB_VER// /}" + if [ "$MARIADB_VER" != "10.11" ] && [ "$MARIADB_VER" != "11.8" ] && [ "$MARIADB_VER" != "12.1" ]; then + MARIADB_VER="11.8" + fi + echo " Using MariaDB $MARIADB_VER" + echo "" + fi + + echo " 🔄 Downloading CyberPanel installation files..." + + # Check if CyberPanel is already installed + if check_cyberpanel_installed; then + echo " ⚠️ CyberPanel is already installed but may not be working properly" + echo " 🔧 Cleaning up existing installation and reinstalling..." + cleanup_existing_cyberpanel + fi + + # Pre-installation system checks + echo " 🔍 Running pre-installation checks..." + + # Ensure system is up to date + if command -v dnf >/dev/null 2>&1; then + echo " Updating system packages..." + dnf update -y >/dev/null 2>&1 || true + elif command -v yum >/dev/null 2>&1; then + echo " Updating system packages..." + yum update -y >/dev/null 2>&1 || true + elif command -v apt >/dev/null 2>&1; then + echo " Updating system packages..." + apt update -y >/dev/null 2>&1 || true + apt upgrade -y >/dev/null 2>&1 || true + fi + + # Ensure required services are available + echo " Checking system services..." + systemctl enable mariadb 2>/dev/null || true + systemctl enable lsws 2>/dev/null || true + + # Clear any previous install temp folders so we never use stale extracted files + rm -rf /tmp/cyberpanel_install_* 2>/dev/null || true + + # Create temporary directory for installation + local temp_dir="/tmp/cyberpanel_install_$$" + mkdir -p "$temp_dir" + cd "$temp_dir" || return 1 + + # Only add dnf exclude when we want to KEEP the current MariaDB (same version as user chose). + # If user chose 11.8 but 10.11 is installed, do NOT exclude — allow install.py to upgrade. + if command -v rpm >/dev/null 2>&1; then + if rpm -qa | grep -qiE "^(mariadb-server|mysql-server|MariaDB-server)" 2>/dev/null; then + local mariadb_version=$(mysql --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) + if [ -n "$mariadb_version" ]; then + local major_ver=$(echo "$mariadb_version" | cut -d. -f1) + local minor_ver=$(echo "$mariadb_version" | cut -d. -f2) + local installed_majmin="${major_ver}.${minor_ver}" + local chosen_ver="${MARIADB_VER:-11.8}" + # Only add exclude when installed version matches user's choice (preserve, no upgrade) + if [ "$installed_majmin" = "$chosen_ver" ]; then + print_status "MariaDB $mariadb_version matches chosen $chosen_ver, adding dnf exclude to preserve it" + + # Add MariaDB-server to dnf excludes (multiple formats for compatibility) + local dnf_conf="/etc/dnf/dnf.conf" + local exclude_added=false + + if [ -f "$dnf_conf" ]; then + # Check if [main] section exists + if grep -q "^\[main\]" "$dnf_conf" 2>/dev/null; then + # [main] section exists, add exclude there + if ! grep -q "exclude=.*MariaDB-server" "$dnf_conf" 2>/dev/null; then + if grep -q "^exclude=" "$dnf_conf" 2>/dev/null; then + # Append to existing exclude line in [main] section + sed -i '/^\[main\]/,/^\[/ { /^exclude=/ s/$/ MariaDB-server*/ }' "$dnf_conf" + else + # Add new exclude line after [main] + sed -i '/^\[main\]/a exclude=MariaDB-server*' "$dnf_conf" + fi + exclude_added=true + fi + else + # No [main] section, add it with exclude + if ! grep -q "exclude=.*MariaDB-server" "$dnf_conf" 2>/dev/null; then + echo "" >> "$dnf_conf" + echo "[main]" >> "$dnf_conf" + echo "exclude=MariaDB-server*" >> "$dnf_conf" + exclude_added=true + fi + fi + else + # Create dnf.conf with exclude + echo "[main]" > "$dnf_conf" + echo "exclude=MariaDB-server*" >> "$dnf_conf" + exclude_added=true + fi + + if [ "$exclude_added" = true ]; then + print_status "Added MariaDB-server* to dnf excludes in $dnf_conf" + fi + + # Also add to yum.conf for compatibility + local yum_conf="/etc/yum.conf" + if [ -f "$yum_conf" ]; then + if ! grep -q "exclude=.*MariaDB-server" "$yum_conf" 2>/dev/null; then + if grep -q "^exclude=" "$yum_conf" 2>/dev/null; then + sed -i 's/^exclude=\(.*\)/exclude=\1 MariaDB-server*/' "$yum_conf" + else + echo "exclude=MariaDB-server*" >> "$yum_conf" + fi + print_status "Added MariaDB-server* to yum excludes" + fi + fi + + # Create a function to disable MariaDB repositories (will be called after repository setup) + disable_mariadb_repos() { + local repo_files=( + "/etc/yum.repos.d/mariadb-main.repo" + "/etc/yum.repos.d/mariadb.repo" + "/etc/yum.repos.d/mariadb-12.1.repo" + ) + + # Also check for any mariadb repo files + while IFS= read -r repo_file; do + repo_files+=("$repo_file") + done < <(find /etc/yum.repos.d -name "*mariadb*.repo" 2>/dev/null) + + for repo_file in "${repo_files[@]}"; do + if [ -f "$repo_file" ] && [ -n "$repo_file" ]; then + # First, try to disable by setting enabled=0 + sed -i 's/^enabled\s*=\s*1/enabled=0/g' "$repo_file" 2>/dev/null + + # If file contains MariaDB 12.1 references, disable or remove it + if grep -qi "mariadb.*12\|12.*mariadb\|mariadb-main" "$repo_file" 2>/dev/null; then + # Try to add enabled=0 to each [mariadb...] section + python3 -c " +import re +import sys +try: + with open('$repo_file', 'r') as f: + content = f.read() + + # Replace enabled=1 with enabled=0 + content = re.sub(r'(enabled\s*=\s*)1', r'\g<1>0', content, flags=re.IGNORECASE) + + # Add enabled=0 after [mariadb...] sections if not present + lines = content.split('\n') + new_lines = [] + in_mariadb_section = False + has_enabled = False + + for i, line in enumerate(lines): + new_lines.append(line) + if re.match(r'^\s*\[.*mariadb.*\]', line, re.IGNORECASE): + in_mariadb_section = True + has_enabled = False + elif in_mariadb_section: + if re.match(r'^\s*enabled\s*=', line, re.IGNORECASE): + has_enabled = True + elif re.match(r'^\s*\[', line) and not re.match(r'^\s*\[.*mariadb.*\]', line, re.IGNORECASE): + if not has_enabled: + new_lines.insert(-1, 'enabled=0') + in_mariadb_section = False + has_enabled = False + + if in_mariadb_section and not has_enabled: + new_lines.append('enabled=0') + + with open('$repo_file', 'w') as f: + f.write('\n'.join(new_lines)) +except: + # Fallback: just rename the file + import os + os.rename('$repo_file', '${repo_file}.disabled') +" 2>/dev/null || \ + # Fallback: rename the file to disable it + mv "$repo_file" "${repo_file}.disabled" 2>/dev/null || true + fi + fi + done + } + + # Export function so it can be called from installer + export -f disable_mariadb_repos + export MARIADB_VERSION="$mariadb_version" + + # Also set up a background process to monitor and disable repos + ( + while [ ! -f /tmp/cyberpanel_install_complete ]; do + sleep 2 + if [ -f /etc/yum.repos.d/mariadb-main.repo ] || [ -f /etc/yum.repos.d/mariadb.repo ]; then + disable_mariadb_repos + fi + done + ) & + local monitor_pid=$! + echo "$monitor_pid" > /tmp/cyberpanel_repo_monitor.pid + print_status "Started background process to monitor and disable MariaDB repositories" + else + # User chose a different version (e.g. 11.8) than installed (e.g. 10.11) — allow upgrade + print_status "MariaDB $mariadb_version installed but you chose $chosen_ver; not adding dnf exclude (installer will upgrade)" + # Remove any existing MariaDB exclude from a previous run so install can proceed + for c in /etc/dnf/dnf.conf /etc/yum.conf; do + if [ -f "$c" ] && grep -q "exclude=.*MariaDB-server" "$c" 2>/dev/null; then + sed -i 's/ *MariaDB-server\* *//g; s/exclude= *$/exclude=/; s/exclude=\s*$/exclude=/' "$c" 2>/dev/null + if grep -q "^exclude=\s*$" "$c" 2>/dev/null; then + sed -i '/^exclude=\s*$/d' "$c" 2>/dev/null + fi + print_status "Removed MariaDB-server from excludes in $c to allow upgrade" + fi + done + fi + fi + fi + fi + + # Download the working CyberPanel installation files from upstream (usmannasir/cyberpanel) + echo "Downloading from: https://raw.githubusercontent.com/usmannasir/cyberpanel/v2.5.5-dev/cyberpanel.sh" + + # First, try to download the repository archive to get the correct installer + # GitHub: branch archives use refs/heads/BRANCH; GitHub returns 302 redirect to codeload, so we must use -L + local archive_url="" + local installer_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/v2.5.5-dev/cyberpanel.sh" + if curl -s -L --head "https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" | grep -q "200 OK"; then + archive_url="https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" + echo " Using development branch (v2.5.5-dev) from usmannasir/cyberpanel" + elif curl -s -L --head "https://github.com/usmannasir/cyberpanel/archive/v2.5.5-dev.tar.gz" | grep -q "200 OK"; then + archive_url="https://github.com/usmannasir/cyberpanel/archive/v2.5.5-dev.tar.gz" + echo " Using development branch (v2.5.5-dev) from usmannasir/cyberpanel" + else + echo " Development branch archive not available, trying installer script directly..." + if ! curl -s -L --head "$installer_url" | grep -q "200 OK"; then + echo " Development branch not available, falling back to stable" + installer_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" + archive_url="https://github.com/usmannasir/cyberpanel/archive/stable.tar.gz" + else + archive_url="https://github.com/usmannasir/cyberpanel/archive/refs/heads/v2.5.5-dev.tar.gz" + fi + fi + + curl --silent -o cyberpanel_installer.sh "$installer_url" 2>/dev/null + if [ $? -ne 0 ] || [ ! -s "cyberpanel_installer.sh" ]; then + print_status "ERROR: Failed to download CyberPanel installer" + return 1 + fi + + # Do NOT patch installer to add --exclude=MariaDB-server*: it blocks initial MariaDB install + # and causes "MariaDB-server requires MariaDB-client but none of the providers can be installed". + + # Make script executable (use full path in case cwd has noexec) + chmod 755 cyberpanel_installer.sh 2>/dev/null || chmod +x cyberpanel_installer.sh 2>/dev/null || true + if [ ! -x "cyberpanel_installer.sh" ]; then + print_status "Note: Script will be run with bash (executable bit not set)" + fi + + # Download the install directory (use archive_url set above; may be branch or stable) + echo "Downloading installation files..." + if [ -z "$archive_url" ] || [ "$installer_url" = "https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" ]; then + archive_url="https://github.com/usmannasir/cyberpanel/archive/stable.tar.gz" + fi + # Append cache-bust so CDNs/proxies don't serve old installer (GitHub ignores query params) + archive_url="${archive_url}?nocache=$(date +%s 2>/dev/null || echo 0)" + + curl --silent -L -o install_files.tar.gz "$archive_url" 2>/dev/null + if [ $? -ne 0 ] || [ ! -s "install_files.tar.gz" ]; then + print_status "ERROR: Failed to download installation files" + return 1 + fi + + # Extract the installation files + tar -xzf install_files.tar.gz 2>/dev/null + if [ $? -ne 0 ]; then + print_status "ERROR: Failed to extract installation files" + return 1 + fi + + # Copy install directory to current location + if [ "$installer_url" = "https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel.sh" ]; then + if [ -d "cyberpanel-stable" ]; then + cp -r cyberpanel-stable/install . 2>/dev/null || true + cp -r cyberpanel-stable/install.sh . 2>/dev/null || true + fi + else + if [ -d "cyberpanel-v2.5.5-dev" ]; then + cp -r cyberpanel-v2.5.5-dev/install . 2>/dev/null || true + cp -r cyberpanel-v2.5.5-dev/install.sh . 2>/dev/null || true + fi + fi + + # Verify install directory was copied + if [ ! -d "install" ]; then + print_status "ERROR: install directory not found after extraction" + print_status "Archive contents:" + ls -la 2>/dev/null | head -20 + return 1 + fi + + print_status "Verified install directory exists" + install_cyberpanel_direct_cont +} + diff --git a/install_modules/03_install_direct.sh b/install_modules/03_install_direct.sh new file mode 100644 index 000000000..a95e46808 --- /dev/null +++ b/install_modules/03_install_direct.sh @@ -0,0 +1,411 @@ +#!/usr/bin/env bash +# CyberPanel install – install_cyberpanel_direct_cont (part 2). Sourced by cyberpanel.sh. + +# Continuation of install_cyberpanel_direct (split for module size) +install_cyberpanel_direct_cont() { + echo " ✓ CyberPanel installation files downloaded" + echo " 🔄 Starting CyberPanel installation..." + echo "" + echo "IMPORTANT: The installation is now running in the background." + echo "You will see detailed output from the CyberPanel installer below." + echo "This is normal and expected - the installation is proceeding!" + echo "" + echo "===============================================================================================================" + echo "" + + # Run the installer with live progress monitoring + echo "Starting CyberPanel installation process..." + echo "This may take several minutes. Please be patient." + echo "" + + # Create log directory (same as v2.4.4: installer logs go here) + mkdir -p /var/log/CyberPanel + echo " Installation logs:" + echo " • /var/log/CyberPanel/install.log (installer script messages)" + echo " • /var/log/CyberPanel/install_output.log (Python installer stdout/stderr)" + echo " • /var/log/installLogs.txt (install.py detailed log)" + echo "" + + # Run the installer with live output monitoring + echo "Starting CyberPanel installer with live progress monitoring..." + echo "" + echo "===============================================================================================================" + echo " LIVE INSTALLATION PROGRESS" + echo "===============================================================================================================" + echo "" + + # Set branch environment variable for the installer + if [ -n "$BRANCH_NAME" ]; then + export CYBERPANEL_BRANCH="$BRANCH_NAME" + echo "Setting installation branch to: $BRANCH_NAME" + else + export CYBERPANEL_BRANCH="stable" + echo "Using default stable branch" + fi + echo "" + + # CRITICAL: Use install/install.py directly instead of cyberpanel_installer.sh + # The cyberpanel_installer.sh is the old wrapper that doesn't support auto-install + # install/install.py is the actual installer that we can control + local installer_py="install/install.py" + if [ -f "$installer_py" ]; then + print_status "Using install/install.py directly for installation (non-interactive mode)" + + # NOTE: We do NOT patch install.py to add --exclude=MariaDB-server* to dnf install. + # That would block the initial MariaDB-server install. install.py now clears dnf exclude + # before installing MariaDB and uses official MariaDB-server packages. + + # Clear MariaDB-server from dnf/yum exclude so the installer can install or reinstall it + # (cyberpanel.sh may have added it earlier when 10.x was detected; partial installs leave exclude in place) + for conf in /etc/dnf/dnf.conf /etc/yum.conf; do + if [ -f "$conf" ] && grep -q "exclude=.*MariaDB-server" "$conf" 2>/dev/null; then + sed -i '/^exclude=/s/MariaDB-server\*\s*//g' "$conf" + sed -i '/^exclude=/s/\s*MariaDB-server\*//g' "$conf" + sed -i '/^exclude=/s/MariaDB-server\s*//g' "$conf" + sed -i '/^exclude=\s*$/d' "$conf" + sed -i '/^exclude=$/d' "$conf" + print_status "Cleared MariaDB-server from exclude in $conf for installation" + fi + done + + # If MariaDB 10.x is installed, disable repositories right before running installer + if [ -n "$MARIADB_VERSION" ] && [ -f /tmp/cyberpanel_repo_monitor.pid ]; then + # Call the disable function one more time before installer runs + if type disable_mariadb_repos >/dev/null 2>&1; then + disable_mariadb_repos + fi + fi + + # Get server IP address (required by install.py) + local server_ip + if command -v curl >/dev/null 2>&1; then + server_ip=$(curl -s --max-time 5 https://api.ipify.org 2>/dev/null || curl -s --max-time 5 https://icanhazip.com 2>/dev/null || echo "") + fi + + if [ -z "$server_ip" ]; then + # Fallback: try to get IP from network interfaces + server_ip=$(ip route get 8.8.8.8 2>/dev/null | awk '{print $7; exit}' || \ + hostname -I 2>/dev/null | awk '{print $1}' || \ + echo "127.0.0.1") + fi + + if [ -z "$server_ip" ] || [ "$server_ip" = "127.0.0.1" ]; then + print_status "WARNING: Could not detect public IP, using 127.0.0.1" + server_ip="127.0.0.1" + fi + + print_status "Detected server IP: $server_ip" + + # CRITICAL: Install Python MySQL dependencies before running install.py + # installCyberPanel.py requires MySQLdb (mysqlclient) which needs development headers + echo "" + echo "===============================================================================================================" + echo "Installing Python MySQL dependencies (required for installCyberPanel.py)..." + echo "===============================================================================================================" + print_status "Installing Python MySQL dependencies..." + + # Detect OS for package installation + local os_family="" + if [ -f /etc/os-release ]; then + . /etc/os-release + case "$ID" in + almalinux|rocky|centos|rhel|fedora) + os_family="rhel" + print_status "Detected RHEL-based OS: $ID" + ;; + ubuntu|debian) + os_family="debian" + print_status "Detected Debian-based OS: $ID" + ;; + *) + print_status "Unknown OS ID: $ID, defaulting to RHEL-based" + os_family="rhel" + ;; + esac + else + print_status "WARNING: /etc/os-release not found, defaulting to RHEL-based" + os_family="rhel" + fi + + # Install MariaDB/MySQL development headers and Python mysqlclient + if [ "$os_family" = "rhel" ]; then + # RHEL-based (AlmaLinux, Rocky, CentOS, RHEL) + print_status "Installing MariaDB development headers for RHEL-based system..." + + # Try to install mariadb-devel (works with MariaDB 10.x and 12.x) + # NOTE: We need mariadb-devel even if we excluded MariaDB-server + # The exclude only applies to MariaDB-server, not development packages + if command -v dnf >/dev/null 2>&1; then + # For AlmaLinux 9/10 and newer - show output for debugging + print_status "Attempting to install mariadb-devel (development headers only, not server)..." + # Temporarily remove exclude for devel packages if needed + local dnf_exclude_backup="" + if [ -f /etc/dnf/dnf.conf ] && grep -q "exclude=.*MariaDB" /etc/dnf/dnf.conf; then + # Check if exclude is too broad + if grep -q "exclude=.*MariaDB-server.*MariaDB-devel" /etc/dnf/dnf.conf || \ + grep -q "exclude=.*MariaDB\*" /etc/dnf/dnf.conf; then + print_status "Temporarily adjusting dnf exclude to allow mariadb-devel installation..." + # We only want to exclude MariaDB-server, not devel packages + sed -i 's/exclude=\(.*\)MariaDB-server\(.*\)MariaDB-devel\(.*\)/exclude=\1MariaDB-server\2\3/' /etc/dnf/dnf.conf 2>/dev/null || true + sed -i 's/exclude=\(.*\)MariaDB\*\(.*\)/exclude=\1MariaDB-server*\2/' /etc/dnf/dnf.conf 2>/dev/null || true + fi + fi + + if dnf install -y --allowerasing --skip-broken --nobest \ + mariadb-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mariadb-devel" + elif dnf install -y --allowerasing --skip-broken --nobest \ + mysql-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mysql-devel" + elif dnf install -y --allowerasing --skip-broken --nobest \ + mariadb-connector-c-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mariadb-connector-c-devel" + else + print_status "⚠️ WARNING: Failed to install MariaDB development headers" + print_status "This may cause MySQLdb installation to fail" + fi + else + # For older systems with yum + print_status "Using yum to install mariadb-devel..." + if yum install -y mariadb-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mariadb-devel" + elif yum install -y mysql-devel pkgconfig gcc python3-devel python3-pip; then + print_status "✓ Successfully installed mysql-devel" + else + print_status "⚠️ WARNING: Failed to install MariaDB development headers" + fi + fi + + # Install mysqlclient Python package + print_status "Installing mysqlclient Python package..." + python3 -m pip install --upgrade pip setuptools wheel 2>&1 | grep -v "already satisfied" || true + if python3 -m pip install mysqlclient 2>&1; then + print_status "✓ Successfully installed mysqlclient" + else + # If pip install fails, try with build dependencies + print_status "Retrying mysqlclient installation with build dependencies..." + python3 -m pip install --no-cache-dir mysqlclient 2>&1 || { + print_status "⚠️ WARNING: Failed to install mysqlclient, trying alternative method..." + # Try installing from source + python3 -m pip install --no-binary mysqlclient mysqlclient 2>&1 || true + } + fi + + elif [ "$os_family" = "debian" ]; then + # Debian-based (Ubuntu, Debian) + print_status "Installing MariaDB development headers for Debian-based system..." + apt-get update -y + if apt-get install -y libmariadb-dev libmariadb-dev-compat pkg-config build-essential python3-dev python3-pip; then + print_status "✓ Successfully installed MariaDB development headers" + elif apt-get install -y default-libmysqlclient-dev pkg-config build-essential python3-dev python3-pip; then + print_status "✓ Successfully installed MySQL development headers" + else + print_status "⚠️ WARNING: Failed to install MariaDB/MySQL development headers" + fi + + # Install mysqlclient Python package + print_status "Installing mysqlclient Python package..." + python3 -m pip install --upgrade pip setuptools wheel 2>&1 | grep -v "already satisfied" || true + if python3 -m pip install mysqlclient 2>&1; then + print_status "✓ Successfully installed mysqlclient" + else + print_status "Retrying mysqlclient installation with build dependencies..." + python3 -m pip install --no-cache-dir mysqlclient 2>&1 || true + fi + fi + + # Verify MySQLdb is available (mysqlclient; some builds lack __version__) + print_status "Verifying MySQLdb module availability..." + if python3 -c "import MySQLdb; getattr(MySQLdb, '__version__', 'ok'); print('MySQLdb OK')" 2>/dev/null || \ + python3 -c "import MySQLdb; MySQLdb; print('MySQLdb OK')" 2>/dev/null; then + print_status "✓ MySQLdb module is available and working" + else + print_status "⚠️ WARNING: MySQLdb module not available" + print_status "Attempting to diagnose the issue..." + python3 -c "import sys; print('Python path:', sys.path)" 2>&1 || true + python3 -m pip list | grep -i mysql || print_status "No MySQL-related packages found in pip list" + print_status "Attempting to continue anyway, but installation may fail..." + fi + echo "" + + # Build installer arguments based on user preferences + # install.py requires publicip as first positional argument + local install_args=("$server_ip") + + # Web server: OpenLiteSpeed (default) or LiteSpeed Enterprise (--ent + --serial) + if [ -n "$LS_ENT" ] && [ -n "$LS_SERIAL" ]; then + install_args+=("--ent" "$LS_ENT" "--serial" "$LS_SERIAL") + fi + # Default: OpenLiteSpeed, Full installation (postfix, powerdns, ftp), Local MySQL + install_args+=("--postfix" "ON") + install_args+=("--powerdns" "ON") + install_args+=("--ftp" "ON") + install_args+=("--remotemysql" "OFF") + # Only pass --mariadb-version if this install.py supports it (avoids "unrecognized arguments" on older archives) + if grep -q "mariadb-version\|mariadb_version" "$installer_py" 2>/dev/null; then + install_args+=("--mariadb-version" "${MARIADB_VER:-11.8}") + fi + + if [ "$DEBUG_MODE" = true ]; then + # Note: install.py doesn't have --debug, but we can set it via environment + export DEBUG_MODE=true + fi + + # CRITICAL: If CyberPanel Python does not exist yet, patch installer to use system Python. + # Fixes FileNotFoundError when archive is cached/old and still references /usr/local/CyberPanel/bin/python. + if [ ! -f /usr/local/CyberPanel/bin/python ]; then + sys_python="/usr/bin/python3" + [ -x "$sys_python" ] || sys_python="/usr/local/bin/python3" + if [ -x "$sys_python" ]; then + for f in install/install_utils.py install/install.py; do + if [ -f "$f" ] && grep -q '/usr/local/CyberPanel/bin/python' "$f" 2>/dev/null; then + sed -i "s|/usr/local/CyberPanel/bin/python|$sys_python|g" "$f" + print_status "Patched $f to use $sys_python (CyberPanel python not yet installed)" + fi + done + fi + fi + + # Run the Python installer directly + if [ "$DEBUG_MODE" = true ]; then + python3 "$installer_py" "${install_args[@]}" 2>&1 | tee /var/log/CyberPanel/install_output.log + else + python3 "$installer_py" "${install_args[@]}" 2>&1 | tee /var/log/CyberPanel/install_output.log + fi + else + # Fallback to cyberpanel_installer.sh if install.py not found + print_status "WARNING: install/install.py not found, using cyberpanel_installer.sh (may be interactive)" + + local installer_script="cyberpanel_installer.sh" + if [ ! -f "$installer_script" ]; then + print_status "ERROR: cyberpanel_installer.sh not found in current directory: $(pwd)" + return 1 + fi + + # Get absolute path to installer script + local installer_path + if [[ "$installer_script" = /* ]]; then + installer_path="$installer_script" + else + installer_path="$(pwd)/$installer_script" + fi + + # If MariaDB 10.x is installed, disable repositories right before running installer + if [ -n "$MARIADB_VERSION" ] && [ -f /tmp/cyberpanel_repo_monitor.pid ]; then + # Call the disable function one more time before installer runs + if type disable_mariadb_repos >/dev/null 2>&1; then + disable_mariadb_repos + fi + fi + + if [ "$DEBUG_MODE" = true ]; then + bash "$installer_path" --debug 2>&1 | tee /var/log/CyberPanel/install_output.log + else + bash "$installer_path" 2>&1 | tee /var/log/CyberPanel/install_output.log + fi + fi + + local install_exit_code=${PIPESTATUS[0]} + + # Stop the repository monitor + if [ -f /tmp/cyberpanel_repo_monitor.pid ]; then + local monitor_pid=$(cat /tmp/cyberpanel_repo_monitor.pid 2>/dev/null) + if [ -n "$monitor_pid" ] && kill -0 "$monitor_pid" 2>/dev/null; then + kill "$monitor_pid" 2>/dev/null + fi + rm -f /tmp/cyberpanel_repo_monitor.pid + fi + touch /tmp/cyberpanel_install_complete 2>/dev/null || true + + local install_exit_code=${PIPESTATUS[0]} + + # Extract the generated password from the installation output + local generated_password=$(grep "Panel password:" /var/log/CyberPanel/install_output.log | awk '{print $NF}') + if [ -n "$generated_password" ]; then + echo "Captured CyberPanel password: $generated_password" + echo "$generated_password" > /root/.cyberpanel_password + chmod 600 /root/.cyberpanel_password + fi + + echo "" + echo "===============================================================================================================" + echo " INSTALLATION COMPLETED" + echo "===============================================================================================================" + echo "" + echo " Installation logs (for troubleshooting):" + echo " • /var/log/CyberPanel/install.log (installer script messages)" + echo " • /var/log/CyberPanel/install_output.log (Python installer stdout/stderr)" + echo " • /var/log/installLogs.txt (install.py detailed log)" + echo "" + + # Check if installation was successful + if [ $install_exit_code -ne 0 ]; then + print_status "ERROR: CyberPanel installation failed with exit code $install_exit_code" + echo "" + echo "Installation log (last 50 lines):" + echo "===============================================================================================================" + tail -50 /var/log/CyberPanel/install_output.log 2>/dev/null || echo "Could not read installation log" + echo "===============================================================================================================" + echo "" + echo "Full installation log available at: /var/log/CyberPanel/install_output.log" + echo "" + return 1 + fi + + # Clean up temporary directory + cd /tmp + rm -rf "$temp_dir" 2>/dev/null || true + + # Check if installation was successful + if [ $install_exit_code -eq 0 ]; then + # Installation succeeded, but don't print success message yet + # The CyberPanel installer has already shown its summary + + # Run static file permission fixes (critical for LiteSpeed) silently + fix_static_file_permissions >/dev/null 2>&1 + + return 0 + else + print_status "ERROR: CyberPanel installation failed (exit code: $install_exit_code)" + echo "" + echo "===============================================================================================================" + echo " INSTALLATION FAILED" + echo "===============================================================================================================" + echo "" + echo "The CyberPanel installation has failed. Here's how to troubleshoot:" + echo "" + echo "📋 LOG FILES LOCATION:" + echo " • Main installer log: /var/log/CyberPanel/install.log" + echo " • Installation output: /var/log/CyberPanel/install_output.log" + echo " • System logs: /var/log/messages" + echo "" + echo "🔍 TROUBLESHOOTING STEPS:" + echo " 1. Check the installation output log for specific errors" + echo " 2. Verify your system meets the requirements" + echo " 3. Ensure you have sufficient disk space and memory" + echo " 4. Check your internet connection" + echo " 5. Try running the installer again" + echo "" + echo "📄 LAST 30 LINES OF INSTALLATION LOG:" + echo "===============================================================================================================" + if [ -f "/var/log/CyberPanel/install_output.log" ]; then + tail -30 /var/log/CyberPanel/install_output.log 2>/dev/null || echo "Could not read installation log" + else + echo "Installation log not found at /var/log/CyberPanel/install_output.log" + fi + echo "===============================================================================================================" + echo "" + echo "💡 QUICK DEBUG COMMANDS:" + echo " • View full log: cat /var/log/CyberPanel/install_output.log" + echo " • Check system: free -h && df -h" + echo " • Check network: ping -c 3 google.com" + echo " • Retry installation: Run the installer again" + echo "" + echo "🆘 NEED HELP?" + echo " • CyberPanel Documentation: https://docs.cyberpanel.net" + echo " • CyberPanel Community: https://forums.cyberpanel.net" + echo " • GitHub Issues: https://github.com/usmannasir/cyberpanel/issues" + echo "" + return 1 + fi +} diff --git a/install_modules/04_fixes_status.sh b/install_modules/04_fixes_status.sh new file mode 100644 index 000000000..4f1d21ed7 --- /dev/null +++ b/install_modules/04_fixes_status.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env bash +# CyberPanel install – apply_fixes, show_status_summary. Sourced by cyberpanel.sh. + +apply_fixes() { + echo "" + echo "Applying post-installation configurations..." + + # Get the actual password that was generated during installation + local admin_password="" + if [ -f "/root/.cyberpanel_password" ]; then + admin_password=$(cat /root/.cyberpanel_password 2>/dev/null) + fi + + # If no password was captured, use the default + if [ -z "$admin_password" ]; then + admin_password="1234567" + echo "$admin_password" > /root/.cyberpanel_password + chmod 600 /root/.cyberpanel_password + fi + + # Fix database issues + systemctl start mariadb 2>/dev/null || true + systemctl enable mariadb 2>/dev/null || true + + # Fix LiteSpeed service only if the web server was actually installed + if [ -x /usr/local/lsws/bin/lswsctrl ] || [ -x /usr/local/lsws/bin/lsctrl ] || [ -f /usr/local/lsws/bin/openlitespeed ]; then + cat > /etc/systemd/system/lsws.service << 'EOF' +[Unit] +Description=LiteSpeed Web Server +After=network.target + +[Service] +Type=forking +User=root +Group=root +ExecStart=/usr/local/lsws/bin/lswsctrl start +ExecStop=/usr/local/lsws/bin/lswsctrl stop +ExecReload=/usr/local/lsws/bin/lswsctrl restart +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + + systemctl daemon-reload + systemctl enable lsws + systemctl start lsws || true + else + echo " • LiteSpeed/OpenLiteSpeed not found at /usr/local/lsws - skipping lsws.service (install may have skipped web server)" + echo " • If the installer failed earlier (e.g. Python error), re-run the installer. Once it completes, open ports 8090 and 7080 in your cloud security group (e.g. AWS EC2 Security Group inbound rules)." + systemctl disable lsws 2>/dev/null || true + rm -f /etc/systemd/system/lsws.service + systemctl daemon-reload + fi + + # Set OpenLiteSpeed admin password to match CyberPanel + echo " • Configuring OpenLiteSpeed admin password..." + if [ -f "/usr/local/lsws/admin/misc/admpass.sh" ]; then + # Auto-answer the prompts for username and password + (echo "admin"; echo "$admin_password"; echo "$admin_password") | /usr/local/lsws/admin/misc/admpass.sh >/dev/null 2>&1 || { + # Alternative method: directly create htpasswd entry + echo "admin:$(openssl passwd -apr1 '$admin_password')" > /usr/local/lsws/admin/htpasswd 2>/dev/null || true + } + echo " ✓ OpenLiteSpeed configured" + fi + + # Ensure CyberPanel (lscpd) service is running + echo " • Starting CyberPanel service..." + systemctl enable lscpd 2>/dev/null || true + systemctl start lscpd 2>/dev/null || true + + # Give services a moment to start + sleep 3 + + # Ensure both 8090 (CyberPanel) and 7080 (LiteSpeed/OLS) are accessible + echo " • Ensuring ports 8090 and 7080 are accessible..." + port_check() { + local port=$1 + command -v ss >/dev/null 2>&1 && ss -tlnp 2>/dev/null | grep -q ":$port " && return 0 + command -v netstat >/dev/null 2>&1 && netstat -tlnp 2>/dev/null | grep -q ":$port " && return 0 + return 1 + } + max_attempts=18 + attempt=0 + while [ $attempt -lt $max_attempts ]; do + need_restart=false + systemctl is-active --quiet mariadb || { systemctl start mariadb 2>/dev/null; need_restart=true; } + systemctl is-active --quiet lsws 2>/dev/null || { [ -x /usr/local/lsws/bin/lswsctrl ] && systemctl start lsws 2>/dev/null; need_restart=true; } + systemctl is-active --quiet lscpd 2>/dev/null || { systemctl start lscpd 2>/dev/null; need_restart=true; } + [ "$need_restart" = true ] && sleep 5 + if port_check 8090 && port_check 7080; then + echo " ✓ Port 8090 (CyberPanel) and 7080 (OpenLiteSpeed) are listening" + break + fi + attempt=$((attempt + 1)) + [ $attempt -lt $max_attempts ] && sleep 5 + done + if ! port_check 8090 || ! port_check 7080; then + systemctl start lscpd 2>/dev/null + systemctl start lsws 2>/dev/null + sleep 10 + if port_check 8090 && port_check 7080; then + echo " ✓ Port 8090 and 7080 are now listening" + else + echo " ⚠ One or both ports not yet listening. Run: systemctl start mariadb lsws lscpd" + echo " ⚠ On AWS/cloud: add inbound rules for TCP 8090 and 7080 in the instance security group." + fi + fi + + echo " ✓ Post-installation configurations completed" +} + +# Helper: check if a port is listening +_port_listening() { + local port=$1 + command -v ss >/dev/null 2>&1 && ss -tlnp 2>/dev/null | grep -q ":$port " && return 0 + command -v netstat >/dev/null 2>&1 && netstat -tlnp 2>/dev/null | grep -q ":$port " && return 0 + return 1 +} + +# Function to show status summary +show_status_summary() { + # Last-chance: try to start services so 8090 and 7080 are accessible + if ! _port_listening 8090 || ! _port_listening 7080; then + systemctl start mariadb 2>/dev/null || true + systemctl start lsws 2>/dev/null || true + systemctl start lscpd 2>/dev/null || true + sleep 8 + fi + + echo "===============================================================================================================" + echo " FINAL STATUS CHECK" + echo "===============================================================================================================" + echo "" + + # Quick service check + local all_services_running=true + + echo "Service Status:" + if systemctl is-active --quiet mariadb; then + echo " ✓ MariaDB Database - Running" + else + echo " ✗ MariaDB Database - Not Running" + all_services_running=false + fi + + if systemctl is-active --quiet lsws; then + echo " ✓ LiteSpeed Web Server - Running" + else + echo " ✗ LiteSpeed Web Server - Not Running" + all_services_running=false + fi + + if systemctl is-active --quiet lscpd; then + echo " ✓ CyberPanel Application - Running" + else + echo " ✗ CyberPanel Application - Not Running (may take a moment to start)" + all_services_running=false + fi + + echo "" + echo "Port Accessibility:" + if _port_listening 8090; then + echo " ✓ Port 8090 (CyberPanel) - Accessible" + else + echo " ✗ Port 8090 (CyberPanel) - Not listening (run: systemctl start lscpd)" + all_services_running=false + fi + if _port_listening 7080; then + echo " ✓ Port 7080 (OpenLiteSpeed) - Accessible" + else + echo " ✗ Port 7080 (OpenLiteSpeed) - Not listening (run: systemctl start lsws)" + all_services_running=false + fi + + # Get the actual password that was set + local admin_password="" + local server_ip=$(curl -s ifconfig.me 2>/dev/null || echo "your-server-ip") + + # Check if password was set in /root/.cyberpanel_password (if it exists) + if [ -f "/root/.cyberpanel_password" ]; then + admin_password=$(cat /root/.cyberpanel_password 2>/dev/null) + fi + + # If we have a password, show access details + if [ -n "$admin_password" ]; then + echo "" + echo "Access Details:" + echo " CyberPanel: https://$server_ip:8090" + echo " Username: admin" + echo " Password: $admin_password" + echo "" + echo " OpenLiteSpeed: https://$server_ip:7080" + echo " Username: admin" + echo " Password: $admin_password" + fi + + echo "" + echo "===============================================================================================================" + + if [ "$all_services_running" = true ]; then + echo "✓ Installation completed successfully! Ports 8090 and 7080 are accessible." + else + echo "⚠ Installation completed with warnings. Some services may need attention." + fi + echo "" +} + +# Function to show main menu diff --git a/install_modules/05_menus_main.sh b/install_modules/05_menus_main.sh new file mode 100644 index 000000000..c59776263 --- /dev/null +++ b/install_modules/05_menus_main.sh @@ -0,0 +1,328 @@ +#!/usr/bin/env bash +# CyberPanel install – main/fresh/version menus. Sourced by cyberpanel.sh. + +show_main_menu() { + show_banner + + echo "===============================================================================================================" + echo " SELECT INSTALLATION TYPE" + echo "===============================================================================================================" + echo "" + echo " 1. Fresh Installation (Recommended)" + echo " 2. Update Existing Installation" + echo " 3. Reinstall CyberPanel" + echo " 4. Force Reinstall (Clean & Install)" + echo " 5. Pre-Upgrade (Download latest upgrade script)" + echo " 6. Check System Status" + echo " 7. Advanced Options" + echo " 8. Exit" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Enter your choice [1-8]: " + read -r choice + + case $choice in + 1) + INSTALLATION_TYPE="fresh" + show_fresh_install_menu + return + ;; + 2) + INSTALLATION_TYPE="update" + show_update_menu + return + ;; + 3) + INSTALLATION_TYPE="reinstall" + show_reinstall_menu + return + ;; + 4) + INSTALLATION_TYPE="force_reinstall" + start_force_reinstall + return + ;; + 5) + start_preupgrade + return + ;; + 6) + show_system_status + return + ;; + 7) + show_advanced_menu + return + ;; + 8) + echo "Goodbye!" + exit 0 + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-7." + echo "" + ;; + esac + done +} + +# Function to show fresh installation menu +show_fresh_install_menu() { + echo "" + echo "===============================================================================================================" + echo " FRESH INSTALLATION SETUP" + echo "===============================================================================================================" + echo "" + + # Check if CyberPanel is already installed + if [ -d "/usr/local/CyberCP" ] && [ -f "/usr/local/CyberCP/manage.py" ]; then + echo "WARNING: CyberPanel appears to be already installed on this system." + echo " Consider using 'Update' or 'Reinstall' options instead." + echo "" + echo -n "Do you want to continue with fresh installation anyway? (y/n): " + read -r response + case $response in + [yY]|[yY][eE][sS]) + ;; + *) + show_main_menu + return + ;; + esac + fi + + echo "Select installation option:" + echo "" + echo " 1. Install Latest Stable Version" + echo " 2. Install Development Version (v2.5.5-dev)" + echo " 3. Install Specific Version/Branch" + echo " 4. Install from Commit Hash" + echo " 5. Quick Install (Auto-configure everything)" + echo " 6. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select installation option [1-6]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + show_installation_preferences + return + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + show_installation_preferences + return + ;; + 3) + show_version_selection + return + ;; + 4) + show_commit_selection + return + ;; + 5) + BRANCH_NAME="" + AUTO_INSTALL=true + start_installation + return + ;; + 6) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-6." + echo "" + ;; +esac + done +} + +# Function to show commit selection +show_commit_selection() { + echo "" + echo "===============================================================================================================" + echo " COMMIT HASH SELECTION" + echo "===============================================================================================================" + echo "" + echo "Enter a specific commit hash to install from:" + echo "" + echo "Examples:" + echo " • Latest commit: Leave empty (press Enter)" + echo " • Specific commit: a1b2c3d4e5f6789012345678901234567890abcd" + echo " • Short commit: a1b2c3d (first 7 characters)" + echo "" + echo "You can find commit hashes at: https://github.com/usmannasir/cyberpanel/commits" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Enter commit hash (or press Enter for latest): " + read -r commit_hash + + if [ -z "$commit_hash" ]; then + echo "Using latest commit..." + BRANCH_NAME="" + show_installation_preferences + return + elif [[ "$commit_hash" =~ ^[a-f0-9]{7,40}$ ]]; then + echo "Using commit: $commit_hash" + BRANCH_NAME="$commit_hash" + show_installation_preferences + return + else + echo "" + echo "ERROR: Invalid commit hash format." + echo " Please enter a valid Git commit hash (7-40 hexadecimal characters)." + echo "" + fi + done +} + +# Function to show version selection +show_version_selection() { + echo "" + echo "===============================================================================================================" + echo " VERSION SELECTION" + echo "===============================================================================================================" + echo "" + echo "Available versions:" + echo "" + echo " 1. Latest Stable (Recommended)" + echo " 2. v2.5.5-dev (Development)" + echo " 3. v2.4.4 (Previous Stable)" + echo " 4. Custom Branch Name" + echo " 5. Custom Commit Hash" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select version [1-5]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + break + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + break + ;; + 3) + BRANCH_NAME="v2.4.4" + break + ;; + 4) + echo -n "Enter branch name (e.g., main, v2.5.5-dev): " + read -r BRANCH_NAME + if [ -z "$BRANCH_NAME" ]; then + echo "ERROR: Branch name cannot be empty." + continue + fi + # Add v prefix if it's a version number without v + if [[ "$BRANCH_NAME" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + if [[ "$BRANCH_NAME" == *"-"* ]]; then + # Already has suffix like 2.5.5-dev, add v prefix + BRANCH_NAME="v$BRANCH_NAME" + else + # Add v prefix and dev suffix for development versions + BRANCH_NAME="v$BRANCH_NAME-dev" + fi + fi + break + ;; + 5) + echo -n "Enter commit hash (7-40 characters): " + read -r commit_hash + if [[ "$commit_hash" =~ ^[a-f0-9]{7,40}$ ]]; then + BRANCH_NAME="$commit_hash" + break + else + echo "ERROR: Invalid commit hash format." + continue + fi + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-5." + echo "" + ;; +esac + done + + show_installation_preferences +} + +# Function to show installation preferences +show_installation_preferences() { + echo "" + echo "===============================================================================================================" + echo " INSTALLATION PREFERENCES" + echo "===============================================================================================================" + echo "" + + # Debug mode + echo -n "Enable debug mode for detailed logging? (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + DEBUG_MODE=true + ;; + *) + DEBUG_MODE=false + ;; + esac + + # Auto-install + echo -n "Auto-install without further prompts? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + AUTO_INSTALL=false + ;; + *) + AUTO_INSTALL=true + ;; + esac + + # Show summary + echo "" + echo "===============================================================================================================" + echo " INSTALLATION SUMMARY" + echo "===============================================================================================================" + echo "" + echo " Type: $INSTALLATION_TYPE" + echo " Version: ${BRANCH_NAME:-'Latest Stable'}" + echo " Debug Mode: $DEBUG_MODE" + echo " Auto Install: $AUTO_INSTALL" + echo "" + echo "===============================================================================================================" + echo "" + + echo -n "Proceed with installation? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + start_installation + ;; + esac +} + +# Function to show update menu diff --git a/install_modules/06_menus_update.sh b/install_modules/06_menus_update.sh new file mode 100644 index 000000000..44ea8067c --- /dev/null +++ b/install_modules/06_menus_update.sh @@ -0,0 +1,247 @@ +#!/usr/bin/env bash +# CyberPanel install – update/reinstall/status menus. Sourced by cyberpanel.sh. + +show_update_menu() { + echo "" + echo "===============================================================================================================" + echo " UPDATE INSTALLATION" + echo "===============================================================================================================" + echo "" + + if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then + echo "ERROR: CyberPanel is not installed on this system." + echo " Please use 'Fresh Installation' instead." + echo "" + read -p "Press Enter to return to main menu..." + show_main_menu + return + fi + + # Check current version + local current_version="unknown" + if [ -f "/usr/local/CyberCP/version.txt" ]; then + current_version=$(cat /usr/local/CyberCP/version.txt 2>/dev/null) + fi + + echo "Current Installation:" + echo "Version: $current_version" + echo "Path: /usr/local/CyberCP" + echo "" + + echo "Select update option:" + echo "" + echo " 1. Update to Latest Stable" + echo " 2. Update to Development Version" + echo " 3. Update to Specific Version/Branch" + echo " 4. Update from Commit Hash" + echo " 5. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select update option [1-5]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + break + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + break + ;; + 3) + show_version_selection + return + ;; + 4) + show_commit_selection + return + ;; + 5) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-5." + echo "" + ;; + esac + done + + echo -n "Proceed with update? (This will backup your current installation) (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + start_upgrade + ;; + esac +} + +# Function to show reinstall menu +show_reinstall_menu() { + echo "" + echo "===============================================================================================================" + echo " REINSTALL CYBERPANEL" + echo "===============================================================================================================" + echo "" + + if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then + echo "ERROR: CyberPanel is not installed on this system." + echo " Please use 'Fresh Installation' instead." + echo "" + read -p "Press Enter to return to main menu..." + show_main_menu + return + fi + + echo "WARNING: This will completely remove the existing CyberPanel installation" + echo " and install a fresh copy. All data will be lost!" + echo "" + + echo -n "Are you sure you want to reinstall? (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + ;; + *) + show_main_menu + return + ;; + esac + + echo "Select reinstall option:" + echo "" + echo " 1. Reinstall Latest Stable" + echo " 2. Reinstall Development Version" + echo " 3. Reinstall Specific Version/Branch" + echo " 4. Reinstall from Commit Hash" + echo " 5. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select reinstall option [1-5]: " + read -r choice + + case $choice in + 1) + BRANCH_NAME="" + break + ;; + 2) + BRANCH_NAME="v2.5.5-dev" + break + ;; + 3) + show_version_selection + return + ;; + 4) + show_commit_selection + return + ;; + 5) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-5." + echo "" + ;; + esac + done + + echo -n "Proceed with reinstall? (This will delete all existing data) (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + start_reinstall + ;; + *) + show_main_menu + ;; + esac +} + +# Function to show system status +show_system_status() { + echo "" + echo "===============================================================================================================" + echo " SYSTEM STATUS CHECK" + echo "===============================================================================================================" + echo "" + + # Check OS + local os_info=$(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2 2>/dev/null || echo 'Unknown') + echo "Operating System: $os_info" + + # Check CyberPanel installation + if [ -d "/usr/local/CyberCP" ] && [ -f "/usr/local/CyberCP/manage.py" ]; then + local version="unknown" + if [ -f "/usr/local/CyberCP/version.txt" ]; then + version=$(cat /usr/local/CyberCP/version.txt 2>/dev/null) + fi + echo "CyberPanel: Installed (Version: $version)" + else + echo "CyberPanel: Not Installed" + fi + + # Check services + echo "" + echo "Services Status:" + if systemctl is-active --quiet mariadb; then + echo " SUCCESS: MariaDB - Running" + else + echo " ERROR: MariaDB - Not Running" + fi + + if systemctl is-active --quiet lsws; then + echo " SUCCESS: LiteSpeed - Running" + else + echo " ERROR: LiteSpeed - Not Running" + fi + + if systemctl is-active --quiet lscpd; then + echo " SUCCESS: CyberPanel - Running" + else + echo " ERROR: CyberPanel - Not Running" + fi + + # Check ports + echo "" + echo "Port Status:" + if netstat -tlnp | grep -q ":8090 "; then + echo " SUCCESS: Port 8090 (CyberPanel) - Listening" + else + echo " ERROR: Port 8090 (CyberPanel) - Not Listening" + fi + + if netstat -tlnp | grep -q ":80 "; then + echo " SUCCESS: Port 80 (HTTP) - Listening" + else + echo " ERROR: Port 80 (HTTP) - Not Listening" + fi + + echo "" + echo -n "Return to main menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + exit 0 + ;; + *) + show_main_menu + ;; + esac +} + +# Function to show advanced menu diff --git a/install_modules/07_menus_advanced.sh b/install_modules/07_menus_advanced.sh new file mode 100644 index 000000000..7287c0f15 --- /dev/null +++ b/install_modules/07_menus_advanced.sh @@ -0,0 +1,273 @@ +#!/usr/bin/env bash +# CyberPanel install – advanced/fix/clean/logs menus. Sourced by cyberpanel.sh. + +show_advanced_menu() { + echo "" + echo "===============================================================================================================" + echo " ADVANCED OPTIONS" + echo "===============================================================================================================" + echo "" + echo " 1. Fix Installation Issues" + echo " 2. Clean Installation Files" + echo " 3. View Installation Logs" + echo " 4. System Diagnostics" + echo " 5. Show Error Help" + echo " 6. Back to Main Menu" + echo "" + echo "===============================================================================================================" + echo "" + + while true; do + echo -n "Select advanced option [1-6]: " + read -r choice + + case $choice in + 1) + show_fix_menu + return + ;; + 2) + show_clean_menu + return + ;; + 3) + show_logs_menu + return + ;; + 4) + show_diagnostics + return + ;; + 5) + show_error_help + return + ;; + 6) + show_main_menu + return + ;; + *) + echo "" + echo "ERROR: Invalid choice. Please enter 1-6." + echo "" + ;; + esac + done +} + +# Function to show error help +show_error_help() { + echo "" + echo "===============================================================================================================" + echo " ERROR TROUBLESHOOTING HELP" + echo "===============================================================================================================" + echo "" + echo "If your CyberPanel installation failed, here's how to troubleshoot:" + echo "" + echo "📋 LOG FILES LOCATION:" + echo " • Main installer log: /var/log/CyberPanel/install.log" + echo " • Installation output: /var/log/CyberPanel/install_output.log" + echo " • Upgrade output: /var/log/CyberPanel/upgrade_output.log" + echo " • System logs: /var/log/messages" + echo "" + echo "🔍 COMMON ISSUES & SOLUTIONS:" + echo "" + echo "1. DEPENDENCY INSTALLATION FAILED:" + echo " • Check internet connection: ping -c 3 google.com" + echo " • Update package lists: yum update -y (RHEL) or apt update (Debian)" + echo " • Check available disk space: df -h" + echo "" + echo "2. CYBERPANEL DOWNLOAD FAILED:" + echo " • Check internet connectivity" + echo " • Verify GitHub access: curl -I https://github.com" + echo " • Try different branch/version" + echo "" + echo "3. PERMISSION ERRORS:" + echo " • Ensure running as root: whoami" + echo " • Check file permissions: ls -la /var/log/CyberPanel/" + echo "" + echo "4. SYSTEM REQUIREMENTS:" + echo " • Minimum 1GB RAM: free -h" + echo " • Minimum 10GB disk space: df -h" + echo " • Supported OS: AlmaLinux 8/9, CentOS 7/8, Ubuntu 18.04+" + echo "" + echo "5. SERVICE CONFLICTS:" + echo " • Check running services: systemctl list-units --state=running" + echo " • Stop conflicting services: systemctl stop apache2 (if running)" + echo "" + echo "💡 QUICK DEBUG COMMANDS:" + echo " • View installation log: cat /var/log/CyberPanel/install_output.log" + echo " • Check system resources: free -h && df -h" + echo " • Test network: ping -c 3 google.com" + echo " • Check services: systemctl status lscpd" + echo " • View system logs: tail -50 /var/log/messages" + echo "" + echo "🆘 GETTING HELP:" + echo " • CyberPanel Documentation: https://docs.cyberpanel.net" + echo " • CyberPanel Community: https://forums.cyberpanel.net" + echo " • GitHub Issues: https://github.com/usmannasir/cyberpanel/issues" + echo " • Discord Support: https://discord.gg/cyberpanel" + echo "" + echo "🔄 RETRY INSTALLATION:" + echo " • Clean installation: Run installer with 'Clean Installation Files' option" + echo " • Different version: Try stable version instead of development" + echo " • Fresh system: Consider using a clean OS installation" + echo "" + echo "===============================================================================================================" + echo "" + read -p "Press Enter to return to main menu..." + show_main_menu +} + +# Function to show fix menu +show_fix_menu() { + echo "" + echo "===============================================================================================================" + echo " FIX INSTALLATION ISSUES" + echo "===============================================================================================================" + echo "" + echo "This will attempt to fix common CyberPanel installation issues:" + echo "• Database connection problems" + echo "• Service configuration issues" + echo "• SSL certificate problems" + echo "• File permission issues" + echo "" + + echo -n "Proceed with fixing installation issues? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_advanced_menu + ;; + *) + print_status "Applying fixes..." + apply_fixes + print_status "SUCCESS: Fixes applied successfully" + echo "" + read -p "Press Enter to return to advanced menu..." + show_advanced_menu + ;; + esac +} + +# Function to show clean menu +show_clean_menu() { + echo "" + echo "===============================================================================================================" + echo " CLEAN INSTALLATION FILES" + echo "===============================================================================================================" + echo "" + echo "WARNING: This will remove temporary installation files and logs." + echo " This action cannot be undone!" + echo "" + + echo -n "Proceed with cleaning? (y/n) [n]: " + read -r response + case $response in + [yY]|[yY][eE][sS]) + rm -rf /tmp/cyberpanel_* + rm -rf /var/log/cyberpanel_install.log + echo "SUCCESS: Cleanup complete! Temporary files and logs have been removed." + ;; + esac + + echo "" + echo -n "Return to advanced menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + show_advanced_menu + ;; + esac +} + +# Function to show logs menu +show_logs_menu() { + echo "" + echo "===============================================================================================================" + echo " VIEW INSTALLATION LOGS" + echo "===============================================================================================================" + echo "" + + local log_file="/var/log/cyberpanel_install.log" + + if [ -f "$log_file" ]; then + echo "Installation Log: $log_file" + echo "Log Size: $(du -h "$log_file" | cut -f1)" + echo "" + + echo -n "View recent log entries? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + ;; + *) + echo "" + echo "Recent log entries:" + tail -n 20 "$log_file" + ;; + esac + else + echo "No installation logs found at $log_file" + fi + + echo "" + echo -n "Return to advanced menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + show_advanced_menu + ;; + esac +} + +# Function to show diagnostics +show_diagnostics() { + echo "" + echo "===============================================================================================================" + echo " SYSTEM DIAGNOSTICS" + echo "===============================================================================================================" + echo "" + + echo "Running system diagnostics..." + echo "" + + # Disk space + echo "Disk Usage:" + df -h | grep -E '^/dev/' + + # Memory usage + echo "" + echo "Memory Usage:" + free -h + + # Load average + echo "" + echo "System Load:" + uptime + + # Network interfaces + echo "" + echo "Network Interfaces:" + ip addr show | grep -E '^[0-9]+:|inet ' + + echo "" + echo -n "Return to advanced menu? (y/n) [y]: " + read -r response + case $response in + [nN]|[nN][oO]) + show_main_menu + ;; + *) + show_advanced_menu + ;; + esac +} + +# Function to start upgrade diff --git a/install_modules/08_actions.sh b/install_modules/08_actions.sh new file mode 100644 index 000000000..663dd2cef --- /dev/null +++ b/install_modules/08_actions.sh @@ -0,0 +1,317 @@ +#!/usr/bin/env bash +# CyberPanel install – start_* actions. Sourced by cyberpanel.sh. + +start_upgrade() { + echo "" + echo "===============================================================================================================" + echo " STARTING UPGRADE" + echo "===============================================================================================================" + echo "" + + # Detect OS + echo "Step 1/5: Detecting operating system..." + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + echo " ✓ Operating system detected successfully" + echo "" + + # Install dependencies + echo "Step 2/5: Installing/updating dependencies..." + install_dependencies + echo "" + + # Download and run the upgrade script + echo "Step 3/5: Downloading CyberPanel upgrade script..." + local upgrade_url="" + if [ -n "$BRANCH_NAME" ]; then + if [[ "$BRANCH_NAME" =~ ^[a-f0-9]{40}$ ]]; then + # It's a commit hash + echo "Downloading from commit: $BRANCH_NAME" + upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" + else + # It's a branch name + echo "Downloading from branch: $BRANCH_NAME" + upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" + fi + else + echo "Downloading from: https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh" + upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh" + fi + + curl --silent -o cyberpanel_upgrade.sh "$upgrade_url" 2>/dev/null + + chmod +x cyberpanel_upgrade.sh + + echo " ✓ CyberPanel upgrade script downloaded" + echo " 🔄 Starting CyberPanel upgrade..." + echo "" + echo "IMPORTANT: The upgrade is now running in the background." + echo "You will see detailed output from the CyberPanel upgrade script below." + echo "This is normal and expected - the upgrade is proceeding!" + echo "" + echo "===============================================================================================================" + echo "" + + # Run the upgrade with live progress monitoring + echo "Starting CyberPanel upgrade process..." + echo "This may take several minutes. Please be patient." + echo "" + + # Create log directory + mkdir -p /var/log/CyberPanel + + # Run the upgrade with live output monitoring + echo "Starting CyberPanel upgrade with live progress monitoring..." + echo "" + echo "===============================================================================================================" + echo " LIVE UPGRADE PROGRESS" + echo "===============================================================================================================" + echo "" + + # Run upgrade and show live output + if [ "$DEBUG_MODE" = true ]; then + ./cyberpanel_upgrade.sh --debug 2>&1 | tee /var/log/CyberPanel/upgrade_output.log + else + ./cyberpanel_upgrade.sh 2>&1 | tee /var/log/CyberPanel/upgrade_output.log + fi + + local upgrade_exit_code=${PIPESTATUS[0]} + + echo "" + echo "===============================================================================================================" + echo " UPGRADE COMPLETED" + echo "===============================================================================================================" + echo "" + + # Clean up downloaded upgrade script + rm -f cyberpanel_upgrade.sh 2>/dev/null + + # Check if upgrade was successful + if [ $upgrade_exit_code -eq 0 ]; then + print_status "SUCCESS: CyberPanel upgraded successfully" + return 0 + else + print_status "ERROR: CyberPanel upgrade failed with exit code $upgrade_exit_code" + echo "" + echo "Upgrade log (last 50 lines):" + echo "===============================================================================================================" + tail -50 /var/log/CyberPanel/upgrade_output.log 2>/dev/null || echo "Could not read upgrade log" + echo "===============================================================================================================" + echo "" + echo "Full upgrade log available at: /var/log/CyberPanel/upgrade_output.log" + echo "" + return 1 + fi +} + +# Function to start force reinstall +start_force_reinstall() { + echo "" + echo "===============================================================================================================" + echo " FORCE REINSTALL CYBERPANEL" + echo "===============================================================================================================" + echo "" + echo "This will completely remove the existing CyberPanel installation and install a fresh copy." + echo "All data and configurations will be lost!" + echo "" + + while true; do + echo -n "Are you sure you want to proceed? (y/N): " + read -r confirm + case $confirm in + [Yy]*) + echo "" + echo "Starting force reinstall..." + echo "" + + # Clean up existing installation + cleanup_existing_cyberpanel + + # Start fresh installation + start_installation + break + ;; + [Nn]*|"") + echo "Force reinstall cancelled." + return + ;; + *) + echo "Please answer yes or no." + ;; + esac + done +} + +# Function to start preupgrade +start_preupgrade() { + echo "" + echo "===============================================================================================================" + echo " PRE-UPGRADE SETUP" + echo "===============================================================================================================" + echo "" + + echo "This will download the latest CyberPanel upgrade script to /usr/local/" + echo "and prepare it for execution." + echo "" + + # Get the latest version + echo "Step 1/3: Fetching latest version information..." + local latest_version=$(curl -s https://cyberpanel.net/version.txt | sed -e 's|{"version":"||g' -e 's|","build":|.|g' | sed 's:}*$::') + local branch_name="v$latest_version" + + echo " ✓ Latest version: $latest_version" + echo " ✓ Branch: $branch_name" + echo "" + + # Download the upgrade script + echo "Step 2/3: Downloading CyberPanel upgrade script..." + local upgrade_url="https://raw.githubusercontent.com/usmannasir/cyberpanel/$branch_name/cyberpanel_upgrade.sh" + echo "Downloading from: $upgrade_url" + + if curl --silent -o /usr/local/cyberpanel_upgrade.sh "$upgrade_url" 2>/dev/null; then + chmod 700 /usr/local/cyberpanel_upgrade.sh + echo " ✓ Upgrade script downloaded to /usr/local/cyberpanel_upgrade.sh" + else + print_status "ERROR: Failed to download upgrade script" + return 1 + fi + echo "" + + # Show instructions + echo "Step 3/3: Setup complete!" + echo "" + echo "The upgrade script is now ready at: /usr/local/cyberpanel_upgrade.sh" + echo "" + echo "To run the upgrade, you can either:" + echo " 1. Use this installer's 'Update Existing Installation' option" + echo " 2. Run directly: /usr/local/cyberpanel_upgrade.sh" + echo "" + echo "===============================================================================================================" + echo "" + + read -p "Press Enter to return to main menu..." + show_main_menu +} + +# Function to start reinstall +start_reinstall() { + echo "" + echo "===============================================================================================================" + echo " STARTING REINSTALL" + echo "===============================================================================================================" + echo "" + + echo "WARNING: This will completely remove the existing CyberPanel installation!" + echo "All data, websites, and configurations will be lost!" + echo "" + + # Detect OS + echo "Step 1/6: Detecting operating system..." + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + echo " ✓ Operating system detected successfully" + echo "" + + # Stop services + echo "Step 2/6: Stopping CyberPanel services..." + systemctl stop lscpd 2>/dev/null || true + systemctl stop lsws 2>/dev/null || true + systemctl stop mariadb 2>/dev/null || true + systemctl stop postfix 2>/dev/null || true + systemctl stop dovecot 2>/dev/null || true + systemctl stop pure-ftpd 2>/dev/null || true + echo " ✓ Services stopped" + echo "" + + # Remove existing installation + echo "Step 3/6: Removing existing CyberPanel installation..." + rm -rf /usr/local/CyberCP 2>/dev/null || true + rm -rf /usr/local/lsws 2>/dev/null || true + rm -rf /home/cyberpanel 2>/dev/null || true + rm -rf /var/lib/mysql 2>/dev/null || true + rm -rf /var/log/cyberpanel 2>/dev/null || true + echo " ✓ Existing installation removed" + echo "" + + # Install dependencies + echo "Step 4/6: Installing dependencies..." + install_dependencies + echo "" + + # Install CyberPanel + echo "Step 5/6: Installing CyberPanel..." + if ! install_cyberpanel; then + print_status "ERROR: CyberPanel installation failed" + exit 1 +fi + echo "" + + # Apply fixes + echo "Step 6/6: Applying installation fixes..." + apply_fixes + echo "" + + # Show status summary + show_status_summary + + print_status "SUCCESS: CyberPanel reinstalled successfully!" +} + +# Function to start installation +start_installation() { + echo "" + echo "===============================================================================================================" + echo " STARTING INSTALLATION" + echo "===============================================================================================================" + echo "" + + # Detect OS + echo "Step 1/6: Detecting operating system..." + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + echo " ✓ Operating system detected successfully" + echo "" + + # Install dependencies + echo "Step 2/6: Installing dependencies..." + install_dependencies + echo "" + + # Install CyberPanel + echo "Step 3/6: Installing CyberPanel..." + if ! install_cyberpanel; then + print_status "ERROR: CyberPanel installation failed" + echo "" + echo "Would you like to see troubleshooting help? (y/n) [y]: " + read -r show_help + case $show_help in + [nN]|[nN][oO]) + echo "Installation failed. Check logs at /var/log/CyberPanel/" + echo "Run the installer again and select 'Advanced Options' → 'Show Error Help' for detailed troubleshooting." + ;; + *) + show_error_help + ;; + esac + exit 1 + fi + echo "" + + # Apply post-installation fixes silently + apply_fixes + + # Create standard aliases (silently) + create_standard_aliases >/dev/null 2>&1 + + # Show final status summary + echo "" + show_status_summary +} + +# Function to parse command line arguments diff --git a/install_modules/09_parse_main.sh b/install_modules/09_parse_main.sh new file mode 100644 index 000000000..f84351407 --- /dev/null +++ b/install_modules/09_parse_main.sh @@ -0,0 +1,247 @@ +#!/usr/bin/env bash +# CyberPanel install – parse_arguments, main. Sourced by cyberpanel.sh. + +parse_arguments() { + while [[ $# -gt 0 ]]; do + case $1 in + -b|--branch) + if [ -n "$2" ]; then + # Convert version number to branch name if needed + if [[ "$2" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + if [[ "$2" == *"-"* ]]; then + # Already has suffix like 2.5.5-dev, add v prefix + BRANCH_NAME="v$2" + else + # Add v prefix and dev suffix for development versions + BRANCH_NAME="v$2-dev" + fi + elif [[ "$2" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + # Already has v prefix, use as is + BRANCH_NAME="$2" + else + # Assume it's already a branch name or commit hash + BRANCH_NAME="$2" + fi + shift 2 + else + echo "ERROR: -b/--branch requires a version number or branch name" + echo "Example: -b 2.5.5-dev or -b v2.5.5-dev" + exit 1 + fi + ;; + -v|--version) + if [ -n "$2" ]; then + # Convert version number to branch name if needed + if [[ "$2" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + if [[ "$2" == *"-"* ]]; then + # Already has suffix like 2.5.5-dev, add v prefix + BRANCH_NAME="v$2" + else + # Add v prefix and dev suffix for development versions + BRANCH_NAME="v$2-dev" + fi + elif [[ "$2" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then + # Already has v prefix, use as is + BRANCH_NAME="$2" + else + # Assume it's already a branch name or commit hash + BRANCH_NAME="$2" + fi + shift 2 + else + echo "ERROR: -v/--version requires a version number or branch name" + echo "Example: -v 2.5.5-dev or -v v2.5.5-dev" + exit 1 + fi + ;; + --debug) + DEBUG_MODE=true + set -x + shift + ;; + --mariadb-version) + if [ -n "$2" ] && [ "$2" = "10.11" ]; then + MARIADB_VER="10.11" + shift 2 + elif [ -n "$2" ] && [ "$2" = "11.8" ]; then + MARIADB_VER="11.8" + shift 2 + elif [ -n "$2" ] && [ "$2" = "12.1" ]; then + MARIADB_VER="12.1" + shift 2 + else + echo "ERROR: --mariadb-version requires 10.11, 11.8 or 12.1" + exit 1 + fi + ;; + --auto) + AUTO_INSTALL=true + shift + ;; + -h|--help) + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " -b, --branch BRANCH Install from specific branch/commit" + echo " -v, --version VER Install specific version (auto-adds v prefix)" + echo " --mariadb-version VER MariaDB version: 10.11, 11.8 or 12.1 (asked after web server)" + echo " --debug Enable debug mode" + echo " --auto Auto mode: OpenLiteSpeed + MariaDB 11.8 unless --mariadb-version set" + echo " -h, --help Show this help message" + echo "" + echo "Examples:" + echo " $0 # Interactive installation" + echo " $0 --debug # Debug mode installation" + echo " $0 --auto # Auto installation" + echo " $0 -b v2.5.5-dev # Install development version" + echo " $0 -v 2.5.5-dev # Install version 2.5.5-dev" + echo " $0 -v 2.4.3 # Install version 2.4.3" + echo " $0 -b main # Install from main branch" + echo " $0 -b a1b2c3d4 # Install from specific commit" + echo " $0 --mariadb-version 10.11 # Use MariaDB 10.11 (same as v2.4.4 style)" + echo " $0 --mariadb-version 12.1 # Use MariaDB 12.1 (no prompt)" + echo " $0 --auto --mariadb-version 11.8 # Fully non-interactive with MariaDB 11.8" + echo "" + echo "Standard CyberPanel Installation Methods:" + echo " sh <(curl https://cyberpanel.net/install.sh)" + echo " bash <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh) -b 2.4.3" + echo " bash <(curl https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/cyberpanel_upgrade.sh) -b 2.5.5-dev" + exit 0 + ;; + *) + print_status "WARNING: Unknown option: $1" + shift + ;; + esac + done +} + +# Function to detect installation mode +detect_installation_mode() { + # Check if this is being called as an upgrade script + if [[ "$0" == *"cyberpanel_upgrade.sh"* ]] || [[ "$0" == *"upgrade"* ]]; then + INSTALLATION_TYPE="upgrade" + return 0 + fi + + # Check if this is being called as a pre-upgrade script + if [[ "$0" == *"preUpgrade.sh"* ]] || [[ "$0" == *"preupgrade"* ]]; then + INSTALLATION_TYPE="preupgrade" + return 0 + fi + + # Check if this is being called as a standard install script + if [[ "$0" == *"install.sh"* ]] || [[ "$0" == *"cyberpanel.sh"* ]]; then + INSTALLATION_TYPE="install" + return 0 + fi + + # Default to install mode + INSTALLATION_TYPE="install" + return 0 +} + +# Function to create standard CyberPanel aliases +create_standard_aliases() { + print_status "Creating standard CyberPanel installation aliases..." + + # Create symbolic links for standard installation methods + local script_dir="/usr/local/bin" + local script_name="cyberpanel_enhanced.sh" + + # Copy this script to /usr/local/bin + if cp "$0" "$script_dir/$script_name" 2>/dev/null; then + chmod +x "$script_dir/$script_name" + + # Create aliases for standard CyberPanel methods + ln -sf "$script_dir/$script_name" "$script_dir/cyberpanel_upgrade.sh" 2>/dev/null || true + ln -sf "$script_dir/$script_name" "$script_dir/preUpgrade.sh" 2>/dev/null || true + ln -sf "$script_dir/$script_name" "$script_dir/install.sh" 2>/dev/null || true + + print_status "✓ Standard CyberPanel aliases created" + print_status " - cyberpanel_upgrade.sh" + print_status " - preUpgrade.sh" + print_status " - install.sh" + else + print_status "WARNING: Could not create standard aliases (permission denied)" + fi +} + +# Main installation function +main() { + # Initialize log directory and file + mkdir -p "/var/log/CyberPanel" + touch "/var/log/CyberPanel/install.log" + + print_status "CyberPanel Enhanced Installer Starting..." + print_status "Log file: /var/log/CyberPanel/install.log" + + # Detect installation mode + detect_installation_mode + + # Parse command line arguments + parse_arguments "$@" + + # Handle different installation modes + case "$INSTALLATION_TYPE" in + "upgrade") + print_status "Running in upgrade mode..." + if [ -n "$BRANCH_NAME" ]; then + print_status "Upgrading to version: $BRANCH_NAME" + fi + start_upgrade + ;; + "preupgrade") + print_status "Running in pre-upgrade mode..." + start_preupgrade + ;; + "install"|*) + if [ "$AUTO_INSTALL" = true ]; then + # Run auto mode + print_status "Starting auto mode..." + + # Detect OS + if ! detect_os; then + print_status "ERROR: Failed to detect operating system" + exit 1 + fi + + # Install dependencies + install_dependencies + + # Install CyberPanel + if ! install_cyberpanel; then + print_status "ERROR: CyberPanel installation failed" + echo "" + echo "Would you like to see troubleshooting help? (y/n) [y]: " + read -r show_help + case $show_help in + [nN]|[nN][oO]) + echo "Installation failed. Check logs at /var/log/CyberPanel/" + ;; + *) + show_error_help + ;; + esac + exit 1 + fi + + # Apply fixes + apply_fixes + + # Create standard aliases + create_standard_aliases + + # Show status summary + show_status_summary + + print_status "SUCCESS: Installation completed successfully!" + else + # Run interactive mode - ensure stdin is the terminal for prompts (e.g. when script was piped from curl) + if [ ! -t 0 ]; then + exec 0 0: + Upgrade.stdOut(f"Updated rainloop→snappymail links in {replace_count} config file(s).", 0) + except Exception as e: + Upgrade.stdOut(f"Warning: Could not replace rainloop links in data files: {str(e)}", 0) + + # Redirect /rainloop to /snappymail so old bookmarks and links keep working + try: + htaccess_path = '/usr/local/CyberCP/public/.htaccess' + redirect_block = ( + '\n# Redirect old RainLoop URL to SnappyMail (2.5.5 upgrade)\n' + '\n' + 'RewriteEngine On\n' + 'RewriteRule ^rainloop/?(.*)$ /snappymail/$1 [R=301,L]\n' + '\n' + ) + if os.path.exists(htaccess_path): + with open(htaccess_path, 'r', encoding='utf-8', errors='replace') as f: + existing = f.read() + if 'Redirect old RainLoop URL to SnappyMail' not in existing: + with open(htaccess_path, 'a', encoding='utf-8') as f: + f.write(redirect_block) + Upgrade.stdOut("Added /rainloop→/snappymail redirect to .htaccess.", 0) + else: + with open(htaccess_path, 'w', encoding='utf-8') as f: + f.write(redirect_block) + Upgrade.stdOut("Created .htaccess with /rainloop→/snappymail redirect.", 0) + except Exception as e: + Upgrade.stdOut(f"Warning: Could not add rainloop redirect to .htaccess: {str(e)}", 0) + return 1 else: Upgrade.stdOut("Warning: Data migration completed with errors. Please verify manually.", 0) @@ -3735,7 +3791,7 @@ class Migration(migrations.Migration): custom_configs = [ '/usr/local/CyberCP/baseTemplate/static/baseTemplate/custom/', '/usr/local/CyberCP/public/phpmyadmin/config.inc.php', - '/usr/local/CyberCP/rainloop/data/_data_/', + '/usr/local/lscp/cyberpanel/snappymail/data/_data_/', ] # Backup Imunify360 directories and configuration @@ -4142,7 +4198,7 @@ echo $oConfig->Save() ? 'Done' : 'Error'; command = "chown -R root:root /usr/local/lscp" Upgrade.executioner(command, 'chown core code', 0) - command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/rainloop" + command = "chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail" Upgrade.executioner(command, 'chown core code', 0) command = "chmod 700 /usr/local/CyberCP/cli/cyberPanel.py" diff --git a/pluginHolder/deploy-plugins-template.sh b/pluginHolder/deploy-plugins-template.sh new file mode 100644 index 000000000..c7c0f8e0a --- /dev/null +++ b/pluginHolder/deploy-plugins-template.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Deploy the latest pluginHolder plugins.html template to CyberPanel and verify. +# Run on the server where CyberPanel is installed. +# From repo root: bash pluginHolder/deploy-plugins-template.sh +# Or from anywhere: REPO_ROOT=/path/to/cyberpanel-repo bash /path/to/deploy-plugins-template.sh + +set -e +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}" +TEMPLATE_SRC="${REPO_ROOT}/pluginHolder/templates/pluginHolder/plugins.html" +TEMPLATE_DEST="/usr/local/CyberCP/pluginHolder/templates/pluginHolder/plugins.html" +MARKER="installedFilterBtnAll" # Present only in latest template (Show: All | Installed only | Active only) + +if [ ! -f "$TEMPLATE_SRC" ]; then + echo "Error: Template not found at $TEMPLATE_SRC" + echo "Set REPO_ROOT to the path of your cyberpanel repo." + exit 1 +fi + +echo "Source: $TEMPLATE_SRC" +echo "Dest: $TEMPLATE_DEST" + +if grep -q "$MARKER" "$TEMPLATE_SRC"; then + echo "Source template is the latest (contains Show/Installed only/Active only)." +else + echo "Warning: Source template does not contain expected marker. Deploy anyway? (y/N)" + read -r ans + if [ "$ans" != "y" ] && [ "$ans" != "Y" ]; then + exit 1 + fi +fi + +if [ -f "$TEMPLATE_DEST" ]; then + cp -a "$TEMPLATE_DEST" "${TEMPLATE_DEST}.bak.$(date +%Y%m%d%H%M%S)" + echo "Backed up existing template." +fi + +mkdir -p "$(dirname "$TEMPLATE_DEST")" +cp -a "$TEMPLATE_SRC" "$TEMPLATE_DEST" +echo "Copied template to $TEMPLATE_DEST" + +if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet lscpd 2>/dev/null; then + echo "Restarting lscpd..." + systemctl restart lscpd + echo "lscpd restarted." +else + echo "Please restart your panel (e.g. systemctl restart lscpd)." +fi + +if grep -q "$MARKER" "$TEMPLATE_DEST"; then + echo "OK: Deployed template is latest. Verify: https://YOUR-PANEL:2087/plugins/installed#grid" +else + echo "Warning: Deployed file missing expected marker." + exit 1 +fi diff --git a/to-do/CYBERCP-GIT-PULL-CONFLICTS-V2.5.5-DEV.md b/to-do/CYBERCP-GIT-PULL-CONFLICTS-V2.5.5-DEV.md new file mode 100644 index 000000000..55134e4a3 --- /dev/null +++ b/to-do/CYBERCP-GIT-PULL-CONFLICTS-V2.5.5-DEV.md @@ -0,0 +1,63 @@ +# CyberCP git pull conflicts on v2.5.5-dev (server at /usr/local/CyberCP) + +## Why Git asks to "remove" or "move" files + +When you run `git pull --ff-only origin v2.5.5-dev` in `/usr/local/CyberCP`, Git can block for two reasons: + +### 1. Modified files (would be overwritten by merge) + +- **Meaning:** You have **local changes** in tracked files (e.g. `CyberCP/settings.py`, `baseTemplate/views.py`, …). The remote branch also changed those files. Git will not overwrite your working tree without you deciding what to do with your changes. +- **So:** You must either **commit** or **stash** (or discard) those local changes before the pull can apply. + +### 2. Untracked files (would be overwritten by merge) + +- **Meaning:** You have **untracked** files/dirs at paths where the **incoming** branch (v2.5.5-dev) **adds** files. For example: `panelAccess/`, `baseTemplate/static/baseTemplate/assets/mobile-responsive.css`, `sql/create_ftp_quotas.sql`, etc. Git will not overwrite untracked content, so it refuses to merge and says "Please move or remove them." +- **So:** You must **move or remove** those untracked paths so Git can write the version from the repo there. + +## Are all these files on v2.5.5-dev? + +- **Yes.** The branch `v2.5.5-dev` on `master3395/cyberpanel` contains: + - All the modified paths (canonical versions). + - All the "untracked" paths (e.g. `panelAccess/`, `mobile-responsive.css`, `readability-fixes.css`, `emailLimitsController.js`, `create_ftp_quotas.sql`, `firewall/migrations/0001_initial.py`, `install/ols_binaries_config.py`, etc.). +- So the **repo** is the source of truth; the server just needs to be brought in line with it. You can confirm by cloning fresh: `git clone -b v2.5.5-dev https://github.com/master3395/cyberpanel.git` and listing those paths. + +## Safe way to sync the server to v2.5.5-dev + +If you are **ok discarding all local and untracked changes** in `/usr/local/CyberCP` and making it exactly match `origin/v2.5.5-dev`: + +```bash +cd /usr/local/CyberCP + +# Optional: backup current state +tar -czf /root/cybercp-backup-before-sync-$(date +%Y%m%d-%H%M%S).tar.gz . + +# Reset tracked files to current HEAD and remove untracked/ignored files +git fetch origin +git checkout v2.5.5-dev +git reset --hard origin/v2.5.5-dev +git clean -fd + +# Ensure you're up to date (should already be after reset) +git pull --ff-only origin v2.5.5-dev +``` + +After this, **Current** in Version Management should match **Latest** (commit `c24f067e` or whatever is the tip of `origin/v2.5.5-dev`). + +## If you need to keep local changes + +- **Tracked changes:** Stash first, then pull, then re-apply: + ```bash + cd /usr/local/CyberCP + git stash push -m "before sync v2.5.5-dev" + # move or remove the untracked paths listed by Git (e.g. backup then delete) + git pull --ff-only origin v2.5.5-dev + git stash pop + ``` +- **Untracked files:** Back them up to another directory (e.g. `/root/cybercp-untracked-backup/`) before removing or moving them, then run the pull. + +## Upgrade script sync step + +The upgrade script’s `Sync_CyberCP_To_Latest()` runs `git fetch`, `checkout`, and `git pull --ff-only`. If the server has local or untracked conflicts like above, that pull will keep failing until you either: + +- Run the "safe way" (reset + clean) on the server once, or +- Change the script to use `git reset --hard origin/$Branch_Name` and `git clean -fd` so the install is forced to match the remote (only do this if you intend the install to always mirror the repo with no local edits). diff --git a/to-do/HTTP-500-AFTER-GIT-SYNC-RECOVERY.md b/to-do/HTTP-500-AFTER-GIT-SYNC-RECOVERY.md new file mode 100644 index 000000000..f82eb4c92 --- /dev/null +++ b/to-do/HTTP-500-AFTER-GIT-SYNC-RECOVERY.md @@ -0,0 +1,113 @@ +# HTTP 500 after git sync – recovery steps + +## Cause + +After running `git reset --hard origin/v2.5.5-dev` and `git clean -fd` in `/usr/local/CyberCP`, the **repo’s** `CyberCP/settings.py` replaced the **server’s** production `settings.py`. The repo file has different (or placeholder) database credentials and config, so the app can’t connect to the DB or behaves incorrectly → **500** on `/base/` and elsewhere. + +## 1. Restore production `settings.py` + +Use one of these options. + +### A. From your tarball backup (recommended) + +You created a backup before sync, e.g.: + +`/root/cybercp-backup-before-sync-YYYYMMDD-HHMMSS.tar.gz` + +Restore only `settings.py`: + +```bash +cd /root +# List to find the exact backup name +ls -la cybercp-backup-before-sync-*.tar.gz + +# Restore CyberCP/settings.py (tarball was created from /usr/local/CyberCP so paths start with . or ./) +BACKUP=$(ls -t cybercp-backup-before-sync-*.tar.gz 2>/dev/null | head -1) +if [ -n "$BACKUP" ]; then + tar -xzf "$BACKUP" -C /usr/local/CyberCP ./CyberCP/settings.py 2>/dev/null || \ + tar -xzf "$BACKUP" -C /usr/local/CyberCP CyberCP/settings.py 2>/dev/null + echo "Restored settings.py from $BACKUP" +else + echo "No backup found in /root" +fi +``` + +If the archive has no leading `./`, try: + +```bash +tar -xzf "$BACKUP" -C /usr/local/CyberCP --strip-components=0 CyberCP/settings.py +# or +tar -xzf "$BACKUP" -C /tmp cp CyberCP/settings.py && mv /tmp/CyberCP/settings.py /usr/local/CyberCP/CyberCP/ +``` + +### B. From upgrade script backup (if a previous upgrade ran) + +The upgrade script backs up to `/tmp/cyberpanel_settings_backup.py`: + +```bash +if [ -f /tmp/cyberpanel_settings_backup.py ]; then + cp /tmp/cyberpanel_settings_backup.py /usr/local/CyberCP/CyberCP/settings.py + echo "Restored settings.py from /tmp" +fi +``` + +### C. If you have no backup + +Edit `/usr/local/CyberCP/CyberCP/settings.py` and set the **DATABASES** section to match your server: + +- Same DB name, user, and password as used before the sync (e.g. from another backup or from the MySQL/MariaDB config your install used). + +## 2. Restart CyberPanel / LiteSpeed + +So the app loads the restored config: + +```bash +systemctl restart lscpd +# or, depending on setup: +# systemctl restart lsws +``` + +Wait a few seconds, then try https://207.180.193.210:2087/ and https://207.180.193.210:2087/base/ again. + +## 3. If 500 persists – get the real error + +Run: + +```bash +# Application log (Django/CyberPanel) +tail -100 /home/cyberpanel/error-logs.txt + +# LiteSpeed / WSGI errors +tail -100 /usr/local/lscp/logs/error.log + +# If present +tail -100 /usr/local/CyberCP/logs/cyberpanel.log +journalctl -u lscpd -n 50 --no-pager +``` + +Then run Django check and migrate: + +```bash +cd /usr/local/CyberCP +source /usr/local/CyberCP/bin/activate # if venv exists +python manage.py check +python manage.py migrate --noinput +``` + +Fix any errors reported (e.g. missing DB user, wrong password, or migrations). + +## 4. Future syncs – keep production settings + +Before running `git reset --hard` again: + +1. Back up `settings.py`: + ```bash + cp /usr/local/CyberCP/CyberCP/settings.py /root/cyberpanel_settings_production.py + ``` +2. After sync, restore it: + ```bash + cp /root/cyberpanel_settings_production.py /usr/local/CyberCP/CyberCP/settings.py + systemctl restart lscpd + ``` + +Or add a small script that does sync then restores `settings.py` and restarts `lscpd`. diff --git a/to-do/INSTALL-MODULES-DESIGN.md b/to-do/INSTALL-MODULES-DESIGN.md new file mode 100644 index 000000000..55eb861de --- /dev/null +++ b/to-do/INSTALL-MODULES-DESIGN.md @@ -0,0 +1,36 @@ +# Install modularization design + +## Overview +- **cyberpanel.sh**: Modular loader; sources `install_modules/00_common.sh` … `09_parse_main.sh`. When `install_modules/` is missing (e.g. one-liner), downloads modules from GitHub. +- **install.sh**: Wrapper that detects OS, checks disk; if repo has `cyberpanel.sh` + `install_modules/`, runs local loader; else downloads `cyberpanel.sh` and runs it. +- **install/venvsetup.sh**: Loader that sources `install/venvsetup_modules/01_*` … `05_*`. Original kept as `install/venvsetup_monolithic.sh`. + +## install_modules/ (repo root) +| Module | Lines | Content | +|--------|-------|---------| +| 00_common.sh | ~418 | Globals, log_message, print_status, show_banner, detect_os, fix_static_file_permissions, fix_post_install_issues | +| 01_verify_deps.sh | ~129 | verify_installation, install_dependencies | +| 02_install_core.sh | ~390 | install_cyberpanel, check_cyberpanel_installed, cleanup_existing_cyberpanel, install_cyberpanel_direct (part 1) | +| 03_install_direct.sh | ~411 | install_cyberpanel_direct_cont | +| 04_fixes_status.sh | ~210 | apply_fixes, _port_listening, show_status_summary | +| 05_menus_main.sh | ~328 | show_main_menu, show_fresh_install_menu, show_commit_selection, show_version_selection, show_installation_preferences | +| 06_menus_update.sh | ~247 | show_update_menu, show_reinstall_menu, show_system_status | +| 07_menus_advanced.sh | ~273 | show_advanced_menu, show_error_help, show_fix_menu, show_clean_menu, show_logs_menu, show_diagnostics | +| 08_actions.sh | ~317 | start_upgrade, start_force_reinstall, start_preupgrade, start_reinstall, start_installation | +| 09_parse_main.sh | ~247 | parse_arguments, detect_installation_mode, create_standard_aliases, main | + +All modules kept under 500 lines. Loader: `cyberpanel.sh`. Backup: `cyberpanel_install_monolithic.sh`. + +## install/venvsetup_modules/ +| Module | Content | +|--------|---------| +| 01_vars_install_required.sh | Vars, safe_pip_install, license_validation, special_change, system_tweak, install_required | +| 02_memcached_main.sh | memcached_installation, redis_installation, check_provider, check_*, interactive_*, main_install | +| 03_main_run_pip.sh | main_install_run, pip_virtualenv | +| 04_after_install.sh | after_install | +| 05_argument_main.sh | argument_mode, main flow (check_OS, install_required, pip_virtualenv, system_tweak, main_install) | + +Loader: `install/venvsetup.sh`. Backup: `install/venvsetup_monolithic.sh`. Refactor: `main_install` calls `main_install_run()` for size split. + +## install/ (Python and other files) +- **install/install.py**, **install/installCyberPanel.py**, etc. are unchanged; they are used by the shell installer and may be split in a future pass (e.g. into Python packages) if needed for the 500-line rule. diff --git a/to-do/PHPMYADMIN-404-AFTER-UPGRADE.md b/to-do/PHPMYADMIN-404-AFTER-UPGRADE.md new file mode 100644 index 000000000..f334cc4fd --- /dev/null +++ b/to-do/PHPMYADMIN-404-AFTER-UPGRADE.md @@ -0,0 +1,49 @@ +# phpMyAdmin 404 After Upgrade + +## Symptom + +After upgrading with: + +```bash +sh <(curl -s https://raw.githubusercontent.com/usmannasir/cyberpanel/v2.5.5-dev/preUpgrade.sh ...) -b v2.5.5-dev --mariadb-version 11.8 +``` + +opening **https://YOUR_IP:2087/phpmyadmin/** (or the panel’s “phpMyAdmin” link) returns **404 Not Found**. + +## Cause + +The upgrade step that installs phpMyAdmin (`download_install_phpmyadmin`) can fail without stopping the upgrade (e.g. network, or extract/mv path mismatch). The panel then has no `/usr/local/CyberCP/public/phpmyadmin/` directory, so the web server returns 404 for `/phpmyadmin/`. + +## Fix on the server + +Run the fix script **as root** on the panel server (e.g. 207.180.193.210): + +```bash +# From the repo (if you have it on the server): +cd /home/cyberpanel-repo +sudo bash fix-phpmyadmin.sh + +# Or one-liner (download and run from repo): +sudo bash -c 'curl -sL https://raw.githubusercontent.com/master3395/cyberpanel/v2.5.5-dev/fix-phpmyadmin.sh | bash' +``` + +Or run the same logic via Python: + +```bash +sudo /usr/local/CyberCP/bin/python -c " +import sys; sys.path.insert(0, '/usr/local/CyberCP') +import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CyberCP.settings') +from plogical.upgrade import Upgrade +Upgrade.download_install_phpmyadmin() +" +sudo chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin +``` + +Then reload **https://YOUR_IP:2087/phpmyadmin/** (or use Databases → phpMyAdmin in the panel). + +## Repo changes + +- **fix-phpmyadmin.sh** – Script to install/fix phpMyAdmin on the server (run as root). +- **plogical/upgrade.py** – `download_install_phpmyadmin()`: + - Resolves extracted folder with `glob` (handles `phpMyAdmin-*-all-languages` or `phpMyAdmin-*`). + - Verifies that `public/phpmyadmin` exists after install and raises if missing so the upgrade step is not silent. diff --git a/to-do/PHPMYADMIN-MARIADB-VERSION-MISMATCH.md b/to-do/PHPMYADMIN-MARIADB-VERSION-MISMATCH.md new file mode 100644 index 000000000..9b5962cbf --- /dev/null +++ b/to-do/PHPMYADMIN-MARIADB-VERSION-MISMATCH.md @@ -0,0 +1,44 @@ +# phpMyAdmin vs CLI MariaDB Version Mismatch + +## Why SSH / `mariadb -V` Shows 11.8 While phpMyAdmin Shows 10.11 + +Two main causes: + +### 1. **Different connection target (most common)** + +- **CLI** (`mariadb -V`, `mariadb -e "SELECT @@version;"`) uses the default connection: usually the **main** MariaDB instance (e.g. port 3306 or default socket). +- **phpMyAdmin** previously used host **`localhost`** (hardcoded). With `localhost`, the PHP MySQL client connects via the **default Unix socket**, not necessarily the same as the main instance. +- If you have (or had) **two** MariaDB instances (e.g. main on 3306 and a second on 3307 from `mysqld_multi`, or an old 10.11 still running), the CLI can hit 11.8 while PHP’s default socket pointed at the 10.11 instance. + +### 2. **Client vs server version** + +- `mariadb -V` prints the **client** version (e.g. 11.8). The upgrade script banner also used that for “Database (MariaDB): 11.8”. +- The **server** version is what phpMyAdmin shows. If the server was still 10.11 (e.g. wrong service restarted or second instance), phpMyAdmin correctly showed 10.11. + +## Fix applied in code + +- The panel now passes **host** (and port) from `/etc/cyberpanel/mysqlPassword` into the phpMyAdmin signon form. +- When the stored host is `localhost`, we send **`127.0.0.1`** so phpMyAdmin connects via **TCP to port 3306** (the main instance), not the default socket. +- So after deploy, phpMyAdmin should show the same MariaDB version as the CLI (the main 11.8 server). + +## Verification on the server + +Run as root: + +```bash +# Server version (what phpMyAdmin should show after fix) +mariadb -e "SELECT @@version;" + +# Listeners (only one MariaDB should be on 3306) +ss -tlnp | grep 3306 + +# Processes (check for duplicate mysqld/mariadbd) +ps aux | grep -E 'mariadb|mysqld' +``` + +If `SELECT @@version` shows 11.8 but phpMyAdmin still showed 10.11 before the fix, it was almost certainly a different connection (socket vs 127.0.0.1:3306 or a second instance). After the code change and a fresh phpMyAdmin login, it should report 11.8. + +## If two instances exist + +- Stop the old 10.11 instance (e.g. `mysqld_multi stop 1` if using `mysqld1` on 3307, or disable its service). +- Ensure only the 11.8 service (e.g. `mariadb.service`) is running and listening on 3306. diff --git a/to-do/PLUGINS-INSTALLED-GRID-VERIFY.md b/to-do/PLUGINS-INSTALLED-GRID-VERIFY.md new file mode 100644 index 000000000..4a27ec166 --- /dev/null +++ b/to-do/PLUGINS-INSTALLED-GRID-VERIFY.md @@ -0,0 +1,45 @@ +# Plugins Installed Grid – Install and Verify + +## How install works + +1. **Grid "Install" button** + - Tries **local install** first: plugin must exist under `/home/cyberpanel/plugins/` or `/home/cyberpanel-plugins/` (with `meta.xml`). + - If the API returns **404** or **"Plugin source not found"**, the UI automatically retries **store install** (download from GitHub `master3395/cyberpanel-plugins` and install). + +2. **Store install** + - Used from the Store view or as fallback when local source is missing. + - Downloads the plugin from GitHub and runs the same installer (extract, pre_install, settings/URLs, inform CyberPanel, collectstatic, post_install). + +3. **"Installed" status** + - A plugin is considered installed if the **directory** exists: `/usr/local/CyberCP//`. + - If that directory exists but `meta.xml` is missing, the UI still shows "Installed". On load of `/plugins/installed`, the backend tries to restore `meta.xml` from source (if source exists). + +## Making sure all grid plugins install correctly + +- **Local source** + Put plugin folders (each with `meta.xml`) in: + - `/home/cyberpanel/plugins//`, or + - `/home/cyberpanel-plugins//` + Then use **Install** in the grid; local install will be used. + +- **No local source** + Click **Install** in the grid; if local source is not found, the UI falls back to **store install** (GitHub). Ensure the plugin exists in `master3395/cyberpanel-plugins` (main branch). + +- **Already installed but broken** + If a plugin directory exists under `/usr/local/CyberCP/` but `meta.xml` was missing, opening **Plugins → Installed** will try to copy `meta.xml` from source into the installed folder so version/update checks work. + +## Quick checks on the server + +```bash +# Installed plugin dirs +ls -la /usr/local/CyberCP/ | grep -E '^d' + +# Local source (grid uses these for local install) +ls -la /home/cyberpanel/plugins/ 2>/dev/null || true +ls -la /home/cyberpanel-plugins/ 2>/dev/null || true + +# Ensure meta.xml exists for an installed plugin (e.g. premiumPlugin) +ls -la /usr/local/CyberCP/premiumPlugin/meta.xml +``` + +After code changes, restart Gunicorn (or the CyberPanel app server) so the updated pluginHolder views and JS are used. diff --git a/to-do/PLUGINS-TEMPLATE-DEPLOY.md b/to-do/PLUGINS-TEMPLATE-DEPLOY.md new file mode 100644 index 000000000..ea6e20cc8 --- /dev/null +++ b/to-do/PLUGINS-TEMPLATE-DEPLOY.md @@ -0,0 +1,44 @@ +# Deploy and verify latest Plugins template on server + +## 1. Check if server has the latest template + +On the server (207.180.193.210), run: + +```bash +grep -q "installedFilterBtnAll" /usr/local/CyberCP/pluginHolder/templates/pluginHolder/plugins.html && echo "LATEST: Yes (Show / Installed only / Active only present)" || echo "LATEST: No (run deploy below)" +``` + +## 2. Deploy latest template to the server + +**Option A – Run on the server (repo already on server)** + +If the cyberpanel repo is on the same machine (e.g. at `/home/cyberpanel-repo`): + +```bash +sudo bash /home/cyberpanel-repo/pluginHolder/deploy-plugins-template.sh +``` + +**Option B – Copy from this machine to the server** + +From your dev machine (where the repo lives): + +```bash +scp /home/cyberpanel-repo/pluginHolder/templates/pluginHolder/plugins.html root@207.180.193.210:/usr/local/CyberCP/pluginHolder/templates/pluginHolder/plugins.html +ssh root@207.180.193.210 "systemctl restart lscpd" +``` + +Then on the server, verify: + +```bash +ssh root@207.180.193.210 'grep -q "installedFilterBtnAll" /usr/local/CyberCP/pluginHolder/templates/pluginHolder/plugins.html && echo "LATEST: Yes" || echo "LATEST: No"' +``` + +## 3. Verify in the browser + +1. Open: https://207.180.193.210:2087/plugins/installed#grid +2. Ensure **Grid View** is selected. +3. You should see two rows under the view toggle: + - **Show:** [All] [Installed only] [Active only] + - **Sort by:** [Name A–Å] [Type] [Date (newest)] + +If you see **Show:** and the three filter buttons, you are on the latest template. diff --git a/to-do/RAINLOOP-TO-SNAPPYMAIL-RENAME.md b/to-do/RAINLOOP-TO-SNAPPYMAIL-RENAME.md new file mode 100644 index 000000000..d25676683 --- /dev/null +++ b/to-do/RAINLOOP-TO-SNAPPYMAIL-RENAME.md @@ -0,0 +1,41 @@ +# RainLoop → SnappyMail rename + +## Summary +RainLoop has been replaced by SnappyMail. All **operational** paths and the install template folder now use SnappyMail. References to "rainloop" remain only where we **migrate from** old installs (2.4.4 → 2.5.5). + +## Changes made + +### Repo folder +- **`install/rainloop/`** renamed to **`install/snappymail/`** +- Template file still `cyberpanel.net.ini` (SnappyMail uses same format). + +### Code updated to SnappyMail paths +- **plogical/mailUtilities.py** — Template path `/usr/local/CyberCP/install/snappymail/cyberpanel.net.ini`; all data paths `/usr/local/lscp/cyberpanel/snappymail/...`. +- **install/install.py** — chown and mkdir use `snappymail`; commented blocks updated for consistency. +- **plogical/acl.py** — `chown ... /usr/local/lscp/cyberpanel/snappymail`. +- **plogical/upgrade.py** — Operational chown and backup path use snappymail. + +### Left as-is (intentional) +- **Migration logic** in `plogical/upgrade.py`, `upgrade_modules/10_post_tweak.sh`, and `cyberpanel_upgrade_monolithic.sh` still uses the **source** path `/usr/local/lscp/cyberpanel/rainloop/data` when upgrading from 2.4.4: they check for old rainloop data and rsync it to `/usr/local/lscp/cyberpanel/snappymail/data/`. That "rainloop" path must stay so existing servers upgrading from RainLoop get their data migrated. + +## Upgrade to 2.5.5-dev: migrate ALL links to SnappyMail + +On upgrade, the following ensure every RainLoop reference becomes SnappyMail: + +1. **Data migration** (existing): rsync from `/usr/local/lscp/cyberpanel/rainloop/data` to `.../snappymail/data`, and update `include.php` paths. + +2. **Replace all rainloop path/URL in migrated data**: After rsync, every config file under `snappymail/data` (`.ini`, `.json`, `.php`, `.cfg`) is scanned and any occurrence of: + - `/usr/local/lscp/cyberpanel/rainloop/data` → `.../snappymail/data` + - `/rainloop/` → `/snappymail/` + - `rainloop/data` → `snappymail/data` + is replaced. So stored links and paths in SnappyMail configs point to SnappyMail. + +3. **HTTP redirect /rainloop → /snappymail**: In `/usr/local/CyberCP/public/.htaccess` a 301 redirect is added (or ensured once) so that: + - `/rainloop`, `/rainloop/`, `/rainloop/anything` → `/snappymail/...` + Old bookmarks and shared links keep working. + +Implemented in: `plogical/upgrade.py` (`migrateRainloopToSnappymail`), `upgrade_modules/10_post_tweak.sh`, `cyberpanel_upgrade_monolithic.sh`. + +## Result +- New installs and day-to-day operations use only SnappyMail paths. +- Upgrades from versions that had RainLoop: data migrated, all config links updated to snappymail, and /rainloop URLs redirect to /snappymail. diff --git a/to-do/REMOVED-UNUSED-INSTALL-FOLDERS.md b/to-do/REMOVED-UNUSED-INSTALL-FOLDERS.md new file mode 100644 index 000000000..468491b5e --- /dev/null +++ b/to-do/REMOVED-UNUSED-INSTALL-FOLDERS.md @@ -0,0 +1,21 @@ +# Removed Unused install/ Folders + +## Summary +Unused config folders under `install/` were removed; only the folders actually referenced by the codebase remain. + +## Removed + +### install/email-configs +- **Reason:** Never referenced. All code uses `install/email-configs-one` (e.g. `install/install.py`, `plogical/mailUtilities.py`, `mailServer/mailserverManager.py`). +- **Removed:** 2025-02-15. + +### install/php-configs +- **Reason:** Never referenced. Code uses `install/phpconfigs` (no hyphen) only: + - `plogical/installUtilities.py`: `shutil.copytree("phpconfigs", ...)` and `include phpconfigs/php*.conf` + - `install/litespeed/conf/httpd_config.conf` and `serverStatus/litespeed/conf/httpd_config.conf`: `include phpconfigs/php53.conf` etc. +- **Note:** `php-configs` contained `php.ini` and `www.conf` (different purpose); `phpconfigs` contains `php53.conf` … `php80.conf` (LiteSpeed PHP version includes). +- **Removed:** 2025-02-15. + +## Still in use +- `install/email-configs-one/` — mail configs used by install and mail utilities. +- `install/phpconfigs/` — LiteSpeed PHP version include configs used by install and httpd_config. diff --git a/to-do/SUPPORTED-OS-INSTALL-UPGRADE.md b/to-do/SUPPORTED-OS-INSTALL-UPGRADE.md new file mode 100644 index 000000000..30f13d349 --- /dev/null +++ b/to-do/SUPPORTED-OS-INSTALL-UPGRADE.md @@ -0,0 +1,37 @@ +# Install/Upgrade Support Matrix (v2.5.5-dev) + +This document summarizes how install and upgrade **detect and handle** each OS in the support table. It does **not** guarantee that every combination has been tested; it reflects what the code paths are. + +## Summary + +| OS family | Detection | Install/upgrade path | Notes | +|-----------|-----------|----------------------|--------| +| **AlmaLinux 10, 9, 8** | `AlmaLinux-8/9/10` in `/etc/os-release` | 9/10 → `AlmaLinux9` (dnf, repo fixes, venv). 8 → `CentOS` + version 8. | Explicit branches for 9/10 (EPEL, MariaDB, python3-venv). | +| **CentOS 7** | `CentOS Linux 7` in os-release | `CentOS` + version 7. | Legacy; EOL. Uses yum, requirments-old.txt. | +| **CloudLinux 9, 8** | `CloudLinux 7/8/9` in os-release | Normalized to `CentOS` + version. Same as RHEL family. | Version from VERSION_ID (e.g. 8 → 8, 9 → 9). | +| **Debian 13, 12, 11** | `Debian GNU/Linux 11/12/13` in os-release | Treated as **Ubuntu** (`Server_OS=Ubuntu`). Version 11/12/13 from VERSION_ID. | Uses **requirments-old.txt** (not requirments.txt). No Debian-specific package blocks; gets generic apt install. install_utils has Debian 13 package mappings. | +| **RHEL 9, 8** | `Red Hat Enterprise Linux` in os-release | Normalized to `CentOS` + version 8 or 9. | Same repo/package logic as CentOS 8/9. RHEL repo names differ; AlmaLinux-specific repo fixes do not run for RHEL. | +| **RockyLinux 9, 8** | `Rocky Linux` in os-release | Normalized to `CentOS`; version 8 or 9. | Same as CentOS 8/9 (EPEL, MariaDB, venv for 9/10). | +| **Ubuntu 24.04, 22.04, 20.04** | `Ubuntu 24.04` etc. in os-release | Explicit branches for 22/24 (packages, python3-venv). 20 → specific fixes. 18 → minimal. | 24.04: externally-managed-environment handled. Uses **requirments.txt** for 22 and 24. | + +## Do we *know* it works on all of them? + +- **Code coverage:** Detection and branching exist for all listed OSes. AlmaLinux 8/9/10, Ubuntu 18/20/22/24, Debian 11/12/13, CentOS 7/8/9, Rocky, RHEL, CloudLinux, and openEuler have explicit or normalized paths. +- **No automated proof:** There is no CI in this repo that runs install or upgrade on each OS. “Works” is based on: + - Manual and community testing + - Code review of detection and branches +- **RHEL:** Uses the same code path as CentOS (RedHat → CentOS). RHEL 9 uses different repo IDs than AlmaLinux; if repo issues appear on RHEL 9, RHEL-specific repo handling may be needed. +- **Debian 11/12/13:** Share the “Ubuntu” path and use **requirments-old.txt**. install_utils has Debian 13 (Trixie) package mappings. No Debian-version-specific blocks in the upgrade script. +- **CentOS 7:** Marked legacy/EOL; still in the script with yum and old requirements. + +## Recommendations + +1. **Staging:** Test install and upgrade on a non-production VM for your chosen OS before production. +2. **CI (optional):** Add a test matrix (e.g. GitHub Actions or other CI) that runs install and/or upgrade on a subset of OSes (e.g. AlmaLinux 9, Ubuntu 22.04, Debian 12) to catch regressions. +3. **Docs:** Keep this file (or a short “Supported platforms” section) in sync with the script when adding or dropping OS versions. + +## Where to look in the repo + +- **Upgrade OS detection:** `cyberpanel_upgrade.sh` (lines ~160–187), `Server_OS_Version` (~187), and branches for `CentOS`/`AlmaLinux9`/`Ubuntu`/`openEuler`. +- **Install OS detection:** `install/install.py` (`preFlightsChecks.detect_os`, `get_distro`), and `install/install_utils.py` (Debian/Ubuntu version and package helpers). +- **Requirements choice:** `cyberpanel_upgrade.sh` `Download_Requirement()`: uses `requirments.txt` for version 22, 24, 9, 10; else `requirments-old.txt`. diff --git a/to-do/WHITELIST-RM-UPGRADE_LOGS-SECURITY-ALERT.md b/to-do/WHITELIST-RM-UPGRADE_LOGS-SECURITY-ALERT.md new file mode 100644 index 000000000..eeeb1606c --- /dev/null +++ b/to-do/WHITELIST-RM-UPGRADE_LOGS-SECURITY-ALERT.md @@ -0,0 +1,119 @@ +# Security alert: `rm -rf /home/cyberpanel/upgrade_logs` + +## Is this an issue? + +**No.** This is **expected behavior** from the CyberPanel upgrade process, not a sign of compromise. + +## What’s going on + +- Your security product (e.g. OSSEC, Wazuh, or similar) flagged: + - **Command:** `sudo ... /bin/rm -rf /home/cyberpanel/upgrade_logs` + - **Context:** `PWD=/tmp/lscpd`, `USER=root` +- The CyberPanel daemon (**lscpd**) runs upgrade-related tasks. The upgrade logic uses `/home/cyberpanel/upgrade_logs` as the path for upgrade logs (see `plogical/upgrade.py`: `LogPathNew = '/home/cyberpanel/upgrade_logs'`). Cleaning that path (file or directory) before or after an upgrade is normal so the next run starts from a clean state. +- So this command is the **panel cleaning its own upgrade logs**, not an attacker. + +## Why does it look “suspicious”? + +- Security tools often treat **any** `rm -rf` as “dangerous” because it can delete a lot if misused. +- They also flag “system file access” or “writes/deletes under /home” to catch abuse. +- Here, the path is a **known, fixed** CyberPanel path and the process is **root from lscpd** (expected for the panel). So the alert is a **false positive** for “suspicious command” in this context. + +## Why “my own local files” look suspicious + +- “Local files” in the alert usually means “commands or file operations on this machine.” The product isn’t saying your personal files are malicious; it’s saying the **behavior** (e.g. `rm -rf` on a path under `/home`) matches a **rule** that can indicate compromise. +- In this case the “local” actor is **CyberPanel itself** (lscpd/upgrade), so the behavior is legitimate. + +## What you can do + +1. **Treat as expected:** No need to change passwords or hunt for backdoors solely because of this alert. +2. **Whitelist/tune the rule:** In your security product, add an exception or rule so that this specific command (or pattern) when run by root from the lscpd context is not reported, e.g.: + - Command pattern: `rm -rf /home/cyberpanel/upgrade_logs` + - Or: allow `rm -rf` for paths under `/home/cyberpanel/` when the process is lscpd/upgrade-related. +3. **Keep monitoring:** Continue to review real suspicious activity (e.g. unknown scripts, unexpected `rm -rf /` or `rm -rf /home/*`). + +## Summary + +- **Not a compromise** – normal CyberPanel upgrade cleanup. +- **“Suspicious”** only in the generic sense (rm -rf + /home); in context it’s the panel’s own operation. +- **Action:** Whitelist or tune the alert for this known-good case; no need to panic or “fix” the panel for this. + +--- + +## Whitelist / rule examples (stop this specific case being reported) + +Use the example that matches your product. After editing config, restart the agent/manager as indicated. + +### OSSEC + +Allow this command so it is not reported as suspicious. + +**1. Local rule to ignore this command** + +Create or edit a local rule file (e.g. `/var/ossec/etc/rules/local_rules.xml`) and add: + +```xml + + + 100002 + rm -rf /home/cyberpanel/upgrade_logs + Whitelist: CyberPanel upgrade log cleanup (expected) + +``` + +If your “suspicious command” rule has a different ``, replace `100002` with that rule’s ID (so this rule only applies when that one fires). If you’re not sure, you can use a broader override that matches the command and sets level 0: + +```xml + + rm -rf /home/cyberpanel/upgrade_logs + Whitelist: CyberPanel upgrade log cleanup + +``` + +Restart OSSEC: + +```bash +systemctl restart ossec +# or +/var/ossec/bin/ossec-control restart +``` + +**2. (Optional) Decoder to tag sudo rm** + +In `/var/ossec/etc/decoders/local_decoder.xml` you can add a decoder so the command is clearly identified; the rule above is enough to stop the alert. + +### Wazuh + +**1. Local rule to not alert on this command** + +Append to `/var/ossec/etc/rules/local_rules.xml` (Wazuh keeps OSSEC-style paths): + +```xml + + + + rm -rf /home/cyberpanel/upgrade_logs + Whitelist: CyberPanel upgrade_logs cleanup (lscpd/upgrade) + + +``` + +If the alert is from a different rule (e.g. “suspicious command” or “syscheck”), you may need to set `` to that rule’s ID so this rule only overrides that case. + +Restart Wazuh: + +```bash +systemctl restart wazuh-agent +# On manager: +systemctl restart wazuh-manager +``` + +**2. (Optional) Broader CyberPanel cleanup** + +To allow any `rm -rf` under `/home/cyberpanel/` when the process is from lscpd/upgrade, you’d need a rule that matches both the command pattern and (if available) the process or PWD. That’s product-specific; the rule above is the minimal, safe whitelist for the exact command you saw. + +### Other products (generic) + +- **Fail2ban / custom script:** If the alert is generated by a script that parses `auth.log` or `secure`, add an exception when the log line contains both `rm -rf` and `/home/cyberpanel/upgrade_logs`. +- **SIEM / cloud:** Add an exception or filter so that events with command `rm -rf /home/cyberpanel/upgrade_logs` and user `root` (and optionally process/source indicating lscpd) are not escalated. + +Once the whitelist is in place, future runs of that CyberPanel cleanup will no longer trigger this specific alert. diff --git a/to-do/fix-phpmyadmin-mariadb-version-on-server.md b/to-do/fix-phpmyadmin-mariadb-version-on-server.md new file mode 100644 index 000000000..fcc536990 --- /dev/null +++ b/to-do/fix-phpmyadmin-mariadb-version-on-server.md @@ -0,0 +1,36 @@ +# Fix phpMyAdmin Showing 10.11 When 11.8 Is Installed + +## 1. Fix CLI SSL error and see real server version + +Run as root on the server: + +```bash +# Allow mariadb client to connect without SSL (11.x client requires SSL by default) +mkdir -p /etc/my.cnf.d +printf '[client]\nskip-ssl = true\n' > /etc/my.cnf.d/cyberpanel-client.cnf + +# Now this should work and show the *actual* server version on 3306 +mariadb -e "SELECT @@version;" +``` + +- If it shows **11.8.x**: the server is 11.8; phpMyAdmin should show 11.8 after you **log out, clear cookies for :2087, then log in again via CyberPanel → Databases → phpMyAdmin**. +- If it still shows **10.11.x**: the process on 3306 is still 10.11. Force the 11.8 service to take over: + +```bash +systemctl stop mariadb +sleep 3 +systemctl start mariadb +mariadb -e "SELECT @@version;" +``` + +If it still shows 10.11, check: + +```bash +rpm -q MariaDB-server +ss -tlnp | grep 3306 +systemctl status mariadb +``` + +## 2. phpMyAdmin config (already correct on your server) + +Your `config.inc.php` already has `host = '127.0.0.1'` and `port = '3306'`. Once the server on 3306 is 11.8 and you log in again via the panel, phpMyAdmin will show 11.8. diff --git a/upgrade_modules/02_checks_part1.txt b/upgrade_modules/02_checks_part1.txt new file mode 100644 index 000000000..c376d56cc --- /dev/null +++ b/upgrade_modules/02_checks_part1.txt @@ -0,0 +1,130 @@ +Check_Root() { +echo -e "\nChecking root privileges..." + # If we're actually root (uid 0), allow regardless of SUDO in environment (e.g. curl | sudo bash) + if [[ $(id -u) -eq 0 ]] 2>/dev/null; then + echo -e "\nYou are running as root...\n" + return 0 + fi + + if echo "$Sudo_Test" | grep SUDO >/dev/null; then + echo -e "\nYou are using SUDO, please run as root user...\n" + echo -e "\nIf you don't have direct access to root user, please run \e[31msudo su -\e[39m command (do NOT miss the \e[31m-\e[39m at end or it will fail) and then run installation command again." + exit 1 + fi + + echo -e "\nYou must run as root user to install CyberPanel...\n" + echo -e "Run: \e[31msudo su -\e[39m then run this script again, or: curl -sL | sudo bash -s -- " + exit 1 +} + +Check_Server_IP() { +echo -e "Checking server location...\n" + +Server_Country=$(curl --silent --max-time 10 -4 https://cyberpanel.sh/?country) +if [[ ${#Server_Country} != "2" ]] ; then + Server_Country="Unknown" +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Server_Country" "$Server_Country" +fi + +if [[ "$*" = *"--mirror"* ]] ; then + Server_Country="CN" + echo -e "Forced to use mirror server due to --mirror argument...\n" +fi + +if [[ "$Server_Country" = *"CN"* ]] ; then + Server_Country="CN" + echo -e "Setting up to use mirror server...\n" +fi +} + +Check_OS() { +if [[ ! -f /etc/os-release ]] ; then + echo -e "Unable to detect the Operating System...\n" + exit +fi + +if ! uname -m | grep -qE 'x86_64|aarch64' ; then + echo -e "x86_64 or ARM system is required...\n" + exit +fi + +if grep -q -E "CentOS Linux 7|CentOS Linux 8|CentOS Linux 9|CentOS Stream 9" /etc/os-release ; then + Server_OS="CentOS" +elif grep -q "Red Hat Enterprise Linux" /etc/os-release ; then + Server_OS="RedHat" +elif grep -q -E "CloudLinux 7|CloudLinux 8|CloudLinux 9" /etc/os-release ; then + Server_OS="CloudLinux" +elif grep -q -E "Rocky Linux" /etc/os-release ; then + Server_OS="RockyLinux" +elif grep -q -E "AlmaLinux-8|AlmaLinux-9|AlmaLinux-10" /etc/os-release ; then + Server_OS="AlmaLinux" + # Set specific version for AlmaLinux 9+ to use dnf instead of yum + if grep -q -E "AlmaLinux-9|AlmaLinux-10" /etc/os-release ; then + Server_OS="AlmaLinux9" + fi +elif grep -q -E "Ubuntu 18.04|Ubuntu 20.04|Ubuntu 20.10|Ubuntu 22.04|Ubuntu 24.04|Ubuntu 24.04.3" /etc/os-release ; then + Server_OS="Ubuntu" +elif grep -q -E "Debian GNU/Linux 11|Debian GNU/Linux 12|Debian GNU/Linux 13" /etc/os-release ; then + Server_OS="Ubuntu" +elif grep -q -E "openEuler 20.03|openEuler 22.03" /etc/os-release ; then + Server_OS="openEuler" +else + echo -e "Unable to detect your system..." + echo -e "\nCyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, Debian 11, Debian 12, Debian 13, CentOS 7, CentOS 8, CentOS 9, CentOS Stream 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, RockyLinux 9, RHEL 8, RHEL 9, CloudLinux 7, CloudLinux 8, CloudLinux 9, openEuler 20.03, openEuler 22.03...\n" + Debug_Log2 "CyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, Debian 11, Debian 12, Debian 13, CentOS 7, CentOS 8, CentOS 9, CentOS Stream 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, RockyLinux 9, RHEL 8, RHEL 9, CloudLinux 7, CloudLinux 8, CloudLinux 9, openEuler 20.03, openEuler 22.03... [404]" + exit +fi + +Server_OS_Version=$(grep VERSION_ID /etc/os-release | awk -F[=,] '{print $2}' | tr -d \" | head -c2 | tr -d . ) +#to make 20.04 display as 20, etc. + +echo -e "System: $Server_OS $Server_OS_Version detected...\n" + +if [[ $Server_OS = "CloudLinux" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "RockyLinux" ]] || [[ "$Server_OS" = "RedHat" ]]; then + # Keep AlmaLinux9 separate for dnf package management + if [[ "$Server_OS" != "AlmaLinux9" ]]; then + Server_OS="CentOS" + #CloudLinux gives version id like 7.8, 7.9, so cut it to show first number only + #treat CloudLinux, Rocky and Alma as CentOS + fi +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Server_OS" "$Server_OS $Server_OS_Version" +fi + +} + +Check_Provider() { +if hash dmidecode >/dev/null 2>&1; then + if [[ "$(dmidecode -s bios-vendor)" = "Google" ]]; then + Server_Provider="Google Cloud Platform" + elif [[ "$(dmidecode -s bios-vendor)" = "DigitalOcean" ]]; then + Server_Provider="Digital Ocean" + elif [[ "$(dmidecode -s system-product-name | cut -c 1-7)" = "Alibaba" ]]; then + Server_Provider="Alibaba Cloud" + elif [[ "$(dmidecode -s system-manufacturer)" = "Microsoft Corporation" ]]; then + Server_Provider="Microsoft Azure" + elif [[ -d /usr/local/qcloud ]]; then + Server_Provider="Tencent Cloud" + else + Server_Provider="Undefined" + fi +else + Server_Provider='Undefined' +fi + +if [[ -f /sys/devices/virtual/dmi/id/product_uuid ]]; then + if [[ "$(cut -c 1-3 /sys/devices/virtual/dmi/id/product_uuid)" = 'EC2' ]] && [[ -d /home/ubuntu ]]; then + Server_Provider='Amazon Web Service' + fi +fi + +if [[ "$Debug" = "On" ]] ; then + Debug_Log "Server_Provider" "$Server_Provider" +fi +} + diff --git a/upgrade_modules/02_checks_part2.txt b/upgrade_modules/02_checks_part2.txt new file mode 100644 index 000000000..ac364d022 --- /dev/null +++ b/upgrade_modules/02_checks_part2.txt @@ -0,0 +1,53 @@ +Migrate_MariaDB_To_UTF8_Requested="" +# MariaDB version: any X.Y or X.Y.Z supported; highlighted: 10.11.16, 11.8 LTS, 12.x (default 11.8) +MARIADB_VER="11.8" +MARIADB_VER_REPO="11.8" + +Check_Argument() { +# Parse --branch / -b (extract first word after -b or --branch) +if [[ "$*" = *"--branch "* ]]; then + Branch_Name=$(echo "$*" | sed -n 's/.*--branch \([^ ]*\).*/\1/p' | head -1) + [[ -n "$Branch_Name" ]] && Branch_Check "$Branch_Name" +elif [[ "$*" = *"-b "* ]]; then + Branch_Name=$(echo "$*" | sed -n 's/.*-b \([^ ]*\).*/\1/p' | head -1) + [[ -n "$Branch_Name" ]] && Branch_Check "$Branch_Name" +fi +# Parse --repo / -r to use any GitHub user (same URL structure as usmannasir/cyberpanel) +if [[ "$*" = *"--repo "* ]]; then + Git_User_Override=$(echo "$*" | sed -n 's/.*--repo \([^ ]*\).*/\1/p' | head -1) +fi +if [[ "$*" = *"-r "* ]] && [[ -z "$Git_User_Override" ]]; then + Git_User_Override=$(echo "$*" | sed -n 's/.*-r \([^ ]*\).*/\1/p' | head -1) +fi +# Parse --no-system-update to skip yum/dnf update -y (faster upgrade when system is already updated) +if [[ "$*" = *"--no-system-update"* ]]; then + Skip_System_Update="yes" + echo -e "\nUsing --no-system-update: skipping full system package update.\n" +fi +# Parse --backup-db / --no-backup-db: pre-upgrade MariaDB backup. Default when neither set: ask user (may take a while). +# --backup-db = always backup; --no-backup-db = never backup; omit both = prompt [y/N] +Backup_DB_Before_Upgrade="" +if [[ "$*" = *"--backup-db"* ]]; then + Backup_DB_Before_Upgrade="yes" + echo -e "\nUsing --backup-db: will create a full MariaDB backup before upgrade.\n" +elif [[ "$*" = *"--no-backup-db"* ]]; then + Backup_DB_Before_Upgrade="no" + echo -e "\nUsing --no-backup-db: skipping MariaDB pre-upgrade backup.\n" +fi +# Parse --migrate-to-utf8: after upgrading to MariaDB 11.x/12.x, convert DBs/tables from latin1 to utf8mb4 (only if your apps support UTF-8) +if [[ "$*" = *"--migrate-to-utf8"* ]]; then + Migrate_MariaDB_To_UTF8_Requested="yes" + echo -e "\nUsing --migrate-to-utf8: will convert databases to UTF-8 (utf8mb4) after MariaDB upgrade.\n" +fi +# Parse --mariadb-version (any version: 10.6, 10.11, 10.11.16, 11.8, 12.1, 12.2, 12.3, etc.). Default 11.8. +# --mariadb is shorthand for --mariadb-version 10.11 +if [[ "$*" = *"--mariadb"* ]] && [[ "$*" != *"--mariadb-version "* ]]; then + MARIADB_VER="10.11" + echo -e "\nUsing --mariadb: MariaDB 10.11 selected (non-interactive).\n" +elif [[ "$*" = *"--mariadb-version "* ]]; then + MARIADB_VER=$(echo "$*" | sed -n 's/.*--mariadb-version \([^ ]*\).*/\1/p' | head -1) + MARIADB_VER="${MARIADB_VER:-11.8}" +fi +# Allow any version; repo paths use major.minor (normalized later) +} + diff --git a/upgrade_modules/10_post_tweak.sh b/upgrade_modules/10_post_tweak.sh index 6c1b0af41..3b9a38c94 100644 --- a/upgrade_modules/10_post_tweak.sh +++ b/upgrade_modules/10_post_tweak.sh @@ -258,6 +258,22 @@ fi # Fix SnappyMail directory permissions for Ubuntu 24.04 and other systems echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Checking SnappyMail directories..." | tee -a /var/log/cyberpanel_upgrade_debug.log +# If public web app is still named rainloop, rename to snappymail so /snappymail/ URL works +if [ -d "/usr/local/CyberCP/public/rainloop" ] && [ ! -d "/usr/local/CyberCP/public/snappymail" ]; then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Renaming public/rainloop to public/snappymail..." | tee -a /var/log/cyberpanel_upgrade_debug.log + mv /usr/local/CyberCP/public/rainloop /usr/local/CyberCP/public/snappymail + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Renamed public/rainloop -> public/snappymail" | tee -a /var/log/cyberpanel_upgrade_debug.log + # Update data path in app config so it uses snappymail data dir + if [ -f "/usr/local/CyberCP/public/snappymail/include.php" ]; then + sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' /usr/local/CyberCP/public/snappymail/include.php + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Updated include.php to use snappymail data path" | tee -a /var/log/cyberpanel_upgrade_debug.log + fi + # Update version-specific include.php (may be under snappymail/v/ or rainloop/v/ after rename) + for inc in /usr/local/CyberCP/public/snappymail/snappymail/v/*/include.php /usr/local/CyberCP/public/snappymail/rainloop/v/*/include.php; do + [ -f "$inc" ] && sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' "$inc" && echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Updated $inc" | tee -a /var/log/cyberpanel_upgrade_debug.log && break + done 2>/dev/null +fi + # Migrate data from old rainloop folder to new snappymail folder (2.4.4 -> 2.5.5 upgrade) if [ -d "/usr/local/lscp/cyberpanel/rainloop/data" ] && [ "$(ls -A /usr/local/lscp/cyberpanel/rainloop/data 2>/dev/null)" ]; then echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Migrating rainloop data to snappymail..." | tee -a /var/log/cyberpanel_upgrade_debug.log @@ -284,6 +300,14 @@ if [ -d "/usr/local/lscp/cyberpanel/rainloop/data" ] && [ "$(ls -A /usr/local/ls sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' /usr/local/CyberCP/public/snappymail/include.php echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Updated include.php to use snappymail data path" | tee -a /var/log/cyberpanel_upgrade_debug.log fi + + # Replace ALL rainloop path/URL references in migrated SnappyMail data (configs, domains, plugins) + if [ -d "/usr/local/lscp/cyberpanel/snappymail/data" ]; then + find /usr/local/lscp/cyberpanel/snappymail/data -type f \( -name "*.ini" -o -name "*.json" -o -name "*.php" -o -name "*.cfg" \) -exec grep -l "rainloop" {} \; 2>/dev/null | while read -r f; do + sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g; s|/rainloop/|/snappymail/|g; s|rainloop/data|snappymail/data|g' "$f" + done + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Replaced rainloop→snappymail links in SnappyMail data files" | tee -a /var/log/cyberpanel_upgrade_debug.log + fi else echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: Data migration completed with errors" | tee -a /var/log/cyberpanel_upgrade_debug.log fi @@ -307,6 +331,20 @@ else echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: lscpd user not found, skipping ownership change" | tee -a /var/log/cyberpanel_upgrade_debug.log fi +# Ensure /rainloop→/snappymail redirect exists (even when no migration ran) +HTACCESS="/usr/local/CyberCP/public/.htaccess" +if [ -d "/usr/local/CyberCP/public" ] && { [ ! -f "$HTACCESS" ] || ! grep -q "Redirect old RainLoop URL to SnappyMail" "$HTACCESS" 2>/dev/null; }; then + { + echo "" + echo "# Redirect old RainLoop URL to SnappyMail (2.5.5 upgrade)" + echo "" + echo "RewriteEngine On" + echo "RewriteRule ^rainloop/?(.*)\$ /snappymail/\$1 [R=301,L]" + echo "" + } >> "$HTACCESS" + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Added /rainloop→/snappymail redirect to .htaccess" | tee -a /var/log/cyberpanel_upgrade_debug.log +fi + # Set proper permissions for SnappyMail data directories (group writable) chmod -R 775 /usr/local/lscp/cyberpanel/snappymail/data/ echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Set SnappyMail data directory permissions to 775 (group writable)" | tee -a /var/log/cyberpanel_upgrade_debug.log
{% trans "ID" %}