feat: initial project scaffold for lxs multi-tool
- add main entrypoint with interactive menu and CLI dispatcher (lxs.sh) - add shared helpers library with colors, loggers, and spinner (lib/common.sh) - add app installers for coolify, pterodactyl, uptime-kuma, cloudpanel, and proxmox (apps/) - add system tools for monitoring, benchmarking, and hardening (tools/) - add VERSION file (0.1.0) as single source of truth for releases - add MIT LICENSE - expand README with usage, project structure, and release workflow
This commit is contained in:
Executable
+637
@@ -0,0 +1,637 @@
|
||||
#!/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}"
|
||||
|
||||
# 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 0 ;;
|
||||
*) echo -e "${RED}Invalid option${NC}" ;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
Reference in New Issue
Block a user