diff --git a/misc/core.func b/misc/core.func index 642d3131c..df35d1e8c 100644 --- a/misc/core.func +++ b/misc/core.func @@ -10,80 +10,80 @@ _CORE_FUNC_LOADED=1 load_functions() { - [[ -n "${__FUNCTIONS_LOADED:-}" ]] && return - __FUNCTIONS_LOADED=1 - color - formatting - icons - default_vars - set_std_mode - # add more + [[ -n "${__FUNCTIONS_LOADED:-}" ]] && return + __FUNCTIONS_LOADED=1 + color + formatting + icons + default_vars + set_std_mode + # add more } # ------------------------------------------------------------------------------ # Sets ANSI color codes used for styled terminal output. # ------------------------------------------------------------------------------ color() { - YW=$(echo "\033[33m") - YWB=$'\e[93m' - BL=$(echo "\033[36m") - RD=$(echo "\033[01;31m") - BGN=$(echo "\033[4;92m") - GN=$(echo "\033[1;92m") - DGN=$(echo "\033[32m") - CL=$(echo "\033[m") + YW=$(echo "\033[33m") + YWB=$'\e[93m' + BL=$(echo "\033[36m") + RD=$(echo "\033[01;31m") + BGN=$(echo "\033[4;92m") + GN=$(echo "\033[1;92m") + DGN=$(echo "\033[32m") + CL=$(echo "\033[m") } # Special for spinner and colorized output via printf color_spinner() { - CS_YW=$'\033[33m' - CS_YWB=$'\033[93m' - CS_CL=$'\033[m' + CS_YW=$'\033[33m' + CS_YWB=$'\033[93m' + CS_CL=$'\033[m' } # ------------------------------------------------------------------------------ # Defines formatting helpers like tab, bold, and line reset sequences. # ------------------------------------------------------------------------------ formatting() { - BFR="\\r\\033[K" - BOLD=$(echo "\033[1m") - HOLD=" " - TAB=" " - TAB3=" " + BFR="\\r\\033[K" + BOLD=$(echo "\033[1m") + HOLD=" " + TAB=" " + TAB3=" " } # ------------------------------------------------------------------------------ # Sets symbolic icons used throughout user feedback and prompts. # ------------------------------------------------------------------------------ icons() { - CM="${TAB}✔️${TAB}" - CROSS="${TAB}✖️${TAB}" - DNSOK="✔️ " - DNSFAIL="${TAB}✖️${TAB}" - INFO="${TAB}💡${TAB}${CL}" - OS="${TAB}🖥️${TAB}${CL}" - OSVERSION="${TAB}🌟${TAB}${CL}" - CONTAINERTYPE="${TAB}📦${TAB}${CL}" - DISKSIZE="${TAB}💾${TAB}${CL}" - CPUCORE="${TAB}🧠${TAB}${CL}" - RAMSIZE="${TAB}🛠️${TAB}${CL}" - SEARCH="${TAB}🔍${TAB}${CL}" - VERBOSE_CROPPED="🔍${TAB}" - VERIFYPW="${TAB}🔐${TAB}${CL}" - CONTAINERID="${TAB}🆔${TAB}${CL}" - HOSTNAME="${TAB}🏠${TAB}${CL}" - BRIDGE="${TAB}🌉${TAB}${CL}" - NETWORK="${TAB}📡${TAB}${CL}" - GATEWAY="${TAB}🌐${TAB}${CL}" - DISABLEIPV6="${TAB}🚫${TAB}${CL}" - DEFAULT="${TAB}⚙️${TAB}${CL}" - MACADDRESS="${TAB}🔗${TAB}${CL}" - VLANTAG="${TAB}🏷️${TAB}${CL}" - ROOTSSH="${TAB}🔑${TAB}${CL}" - CREATING="${TAB}🚀${TAB}${CL}" - ADVANCED="${TAB}🧩${TAB}${CL}" - FUSE="${TAB}🗂️${TAB}${CL}" - HOURGLASS="${TAB}⏳${TAB}" + CM="${TAB}✔️${TAB}" + CROSS="${TAB}✖️${TAB}" + DNSOK="✔️ " + DNSFAIL="${TAB}✖️${TAB}" + INFO="${TAB}💡${TAB}${CL}" + OS="${TAB}🖥️${TAB}${CL}" + OSVERSION="${TAB}🌟${TAB}${CL}" + CONTAINERTYPE="${TAB}📦${TAB}${CL}" + DISKSIZE="${TAB}💾${TAB}${CL}" + CPUCORE="${TAB}🧠${TAB}${CL}" + RAMSIZE="${TAB}🛠️${TAB}${CL}" + SEARCH="${TAB}🔍${TAB}${CL}" + VERBOSE_CROPPED="🔍${TAB}" + VERIFYPW="${TAB}🔐${TAB}${CL}" + CONTAINERID="${TAB}🆔${TAB}${CL}" + HOSTNAME="${TAB}🏠${TAB}${CL}" + BRIDGE="${TAB}🌉${TAB}${CL}" + NETWORK="${TAB}📡${TAB}${CL}" + GATEWAY="${TAB}🌐${TAB}${CL}" + DISABLEIPV6="${TAB}🚫${TAB}${CL}" + DEFAULT="${TAB}⚙️${TAB}${CL}" + MACADDRESS="${TAB}🔗${TAB}${CL}" + VLANTAG="${TAB}🏷️${TAB}${CL}" + ROOTSSH="${TAB}🔑${TAB}${CL}" + CREATING="${TAB}🚀${TAB}${CL}" + ADVANCED="${TAB}🧩${TAB}${CL}" + FUSE="${TAB}🗂️${TAB}${CL}" + HOURGLASS="${TAB}⏳${TAB}" } @@ -91,132 +91,132 @@ icons() { # Sets default retry and wait variables used for system actions. # ------------------------------------------------------------------------------ default_vars() { - RETRY_NUM=10 - RETRY_EVERY=3 - i=$RETRY_NUM - #[[ "${VAR_OS:-}" == "unknown" ]] + RETRY_NUM=10 + RETRY_EVERY=3 + i=$RETRY_NUM + #[[ "${VAR_OS:-}" == "unknown" ]] } # ------------------------------------------------------------------------------ # Sets default verbose mode for script and os execution. # ------------------------------------------------------------------------------ set_std_mode() { - if [ "${VERBOSE:-no}" = "yes" ]; then - STD="" - else - STD="silent" - fi + if [ "${VERBOSE:-no}" = "yes" ]; then + STD="" + else + STD="silent" + fi } SILENT_LOGFILE="/tmp/install-$(date +%Y%m%d_%H%M%S)_${SESSION_ID:-$(date +%s)}.log" silent() { - local cmd="$*" - local caller_line="${BASH_LINENO[0]:-unknown}" + local cmd="$*" + local caller_line="${BASH_LINENO[0]:-unknown}" - set +Eeuo pipefail - trap - ERR + set +Eeuo pipefail + trap - ERR - "$@" >>"$SILENT_LOGFILE" 2>&1 - local rc=$? + "$@" >>"$SILENT_LOGFILE" 2>&1 + local rc=$? - set -Eeuo pipefail - trap 'error_handler' ERR + set -Eeuo pipefail + trap 'error_handler' ERR - if [[ $rc -ne 0 ]]; then - # Source explain_exit_code if needed - if ! declare -f explain_exit_code >/dev/null 2>&1; then - source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func) - fi - - local explanation - explanation="$(explain_exit_code "$rc")" - - printf "\e[?25h" - msg_error "in line ${caller_line}: exit code ${rc} (${explanation})" - msg_custom "→" "${YWB}" "${cmd}" - - if [[ -s "$SILENT_LOGFILE" ]]; then - local log_lines=$(wc -l <"$SILENT_LOGFILE") - echo "--- Last 10 lines of silent log ---" - tail -n 10 "$SILENT_LOGFILE" - echo "-----------------------------------" - - # Show how to view full log if there are more lines - if [[ $log_lines -gt 10 ]]; then - msg_custom "📋" "${YW}" "View full log (${log_lines} lines): /tmp/install-*_${SESSION_ID:-*}.log" - fi - fi - - exit "$rc" + if [[ $rc -ne 0 ]]; then + # Source explain_exit_code if needed + if ! declare -f explain_exit_code >/dev/null 2>&1; then + source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func) fi + + local explanation + explanation="$(explain_exit_code "$rc")" + + printf "\e[?25h" + msg_error "in line ${caller_line}: exit code ${rc} (${explanation})" + msg_custom "→" "${YWB}" "${cmd}" + + if [[ -s "$SILENT_LOGFILE" ]]; then + local log_lines=$(wc -l <"$SILENT_LOGFILE") + echo "--- Last 10 lines of silent log ---" + tail -n 10 "$SILENT_LOGFILE" + echo "-----------------------------------" + + # Show how to view full log if there are more lines + if [[ $log_lines -gt 10 ]]; then + msg_custom "📋" "${YW}" "View full log (${log_lines} lines): /tmp/install-*_${SESSION_ID:-*}.log" + fi + fi + + exit "$rc" + fi } # Check if the shell is using bash shell_check() { - if [[ "$(ps -p $$ -o comm=)" != "bash" ]]; then - clear - msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(ps -p $$ -o comm=)" != "bash" ]]; then + clear + msg_error "Your default shell is currently not set to Bash. To use these scripts, please switch to the Bash shell." + echo -e "\nExiting..." + sleep 2 + exit + fi } # Run as root only root_check() { - if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then - clear - msg_error "Please run this script as root." - echo -e "\nExiting..." - sleep 2 - exit - fi + if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then + clear + msg_error "Please run this script as root." + echo -e "\nExiting..." + sleep 2 + exit + fi } # This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported. # Supported: Proxmox VE 8.0.x – 8.9.x and 9.0 (NOT 9.1+) pve_check() { - local PVE_VER - PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" + local PVE_VER + PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" - # Check for Proxmox VE 8.x: allow 8.0–8.9 - if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then - local MINOR="${BASH_REMATCH[1]}" - if ((MINOR < 0 || MINOR > 9)); then - msg_error "This version of Proxmox VE is not supported." - msg_error "Supported: Proxmox VE version 8.0 – 8.9" - exit 1 - fi - return 0 + # Check for Proxmox VE 8.x: allow 8.0–8.9 + if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then + local MINOR="${BASH_REMATCH[1]}" + if ((MINOR < 0 || MINOR > 9)); then + msg_error "This version of Proxmox VE is not supported." + msg_error "Supported: Proxmox VE version 8.0 – 8.9" + exit 1 fi + return 0 + fi - # Check for Proxmox VE 9.x: allow ONLY 9.0 - if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then - local MINOR="${BASH_REMATCH[1]}" - if ((MINOR != 0)); then - msg_error "This version of Proxmox VE is not yet supported." - msg_error "Supported: Proxmox VE version 9.0" - exit 1 - fi - return 0 + # Check for Proxmox VE 9.x: allow ONLY 9.0 + if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then + local MINOR="${BASH_REMATCH[1]}" + if ((MINOR != 0)); then + msg_error "This version of Proxmox VE is not yet supported." + msg_error "Supported: Proxmox VE version 9.0" + exit 1 fi + return 0 + fi - # All other unsupported versions - msg_error "This version of Proxmox VE is not supported." - msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0" - exit 1 + # All other unsupported versions + msg_error "This version of Proxmox VE is not supported." + msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0" + exit 1 } # This function checks the system architecture and exits if it's not "amd64". arch_check() { - if [ "$(dpkg --print-architecture)" != "amd64" ]; then - echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" - echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" - echo -e "Exiting..." - sleep 2 - exit - fi + if [ "$(dpkg --print-architecture)" != "amd64" ]; then + echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n" + echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n" + echo -e "Exiting..." + sleep 2 + exit + fi } # ------------------------------------------------------------------------------ @@ -227,280 +227,280 @@ arch_check() { # - User can choose to continue or abort # ------------------------------------------------------------------------------ ssh_check() { - if [ -n "$SSH_CLIENT" ]; then - local client_ip=$(awk '{print $1}' <<<"$SSH_CLIENT") - local host_ip=$(hostname -I | awk '{print $1}') + if [ -n "$SSH_CLIENT" ]; then + local client_ip=$(awk '{print $1}' <<<"$SSH_CLIENT") + local host_ip=$(hostname -I | awk '{print $1}') - # Check if connection is local (Proxmox WebUI or same machine) - # - localhost (127.0.0.1, ::1) - # - same IP as host - # - local network range (10.x, 172.16-31.x, 192.168.x) - if [[ "$client_ip" == "127.0.0.1" || "$client_ip" == "::1" || "$client_ip" == "$host_ip" ]]; then - return - fi - - # Check if client is in same local network (optional, safer approach) - local host_subnet=$(echo "$host_ip" | cut -d. -f1-3) - local client_subnet=$(echo "$client_ip" | cut -d. -f1-3) - if [[ "$host_subnet" == "$client_subnet" ]]; then - return - fi - - # Only warn for truly external connections - msg_warn "Running via external SSH (client: $client_ip)." - msg_warn "For better stability, consider using the Proxmox Shell (Console) instead." + # Check if connection is local (Proxmox WebUI or same machine) + # - localhost (127.0.0.1, ::1) + # - same IP as host + # - local network range (10.x, 172.16-31.x, 192.168.x) + if [[ "$client_ip" == "127.0.0.1" || "$client_ip" == "::1" || "$client_ip" == "$host_ip" ]]; then + return fi + + # Check if client is in same local network (optional, safer approach) + local host_subnet=$(echo "$host_ip" | cut -d. -f1-3) + local client_subnet=$(echo "$client_ip" | cut -d. -f1-3) + if [[ "$host_subnet" == "$client_subnet" ]]; then + return + fi + + # Only warn for truly external connections + msg_warn "Running via external SSH (client: $client_ip)." + msg_warn "For better stability, consider using the Proxmox Shell (Console) instead." + fi } # Function to download & save header files get_header() { - local app_name=$(echo "${APP,,}" | tr -d ' ') - local app_type=${APP_TYPE:-ct} # Default zu 'ct' falls nicht gesetzt - local header_url="https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/${app_type}/headers/${app_name}" - local local_header_path="/usr/local/community-scripts/headers/${app_type}/${app_name}" + local app_name=$(echo "${APP,,}" | tr -d ' ') + local app_type=${APP_TYPE:-ct} # Default zu 'ct' falls nicht gesetzt + local header_url="https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/${app_type}/headers/${app_name}" + local local_header_path="/usr/local/community-scripts/headers/${app_type}/${app_name}" - mkdir -p "$(dirname "$local_header_path")" + mkdir -p "$(dirname "$local_header_path")" - if [ ! -s "$local_header_path" ]; then - if ! curl -fsSL "$header_url" -o "$local_header_path"; then - return 1 - fi + if [ ! -s "$local_header_path" ]; then + if ! curl -fsSL "$header_url" -o "$local_header_path"; then + return 1 fi + fi - cat "$local_header_path" 2>/dev/null || true + cat "$local_header_path" 2>/dev/null || true } header_info() { - local app_name=$(echo "${APP,,}" | tr -d ' ') - local header_content + local app_name=$(echo "${APP,,}" | tr -d ' ') + local header_content - header_content=$(get_header "$app_name") || header_content="" + header_content=$(get_header "$app_name") || header_content="" - clear - local term_width - term_width=$(tput cols 2>/dev/null || echo 120) + clear + local term_width + term_width=$(tput cols 2>/dev/null || echo 120) - if [ -n "$header_content" ]; then - echo "$header_content" - fi + if [ -n "$header_content" ]; then + echo "$header_content" + fi } ensure_tput() { - if ! command -v tput >/dev/null 2>&1; then - if grep -qi 'alpine' /etc/os-release; then - apk add --no-cache ncurses >/dev/null 2>&1 - elif command -v apt-get >/dev/null 2>&1; then - apt-get update -qq >/dev/null - apt-get install -y -qq ncurses-bin >/dev/null 2>&1 - fi + if ! command -v tput >/dev/null 2>&1; then + if grep -qi 'alpine' /etc/os-release; then + apk add --no-cache ncurses >/dev/null 2>&1 + elif command -v apt-get >/dev/null 2>&1; then + apt-get update -qq >/dev/null + apt-get install -y -qq ncurses-bin >/dev/null 2>&1 fi + fi } is_alpine() { - local os_id="${var_os:-${PCT_OSTYPE:-}}" + local os_id="${var_os:-${PCT_OSTYPE:-}}" - if [[ -z "$os_id" && -f /etc/os-release ]]; then - os_id="$( - . /etc/os-release 2>/dev/null - echo "${ID:-}" - )" - fi + if [[ -z "$os_id" && -f /etc/os-release ]]; then + os_id="$( + . /etc/os-release 2>/dev/null + echo "${ID:-}" + )" + fi - [[ "$os_id" == "alpine" ]] + [[ "$os_id" == "alpine" ]] } is_verbose_mode() { - local verbose="${VERBOSE:-${var_verbose:-no}}" - local tty_status - if [[ -t 2 ]]; then - tty_status="interactive" - else - tty_status="not-a-tty" - fi - [[ "$verbose" != "no" || ! -t 2 ]] + local verbose="${VERBOSE:-${var_verbose:-no}}" + local tty_status + if [[ -t 2 ]]; then + tty_status="interactive" + else + tty_status="not-a-tty" + fi + [[ "$verbose" != "no" || ! -t 2 ]] } fatal() { - msg_error "$1" - kill -INT $$ + msg_error "$1" + kill -INT $$ } spinner() { - local chars=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) - local i=0 - while true; do - local index=$((i++ % ${#chars[@]})) - printf "\r\033[2K%s %b" "${CS_YWB}${chars[$index]}${CS_CL}" "${CS_YWB}${SPINNER_MSG:-}${CS_CL}" - sleep 0.1 - done + local chars=(⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏) + local i=0 + while true; do + local index=$((i++ % ${#chars[@]})) + printf "\r\033[2K%s %b" "${CS_YWB}${chars[$index]}${CS_CL}" "${CS_YWB}${SPINNER_MSG:-}${CS_CL}" + sleep 0.1 + done } clear_line() { - tput cr 2>/dev/null || echo -en "\r" - tput el 2>/dev/null || echo -en "\033[K" + tput cr 2>/dev/null || echo -en "\r" + tput el 2>/dev/null || echo -en "\033[K" } stop_spinner() { - local pid="${SPINNER_PID:-}" - [[ -z "$pid" && -f /tmp/.spinner.pid ]] && pid=$(/dev/null; then - sleep 0.05 - kill -9 "$pid" 2>/dev/null || true - wait "$pid" 2>/dev/null || true - fi - rm -f /tmp/.spinner.pid + if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]]; then + if kill "$pid" 2>/dev/null; then + sleep 0.05 + kill -9 "$pid" 2>/dev/null || true + wait "$pid" 2>/dev/null || true fi + rm -f /tmp/.spinner.pid + fi - unset SPINNER_PID SPINNER_MSG - stty sane 2>/dev/null || true + unset SPINNER_PID SPINNER_MSG + stty sane 2>/dev/null || true } msg_info() { - local msg="$1" - [[ -z "$msg" ]] && return + local msg="$1" + [[ -z "$msg" ]] && return - if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then - declare -gA MSG_INFO_SHOWN=() - fi - [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return - MSG_INFO_SHOWN["$msg"]=1 + if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then + declare -gA MSG_INFO_SHOWN=() + fi + [[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return + MSG_INFO_SHOWN["$msg"]=1 - stop_spinner - SPINNER_MSG="$msg" + stop_spinner + SPINNER_MSG="$msg" - if is_verbose_mode || is_alpine; then - local HOURGLASS="${TAB}⏳${TAB}" - printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2 - return - fi + if is_verbose_mode || is_alpine; then + local HOURGLASS="${TAB}⏳${TAB}" + printf "\r\e[2K%s %b" "$HOURGLASS" "${YW}${msg}${CL}" >&2 + return + fi - color_spinner - spinner & - SPINNER_PID=$! - echo "$SPINNER_PID" >/tmp/.spinner.pid - disown "$SPINNER_PID" 2>/dev/null || true + color_spinner + spinner & + SPINNER_PID=$! + echo "$SPINNER_PID" >/tmp/.spinner.pid + disown "$SPINNER_PID" 2>/dev/null || true } msg_ok() { - local msg="$1" - [[ -z "$msg" ]] && return - stop_spinner - clear_line - printf "%s %b\n" "$CM" "${GN}${msg}${CL}" >&2 - unset MSG_INFO_SHOWN["$msg"] + local msg="$1" + [[ -z "$msg" ]] && return + stop_spinner + clear_line + echo -e "$CM ${GN}${msg}${CL}" + unset MSG_INFO_SHOWN["$msg"] } msg_error() { - stop_spinner - local msg="$1" - echo -e "${BFR:-} ${CROSS:-✖️} ${RD}${msg}${CL}" + stop_spinner + local msg="$1" + echo -e "${BFR:-}${CROSS:-✖️} ${RD}${msg}${CL}" >&2 } msg_warn() { - stop_spinner - local msg="$1" - echo -e "${BFR:-} ${INFO:-ℹ️} ${YWB}${msg}${CL}" + stop_spinner + local msg="$1" + echo -e "${BFR:-}${INFO:-ℹ️} ${YWB}${msg}${CL}" >&2 } msg_custom() { - local symbol="${1:-"[*]"}" - local color="${2:-"\e[36m"}" - local msg="${3:-}" - [[ -z "$msg" ]] && return - stop_spinner - echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" + local symbol="${1:-"[*]"}" + local color="${2:-"\e[36m"}" + local msg="${3:-}" + [[ -z "$msg" ]] && return + stop_spinner + echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}" } function msg_debug() { - if [[ "${var_full_verbose:-0}" == "1" ]]; then - [[ "${var_verbose:-0}" != "1" ]] && var_verbose=1 - echo -e "${YWB}[$(date '+%F %T')] [DEBUG]${CL} $*" - fi + if [[ "${var_full_verbose:-0}" == "1" ]]; then + [[ "${var_verbose:-0}" != "1" ]] && var_verbose=1 + echo -e "${YWB}[$(date '+%F %T')] [DEBUG]${CL} $*" + fi } cleanup_lxc() { - msg_info "Cleaning up" - if is_alpine; then - $STD apk cache clean || true - rm -rf /var/cache/apk/* - else - $STD apt -y autoremove || true - $STD apt -y autoclean || true - $STD apt -y clean || true - fi + msg_info "Cleaning up" + if is_alpine; then + $STD apk cache clean || true + rm -rf /var/cache/apk/* + else + $STD apt -y autoremove || true + $STD apt -y autoclean || true + $STD apt -y clean || true + fi - rm -rf /tmp/* /var/tmp/* + rm -rf /tmp/* /var/tmp/* - # Remove temp files created by mktemp/tempfile - find /tmp /var/tmp -type f -name 'tmp*' -delete 2>/dev/null || true - find /tmp /var/tmp -type f -name 'tempfile*' -delete 2>/dev/null || true + # Remove temp files created by mktemp/tempfile + find /tmp /var/tmp -type f -name 'tmp*' -delete 2>/dev/null || true + find /tmp /var/tmp -type f -name 'tempfile*' -delete 2>/dev/null || true - find /var/log -type f -exec truncate -s 0 {} + + find /var/log -type f -exec truncate -s 0 {} + - # Python pip - if command -v pip &>/dev/null; then pip cache purge || true; fi - # Python uv - if command -v uv &>/dev/null; then uv cache clear || true; fi - # Node.js npm - if command -v npm &>/dev/null; then npm cache clean --force || true; fi - # Node.js yarn - if command -v yarn &>/dev/null; then yarn cache clean || true; fi - # Node.js pnpm - if command -v pnpm &>/dev/null; then pnpm store prune || true; fi - # Go - if command -v go &>/dev/null; then go clean -cache -modcache || true; fi - # Rust cargo - if command -v cargo &>/dev/null; then cargo clean || true; fi - # Ruby gem - if command -v gem &>/dev/null; then gem cleanup || true; fi - # Composer (PHP) - if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi + # Python pip + if command -v pip &>/dev/null; then pip cache purge || true; fi + # Python uv + if command -v uv &>/dev/null; then uv cache clear || true; fi + # Node.js npm + if command -v npm &>/dev/null; then npm cache clean --force || true; fi + # Node.js yarn + if command -v yarn &>/dev/null; then yarn cache clean || true; fi + # Node.js pnpm + if command -v pnpm &>/dev/null; then pnpm store prune || true; fi + # Go + if command -v go &>/dev/null; then go clean -cache -modcache || true; fi + # Rust cargo + if command -v cargo &>/dev/null; then cargo clean || true; fi + # Ruby gem + if command -v gem &>/dev/null; then gem cleanup || true; fi + # Composer (PHP) + if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi - if command -v journalctl &>/dev/null; then - $STD journalctl --rotate - $STD journalctl --vacuum-time=10m - fi - msg_ok "Cleaned" + if command -v journalctl &>/dev/null; then + $STD journalctl --rotate + $STD journalctl --vacuum-time=10m + fi + msg_ok "Cleaned" } check_or_create_swap() { - msg_info "Checking for active swap" + msg_info "Checking for active swap" - if swapon --noheadings --show | grep -q 'swap'; then - msg_ok "Swap is active" - return 0 - fi + if swapon --noheadings --show | grep -q 'swap'; then + msg_ok "Swap is active" + return 0 + fi - msg_error "No active swap detected" + msg_error "No active swap detected" - read -p "Do you want to create a swap file? [y/N]: " create_swap - create_swap="${create_swap,,}" # to lowercase + read -p "Do you want to create a swap file? [y/N]: " create_swap + create_swap="${create_swap,,}" # to lowercase - if [[ "$create_swap" != "y" && "$create_swap" != "yes" ]]; then - msg_info "Skipping swap file creation" - return 1 - fi + if [[ "$create_swap" != "y" && "$create_swap" != "yes" ]]; then + msg_info "Skipping swap file creation" + return 1 + fi - read -p "Enter swap size in MB (e.g., 2048 for 2GB): " swap_size_mb - if ! [[ "$swap_size_mb" =~ ^[0-9]+$ ]]; then - msg_error "Invalid size input. Aborting." - return 1 - fi + read -p "Enter swap size in MB (e.g., 2048 for 2GB): " swap_size_mb + if ! [[ "$swap_size_mb" =~ ^[0-9]+$ ]]; then + msg_error "Invalid size input. Aborting." + return 1 + fi - local swap_file="/swapfile" + local swap_file="/swapfile" - msg_info "Creating ${swap_size_mb}MB swap file at $swap_file" - if dd if=/dev/zero of="$swap_file" bs=1M count="$swap_size_mb" status=progress && - chmod 600 "$swap_file" && - mkswap "$swap_file" && - swapon "$swap_file"; then - msg_ok "Swap file created and activated successfully" - else - msg_error "Failed to create or activate swap" - return 1 - fi + msg_info "Creating ${swap_size_mb}MB swap file at $swap_file" + if dd if=/dev/zero of="$swap_file" bs=1M count="$swap_size_mb" status=progress && + chmod 600 "$swap_file" && + mkswap "$swap_file" && + swapon "$swap_file"; then + msg_ok "Swap file created and activated successfully" + else + msg_error "Failed to create or activate swap" + return 1 + fi } trap 'stop_spinner' EXIT INT TERM