diff --git a/cyberpanel.sh b/cyberpanel.sh index 1b7d9007e..8d074e1b9 100644 --- a/cyberpanel.sh +++ b/cyberpanel.sh @@ -528,9 +528,13 @@ curl --max-time 20 -d '{"ipAddress": "'"$Server_IP"'", "InstallCyberPanelStatus" } Branch_Check() { -if [[ "$1" = *.*.* ]]; then - #check input if it's valid format as X.Y.Z - Output=$(awk -v num1="$Base_Number" -v num2="${1//[[:space:]]/}" ' +# Enhanced version validation to handle stable versions, development versions, and commit hashes +if [[ "$1" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-dev)?$ ]]; then + # Handle version numbers (stable and development) + version_number=$(echo "$1" | sed 's/-dev$//') + + # Check if version is higher than 2.3.4 + Output=$(awk -v num1="$Base_Number" -v num2="$version_number" ' BEGIN { print "num1", (num1 < num2 ? "<" : ">="), "num2" } @@ -539,11 +543,26 @@ if [[ "$1" = *.*.* ]]; then echo -e "\nYou must use version number higher than 2.3.4" exit else - Branch_Name="v${1//[[:space:]]/}" - echo -e "\nSet branch name to $Branch_Name..." + # Handle both stable and development versions + if [[ "$1" =~ -dev$ ]]; then + Branch_Name="${1//[[:space:]]/}" + echo -e "\nSet branch name to $Branch_Name (development version)..." + else + Branch_Name="v${1//[[:space:]]/}" + echo -e "\nSet branch name to $Branch_Name (stable version)..." + fi fi +elif [[ "$1" =~ ^[a-f0-9]{7,40}$ ]]; then + # Handle commit hashes (7-40 character hex strings) + commit_hash="${1//[[:space:]]/}" + Branch_Name="commit:$commit_hash" + echo -e "\nSet branch name to commit $commit_hash..." + echo -e "This will install from the specific commit: $commit_hash" else - echo -e "\nPlease input a valid format version number." + echo -e "\nPlease input a valid format:" + echo -e " Version number: 2.4.4, 2.5.0, 2.5.5-dev" + echo -e " Commit hash: b05d9cb5bb3c277b22a6070f04844e8a7951585b" + echo -e " Short commit: b05d9cb" exit fi } @@ -1195,7 +1214,13 @@ else echo -e "\nLocal MySQL selected..." fi -echo -e "\nPress \e[31mEnter\e[39m key to continue with latest version or Enter specific version such as: \e[31m2.3.4\e[39m , \e[31m2.4.4\e[39m , \e[31m2.5.0\e[39m ...etc" +echo -e "\nPress \e[31mEnter\e[39m key to continue with latest version or Enter specific version such as:" +echo -e " \e[31m2.4.4\e[39m (stable version)" +echo -e " \e[31m2.5.0\e[39m (stable version)" +echo -e " \e[31m2.5.5-dev\e[39m (development version)" +echo -e " \e[31m2.6.0-dev\e[39m (development version)" +echo -e " \e[31mb05d9cb5bb3c277b22a6070f04844e8a7951585b\e[39m (specific commit)" +echo -e " \e[31mb05d9cb\e[39m (short commit hash)" printf "%s" "" read -r Tmp_Input diff --git a/cyberpanel_upgrade.sh b/cyberpanel_upgrade.sh index 2eeebdd95..c4fe53f9f 100644 --- a/cyberpanel_upgrade.sh +++ b/cyberpanel_upgrade.sh @@ -151,6 +151,10 @@ 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 @@ -170,9 +174,12 @@ Server_OS_Version=$(grep VERSION_ID /etc/os-release | awk -F[=,] '{print $2}' | echo -e "System: $Server_OS $Server_OS_Version detected...\n" if [[ $Server_OS = "CloudLinux" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "RockyLinux" ]] || [[ "$Server_OS" = "RedHat" ]]; 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 + # 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 @@ -358,8 +365,8 @@ mysql -uroot -p"$MySQL_Password" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'loca Pre_Upgrade_Setup_Repository() { echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Pre_Upgrade_Setup_Repository started for OS: $Server_OS" | tee -a /var/log/cyberpanel_upgrade_debug.log -if [[ "$Server_OS" = "CentOS" ]] ; then - echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Setting up CentOS repositories..." | tee -a /var/log/cyberpanel_upgrade_debug.log +if [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] ; then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Setting up repositories for $Server_OS..." | tee -a /var/log/cyberpanel_upgrade_debug.log rm -f /etc/yum.repos.d/CyberPanel.repo rm -f /etc/yum.repos.d/litespeed.repo if [[ "$Server_Country" = "CN" ]] ; then @@ -477,6 +484,28 @@ EOF fi dnf install epel-release -y + + # AlmaLinux 9 specific package installation + if [[ "$Server_OS" = "AlmaLinux9" ]] ; then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing AlmaLinux 9 specific packages..." | tee -a /var/log/cyberpanel_upgrade_debug.log + + # Install essential build tools + dnf groupinstall -y 'Development Tools' + + # Install PHP dependencies that are missing on AlmaLinux 9 + dnf install -y ImageMagick ImageMagick-devel gd gd-devel libicu libicu-devel \ + oniguruma oniguruma-devel aspell aspell-devel libc-client libc-client-devel \ + libmemcached libmemcached-devel freetype-devel libjpeg-turbo-devel \ + libpng-devel libwebp-devel libXpm-devel libzip-devel openssl-devel \ + sqlite-devel libxml2-devel libxslt-devel curl-devel libedit-devel \ + readline-devel pkgconfig cmake gcc-c++ + + # Install MariaDB + dnf install -y mariadb-server mariadb-devel mariadb-client + + # Install additional required packages + dnf install -y wget curl unzip zip rsync firewalld psmisc git python3 python3-pip python3-devel + fi dnf install -y wget strace htop net-tools telnet curl which bc telnet htop libevent-devel gcc libattr-devel xz-devel mariadb-connector-c-devel curl-devel git platform-python-devel tar socat bind-utils dnf install gpgme-devel -y @@ -977,9 +1006,12 @@ if [[ $NEEDS_RECREATE -eq 1 ]] || [[ ! -d /usr/local/CyberCP/bin ]]; then if [[ "$Server_OS" = "Ubuntu" ]] && [[ "$Server_OS_Version" = "22" ]]; then echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu 22.04 detected, ensuring virtualenv is properly installed..." | tee -a /var/log/cyberpanel_upgrade_debug.log pip3 install --upgrade virtualenv 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log - elif [[ "$Server_OS" = "CentOS" ]] && ([[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]); then - echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky Linux 9/10 detected, ensuring virtualenv is properly installed..." | tee -a /var/log/cyberpanel_upgrade_debug.log - pip3 install --upgrade virtualenv 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log + elif [[ "$Server_OS" = "CentOS" ]] && ([[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]); then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky Linux 9/10 detected, ensuring virtualenv is properly installed..." | tee -a /var/log/cyberpanel_upgrade_debug.log + pip3 install --upgrade virtualenv 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log + elif [[ "$Server_OS" = "AlmaLinux9" ]]; then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux 9 detected, ensuring virtualenv is properly installed..." | tee -a /var/log/cyberpanel_upgrade_debug.log + pip3 install --upgrade virtualenv 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log fi # Find the correct python3 path @@ -987,6 +1019,10 @@ if [[ $NEEDS_RECREATE -eq 1 ]] || [[ ! -d /usr/local/CyberCP/bin ]]; then PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3") echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Using Python path: $PYTHON_PATH" | tee -a /var/log/cyberpanel_upgrade_debug.log virtualenv_output=$(virtualenv -p "$PYTHON_PATH" /usr/local/CyberCP 2>&1) + elif [[ "$Server_OS" = "AlmaLinux9" ]]; then + PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3") + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux 9 - Using Python path: $PYTHON_PATH" | tee -a /var/log/cyberpanel_upgrade_debug.log + virtualenv_output=$(virtualenv -p "$PYTHON_PATH" /usr/local/CyberCP 2>&1) else virtualenv_output=$(virtualenv -p /usr/bin/python3 /usr/local/CyberCP 2>&1) fi diff --git a/install.sh b/install.sh index 4e4f7b9ed..46757eb24 100644 --- a/install.sh +++ b/install.sh @@ -34,8 +34,15 @@ yum update curl wget ca-certificates -y 1> /dev/null elif echo $OUTPUT | grep -q "AlmaLinux 9" ; then echo -e "\nDetecting AlmaLinux 9...\n" SERVER_OS="AlmaLinux9" -dnf install curl wget -y 1> /dev/null -dnf update curl wget ca-certificates -y 1> /dev/null + echo "Installing essential packages for AlmaLinux 9..." + dnf install curl wget -y 1> /dev/null + dnf update curl wget ca-certificates -y 1> /dev/null + + # Install additional packages needed for AlmaLinux 9 + echo "Installing additional dependencies for AlmaLinux 9..." + dnf install -y epel-release 1> /dev/null + dnf groupinstall -y 'Development Tools' 1> /dev/null + dnf install -y ImageMagick gd libicu oniguruma aspell libc-client 1> /dev/null elif echo $OUTPUT | grep -q "AlmaLinux 10" ; then echo -e "\nDetecting AlmaLinux 10...\n" SERVER_OS="AlmaLinux10" @@ -143,12 +150,27 @@ fi rm -f cyberpanel.sh rm -f install.tar.gz -# Download from appropriate source based on branch +# Download from appropriate source based on branch/commit if [ -n "$BRANCH_NAME" ]; then - echo "Installing CyberPanel from branch: $BRANCH_NAME" - curl --silent -o cyberpanel.sh "https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel.sh" 2>/dev/null - # Set environment variable for version detection - export CYBERPANEL_BRANCH="$BRANCH_NAME" + # Check if it's a commit hash + if [[ "$BRANCH_NAME" =~ ^[a-f0-9]{7,40}$ ]]; then + echo "Installing CyberPanel from commit: $BRANCH_NAME" + curl --silent -o cyberpanel.sh "https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel.sh" 2>/dev/null + # Set environment variable for commit detection + export CYBERPANEL_BRANCH="$BRANCH_NAME" + elif [[ "$BRANCH_NAME" =~ ^commit: ]]; then + # It's a commit with prefix + commit_hash="${BRANCH_NAME#commit:}" + echo "Installing CyberPanel from commit: $commit_hash" + curl --silent -o cyberpanel.sh "https://raw.githubusercontent.com/usmannasir/cyberpanel/$commit_hash/cyberpanel.sh" 2>/dev/null + # Set environment variable for commit detection + export CYBERPANEL_BRANCH="$commit_hash" + else + echo "Installing CyberPanel from branch: $BRANCH_NAME" + curl --silent -o cyberpanel.sh "https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel.sh" 2>/dev/null + # Set environment variable for version detection + export CYBERPANEL_BRANCH="$BRANCH_NAME" + fi else echo "Installing CyberPanel stable version" curl --silent -o cyberpanel.sh "https://cyberpanel.sh/?dl&$SERVER_OS" 2>/dev/null diff --git a/install/install.py b/install/install.py index 315256d78..f7910c08f 100644 --- a/install/install.py +++ b/install/install.py @@ -1438,12 +1438,40 @@ class preFlightsChecks: # Ensure the parent directory exists os.makedirs("/usr/local", exist_ok=True) + # Determine the correct branch/tag/commit to clone + branch_name = os.environ.get('CYBERPANEL_BRANCH', 'stable') + # Try multiple clone methods for better reliability - clone_commands = [ + clone_commands = [] + + # If a specific branch/tag/commit is specified, try to clone it + if branch_name and branch_name != 'stable': + if branch_name.startswith('commit:'): + # It's a commit hash (e.g., commit:b05d9cb5bb3c277b22a6070f04844e8a7951585b) + commit_hash = branch_name[7:] # Remove 'commit:' prefix + clone_commands.append(f"git clone https://github.com/usmannasir/cyberpanel /usr/local/CyberCP") + clone_commands.append(f"cd /usr/local/CyberCP && git checkout {commit_hash}") + elif branch_name.startswith('v'): + # It's a tag (e.g., v2.4.4) + clone_commands.append(f"git clone --depth 1 --branch {branch_name} https://github.com/usmannasir/cyberpanel /usr/local/CyberCP") + elif branch_name.endswith('-dev'): + # It's a development branch (e.g., 2.5.5-dev) + clone_commands.append(f"git clone --depth 1 --branch {branch_name} https://github.com/usmannasir/cyberpanel /usr/local/CyberCP") + elif len(branch_name) >= 7 and all(c in '0123456789abcdef' for c in branch_name.lower()): + # It's a commit hash (e.g., b05d9cb5bb3c277b22a6070f04844e8a7951585b) + clone_commands.append(f"git clone https://github.com/usmannasir/cyberpanel /usr/local/CyberCP") + clone_commands.append(f"cd /usr/local/CyberCP && git checkout {branch_name}") + else: + # It's a version number, try as both tag and branch + clone_commands.append(f"git clone --depth 1 --branch v{branch_name} https://github.com/usmannasir/cyberpanel /usr/local/CyberCP") + clone_commands.append(f"git clone --depth 1 --branch {branch_name} https://github.com/usmannasir/cyberpanel /usr/local/CyberCP") + + # Fallback to stable branch + clone_commands.extend([ "git clone https://github.com/usmannasir/cyberpanel /usr/local/CyberCP", "git clone --depth 1 https://github.com/usmannasir/cyberpanel /usr/local/CyberCP", "git clone --single-branch --branch stable https://github.com/usmannasir/cyberpanel /usr/local/CyberCP" - ] + ]) clone_success = False for cmd in clone_commands: @@ -1461,13 +1489,42 @@ class preFlightsChecks: # Try manual download as fallback logging.InstallLog.writeToFile("Attempting manual download as fallback...") - command = "wget -O /tmp/cyberpanel.zip https://github.com/usmannasir/cyberpanel/archive/refs/heads/stable.zip" + + # Determine the correct download URL based on branch/tag/commit + if branch_name and branch_name != 'stable': + if branch_name.startswith('commit:'): + # It's a commit hash - use the commit hash directly + commit_hash = branch_name[7:] # Remove 'commit:' prefix + download_url = f"https://github.com/usmannasir/cyberpanel/archive/{commit_hash}.zip" + extract_dir = f"cyberpanel-{commit_hash}" + elif len(branch_name) >= 7 and all(c in '0123456789abcdef' for c in branch_name.lower()): + # It's a commit hash (e.g., b05d9cb5bb3c277b22a6070f04844e8a7951585b) + download_url = f"https://github.com/usmannasir/cyberpanel/archive/{branch_name}.zip" + extract_dir = f"cyberpanel-{branch_name}" + elif branch_name.startswith('v'): + # It's a tag + download_url = f"https://github.com/usmannasir/cyberpanel/archive/refs/tags/{branch_name}.zip" + extract_dir = f"cyberpanel-{branch_name[1:]}" # Remove 'v' prefix + elif branch_name.endswith('-dev'): + # It's a development branch + download_url = f"https://github.com/usmannasir/cyberpanel/archive/refs/heads/{branch_name}.zip" + extract_dir = f"cyberpanel-{branch_name}" + else: + # It's a version number, try as tag first + download_url = f"https://github.com/usmannasir/cyberpanel/archive/refs/tags/v{branch_name}.zip" + extract_dir = f"cyberpanel-{branch_name}" + else: + # Default to stable + download_url = "https://github.com/usmannasir/cyberpanel/archive/refs/heads/stable.zip" + extract_dir = "cyberpanel-stable" + + command = f"wget -O /tmp/cyberpanel.zip {download_url}" preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) command = "unzip /tmp/cyberpanel.zip -d /usr/local/" preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) - command = "mv /usr/local/cyberpanel-stable /usr/local/CyberCP" + command = f"mv /usr/local/{extract_dir} /usr/local/CyberCP" preFlightsChecks.call(command, self.distro, command, command, 1, 1, os.EX_OSERR) command = "rm -f /tmp/cyberpanel.zip" diff --git a/test_installation.sh b/test_installation.sh new file mode 100644 index 000000000..0284ed423 --- /dev/null +++ b/test_installation.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +# CyberPanel Installation Test Script +# Tests the updated installer with different version inputs + +echo "==========================================" +echo "CyberPanel Installation Test Script" +echo "==========================================" + +# Test 1: Test version validation function +echo "Test 1: Testing version validation function..." + +# Source the cyberpanel.sh script to get the Branch_Check function +source cyberpanel.sh 2>/dev/null || true + +# Test cases +test_versions=("2.4.4" "2.5.0" "2.5.5-dev" "2.6.0-dev" "b05d9cb5bb3c277b22a6070f04844e8a7951585b" "b05d9cb" "invalid-version" "2.3.3") + +for version in "${test_versions[@]}"; do + echo "Testing version: $version" + if Branch_Check "$version" 2>/dev/null; then + echo " ✓ PASS: $version is valid" + else + echo " ✗ FAIL: $version is invalid" + fi +done + +echo "" +echo "Test 2: Testing OS detection..." + +# Test OS detection +if [[ -f /etc/os-release ]]; then + source /etc/os-release + echo "Detected OS: $NAME $VERSION_ID" + + if [[ "$NAME" == "AlmaLinux" ]] && [[ "$VERSION_ID" == "9"* ]]; then + echo " ✓ PASS: AlmaLinux 9 detected correctly" + else + echo " ℹ INFO: Not AlmaLinux 9, skipping AlmaLinux 9 specific tests" + fi +else + echo " ✗ FAIL: Cannot detect OS (no /etc/os-release)" +fi + +echo "" +echo "Test 3: Testing package availability..." + +# Test if required packages are available +if command -v dnf >/dev/null 2>&1; then + echo "Testing dnf package availability..." + + required_packages=("ImageMagick" "gd" "libicu" "oniguruma" "aspell" "libc-client" "mariadb-server") + + for package in "${required_packages[@]}"; do + if dnf list available "$package" >/dev/null 2>&1; then + echo " ✓ PASS: $package is available" + else + echo " ✗ FAIL: $package is not available" + fi + done +elif command -v yum >/dev/null 2>&1; then + echo "Testing yum package availability..." + + required_packages=("ImageMagick" "gd" "libicu" "oniguruma" "aspell" "libc-client" "mariadb-server") + + for package in "${required_packages[@]}"; do + if yum list available "$package" >/dev/null 2>&1; then + echo " ✓ PASS: $package is available" + else + echo " ✗ FAIL: $package is not available" + fi + done +else + echo " ℹ INFO: No dnf/yum available, skipping package tests" +fi + +echo "" +echo "Test 4: Testing Git clone functionality..." + +# Test Git clone with different branches and commits +test_branches=("stable" "v2.4.4" "2.5.5-dev" "b05d9cb5bb3c277b22a6070f04844e8a7951585b" "b05d9cb") + +for branch in "${test_branches[@]}"; do + echo "Testing Git clone for branch/commit: $branch" + + # Create temporary directory for testing + test_dir="/tmp/cyberpanel_test_$branch" + rm -rf "$test_dir" + + if [[ "$branch" == "stable" ]]; then + clone_cmd="git clone --depth 1 https://github.com/usmannasir/cyberpanel $test_dir" + elif [[ "$branch" == v* ]]; then + clone_cmd="git clone --depth 1 --branch $branch https://github.com/usmannasir/cyberpanel $test_dir" + elif [[ "$branch" =~ ^[a-f0-9]{7,40}$ ]]; then + # It's a commit hash + clone_cmd="git clone https://github.com/usmannasir/cyberpanel $test_dir && cd $test_dir && git checkout $branch" + else + clone_cmd="git clone --depth 1 --branch $branch https://github.com/usmannasir/cyberpanel $test_dir" + fi + + if eval "$clone_cmd" >/dev/null 2>&1; then + if [[ -d "$test_dir" ]] && [[ -f "$test_dir/install/install.py" ]]; then + echo " ✓ PASS: Successfully cloned $branch" + else + echo " ✗ FAIL: Cloned $branch but missing files" + fi + rm -rf "$test_dir" + else + echo " ✗ FAIL: Failed to clone $branch" + fi +done + +echo "" +echo "Test 5: Testing environment variable handling..." + +# Test environment variable handling +export CYBERPANEL_BRANCH="2.5.5-dev" +echo "Testing with CYBERPANEL_BRANCH=$CYBERPANEL_BRANCH" + +if [[ "$CYBERPANEL_BRANCH" == *"-dev" ]]; then + echo " ✓ PASS: Development branch detected correctly" +else + echo " ✗ FAIL: Development branch not detected" +fi + +unset CYBERPANEL_BRANCH + +echo "" +echo "==========================================" +echo "Test Summary:" +echo "==========================================" +echo "1. Version validation: Check if all test versions are handled correctly" +echo "2. OS detection: Verify AlmaLinux 9 is detected properly" +echo "3. Package availability: Ensure required packages are available" +echo "4. Git clone: Test cloning different branches/tags" +echo "5. Environment variables: Test branch detection from environment" +echo "" +echo "If all tests pass, the installer should work correctly." +echo "If any tests fail, check the specific error messages above."