#!/bin/bash # Usage: curl -sSL https://git.ivanch.me/ivanch/server-scripts/raw/branch/main/scripts-download.sh | bash set -euo pipefail #============================================================================== # CONFIGURATION #============================================================================== # Color definitions for output formatting readonly RED='\033[1;31m' readonly GREEN='\033[1;32m' readonly NC='\033[0m' readonly LIGHT_BLUE='\033[1;34m' readonly LIGHT_RED='\033[1;31m' readonly LIGHT_GREEN='\033[1;32m' readonly GREY='\033[1;30m' readonly YELLOW='\033[1;33m' # Configuration readonly FILES_URL="https://git.ivanch.me/ivanch/server-scripts/raw/branch/main" readonly REQUIRED_PACKAGES=("zip" "unzip" "curl") readonly REQUIRED_COMMANDS=("zip" "unzip" "sha256sum" "curl" "crontab") readonly AVAILABLE_SCRIPTS=("clean.sh" "backup.sh" "docker-updater.sh") # Format: [script_name]="cron_schedule" declare -A CRONTAB_SCHEDULES=( ["clean.sh"]="0 23 * * *" # Daily at 11 PM ["backup.sh"]="30 23 * * 1,5" # Monday and Friday at 11:30 PM ["docker-updater.sh"]="0 3 */4 * *" # Every 4 days at 3 AM ) #============================================================================== # UTILITY FUNCTIONS #============================================================================== # Print formatted log messages log_info() { echo -e "${GREY}[i] $1${NC}"; } log_success() { echo -e "${GREEN}[✓] $1${NC}"; } log_warning() { echo -e "${YELLOW}[!] $1${NC}"; } log_error() { echo -e "${RED}[x] $1${NC}" >&2; } log_step() { echo -e "${LIGHT_BLUE}[i] $1${NC}"; } # Exit with error message die() { log_error "$1" exit 1 } # Check if a command exists command_exists() { command -v "$1" >/dev/null 2>&1 } # Check if a process is running process_running() { pgrep "$1" >/dev/null 2>&1 } #============================================================================== # MAIN FUNCTIONS #============================================================================== # Detect the operating system detect_operating_system() { if command_exists apk; then echo "Alpine" elif command_exists apt; then echo "Debian" else die "Unsupported operating system. This script supports Alpine and Debian-based systems only." fi } # Check for missing packages get_missing_packages() { local missing=() # Check each required command and map to package names if ! command_exists "zip"; then missing+=("zip") fi if ! command_exists "unzip"; then missing+=("unzip") fi if ! command_exists "curl"; then missing+=("curl") fi # sha256sum is part of coreutils (usually pre-installed) # crontab is part of cron package, but we'll check for cron service later # Only print if there are missing packages if [[ ${#missing[@]} -gt 0 ]]; then printf '%s\n' "${missing[@]}" fi } # Install packages based on the detected OS install_packages() { local os="$1" shift local packages=("$@") if [[ ${#packages[@]} -eq 0 ]]; then log_info "No packages to install" return 0 fi log_info "Installing required packages: ${packages[*]}" log_info "Debug: Installing ${#packages[@]} packages on $os" case "$os" in "Alpine") log_info "Updating APK package index..." apk update >/dev/null || die "Failed to update APK package index" log_info "Installing packages via APK..." apk add --no-cache "${packages[@]}" >/dev/null || die "Failed to install packages via APK" ;; "Debian") log_info "Ensuring /var/cache/apt/archives/partial exists..." mkdir -p /var/cache/apt/archives/partial || die "Failed to create /var/cache/apt/archives/partial" log_info "Updating APT package index..." apt-get update -y >/dev/null || die "Failed to update APT package index" log_info "Installing packages via APT..." apt-get install -y "${packages[@]}" >/dev/null || die "Failed to install packages via APT" ;; *) log_error "Debug info - OS variable content: '$os'" log_error "Debug info - OS variable length: ${#os}" die "Unknown operating system: '$os'" ;; esac } # Verify all required packages are available verify_packages() { log_info "Verifying package installation..." local missing_packages readarray -t missing_packages < <(get_missing_packages) if [[ ${#missing_packages[@]} -gt 0 ]]; then log_error "Failed to install required packages: ${missing_packages[*]}" die "Please install the missing packages manually and try again" fi log_success "All required packages are available" } # Check if crontab service is running check_crontab_service() { log_info "Checking crontab service status..." if ! process_running "cron"; then die "Crontab service is not running. Please start the cron service first." fi log_success "Crontab service is running" } # Prompt user to select scripts for installation select_scripts() { local selected=() echo >&2 # Send to stderr so it doesn't get captured echo -e "${GREY}[i] Available scripts for download and installation:${NC}" >&2 echo >&2 for script in "${AVAILABLE_SCRIPTS[@]}"; do local schedule="${CRONTAB_SCHEDULES[$script]:-"0 0 * * *"}" echo -e " ${LIGHT_BLUE}$script${NC} - Schedule: ${GREY}$schedule${NC}" >&2 done echo >&2 echo -e "${GREY}[i] Select scripts to download and install:${NC}" >&2 for script in "${AVAILABLE_SCRIPTS[@]}"; do read -p "Install $script? [Y/n]: " choice &2 exit 1 fi # Only output the selected scripts to stdout printf '%s\n' "${selected[@]}" } # Verify server connectivity for selected scripts verify_server_connectivity() { local scripts=("$@") log_info "Verifying server connectivity..." for script in "${scripts[@]}"; do local url="$FILES_URL/$script" if ! curl -s --head "$url" | head -n 1 | grep -E "HTTP/[12] [23].." >/dev/null; then die "Script '$script' not found on server: $url" fi done log_success "Server connectivity verified" } # Download selected scripts download_scripts() { local scripts=("$@") log_info "Downloading ${#scripts[@]} script(s)..." for script in "${scripts[@]}"; do local url="$FILES_URL/$script" log_step "Downloading $script..." if ! curl -s -o "./$script" "$url"; then die "Failed to download $script from $url" fi # Set executable permissions chmod +x "./$script" || die "Failed to set executable permissions for $script" done log_success "All scripts downloaded and configured" } # Setup crontab entries for selected scripts setup_crontab() { local scripts=("$@") local current_workdir current_workdir=$(pwd) log_info "Setting up crontab entries..." for script in "${scripts[@]}"; do local schedule="${CRONTAB_SCHEDULES[$script]:-"0 0 * * *"}" local log_file="/tmp/${script%.*}.log" local cron_entry="$schedule $current_workdir/$script > $log_file 2>&1" log_step "Configuring crontab for $script (Schedule: $schedule)..." # Remove existing crontab entry for this script if crontab -l 2>/dev/null | grep -q "$script"; then log_step "Removing existing crontab entry for $script..." crontab -l 2>/dev/null | grep -v "$script" | crontab - || die "Failed to remove existing crontab entry" fi # Add new crontab entry (crontab -l 2>/dev/null; echo "$cron_entry") | crontab - || die "Failed to add crontab entry for $script" # Verify the entry was added if ! crontab -l 2>/dev/null | grep -q "$script"; then die "Failed to verify crontab entry for $script" fi log_success "Crontab configured for $script" done log_success "All crontab entries configured successfully" } #============================================================================== # MAIN EXECUTION #============================================================================== main() { log_step "Starting Server Scripts Downloader" echo # System detection and validation log_info "Detecting operating system..." local detected_os detected_os=$(detect_operating_system) detected_os=$(echo "$detected_os" | tr -d '\n\r' | xargs) # Clean any whitespace/newlines log_success "Detected $detected_os Linux" # Package management local missing_packages readarray -t missing_packages < <(get_missing_packages) # Filter out empty strings local filtered_packages=() for pkg in "${missing_packages[@]}"; do if [[ -n "$pkg" ]]; then filtered_packages+=("$pkg") fi done missing_packages=("${filtered_packages[@]}") # Debug output log_info "Debug: Found ${#missing_packages[@]} missing packages" for i in "${!missing_packages[@]}"; do log_info "Debug: Missing package $((i+1)): '${missing_packages[i]}'" done if [[ ${#missing_packages[@]} -gt 0 ]]; then log_warning "Missing packages detected: ${missing_packages[*]}" install_packages "$detected_os" "${missing_packages[@]}" else log_success "All required packages are already installed" fi verify_packages check_crontab_service # Script selection and installation local selected_scripts readarray -t selected_scripts < <(select_scripts) log_info "Selected scripts: ${selected_scripts[*]}" verify_server_connectivity "${selected_scripts[@]}" download_scripts "${selected_scripts[@]}" setup_crontab "${selected_scripts[@]}" echo log_success "Installation completed successfully!" log_info "Scripts have been downloaded to: $(pwd)" log_info "Crontab entries have been configured. Use 'crontab -l' to view them." log_info "Log files will be created in /tmp/ directory." } # Execute main function main "$@"