173b3bd581
- app submenus return 75 on back/exit instead of 0 - index menus capture child exit code and skip pause when rc is 75 - applies to apps (coolify, pterodactyl, uptime-kuma, cloudpanel, proxmox) and tools (server-benchmark, system-infos) indexes
651 lines
24 KiB
Bash
Executable File
651 lines
24 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# LXS - CloudPanel Installation Script
|
|
# Description: Install and manage CloudPanel hosting platform
|
|
# Author: LXS
|
|
# Date: 2025
|
|
|
|
# Load LXS common library (colors, separator, run_spinner, loggers)
|
|
LXS_RAW_BASE="${LXS_RAW_BASE:-https://git.hyko.cx/hykocx/lxs/raw/branch/main}"
|
|
_lib=$(curl -fsSL "${LXS_RAW_BASE}/lib/common.sh") || { echo "Failed to fetch lib/common.sh" >&2; exit 1; }
|
|
eval "$_lib"
|
|
unset _lib
|
|
export LXS_LOG_FILE="/tmp/lxs_cloudpanel.log"
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
# Configuration
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
INSTALL_DIR="/usr/local/cloudpanel"
|
|
PANEL_PORT=8443
|
|
INSTALLER_URL="https://installer.cloudpanel.io/ce/v2/install.sh"
|
|
INSTALLER_SHA256="19cfa702e7936a79e47812ff57d9859175ea902c62a68b2c15ccd1ebaf36caeb"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
# Helper Functions
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
is_installed() {
|
|
[ -d "$INSTALL_DIR" ] || command -v clpctl &> /dev/null || [ -f "/usr/local/bin/clpctl" ]
|
|
}
|
|
|
|
check_requirements() {
|
|
echo -e "${WHITE}Checking System Requirements...${NC}"
|
|
|
|
# Check root access
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo -e "${RED}[✗] This script must be run as root${NC}"
|
|
return 1
|
|
fi
|
|
echo -e "${GREEN}[✓] Running as root${NC}"
|
|
|
|
local cpu_cores=$(nproc)
|
|
[ $cpu_cores -lt 1 ] && echo -e "${RED}[✗] Insufficient CPU cores (minimum: 1)${NC}" && return 1
|
|
echo -e "${GREEN}[✓] CPU cores: $cpu_cores${NC}"
|
|
|
|
local total_mem_gb=$(($(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024 / 1024))
|
|
if [ $total_mem_gb -lt 1 ]; then
|
|
echo -e "${RED}[✗] Insufficient RAM: ${total_mem_gb}GB (minimum: 1GB)${NC}"
|
|
return 1
|
|
elif [ $total_mem_gb -lt 2 ]; then
|
|
echo -e "${YELLOW}[!] Warning: 2GB RAM is recommended (found: ${total_mem_gb}GB)${NC}"
|
|
else
|
|
echo -e "${GREEN}[✓] Memory: ${total_mem_gb}GB${NC}"
|
|
fi
|
|
|
|
local available_gb=$(($(df / | awk 'NR==2 {print $4}') / 1024 / 1024))
|
|
if [ $available_gb -lt 10 ]; then
|
|
echo -e "${RED}[✗] Insufficient disk space: ${available_gb}GB (minimum: 10GB)${NC}"
|
|
return 1
|
|
elif [ $available_gb -lt 20 ]; then
|
|
echo -e "${YELLOW}[!] Warning: 20GB free space is recommended (found: ${available_gb}GB)${NC}"
|
|
else
|
|
echo -e "${GREEN}[✓] Disk space: ${available_gb}GB available${NC}"
|
|
fi
|
|
|
|
local arch=$(uname -m)
|
|
if [[ "$arch" != "x86_64" && "$arch" != "aarch64" ]]; then
|
|
echo -e "${RED}[✗] Unsupported architecture: $arch${NC}"
|
|
return 1
|
|
fi
|
|
echo -e "${GREEN}[✓] Architecture: $arch${NC}"
|
|
|
|
# Check OS - CloudPanel supports Ubuntu 24.04, 22.04, Debian 12, 11
|
|
if [ -f /etc/os-release ]; then
|
|
. /etc/os-release
|
|
case "$ID" in
|
|
ubuntu)
|
|
if [[ "$VERSION_ID" == "24.04" || "$VERSION_ID" == "22.04" ]]; then
|
|
echo -e "${GREEN}[✓] OS: $PRETTY_NAME${NC}"
|
|
else
|
|
echo -e "${YELLOW}[!] Warning: Ubuntu version $VERSION_ID may not be officially supported${NC}"
|
|
echo -e "${GRAY} Supported: Ubuntu 24.04 LTS, Ubuntu 22.04 LTS${NC}"
|
|
fi
|
|
;;
|
|
debian)
|
|
if [[ "$VERSION_ID" == "12" || "$VERSION_ID" == "11" ]]; then
|
|
echo -e "${GREEN}[✓] OS: $PRETTY_NAME${NC}"
|
|
else
|
|
echo -e "${YELLOW}[!] Warning: Debian version $VERSION_ID may not be officially supported${NC}"
|
|
echo -e "${GRAY} Supported: Debian 12 LTS, Debian 11 LTS${NC}"
|
|
fi
|
|
;;
|
|
*)
|
|
echo -e "${RED}[✗] Unsupported OS: $PRETTY_NAME${NC}"
|
|
echo -e "${GRAY} Supported: Ubuntu 24.04/22.04, Debian 12/11${NC}"
|
|
return 1
|
|
;;
|
|
esac
|
|
else
|
|
echo -e "${YELLOW}[!] Warning: Cannot detect OS version${NC}"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
get_clpctl_path() {
|
|
local max_attempts=30
|
|
local attempt=0
|
|
local clpctl_path=""
|
|
|
|
while [ $attempt -lt $max_attempts ]; do
|
|
if command -v clpctl &> /dev/null; then
|
|
clpctl_path="clpctl"
|
|
break
|
|
elif [ -f "/usr/local/bin/clpctl" ]; then
|
|
clpctl_path="/usr/local/bin/clpctl"
|
|
break
|
|
fi
|
|
|
|
attempt=$((attempt + 1))
|
|
sleep 2
|
|
done
|
|
|
|
echo "$clpctl_path"
|
|
}
|
|
|
|
configure_cloudpanel_basic_auth() {
|
|
echo ""
|
|
echo -e "${WHITE}${BOLD}Configuring CloudPanel Basic Auth...${NC}\n"
|
|
|
|
# Wait for clpctl to be available
|
|
echo -e "${PURPLE}[*] Waiting for CloudPanel CLI to be ready...${NC}"
|
|
local clpctl_path=$(get_clpctl_path)
|
|
|
|
if [ -z "$clpctl_path" ]; then
|
|
echo -e "${YELLOW}[!] Warning: CloudPanel CLI not found, skipping Basic Auth configuration${NC}"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "${GREEN}[✓] CloudPanel CLI is ready${NC}"
|
|
echo ""
|
|
|
|
# Generate random credentials (global variables for display later)
|
|
BASIC_AUTH_USERNAME=$(generate_password 8)
|
|
BASIC_AUTH_PASSWORD=$(generate_password 20)
|
|
|
|
echo -e "${PURPLE}[*] Enabling Basic Auth...${NC}"
|
|
|
|
# Enable Basic Auth
|
|
if $clpctl_path cloudpanel:enable:basic-auth --userName="$BASIC_AUTH_USERNAME" --password="$BASIC_AUTH_PASSWORD" >> /tmp/lxs_cloudpanel.log 2>&1; then
|
|
echo -e "${GREEN}[✓] Basic Auth enabled successfully${NC}"
|
|
echo ""
|
|
return 0
|
|
else
|
|
echo -e "${YELLOW}[!] Warning: Failed to enable Basic Auth${NC}"
|
|
echo -e "${GRAY} You can enable it manually later with:${NC}"
|
|
echo -e "${GRAY} clpctl cloudpanel:enable:basic-auth --userName=USERNAME --password='PASSWORD'${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
create_cloudpanel_admin() {
|
|
echo ""
|
|
echo -e "${WHITE}${BOLD}Creating CloudPanel Admin Account...${NC}\n"
|
|
|
|
# Wait for clpctl to be available
|
|
echo -e "${PURPLE}[*] Waiting for CloudPanel CLI to be ready...${NC}"
|
|
local clpctl_path=$(get_clpctl_path)
|
|
|
|
if [ -z "$clpctl_path" ]; then
|
|
echo -e "${YELLOW}[!] Warning: CloudPanel CLI not found, skipping admin account creation${NC}"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "${GREEN}[✓] CloudPanel CLI is ready${NC}"
|
|
echo ""
|
|
|
|
# Ask for admin email
|
|
echo -e "${CYAN}Admin Email (ex. admin@example.com):${NC}"
|
|
read -r ADMIN_EMAIL
|
|
while [ -z "$ADMIN_EMAIL" ]; do
|
|
echo -e "${RED}Email is required!${NC}"
|
|
read -r ADMIN_EMAIL
|
|
done
|
|
echo ""
|
|
|
|
# Generate random credentials (global variables for display later)
|
|
ADMIN_USERNAME=$(generate_password 8 | tr '[:upper:]' '[:lower:]')
|
|
ADMIN_PASSWORD=$(generate_password 20)
|
|
|
|
echo -e "${PURPLE}[*] Creating admin account...${NC}"
|
|
|
|
# Create admin user
|
|
if $clpctl_path user:add --userName="$ADMIN_USERNAME" --email="$ADMIN_EMAIL" --firstName="Admin" --lastName="User" --password="$ADMIN_PASSWORD" --role="admin" --timezone="UTC" --status="1" >> /tmp/lxs_cloudpanel.log 2>&1; then
|
|
echo -e "${GREEN}[✓] Admin account created successfully${NC}"
|
|
echo ""
|
|
return 0
|
|
else
|
|
echo -e "${YELLOW}[!] Warning: Failed to create admin account${NC}"
|
|
echo -e "${GRAY} You can create it manually later with:${NC}"
|
|
echo -e "${GRAY} clpctl user:add --userName=$ADMIN_USERNAME --email=$ADMIN_EMAIL --firstName='Admin' --lastName='User' --password='$ADMIN_PASSWORD' --role='admin' --timezone='UTC' --status='1'${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
# Installation Functions
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
install_cloudpanel() {
|
|
local start_time=$(date +%s)
|
|
|
|
apt_noninteractive
|
|
|
|
echo -e "${WHITE}${BOLD}CLOUDPANEL INSTALLATION${NC}\n"
|
|
|
|
if is_installed; then
|
|
echo -e "${YELLOW}CloudPanel is already installed!${NC}"
|
|
return 0
|
|
fi
|
|
|
|
check_requirements || return 1
|
|
echo ""
|
|
|
|
wait_for_apt || return 1
|
|
echo ""
|
|
|
|
# Update system and install required packages
|
|
echo -e "${PURPLE}[*] Updating system packages...${NC}"
|
|
if ! run_spinner "Updating system" apt update && apt -y upgrade && apt -y install curl wget sudo; then
|
|
echo -e "${RED}[✗] Failed to update system packages${NC}"
|
|
return 1
|
|
fi
|
|
echo ""
|
|
|
|
# Set database engine to MySQL 8.4
|
|
DB_ENGINE="MYSQL_8.4"
|
|
echo -e "${GREEN}[✓] Database engine: MySQL 8.4${NC}"
|
|
echo ""
|
|
|
|
# Download installer
|
|
echo -e "${PURPLE}[*] Downloading CloudPanel installer...${NC}"
|
|
if ! curl -sS "$INSTALLER_URL" -o /tmp/cloudpanel_install.sh; then
|
|
echo -e "${RED}[✗] Failed to download installer${NC}"
|
|
return 1
|
|
fi
|
|
|
|
# Verify SHA256 checksum
|
|
echo -e "${PURPLE}[*] Verifying installer checksum...${NC}"
|
|
local calculated_sha=$(sha256sum /tmp/cloudpanel_install.sh | awk '{print $1}')
|
|
if [ "$calculated_sha" != "$INSTALLER_SHA256" ]; then
|
|
echo -e "${RED}[✗] Installer checksum verification failed!${NC}"
|
|
echo -e "${GRAY} Expected: $INSTALLER_SHA256${NC}"
|
|
echo -e "${GRAY} Got: $calculated_sha${NC}"
|
|
rm -f /tmp/cloudpanel_install.sh
|
|
return 1
|
|
fi
|
|
echo -e "${GREEN}[✓] Installer checksum verified${NC}"
|
|
echo ""
|
|
|
|
# Get server IP
|
|
local server_ip=$(get_public_ip)
|
|
|
|
echo -e "${WHITE}Starting Installation...${NC}"
|
|
echo -e "${GRAY}[i] This may take 10-20 minutes...${NC}"
|
|
echo ""
|
|
|
|
# Execute installation
|
|
show_separator
|
|
DB_ENGINE=$DB_ENGINE bash /tmp/cloudpanel_install.sh
|
|
local install_exit_code=$?
|
|
show_separator
|
|
|
|
# Clean up installer
|
|
rm -f /tmp/cloudpanel_install.sh
|
|
|
|
if [ $install_exit_code -ne 0 ]; then
|
|
echo ""
|
|
echo -e "${RED}[✗] Installation failed!${NC}"
|
|
echo -e "${GRAY}Check /tmp/lxs_cloudpanel.log for details${NC}"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "${GREEN}[✓] Installation completed${NC}"
|
|
|
|
ufw_allow 20/tcp "CloudPanel FTP data"
|
|
ufw_allow 21/tcp "CloudPanel FTP"
|
|
ufw_allow 25/tcp "CloudPanel SMTP"
|
|
ufw_allow 53/tcp "CloudPanel DNS (TCP)"
|
|
ufw_allow 53/udp "CloudPanel DNS (UDP)"
|
|
ufw_allow 80/tcp "CloudPanel HTTP"
|
|
ufw_allow 443/tcp "CloudPanel HTTPS"
|
|
ufw_allow 465/tcp "CloudPanel SMTPS"
|
|
ufw_allow 587/tcp "CloudPanel submission"
|
|
ufw_allow 993/tcp "CloudPanel IMAPS"
|
|
ufw_allow 995/tcp "CloudPanel POP3S"
|
|
ufw_allow "${PANEL_PORT}/tcp" "CloudPanel admin"
|
|
|
|
# Configure Basic Auth
|
|
configure_cloudpanel_basic_auth
|
|
|
|
# Create admin account
|
|
create_cloudpanel_admin
|
|
|
|
local duration=$(( $(date +%s) - start_time ))
|
|
local minutes=$((duration / 60))
|
|
local seconds=$((duration % 60))
|
|
|
|
echo ""
|
|
echo -e "${GREEN}${BOLD}Installation Completed Successfully!${NC}"
|
|
echo -e "${GRAY}Installation time: ${minutes}m ${seconds}s${NC}"
|
|
echo ""
|
|
show_separator
|
|
echo -e "${WHITE}${BOLD}CLOUDPANEL ACCESS INFORMATION${NC}"
|
|
show_separator
|
|
echo -e "${WHITE}Panel URL: ${GREEN}${BOLD}https://$server_ip:$PANEL_PORT${NC}"
|
|
|
|
# Display Basic Auth credentials if configured
|
|
if [ -n "$BASIC_AUTH_USERNAME" ] && [ -n "$BASIC_AUTH_PASSWORD" ]; then
|
|
echo ""
|
|
echo -e "${WHITE}${BOLD}BASIC AUTH CREDENTIALS${NC}"
|
|
echo -e "${WHITE}Username: ${GREEN}${BOLD}$BASIC_AUTH_USERNAME${NC}"
|
|
echo -e "${WHITE}Password: ${GREEN}${BOLD}$BASIC_AUTH_PASSWORD${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}[!] Basic Auth is enabled. You will need these credentials to access CloudPanel.${NC}"
|
|
fi
|
|
|
|
# Display Admin account credentials if created
|
|
if [ -n "$ADMIN_USERNAME" ] && [ -n "$ADMIN_PASSWORD" ]; then
|
|
echo ""
|
|
echo -e "${WHITE}${BOLD}ADMIN ACCOUNT CREDENTIALS${NC}"
|
|
echo -e "${WHITE}Email: ${GREEN}${BOLD}$ADMIN_EMAIL${NC}"
|
|
echo -e "${WHITE}Username: ${GREEN}${BOLD}$ADMIN_USERNAME${NC}"
|
|
echo -e "${WHITE}Password: ${GREEN}${BOLD}$ADMIN_PASSWORD${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${RED}${BOLD}IMPORTANT SECURITY STEPS:${NC}"
|
|
echo -e "${YELLOW}1. Access CloudPanel immediately via the URL above${NC}"
|
|
echo -e "${YELLOW}2. Ignore the self-signed certificate warning${NC}"
|
|
echo -e "${YELLOW}3. Click 'Advanced' and 'Proceed' to continue${NC}"
|
|
if [ -n "$BASIC_AUTH_USERNAME" ] && [ -n "$BASIC_AUTH_PASSWORD" ]; then
|
|
echo -e "${YELLOW}4. Enter Basic Auth credentials when prompted${NC}"
|
|
fi
|
|
if [ -n "$ADMIN_USERNAME" ] && [ -n "$ADMIN_PASSWORD" ]; then
|
|
echo -e "${YELLOW}$([ -n "$BASIC_AUTH_USERNAME" ] && echo "5" || echo "4"). Login with admin credentials above${NC}"
|
|
fi
|
|
echo ""
|
|
echo -e "${RED}${BOLD}REQUIRED FIREWALL PORTS:${NC}"
|
|
echo -e "${GRAY}20, 21, 22, 25, 53, 80, 443, 465, 587, 993, 995, $PANEL_PORT${NC}"
|
|
show_separator
|
|
|
|
if [ -n "$BASIC_AUTH_USERNAME" ] && [ -n "$BASIC_AUTH_PASSWORD" ]; then
|
|
echo ""
|
|
echo -e "${RED}${BOLD}IMPORTANT:${NC} ${YELLOW}Save Basic Auth credentials securely!${NC}"
|
|
fi
|
|
if [ -n "$ADMIN_USERNAME" ] && [ -n "$ADMIN_PASSWORD" ]; then
|
|
echo ""
|
|
echo -e "${RED}${BOLD}IMPORTANT:${NC} ${YELLOW}Save admin credentials securely!${NC}"
|
|
fi
|
|
}
|
|
|
|
update_cloudpanel() {
|
|
echo -e "${WHITE}${BOLD}CLOUDPANEL UPDATE${NC}\n"
|
|
|
|
apt_noninteractive
|
|
|
|
if ! is_installed; then
|
|
echo -e "${RED}CloudPanel is not installed!${NC}"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "${PURPLE}[*] Updating CloudPanel...${NC}"
|
|
|
|
# Use clpctl if available
|
|
if command -v clpctl &> /dev/null; then
|
|
clpctl update
|
|
elif [ -f "/usr/local/bin/clpctl" ]; then
|
|
/usr/local/bin/clpctl update
|
|
else
|
|
echo -e "${YELLOW}[!] CloudPanel CLI not found, downloading latest installer...${NC}"
|
|
curl -sS "$INSTALLER_URL" -o /tmp/cloudpanel_update.sh
|
|
if echo "$INSTALLER_SHA256 /tmp/cloudpanel_update.sh" | sha256sum -c --quiet; then
|
|
bash /tmp/cloudpanel_update.sh
|
|
rm -f /tmp/cloudpanel_update.sh
|
|
else
|
|
echo -e "${RED}[✗] Failed to verify update installer${NC}"
|
|
rm -f /tmp/cloudpanel_update.sh
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
[ $? -eq 0 ] && echo -e "${GREEN}[✓] Update completed${NC}" || echo -e "${RED}[✗] Update failed${NC}"
|
|
}
|
|
|
|
show_status() {
|
|
echo -e "${WHITE}${BOLD}CLOUDPANEL STATUS${NC}\n"
|
|
|
|
if ! is_installed; then
|
|
echo -e "${RED}CloudPanel is not installed!${NC}"
|
|
return 1
|
|
fi
|
|
|
|
# Check CloudPanel service
|
|
if systemctl is-active --quiet cloudpanel; then
|
|
echo -e "${GREEN}[✓] CloudPanel service is running${NC}"
|
|
else
|
|
echo -e "${YELLOW}[!] CloudPanel service status unknown${NC}"
|
|
fi
|
|
|
|
# Check web server
|
|
if systemctl is-active --quiet nginx || systemctl is-active --quiet apache2; then
|
|
echo -e "${GREEN}[✓] Web server is running${NC}"
|
|
else
|
|
echo -e "${YELLOW}[!] Web server status unknown${NC}"
|
|
fi
|
|
|
|
# Check database
|
|
if systemctl is-active --quiet mysql || systemctl is-active --quiet mariadb; then
|
|
echo -e "${GREEN}[✓] Database service is running${NC}"
|
|
else
|
|
echo -e "${YELLOW}[!] Database service status unknown${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
local server_ip=$(get_public_ip)
|
|
echo -e "${CYAN}Panel URL: ${BOLD}https://$server_ip:$PANEL_PORT${NC}"
|
|
|
|
# Show clpctl status if available
|
|
if command -v clpctl &> /dev/null || [ -f "/usr/local/bin/clpctl" ]; then
|
|
echo ""
|
|
echo -e "${WHITE}CloudPanel CLI available${NC}"
|
|
echo -e "${GRAY}Run 'clpctl' for available commands${NC}"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
install_rclone() {
|
|
echo -e "${PURPLE}[*] Checking rclone installation...${NC}"
|
|
|
|
if command -v rclone &> /dev/null; then
|
|
local rclone_version=$(rclone version | head -n 1 | awk '{print $2}')
|
|
echo -e "${GREEN}[✓] rclone is already installed (version: $rclone_version)${NC}"
|
|
return 0
|
|
fi
|
|
|
|
echo -e "${PURPLE}[*] Installing rclone...${NC}"
|
|
|
|
wait_for_apt || return 1
|
|
|
|
# Install rclone using official method
|
|
if ! run_spinner "Installing rclone" curl https://rclone.org/install.sh | bash; then
|
|
echo -e "${RED}[✗] Failed to install rclone${NC}"
|
|
return 1
|
|
fi
|
|
|
|
if command -v rclone &> /dev/null; then
|
|
local rclone_version=$(rclone version | head -n 1 | awk '{print $2}')
|
|
echo -e "${GREEN}[✓] rclone installed successfully (version: $rclone_version)${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}[✗] rclone installation failed${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
configure_rclone_backblaze() {
|
|
echo ""
|
|
echo -e "${WHITE}${BOLD}Configure rclone for Backblaze B2${NC}\n"
|
|
|
|
# Check if CloudPanel is installed
|
|
if ! is_installed; then
|
|
echo -e "${YELLOW}[!] CloudPanel is not installed. Please install CloudPanel first.${NC}"
|
|
return 1
|
|
fi
|
|
|
|
# Install rclone if needed
|
|
if ! install_rclone; then
|
|
return 1
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${CYAN}Backblaze B2 Configuration${NC}"
|
|
echo -e "${GRAY}You need to provide your Backblaze B2 credentials.${NC}"
|
|
echo -e "${GRAY}To get your credentials:${NC}"
|
|
echo -e "${GRAY} 1. Log in to your Backblaze account${NC}"
|
|
echo -e "${GRAY} 2. Go to 'App Keys' section${NC}"
|
|
echo -e "${GRAY} 3. Create a new Application Key (or use an existing one)${NC}"
|
|
echo -e "${GRAY} 4. Copy the 'Key ID' (Account ID) and 'Application Key'${NC}"
|
|
echo ""
|
|
|
|
# Ask for Account ID (Key ID)
|
|
echo -e "${CYAN}Account ID (Key ID):${NC}"
|
|
read -r B2_ACCOUNT_ID
|
|
while [ -z "$B2_ACCOUNT_ID" ]; do
|
|
echo -e "${RED}Account ID is required!${NC}"
|
|
read -r B2_ACCOUNT_ID
|
|
done
|
|
|
|
# Ask for Application Key
|
|
echo ""
|
|
echo -e "${CYAN}Application Key:${NC}"
|
|
read -rs B2_APPLICATION_KEY
|
|
while [ -z "$B2_APPLICATION_KEY" ]; do
|
|
echo -e "${RED}Application Key is required!${NC}"
|
|
read -rs B2_APPLICATION_KEY
|
|
done
|
|
echo ""
|
|
|
|
# Ask for bucket name (optional, for information)
|
|
echo ""
|
|
echo -e "${CYAN}Bucket Name (optional, for reference):${NC}"
|
|
read -r B2_BUCKET_NAME
|
|
|
|
echo ""
|
|
echo -e "${PURPLE}[*] Configuring rclone...${NC}"
|
|
|
|
# Create rclone config directory if it doesn't exist
|
|
# Use root's home directory since script runs as root
|
|
local rclone_config_dir="/root/.config/rclone"
|
|
mkdir -p "$rclone_config_dir"
|
|
|
|
# Configure rclone non-interactively
|
|
# The remote name must be "remote" for CloudPanel to recognize it
|
|
local rclone_config_file="$rclone_config_dir/rclone.conf"
|
|
|
|
# Check if remote already exists
|
|
if [ -f "$rclone_config_file" ] && grep -q "^\[remote\]" "$rclone_config_file" 2>/dev/null; then
|
|
echo -e "${YELLOW}[!] A remote named 'remote' already exists.${NC}"
|
|
echo -e "${CYAN}Do you want to overwrite it? (y/n):${NC}"
|
|
read -r overwrite_choice
|
|
if [[ ! "$overwrite_choice" =~ ^[Yy]$ ]]; then
|
|
echo -e "${YELLOW}[!] Configuration cancelled${NC}"
|
|
return 1
|
|
fi
|
|
|
|
# Create a temporary file without the [remote] section
|
|
local temp_config=$(mktemp)
|
|
local in_remote_section=false
|
|
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
if [[ "$line" =~ ^\[remote\] ]]; then
|
|
in_remote_section=true
|
|
continue
|
|
elif [[ "$line" =~ ^\[ ]] && [ "$in_remote_section" = true ]; then
|
|
in_remote_section=false
|
|
echo "$line" >> "$temp_config"
|
|
elif [ "$in_remote_section" = false ]; then
|
|
echo "$line" >> "$temp_config"
|
|
fi
|
|
done < "$rclone_config_file"
|
|
|
|
mv "$temp_config" "$rclone_config_file"
|
|
fi
|
|
|
|
# Add new remote configuration
|
|
cat >> "$rclone_config_file" << EOF
|
|
|
|
[remote]
|
|
type = b2
|
|
account = $B2_ACCOUNT_ID
|
|
key = $B2_APPLICATION_KEY
|
|
hard_delete = false
|
|
EOF
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}[✓] rclone configured successfully${NC}"
|
|
else
|
|
echo -e "${RED}[✗] Failed to configure rclone${NC}"
|
|
return 1
|
|
fi
|
|
|
|
# Test the configuration
|
|
echo ""
|
|
echo -e "${PURPLE}[*] Testing rclone configuration...${NC}"
|
|
if rclone lsd remote: > /dev/null 2>&1; then
|
|
echo -e "${GREEN}[✓] rclone connection test successful${NC}"
|
|
|
|
# List buckets if available
|
|
echo ""
|
|
echo -e "${CYAN}Available buckets:${NC}"
|
|
rclone lsd remote: 2>/dev/null | awk '{print " - " $5}' || echo -e "${GRAY} (Unable to list buckets)${NC}"
|
|
else
|
|
echo -e "${YELLOW}[!] Warning: Could not test connection to Backblaze B2${NC}"
|
|
echo -e "${GRAY} Please verify your credentials are correct${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
show_separator
|
|
echo -e "${WHITE}${BOLD}Configuration Complete!${NC}"
|
|
show_separator
|
|
echo ""
|
|
echo -e "${GREEN}[✓] rclone has been configured with Backblaze B2${NC}"
|
|
echo ""
|
|
echo -e "${WHITE}${BOLD}Next Steps:${NC}"
|
|
echo -e "${CYAN}1. Access CloudPanel at: ${BOLD}https://$(get_public_ip):$PANEL_PORT${NC}"
|
|
echo -e "${CYAN}2. Go to Settings > Backups${NC}"
|
|
echo -e "${CYAN}3. Select 'Custom Rclone Config' as the storage provider${NC}"
|
|
if [ -n "$B2_BUCKET_NAME" ]; then
|
|
echo -e "${CYAN}4. In 'Storage Directory', enter: ${BOLD}$B2_BUCKET_NAME${NC}"
|
|
else
|
|
echo -e "${CYAN}4. In 'Storage Directory', enter your Backblaze B2 bucket name${NC}"
|
|
fi
|
|
echo -e "${CYAN}5. Configure backup frequency and retention as needed${NC}"
|
|
echo -e "${CYAN}6. Save the configuration${NC}"
|
|
echo ""
|
|
echo -e "${GRAY}[i] Note: The rclone remote is named 'remote' as required by CloudPanel${NC}"
|
|
show_separator
|
|
}
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
# Main Menu
|
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
show_menu() {
|
|
clear
|
|
echo -e "${WHITE}${BOLD}CLOUDPANEL MANAGEMENT${NC}\n"
|
|
echo -e " ${GREEN}[1]${NC} Install CloudPanel"
|
|
echo -e " ${YELLOW}[2]${NC} Update CloudPanel"
|
|
echo -e " ${CYAN}[3]${NC} View Status"
|
|
echo -e " ${PURPLE}[4]${NC} Configure rclone for Backblaze B2"
|
|
echo -e " ${RED}[0]${NC} Back to main menu"
|
|
echo ""
|
|
echo -n "Choice [0-4]: "
|
|
}
|
|
|
|
main() {
|
|
while true; do
|
|
show_menu
|
|
read -r choice
|
|
echo ""
|
|
|
|
case $choice in
|
|
1) install_cloudpanel ;;
|
|
2) update_cloudpanel ;;
|
|
3) show_status ;;
|
|
4) configure_rclone_backblaze ;;
|
|
0) return 75 ;;
|
|
*) echo -e "${RED}Invalid option${NC}" ;;
|
|
esac
|
|
|
|
echo ""
|
|
read -p "Press Enter to continue..."
|
|
done
|
|
}
|
|
|
|
main
|
|
|