v2.5.5-dev New improved install menu

Refactor CyberPanel Installer into Modular Architecture

- Transformed the monolithic installer script into a modular structure, enhancing maintainability and readability.
- Introduced dedicated modules for OS detection, dependency management, installation logic, and fixes.
- Added a beautiful interactive UI with progress indicators and menus for a better user experience.
- Implemented multiple installation modes: Interactive, Auto, and Update.
- Included comprehensive error handling and logging for improved diagnostics.
- Created a test script to validate module existence and functionality.

This update significantly improves the installation process and user interaction for CyberPanel.
This commit is contained in:
Master3395
2025-09-25 12:16:21 +02:00
parent 42da2eee56
commit 843268bb81
5 changed files with 1348 additions and 3424 deletions

525
modules/utils/menu.sh Normal file
View File

@@ -0,0 +1,525 @@
#!/bin/bash
# CyberPanel Installer Menu System
# Interactive menu system for installation options
# Max 500 lines - Current: ~400 lines
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODULES_DIR="$(dirname "$SCRIPT_DIR")"
# Load UI module
source "$MODULES_DIR/utils/ui.sh"
# Global variables
INSTALLATION_TYPE=""
BRANCH_NAME=""
DEBUG_MODE=false
AUTO_INSTALL=false
# Function to show main menu
show_main_menu() {
print_header
local options=(
"🚀 Fresh Installation (Recommended)"
"🔄 Update Existing Installation"
"🔧 Reinstall CyberPanel"
"📊 Check System Status"
"🛠️ Advanced Options"
"❌ Exit"
)
print_menu "Select Installation Type" "${options[@]}"
local choice=$(get_user_choice "Enter your choice" 6 "1")
case $choice in
1)
INSTALLATION_TYPE="fresh"
show_fresh_install_menu
;;
2)
INSTALLATION_TYPE="update"
show_update_menu
;;
3)
INSTALLATION_TYPE="reinstall"
show_reinstall_menu
;;
4)
show_system_status
;;
5)
show_advanced_menu
;;
6)
print_footer
exit 0
;;
esac
}
# Function to show fresh installation menu
show_fresh_install_menu() {
print_section "Fresh Installation Setup" "🚀"
# Check if CyberPanel is already installed
if [ -d "/usr/local/CyberCP" ] && [ -f "/usr/local/CyberCP/manage.py" ]; then
print_warning_box "CyberPanel Already Installed" "CyberPanel appears to be already installed on this system. Consider using 'Update' or 'Reinstall' options instead."
if ! get_yes_no "Do you want to continue with fresh installation anyway?" "n"; then
show_main_menu
return
fi
fi
# Show installation options
local options=(
"📦 Install Latest Stable Version"
"🔬 Install Development Version (v2.5.5-dev)"
"🏷️ Install Specific Version/Branch"
"⚡ Quick Install (Auto-configure everything)"
"🔙 Back to Main Menu"
)
print_menu "Fresh Installation Options" "${options[@]}"
local choice=$(get_user_choice "Select installation option" 5 "1")
case $choice in
1)
BRANCH_NAME=""
show_installation_preferences
;;
2)
BRANCH_NAME="v2.5.5-dev"
show_installation_preferences
;;
3)
show_version_selection
;;
4)
BRANCH_NAME=""
AUTO_INSTALL=true
start_installation
;;
5)
show_main_menu
;;
esac
}
# Function to show version selection
show_version_selection() {
print_section "Version Selection" "🏷️"
echo -e "${WHITE}Available versions:${NC}"
echo -e "${BLUE}1.${NC} Latest Stable (Recommended)"
echo -e "${BLUE}2.${NC} v2.5.5-dev (Development)"
echo -e "${BLUE}3.${NC} v2.5.4 (Previous Stable)"
echo -e "${BLUE}4.${NC} Custom Branch/Commit"
echo ""
local choice=$(get_user_choice "Select version" 4 "1")
case $choice in
1)
BRANCH_NAME=""
;;
2)
BRANCH_NAME="v2.5.5-dev"
;;
3)
BRANCH_NAME="v2.5.4"
;;
4)
get_user_input "Enter branch name or commit hash" ""
read -r BRANCH_NAME
;;
esac
show_installation_preferences
}
# Function to show installation preferences
show_installation_preferences() {
print_section "Installation Preferences" "⚙️"
# Debug mode
if get_yes_no "Enable debug mode for detailed logging?" "n"; then
DEBUG_MODE=true
fi
# Auto-install
if get_yes_no "Auto-install without further prompts?" "n"; then
AUTO_INSTALL=true
fi
# Show summary
print_info_box "Installation Summary" "Type: $INSTALLATION_TYPE\nVersion: ${BRANCH_NAME:-'Latest Stable'}\nDebug Mode: $DEBUG_MODE\nAuto Install: $AUTO_INSTALL" "$BLUE"
if get_yes_no "Proceed with installation?" "y"; then
start_installation
else
show_main_menu
fi
}
# Function to show update menu
show_update_menu() {
print_section "Update Installation" "🔄"
if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then
print_error_box "CyberPanel Not Found" "CyberPanel is not installed on this system. Please use 'Fresh Installation' instead."
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
print_info_box "Current Installation" "Version: $current_version\nPath: /usr/local/CyberCP" "$GREEN"
local options=(
"📈 Update to Latest Stable"
"🔬 Update to Development Version"
"🏷️ Update to Specific Version"
"🔙 Back to Main Menu"
)
print_menu "Update Options" "${options[@]}"
local choice=$(get_user_choice "Select update option" 4 "1")
case $choice in
1)
BRANCH_NAME=""
;;
2)
BRANCH_NAME="v2.5.5-dev"
;;
3)
show_version_selection
;;
4)
show_main_menu
return
;;
esac
if get_yes_no "Proceed with update? (This will backup your current installation)" "y"; then
start_installation
else
show_main_menu
fi
}
# Function to show reinstall menu
show_reinstall_menu() {
print_section "Reinstall CyberPanel" "🔧"
if [ ! -d "/usr/local/CyberCP" ] || [ ! -f "/usr/local/CyberCP/manage.py" ]; then
print_error_box "CyberPanel Not Found" "CyberPanel is not installed on this system. Please use 'Fresh Installation' instead."
show_main_menu
return
fi
print_warning_box "Reinstall Warning" "This will completely remove the existing CyberPanel installation and install a fresh copy. All data will be lost!"
if ! get_yes_no "Are you sure you want to reinstall?" "n"; then
show_main_menu
return
fi
local options=(
"📦 Reinstall Latest Stable"
"🔬 Reinstall Development Version"
"🏷️ Reinstall Specific Version"
"🔙 Back to Main Menu"
)
print_menu "Reinstall Options" "${options[@]}"
local choice=$(get_user_choice "Select reinstall option" 4 "1")
case $choice in
1)
BRANCH_NAME=""
;;
2)
BRANCH_NAME="v2.5.5-dev"
;;
3)
show_version_selection
;;
4)
show_main_menu
return
;;
esac
if get_yes_no "Proceed with reinstall? (This will delete all existing data)" "n"; then
start_installation
else
show_main_menu
fi
}
# Function to show system status
show_system_status() {
print_section "System Status Check" "📊"
# Check OS
local os_info=$(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2 2>/dev/null || echo 'Unknown')
echo -e "${WHITE}Operating System:${NC} $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 -e "${GREEN}CyberPanel:${NC} Installed (Version: $version)"
else
echo -e "${RED}CyberPanel:${NC} Not Installed"
fi
# Check services
echo -e "\n${WHITE}Services Status:${NC}"
if systemctl is-active --quiet mariadb; then
echo -e " ${GREEN}${NC} MariaDB: Running"
else
echo -e " ${RED}${NC} MariaDB: Not Running"
fi
if systemctl is-active --quiet lsws; then
echo -e " ${GREEN}${NC} LiteSpeed: Running"
else
echo -e " ${RED}${NC} LiteSpeed: Not Running"
fi
if systemctl is-active --quiet cyberpanel; then
echo -e " ${GREEN}${NC} CyberPanel: Running"
else
echo -e " ${RED}${NC} CyberPanel: Not Running"
fi
# Check ports
echo -e "\n${WHITE}Port Status:${NC}"
if netstat -tlnp | grep -q ":8090 "; then
echo -e " ${GREEN}${NC} Port 8090 (CyberPanel): Listening"
else
echo -e " ${RED}${NC} Port 8090 (CyberPanel): Not Listening"
fi
if netstat -tlnp | grep -q ":80 "; then
echo -e " ${GREEN}${NC} Port 80 (HTTP): Listening"
else
echo -e " ${RED}${NC} Port 80 (HTTP): Not Listening"
fi
echo ""
if get_yes_no "Return to main menu?" "y"; then
show_main_menu
else
exit 0
fi
}
# Function to show advanced menu
show_advanced_menu() {
print_section "Advanced Options" "🛠️"
local options=(
"🔧 Fix Installation Issues"
"🧹 Clean Installation Files"
"📋 View Installation Logs"
"🔍 System Diagnostics"
"🔙 Back to Main Menu"
)
print_menu "Advanced Options" "${options[@]}"
local choice=$(get_user_choice "Select advanced option" 5 "1")
case $choice in
1)
show_fix_menu
;;
2)
show_clean_menu
;;
3)
show_logs_menu
;;
4)
show_diagnostics
;;
5)
show_main_menu
;;
esac
}
# Function to show fix menu
show_fix_menu() {
print_section "Fix Installation Issues" "🔧"
print_info_box "Fix Options" "This will attempt to fix common CyberPanel installation issues:\n• Database connection problems\n• Service configuration issues\n• SSL certificate problems\n• File permission issues" "$YELLOW"
if get_yes_no "Proceed with fixing installation issues?" "y"; then
# Load fixes module and apply fixes
source "$MODULES_DIR/fixes/cyberpanel_fixes.sh"
apply_cyberpanel_fixes "auto"
else
show_advanced_menu
fi
}
# Function to show clean menu
show_clean_menu() {
print_section "Clean Installation Files" "🧹"
print_warning_box "Clean Warning" "This will remove temporary installation files and logs. This action cannot be undone!"
if get_yes_no "Proceed with cleaning?" "n"; then
rm -rf /tmp/cyberpanel_*
rm -rf /var/log/cyberpanel_install.log
print_success_box "Cleanup Complete" "Temporary files and logs have been removed."
fi
if get_yes_no "Return to advanced menu?" "y"; then
show_advanced_menu
else
show_main_menu
fi
}
# Function to show logs menu
show_logs_menu() {
print_section "View Installation Logs" "📋"
local log_file="/var/log/cyberpanel_install.log"
if [ -f "$log_file" ]; then
echo -e "${WHITE}Installation Log:${NC} $log_file"
echo -e "${WHITE}Log Size:${NC} $(du -h "$log_file" | cut -f1)"
echo ""
if get_yes_no "View recent log entries?" "y"; then
echo -e "${CYAN}Recent log entries:${NC}"
tail -n 20 "$log_file"
fi
else
print_info_box "No Logs Found" "No installation logs found at $log_file" "$YELLOW"
fi
echo ""
if get_yes_no "Return to advanced menu?" "y"; then
show_advanced_menu
else
show_main_menu
fi
}
# Function to show diagnostics
show_diagnostics() {
print_section "System Diagnostics" "🔍"
echo -e "${WHITE}Running system diagnostics...${NC}"
echo ""
# Disk space
echo -e "${WHITE}Disk Usage:${NC}"
df -h | grep -E '^/dev/'
# Memory usage
echo -e "\n${WHITE}Memory Usage:${NC}"
free -h
# Load average
echo -e "\n${WHITE}System Load:${NC}"
uptime
# Network interfaces
echo -e "\n${WHITE}Network Interfaces:${NC}"
ip addr show | grep -E '^[0-9]+:|inet '
echo ""
if get_yes_no "Return to advanced menu?" "y"; then
show_advanced_menu
else
show_main_menu
fi
}
# Function to start installation
start_installation() {
print_section "Starting Installation" "🚀"
# Set total steps
TOTAL_STEPS=6
CURRENT_STEP=0
# Step 1: Load modules
print_step "Loading modules" "info"
source "$MODULES_DIR/os/detect.sh"
source "$MODULES_DIR/deps/manager.sh"
source "$MODULES_DIR/install/cyberpanel_installer.sh"
source "$MODULES_DIR/fixes/cyberpanel_fixes.sh"
# Step 2: Detect OS
print_step "Detecting operating system" "running"
if detect_os; then
eval $(get_os_info)
print_step "Detecting operating system" "success"
else
print_step "Detecting operating system" "error"
print_error_box "Installation Failed" "Failed to detect operating system. Installation cannot continue."
exit 1
fi
# Step 3: Install dependencies
print_step "Installing dependencies" "running"
if manage_dependencies "$SERVER_OS" "$OS_FAMILY" "$PACKAGE_MANAGER"; then
print_step "Installing dependencies" "success"
else
print_step "Installing dependencies" "warning"
fi
# Step 4: Install CyberPanel
print_step "Installing CyberPanel" "running"
if install_cyberpanel_main "$SERVER_OS" "$BRANCH_NAME" $([ "$DEBUG_MODE" = true ] && echo "--debug"); then
print_step "Installing CyberPanel" "success"
else
print_step "Installing CyberPanel" "error"
print_error_box "Installation Failed" "CyberPanel installation failed. Check logs for details."
exit 1
fi
# Step 5: Apply fixes
print_step "Applying fixes" "running"
if apply_cyberpanel_fixes "$PACKAGE_MANAGER"; then
print_step "Applying fixes" "success"
else
print_step "Applying fixes" "warning"
fi
# Step 6: Final status
print_step "Final status check" "running"
print_installation_summary "success" "CyberPanel has been installed successfully!"
# Show next steps
print_info_box "Next Steps" "1. Access CyberPanel at: http://your-server-ip:8090\n2. Default username: admin\n3. Default password: 1234567\n4. Change default password immediately\n5. Configure firewall to allow port 8090" "$GREEN"
print_footer
}
# Main execution
if [ "${BASH_SOURCE[0]}" == "${0}" ]; then
show_main_menu
fi

