Files
Linux-Server-Management-Too…/lib/common-functions.sh
T

331 lines
9.0 KiB
Bash
Executable File

#!/bin/bash
#############################################################################
# Common Functions Library
# Shared utilities for all Server Management Toolkit modules
#############################################################################
#############################################################################
# Professional Color Scheme
# - Uses ONLY basic ANSI colors (works on ANY terminal)
# - High contrast for readability
# - No emojis (terminal-agnostic)
# - Industry standard: Red=error, Yellow=warning, Green=success, Blue=info
#
# To disable colors completely: export TOOLKIT_NO_COLOR=1
#############################################################################
# Detect if colors should be disabled or adjusted
if [ "${TOOLKIT_NO_COLOR:-0}" = "1" ] || [ ! -t 1 ]; then
# No color mode (monochrome terminals, piped output, etc.)
export RED=''
export YELLOW=''
export GREEN=''
export BLUE=''
export CYAN=''
export WHITE=''
export BOLD=''
export DIM=''
export NC=''
elif [ "${TOOLKIT_HIGH_CONTRAST:-0}" = "1" ]; then
# High contrast mode - BOLD colors for light backgrounds
# These work well on BOTH light and dark backgrounds
export RED='\033[1;31m' # Errors, critical alerts (BOLD RED)
export YELLOW='\033[1;33m' # Warnings, caution (BOLD YELLOW)
export GREEN='\033[1;32m' # Success, completed (BOLD GREEN)
export BLUE='\033[1;34m' # Info, neutral status (BOLD BLUE)
export CYAN='\033[1;36m' # Headers, sections (BOLD CYAN)
export WHITE='\033[1;37m' # Emphasis, highlights (BOLD WHITE)
export BOLD='\033[1m' # Important text
export DIM='\033[2m' # Secondary/less important
export NC='\033[0m' # Reset/No Color
else
# Normal color mode (default - optimized for dark backgrounds)
export RED='\033[0;31m' # Errors, critical alerts
export YELLOW='\033[0;33m' # Warnings, caution
export GREEN='\033[0;32m' # Success, completed
export BLUE='\033[0;34m' # Info, neutral status
export CYAN='\033[0;36m' # Headers, sections
export WHITE='\033[1;37m' # Emphasis, highlights
export BOLD='\033[1m' # Important text
export DIM='\033[2m' # Secondary/less important
export NC='\033[0m' # Reset/No Color
fi
# Print functions - professional, no emojis
print_banner() {
local title="$1"
echo ""
echo "==============================================================================="
echo " $title"
echo "==============================================================================="
echo ""
}
print_section() {
local title="$1"
echo ""
echo -e "${BOLD}$title${NC}"
echo "───────────────────────────────────────────────────────────────────────────────"
}
print_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[OK]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_critical() {
echo -e "${RED}${BOLD}[CRITICAL]${NC} $1"
}
print_alert() {
echo -e "${RED}[ALERT]${NC} $1"
}
print_header() {
echo -e "${CYAN}${BOLD}$1${NC}"
}
#############################################################################
# Color Echo Helper - ALWAYS use this when printing colored text
#
# PROBLEM: Using 'echo' without -e flag doesn't interpret escape sequences
# BAD: echo " ${BOLD}1${NC} - Menu option" → Shows: \033[1m1\033[0m
# GOOD: cecho " ${BOLD}1${NC} - Menu option" → Shows: 1 (bold)
#
# USAGE:
# cecho "Normal text with ${RED}colored${NC} parts"
# cecho "${BOLD}Bold text${NC}"
#
# WHY: Prevents common bug where color codes show as literal text
#############################################################################
cecho() {
echo -e "$@"
}
# Wait for user input
press_enter() {
echo ""
read -p "Press Enter to continue..." _
}
# Show banner (wrapper for print_banner for compatibility)
show_banner() {
if [ -n "$1" ]; then
print_banner "$1"
else
print_banner "Server Toolkit"
fi
}
# Progress indicator - terminal safe (no fancy characters)
show_progress() {
local current=$1
local total=$2
local message="$3"
# Avoid division by zero
if [ "$total" -eq 0 ]; then
printf "\r[INFO] Progress: [####################] 100%% - %s" "$message"
return
fi
local percent=$((current * 100 / total))
local bars=$((percent / 5)) # 20 chars wide
printf "\r[INFO] Progress: ["
printf "%${bars}s" | tr ' ' '#'
printf "%$((20-bars))s" | tr ' ' '-'
printf "] %3d%% - %s" "$percent" "$message"
}
# Finish progress line
finish_progress() {
echo ""
}
# Display terminal info (for debugging)
show_terminal_info() {
echo ""
echo "Terminal Information:"
echo " TERM: ${TERM:-not set}"
echo " Colors: $([ -t 1 ] && echo "enabled" || echo "disabled (not a tty)")"
echo " TOOLKIT_NO_COLOR: ${TOOLKIT_NO_COLOR:-0}"
echo " Columns: ${COLUMNS:-$(tput cols 2>/dev/null || echo "unknown")}"
echo ""
}
# Create temporary session directory
create_temp_session() {
export SESSION_ID=$$
export TEMP_SESSION_DIR=$(mktemp -d -t server-toolkit.XXXXXX)
# Cleanup on exit
trap '[ -n "$TEMP_SESSION_DIR" ] && rm -rf "$TEMP_SESSION_DIR" 2>/dev/null' EXIT INT TERM
}
# Ask user for confirmation
confirm() {
local prompt="$1"
local default="${2:-N}"
if [[ "$default" == "Y" ]]; then
read -p "$prompt [Y/n]: " -n 1 -r
else
read -p "$prompt [y/N]: " -n 1 -r
fi
echo
if [[ "$default" == "Y" ]]; then
[[ ! $REPLY =~ ^[Nn]$ ]]
else
[[ $REPLY =~ ^[Yy]$ ]]
fi
}
# Format bytes to human readable
format_bytes() {
local bytes=$1
if [ -z "$bytes" ] || [ "$bytes" -eq 0 ]; then
echo "0 B"
return
fi
local units=("B" "KB" "MB" "GB" "TB")
local unit=0
local size=$bytes
while [ "${size:-0}" -gt 1024 ] && [ "${unit:-0}" -lt 4 ]; do
size=$((size / 1024))
unit=$((unit + 1))
done
echo "${size} ${units[$unit]}"
}
# Format seconds to human readable time
format_duration() {
[ -z "$1" ] && return 1
local seconds=$1
local days=$((seconds / 86400))
local hours=$(((seconds % 86400) / 3600))
local minutes=$(((seconds % 3600) / 60))
local secs=$((seconds % 60))
if [ "${days:-0}" -gt 0 ]; then
echo "${days}d ${hours}h ${minutes}m"
elif [ "${hours:-0}" -gt 0 ]; then
echo "${hours}h ${minutes}m ${secs}s"
elif [ "${minutes:-0}" -gt 0 ]; then
echo "${minutes}m ${secs}s"
else
echo "${secs}s"
fi
}
# Check if command exists
command_exists() {
[ -z "$1" ] && return 1
command -v "$1" >/dev/null 2>&1
}
# Check if running as root
require_root() {
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root"
return 1
fi
}
# Safe file append (creates backup)
safe_append() {
local file="$1"
local content="$2"
if [ -f "$file" ]; then
cp "$file" "${file}.bak.$(date +%s)"
fi
echo "$content" >> "$file"
}
# Log message to file
log_message() {
local level="$1"
local message="$2"
local log_file="${3:-/var/log/server-toolkit.log}"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message" >> "$log_file"
}
# Get script directory (works even when sourced)
get_script_dir() {
local source="${BASH_SOURCE[0]}"
while [ -h "$source" ]; do
local dir="$(cd -P "$(dirname "$source")" && pwd)"
source="$(readlink "$source")"
[[ $source != /* ]] && source="$dir/$source"
done
echo "$(cd -P "$(dirname "$source")" && pwd)"
}
# Detect toolkit base directory
get_toolkit_dir() {
local script_dir=$(get_script_dir)
echo "$(cd "$script_dir/.." && pwd)"
}
# Export toolkit directories
export TOOLKIT_BASE_DIR=$(get_toolkit_dir)
export TOOLKIT_LIB_DIR="${TOOLKIT_BASE_DIR}/lib"
export TOOLKIT_MODULES_DIR="${TOOLKIT_BASE_DIR}/modules"
export TOOLKIT_CONFIG_DIR="${TOOLKIT_BASE_DIR}/config"
# Load configuration if exists
load_config() {
local config_file="${TOOLKIT_CONFIG_DIR}/settings.conf"
if [ -f "$config_file" ]; then
source "$config_file"
fi
}
# Export all functions for use in subshells and sourced scripts
export -f print_banner
export -f print_section
export -f print_info
export -f print_success
export -f print_warning
export -f print_error
export -f print_critical
export -f print_alert
export -f print_header
export -f cecho
export -f press_enter
export -f show_banner
export -f show_progress
export -f finish_progress
export -f show_terminal_info
export -f create_temp_session
export -f confirm
export -f format_bytes
export -f format_duration
export -f command_exists
export -f require_root
export -f safe_append
export -f log_message
export -f get_script_dir
export -f get_toolkit_dir
export -f load_config