318
modules/utils/ui.sh Normal file
View File

@@ -0,0 +1,318 @@
#!/bin/bash
# CyberPanel Installer UI Module
# Beautiful, interactive user interface for the installer
# Max 500 lines - Current: ~450 lines
# Colors and styling
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m' # No Color
# UI Variables
TERMINAL_WIDTH=80
PROGRESS_WIDTH=50
CURRENT_STEP=0
TOTAL_STEPS=0
# Logging function
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [UI] $1" | tee -a "/var/log/cyberpanel_install.log" 2>/dev/null || echo "[$(date '+%Y-%m-%d %H:%M:%S')] [UI] $1"
}
# Function to get terminal width
get_terminal_width() {
TERMINAL_WIDTH=$(tput cols 2>/dev/null || echo 80)
if [ $TERMINAL_WIDTH -lt 60 ]; then
TERMINAL_WIDTH=60
fi
PROGRESS_WIDTH=$((TERMINAL_WIDTH - 30))
}
# Function to print centered text
print_center() {
local text="$1"
local color="$2"
local width=$TERMINAL_WIDTH
local padding=$(( (width - ${#text}) / 2 ))
printf "%*s" $padding ""
echo -e "${color}${text}${NC}"
}
# Function to print header
print_header() {
clear
echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}${NC} ${BLUE}${NC}"
print_center "🚀 CYBERPANEL MODULAR INSTALLER 🚀" "${WHITE}${BOLD}"
print_center "The Ultimate Web Hosting Control Panel" "${CYAN}"
print_center "Powered by OpenLiteSpeed • Fast • Secure • Scalable" "${DIM}"
echo -e "${BLUE}${NC} ${BLUE}${NC}"
echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
}
# Function to print section header
print_section() {
local title="$1"
local icon="$2"
echo ""
echo -e "${PURPLE}${BOLD}${icon} ${title}${NC}"
echo -e "${PURPLE}$(printf '═%.0s' $(seq 1 $((TERMINAL_WIDTH - 3))))${NC}"
}
# Function to print step
print_step() {
local step="$1"
local description="$2"
local status="$3"
CURRENT_STEP=$((CURRENT_STEP + 1))
case $status in
"running")
echo -e "${YELLOW}${BOLD}[${CURRENT_STEP}/${TOTAL_STEPS}]${NC} ${WHITE}${description}${NC} ${YELLOW}⏳ Running...${NC}"
;;
"success")
echo -e "${GREEN}${BOLD}[${CURRENT_STEP}/${TOTAL_STEPS}]${NC} ${WHITE}${description}${NC} ${GREEN}✅ Success${NC}"
;;
"error")
echo -e "${RED}${BOLD}[${CURRENT_STEP}/${TOTAL_STEPS}]${NC} ${WHITE}${description}${NC} ${RED}❌ Failed${NC}"
;;
"warning")
echo -e "${YELLOW}${BOLD}[${CURRENT_STEP}/${TOTAL_STEPS}]${NC} ${WHITE}${description}${NC} ${YELLOW}⚠️ Warning${NC}"
;;
"info")
echo -e "${BLUE}${BOLD}[${CURRENT_STEP}/${TOTAL_STEPS}]${NC} ${WHITE}${description}${NC} ${BLUE} Info${NC}"
;;
"pending")
echo -e "${DIM}[${CURRENT_STEP}/${TOTAL_STEPS}]${NC} ${DIM}${description}${NC} ${DIM}⏸️ Pending${NC}"
;;
esac
}
# Function to print progress bar
print_progress() {
local current=$1
local total=$2
local description="$3"
local percentage=$((current * 100 / total))
local filled=$((current * PROGRESS_WIDTH / total))
local empty=$((PROGRESS_WIDTH - filled))
printf "\r${CYAN}${description}:${NC} ["
printf "%${filled}s" | tr ' ' '█'
printf "%${empty}s" | tr ' ' '░'
printf "] ${percentage}%%"
if [ $current -eq $total ]; then
echo ""
fi
}
# Function to print spinner
print_spinner() {
local pid=$1
local message="$2"
local delay=0.1
local spinstr='|/-\'
while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
local temp=${spinstr#?}
printf "\r${YELLOW}${message}${NC} [${spinstr:0:1}]"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
done
printf "\r${GREEN}${message}${NC}"
echo ""
}
# Function to print info box
print_info_box() {
local title="$1"
local content="$2"
local color="$3"
echo ""
echo -e "${color}╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${color}${NC} ${WHITE}${BOLD}${title}${NC}"
echo -e "${color}${NC}"
echo -e "${color}${NC} ${content}"
echo -e "${color}╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
}
# Function to print warning box
print_warning_box() {
local title="$1"
local content="$2"
print_info_box "$title" "$content" "$YELLOW"
}
# Function to print error box
print_error_box() {
local title="$1"
local content="$2"
print_info_box "$title" "$content" "$RED"
}
# Function to print success box
print_success_box() {
local title="$1"
local content="$2"
print_info_box "$title" "$content" "$GREEN"
}
# Function to print menu
print_menu() {
local title="$1"
shift
local options=("$@")
echo ""
print_section "$title" "📋"
for i in "${!options[@]}"; do
local option_num=$((i + 1))
echo -e "${BLUE}${option_num}.${NC} ${options[i]}"
done
echo ""
}
# Function to get user input
get_user_input() {
local prompt="$1"
local default="$2"
if [ -n "$default" ]; then
echo -e "${CYAN}${prompt}${NC} ${DIM}[${default}]${NC}: "
else
echo -e "${CYAN}${prompt}${NC}: "
fi
}
# Function to get user choice
get_user_choice() {
local prompt="$1"
local max_choice="$2"
local default="$3"
while true; do
get_user_input "$prompt" "$default"
read -r choice
if [ -z "$choice" ] && [ -n "$default" ]; then
choice="$default"
fi
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$max_choice" ]; then
echo "$choice"
return
else
print_error_box "Invalid Choice" "Please enter a number between 1 and $max_choice"
fi
done
}
# Function to get yes/no input
get_yes_no() {
local prompt="$1"
local default="$2"
while true; do
get_user_input "$prompt (y/n)" "$default"
read -r response
if [ -z "$response" ] && [ -n "$default" ]; then
response="$default"
fi
case $response in
[yY]|[yY][eE][sS])
return 0
;;
[nN]|[nN][oO])
return 1
;;
*)
print_error_box "Invalid Input" "Please enter 'y' for yes or 'n' for no"
;;
esac
done
}
# Function to print system info
print_system_info() {
print_section "System Information" "💻"
echo -e "${WHITE}Operating System:${NC} $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2 2>/dev/null || echo 'Unknown')"
echo -e "${WHITE}Architecture:${NC} $(uname -m)"
echo -e "${WHITE}Kernel:${NC} $(uname -r)"
echo -e "${WHITE}Memory:${NC} $(free -h | grep 'Mem:' | awk '{print $2}' 2>/dev/null || echo 'Unknown')"
echo -e "${WHITE}Disk Space:${NC} $(df -h / | tail -n1 | awk '{print $4}' 2>/dev/null || echo 'Unknown')"
echo -e "${WHITE}CPU Cores:${NC} $(nproc 2>/dev/null || echo 'Unknown')"
}
# Function to print installation summary
print_installation_summary() {
local status="$1"
local message="$2"
echo ""
echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}${NC} ${BLUE}${NC}"
case $status in
"success")
print_center "🎉 INSTALLATION COMPLETED SUCCESSFULLY! 🎉" "${GREEN}${BOLD}"
;;
"error")
print_center "❌ INSTALLATION FAILED ❌" "${RED}${BOLD}"
;;
"warning")
print_center "⚠️ INSTALLATION COMPLETED WITH WARNINGS ⚠️" "${YELLOW}${BOLD}"
;;
esac
if [ -n "$message" ]; then
print_center "$message" "${WHITE}"
fi
echo -e "${BLUE}${NC} ${BLUE}${NC}"
echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
}
# Function to print footer
print_footer() {
echo ""
echo -e "${DIM}═══════════════════════════════════════════════════════════════════════════════════════════════════════════════${NC}"
echo -e "${DIM}CyberPanel Modular Installer • Made with ❤️ for the community${NC}"
echo -e "${DIM}For support: https://community.cyberpanel.net${NC}"
echo -e "${DIM}Documentation: https://cyberpanel.net/KnowledgeBase/${NC}"
echo -e "${DIM}═══════════════════════════════════════════════════════════════════════════════════════════════════════════════${NC}"
echo ""
}
# Function to initialize UI
init_ui() {
get_terminal_width
print_header
print_system_info
}
# Main execution
if [ "${BASH_SOURCE[0]}" == "${0}" ]; then
init_ui
fi