Merge from VE

This commit is contained in:
CanbiZ (MickLesk) 2026-01-27 09:29:22 +01:00
parent 7f68c58181
commit 6f9a1965f9
3 changed files with 193 additions and 237 deletions

View File

@ -1,6 +1,6 @@
# Copyright (c) 2021-2026 community-scripts ORG
# Author: michelroegl-brunner
# License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE
# License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/LICENSE
# ==============================================================================
# API.FUNC - TELEMETRY & DIAGNOSTICS API
@ -36,14 +36,16 @@
#
# - Maps numeric exit codes to human-readable error descriptions
# - Supports:
# * Generic/Shell errors (1, 2, 126, 127, 128, 130, 137, 139, 143)
# * Package manager errors (APT, DPKG: 100, 101, 255)
# * Node.js/npm errors (243-249, 254)
# * Python/pip/uv errors (210-212)
# * PostgreSQL errors (231-234)
# * MySQL/MariaDB errors (241-244)
# * MongoDB errors (251-254)
# * Generic/Shell errors (1, 2, 124, 126-130, 134, 137, 139, 141, 143)
# * curl/wget errors (6, 7, 22, 28, 35)
# * Package manager errors (APT, DPKG: 100-102, 255)
# * Systemd/Service errors (150-154)
# * Python/pip/uv errors (160-162)
# * PostgreSQL errors (170-173)
# * MySQL/MariaDB errors (180-183)
# * MongoDB errors (190-193)
# * Proxmox custom codes (200-231)
# * Node.js/npm errors (243, 245-249)
# - Returns description string for given exit code
# - Shared function with error_handler.func for consistency
# ------------------------------------------------------------------------------
@ -53,73 +55,98 @@ explain_exit_code() {
# --- Generic / Shell ---
1) echo "General error / Operation not permitted" ;;
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
126) echo "Command invoked cannot execute (permission problem?)" ;;
127) echo "Command not found" ;;
128) echo "Invalid argument to exit" ;;
130) echo "Terminated by Ctrl+C (SIGINT)" ;;
137) echo "Killed (SIGKILL / Out of memory?)" ;;
139) echo "Segmentation fault (core dumped)" ;;
143) echo "Terminated (SIGTERM)" ;;
# --- curl / wget errors (commonly seen in downloads) ---
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
# --- Package manager / APT / DPKG ---
100) echo "APT: Package manager error (broken packages / dependency problems)" ;;
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
255) echo "DPKG: Fatal internal error" ;;
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
# --- Node.js / npm / pnpm / yarn ---
# --- Common shell/system errors ---
124) echo "Command timed out (timeout command)" ;;
126) echo "Command invoked cannot execute (permission problem?)" ;;
127) echo "Command not found" ;;
128) echo "Invalid argument to exit" ;;
130) echo "Terminated by Ctrl+C (SIGINT)" ;;
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
137) echo "Killed (SIGKILL / Out of memory?)" ;;
139) echo "Segmentation fault (core dumped)" ;;
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
143) echo "Terminated (SIGTERM)" ;;
# --- Systemd / Service errors (150-154) ---
150) echo "Systemd: Service failed to start" ;;
151) echo "Systemd: Service unit not found" ;;
152) echo "Permission denied (EACCES)" ;;
153) echo "Build/compile failed (make/gcc/cmake)" ;;
154) echo "Node.js: Native addon build failed (node-gyp)" ;;
# --- Python / pip / uv (160-162) ---
160) echo "Python: Virtualenv / uv environment missing or broken" ;;
161) echo "Python: Dependency resolution failed" ;;
162) echo "Python: Installation aborted (permissions or EXTERNALLY-MANAGED)" ;;
# --- PostgreSQL (170-173) ---
170) echo "PostgreSQL: Connection failed (server not running / wrong socket)" ;;
171) echo "PostgreSQL: Authentication failed (bad user/password)" ;;
172) echo "PostgreSQL: Database does not exist" ;;
173) echo "PostgreSQL: Fatal error in query / syntax" ;;
# --- MySQL / MariaDB (180-183) ---
180) echo "MySQL/MariaDB: Connection failed (server not running / wrong socket)" ;;
181) echo "MySQL/MariaDB: Authentication failed (bad user/password)" ;;
182) echo "MySQL/MariaDB: Database does not exist" ;;
183) echo "MySQL/MariaDB: Fatal error in query / syntax" ;;
# --- MongoDB (190-193) ---
190) echo "MongoDB: Connection failed (server not running)" ;;
191) echo "MongoDB: Authentication failed (bad user/password)" ;;
192) echo "MongoDB: Database not found" ;;
193) echo "MongoDB: Fatal query error" ;;
# --- Proxmox Custom Codes (200-231) ---
200) echo "Proxmox: Failed to create lock file" ;;
203) echo "Proxmox: Missing CTID variable" ;;
204) echo "Proxmox: Missing PCT_OSTYPE variable" ;;
205) echo "Proxmox: Invalid CTID (<100)" ;;
206) echo "Proxmox: CTID already in use" ;;
207) echo "Proxmox: Password contains unescaped special characters" ;;
208) echo "Proxmox: Invalid configuration (DNS/MAC/Network format)" ;;
209) echo "Proxmox: Container creation failed" ;;
210) echo "Proxmox: Cluster not quorate" ;;
211) echo "Proxmox: Timeout waiting for template lock" ;;
212) echo "Proxmox: Storage type 'iscsidirect' does not support containers (VMs only)" ;;
213) echo "Proxmox: Storage type does not support 'rootdir' content" ;;
214) echo "Proxmox: Not enough storage space" ;;
215) echo "Proxmox: Container created but not listed (ghost state)" ;;
216) echo "Proxmox: RootFS entry missing in config" ;;
217) echo "Proxmox: Storage not accessible" ;;
218) echo "Proxmox: Template file corrupted or incomplete" ;;
219) echo "Proxmox: CephFS does not support containers - use RBD" ;;
220) echo "Proxmox: Unable to resolve template path" ;;
221) echo "Proxmox: Template file not readable" ;;
222) echo "Proxmox: Template download failed" ;;
223) echo "Proxmox: Template not available after download" ;;
224) echo "Proxmox: PBS storage is for backups only" ;;
225) echo "Proxmox: No template available for OS/Version" ;;
231) echo "Proxmox: LXC stack upgrade failed" ;;
# --- Node.js / npm / pnpm / yarn (243-249) ---
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
245) echo "Node.js: Invalid command-line option" ;;
246) echo "Node.js: Internal JavaScript Parse Error" ;;
247) echo "Node.js: Fatal internal error" ;;
248) echo "Node.js: Invalid C++ addon / N-API failure" ;;
249) echo "Node.js: Inspector error" ;;
254) echo "npm/pnpm/yarn: Unknown fatal error" ;;
249) echo "npm/pnpm/yarn: Unknown fatal error" ;;
# --- Python / pip / uv ---
210) echo "Python: Virtualenv / uv environment missing or broken" ;;
211) echo "Python: Dependency resolution failed" ;;
212) echo "Python: Installation aborted (permissions or EXTERNALLY-MANAGED)" ;;
# --- PostgreSQL ---
231) echo "PostgreSQL: Connection failed (server not running / wrong socket)" ;;
232) echo "PostgreSQL: Authentication failed (bad user/password)" ;;
233) echo "PostgreSQL: Database does not exist" ;;
234) echo "PostgreSQL: Fatal error in query / syntax" ;;
# --- MySQL / MariaDB ---
241) echo "MySQL/MariaDB: Connection failed (server not running / wrong socket)" ;;
242) echo "MySQL/MariaDB: Authentication failed (bad user/password)" ;;
243) echo "MySQL/MariaDB: Database does not exist" ;;
244) echo "MySQL/MariaDB: Fatal error in query / syntax" ;;
# --- MongoDB ---
251) echo "MongoDB: Connection failed (server not running)" ;;
252) echo "MongoDB: Authentication failed (bad user/password)" ;;
253) echo "MongoDB: Database not found" ;;
254) echo "MongoDB: Fatal query error" ;;
# --- Proxmox Custom Codes ---
200) echo "Custom: Failed to create lock file" ;;
203) echo "Custom: Missing CTID variable" ;;
204) echo "Custom: Missing PCT_OSTYPE variable" ;;
205) echo "Custom: Invalid CTID (<100)" ;;
206) echo "Custom: CTID already in use (check 'pct list' and /etc/pve/lxc/)" ;;
207) echo "Custom: Password contains unescaped special characters (-, /, \\, *, etc.)" ;;
208) echo "Custom: Invalid configuration (DNS/MAC/Network format error)" ;;
209) echo "Custom: Container creation failed (check logs for pct create output)" ;;
210) echo "Custom: Cluster not quorate" ;;
211) echo "Custom: Timeout waiting for template lock (concurrent download in progress)" ;;
214) echo "Custom: Not enough storage space" ;;
215) echo "Custom: Container created but not listed (ghost state - check /etc/pve/lxc/)" ;;
216) echo "Custom: RootFS entry missing in config (incomplete creation)" ;;
217) echo "Custom: Storage does not support rootdir (check storage capabilities)" ;;
218) echo "Custom: Template file corrupted or incomplete download (size <1MB or invalid archive)" ;;
220) echo "Custom: Unable to resolve template path" ;;
221) echo "Custom: Template file exists but not readable (check file permissions)" ;;
222) echo "Custom: Template download failed after 3 attempts (network/storage issue)" ;;
223) echo "Custom: Template not available after download (storage sync issue)" ;;
225) echo "Custom: No template available for OS/Version (check 'pveam available')" ;;
231) echo "Custom: LXC stack upgrade/retry failed (outdated pve-container - check https://github.com/community-scripts/ProxmoxVE/discussions/8126)" ;;
# --- DPKG ---
255) echo "DPKG: Fatal internal error" ;;
# --- Default ---
*) echo "Unknown error" ;;

View File

@ -1,8 +1,7 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: tteck (tteckster) | MickLesk | michelroegl-brunner
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/branch/main/LICENSE
# Revision: 1
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/branch/main/LICENSE
# ==============================================================================
# BUILD.FUNC - LXC CONTAINER BUILD & CONFIGURATION
@ -81,109 +80,6 @@ variables() {
fi
}
# -----------------------------------------------------------------------------
# Community-Scripts bootstrap loader
# - Always sources build.func from remote
# - Updates local core files only if build.func changed
# - Local cache: /usr/local/community-scripts/core
# -----------------------------------------------------------------------------
# FUNC_DIR="/usr/local/community-scripts/core"
# mkdir -p "$FUNC_DIR"
# BUILD_URL="https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func"
# BUILD_REV="$FUNC_DIR/build.rev"
# DEVMODE="${DEVMODE:-no}"
# # --- Step 1: fetch build.func content once, compute hash ---
# build_content="$(curl -fsSL "$BUILD_URL")" || {
# echo "❌ Failed to fetch build.func"
# exit 1
# }
# newhash=$(printf "%s" "$build_content" | sha256sum | awk '{print $1}')
# oldhash=$(cat "$BUILD_REV" 2>/dev/null || echo "")
# # --- Step 2: if build.func changed, offer update for core files ---
# if [ "$newhash" != "$oldhash" ]; then
# echo "⚠️ build.func changed!"
# while true; do
# read -rp "Refresh local core files? [y/N/diff]: " ans
# case "$ans" in
# [Yy]*)
# echo "$newhash" >"$BUILD_REV"
# update_func_file() {
# local file="$1"
# local url="https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/$file"
# local local_path="$FUNC_DIR/$file"
# echo "⬇️ Downloading $file ..."
# curl -fsSL "$url" -o "$local_path" || {
# echo "❌ Failed to fetch $file"
# exit 1
# }
# echo "✔️ Updated $file"
# }
# update_func_file core.func
# update_func_file error_handler.func
# update_func_file tools.func
# break
# ;;
# [Dd]*)
# for file in core.func error_handler.func tools.func; do
# local_path="$FUNC_DIR/$file"
# url="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/$file"
# remote_tmp="$(mktemp)"
# curl -fsSL "$url" -o "$remote_tmp" || continue
# if [ -f "$local_path" ]; then
# echo "🔍 Diff for $file:"
# diff -u "$local_path" "$remote_tmp" || echo "(no differences)"
# else
# echo "📦 New file $file will be installed"
# fi
# rm -f "$remote_tmp"
# done
# ;;
# *)
# echo "❌ Skipped updating local core files"
# break
# ;;
# esac
# done
# else
# if [ "$DEVMODE" != "yes" ]; then
# echo "✔️ build.func unchanged → using existing local core files"
# fi
# fi
# if [ -n "${_COMMUNITY_SCRIPTS_LOADER:-}" ]; then
# return 0 2>/dev/null || exit 0
# fi
# _COMMUNITY_SCRIPTS_LOADER=1
# # --- Step 3: always source local versions of the core files ---
# source "$FUNC_DIR/core.func"
# source "$FUNC_DIR/error_handler.func"
# source "$FUNC_DIR/tools.func"
# # --- Step 4: finally, source build.func directly from memory ---
# # (no tmp file needed)
# source <(printf "%s" "$build_content")
# ------------------------------------------------------------------------------
# Load core + error handler functions from community-scripts repo
#
# - Prefer curl if available, fallback to wget
# - Load: core.func, error_handler.func, api.func
# - Initialize error traps after loading
# ------------------------------------------------------------------------------
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/api.func)
if command -v curl >/dev/null 2>&1; then
@ -191,13 +87,11 @@ if command -v curl >/dev/null 2>&1; then
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func)
load_functions
catch_errors
#echo "(build.func) Loaded core.func via curl"
elif command -v wget >/dev/null 2>&1; then
source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/core.func)
source <(wget -qO- https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/error_handler.func)
load_functions
catch_errors
#echo "(build.func) Loaded core.func via wget"
fi
# ==============================================================================
@ -266,17 +160,29 @@ maxkeys_check() {
#
# - Returns current container IP depending on OS type
# - Debian/Ubuntu: uses `hostname -I`
# - Alpine: parses eth0 via `ip -4 addr`
# - Alpine: parses eth0 via `ip -4 addr` or `ip -6 addr`
# - Supports IPv6-only environments as fallback
# - Returns "Unknown" if OS type cannot be determined
# ------------------------------------------------------------------------------
get_current_ip() {
CURRENT_IP=""
if [ -f /etc/os-release ]; then
# Check for Debian/Ubuntu (uses hostname -I)
if grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
CURRENT_IP=$(hostname -I | awk '{print $1}')
# Try IPv4 first
CURRENT_IP=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -n1)
# Fallback to IPv6 if no IPv4
if [[ -z "$CURRENT_IP" ]]; then
CURRENT_IP=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E ':' | head -n1)
fi
# Check for Alpine (uses ip command)
elif grep -q 'ID=alpine' /etc/os-release; then
CURRENT_IP=$(ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
# Try IPv4 first
CURRENT_IP=$(ip -4 addr show eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
# Fallback to IPv6 if no IPv4
if [[ -z "$CURRENT_IP" ]]; then
CURRENT_IP=$(ip -6 addr show eth0 scope global 2>/dev/null | awk '/inet6 / {print $2}' | cut -d/ -f1 | head -n 1)
fi
else
CURRENT_IP="Unknown"
fi
@ -308,6 +214,7 @@ update_motd_ip() {
#
# - Installs SSH keys into container root account if SSH is enabled
# - Uses pct push or direct input to authorized_keys
# - Supports both SSH_KEYS_FILE (from advanced settings) and SSH_AUTHORIZED_KEY (from user defaults)
# - Falls back to warning if no keys provided
# ------------------------------------------------------------------------------
install_ssh_keys_into_ct() {
@ -316,6 +223,13 @@ install_ssh_keys_into_ct() {
# Ensure SSH_KEYS_FILE is defined (may not be set if advanced_settings was skipped)
: "${SSH_KEYS_FILE:=}"
# If SSH_KEYS_FILE doesn't exist but SSH_AUTHORIZED_KEY is set (from user defaults),
# create a temporary SSH_KEYS_FILE with the key
if [[ -z "$SSH_KEYS_FILE" || ! -s "$SSH_KEYS_FILE" ]] && [[ -n "${SSH_AUTHORIZED_KEY:-}" ]]; then
SSH_KEYS_FILE="$(mktemp)"
printf '%s\n' "$SSH_AUTHORIZED_KEY" >"$SSH_KEYS_FILE"
fi
if [[ -n "$SSH_KEYS_FILE" && -s "$SSH_KEYS_FILE" ]]; then
msg_info "Installing selected SSH keys into CT ${CTID}"
pct exec "$CTID" -- sh -c 'mkdir -p /root/.ssh && chmod 700 /root/.ssh' || {
@ -1025,7 +939,6 @@ base_settings() {
ENABLE_NESTING=${var_nesting:-"1"}
ENABLE_KEYCTL=${var_keyctl:-"0"}
ENABLE_MKNOD=${var_mknod:-"0"}
MOUNT_FS=${var_mount_fs:-""}
PROTECT_CT=${var_protection:-"no"}
CT_TIMEZONE=${var_timezone:-"$timezone"}
[[ "${CT_TIMEZONE:-}" == Etc/* ]] && CT_TIMEZONE="host" # pct doesn't accept Etc/* zones

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# License: MIT | https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/LICENSE
# License: MIT | https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/LICENSE
# ==============================================================================
# CORE FUNCTIONS - LXC CONTAINER UTILITIES
@ -123,6 +123,7 @@ icons() {
CREATING="${TAB}🚀${TAB}${CL}"
ADVANCED="${TAB}🧩${TAB}${CL}"
FUSE="${TAB}🗂️${TAB}${CL}"
GPU="${TAB}🎮${TAB}${CL}"
HOURGLASS="${TAB}${TAB}"
}
@ -551,11 +552,8 @@ msg_info() {
if ! declare -p MSG_INFO_SHOWN &>/dev/null || ! declare -A MSG_INFO_SHOWN &>/dev/null; then
declare -gA MSG_INFO_SHOWN=()
fi
# Sanitize message for use as associative array key (remove ANSI codes and special chars)
local sanitized_msg
sanitized_msg=$(printf '%s' "$msg" | sed 's/\x1b\[[0-9;]*m//g; s/[^a-zA-Z0-9_]/_/g')
[[ -n "${MSG_INFO_SHOWN["$sanitized_msg"]+x}" ]] && return
MSG_INFO_SHOWN["$sanitized_msg"]=1
[[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return
MSG_INFO_SHOWN["$msg"]=1
stop_spinner
SPINNER_MSG="$msg"
@ -600,7 +598,6 @@ msg_ok() {
stop_spinner
clear_line
echo -e "$CM ${GN}${msg}${CL}"
# Sanitize message for use as associative array key (remove ANSI codes and special chars)
local sanitized_msg
sanitized_msg=$(printf '%s' "$msg" | sed 's/\x1b\[[0-9;]*m//g; s/[^a-zA-Z0-9_]/_/g')
unset 'MSG_INFO_SHOWN['"$sanitized_msg"']' 2>/dev/null || true
@ -717,7 +714,7 @@ exit_script() {
# ------------------------------------------------------------------------------
get_header() {
local app_name=$(echo "${APP,,}" | tr -d ' ')
local app_type=${APP_TYPE:-ct} # Default zu 'ct' falls nicht gesetzt
local app_type=${APP_TYPE:-ct} # Default to 'ct' if not set
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}"
@ -820,71 +817,64 @@ is_verbose_mode() {
# ------------------------------------------------------------------------------
# cleanup_lxc()
#
# - Comprehensive cleanup of package managers, caches, and logs
# - Supports Alpine (apk), Debian/Ubuntu (apt), Fedora/Rocky/CentOS (dnf/yum),
# openSUSE (zypper), Gentoo (emerge), and language package managers
# - Cleans: Python (pip/uv), Node.js (npm/yarn/pnpm), Go, Rust, Ruby, PHP
# - Truncates log files and vacuums systemd journal
# - Run at end of container creation to minimize disk usage
# - Cleans package manager and language caches (safe for installs AND updates)
# - Supports Alpine (apk), Debian/Ubuntu (apt), Python, Node.js, Go, Rust, Ruby, PHP
# - Uses fallback error handling to prevent cleanup failures from breaking installs
# ------------------------------------------------------------------------------
cleanup_lxc() {
msg_info "Cleaning up"
# OS-specific package manager cleanup
if is_alpine; then
$STD apk cache clean 2>/dev/null || true
$STD apk cache clean || true
rm -rf /var/cache/apk/*
elif command -v apt &>/dev/null; then
# Debian/Ubuntu/Devuan
$STD apt -y autoremove 2>/dev/null || true
$STD apt -y autoclean 2>/dev/null || true
$STD apt -y clean 2>/dev/null || true
elif command -v dnf &>/dev/null; then
# Fedora/Rocky/AlmaLinux/CentOS 8+
$STD dnf clean all 2>/dev/null || true
$STD dnf autoremove -y 2>/dev/null || true
elif command -v yum &>/dev/null; then
# CentOS 7/older RHEL
$STD yum clean all 2>/dev/null || true
elif command -v zypper &>/dev/null; then
# openSUSE
$STD zypper clean --all 2>/dev/null || true
elif command -v emerge &>/dev/null; then
# Gentoo
$STD emerge --quiet --depclean 2>/dev/null || true
$STD eclean-dist -d 2>/dev/null || true
$STD eclean-pkg -d 2>/dev/null || true
else
$STD apt -y autoremove 2>/dev/null || msg_warn "apt autoremove failed (non-critical)"
$STD apt -y autoclean 2>/dev/null || msg_warn "apt autoclean failed (non-critical)"
$STD apt -y clean 2>/dev/null || msg_warn "apt clean failed (non-critical)"
fi
# Clear temp artifacts (keep sockets/FIFOs; ignore errors)
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
# Truncate writable log files silently (permission errors ignored)
if command -v truncate >/dev/null 2>&1; then
find /var/log -type f -writable -print0 2>/dev/null |
xargs -0 -n1 truncate -s 0 2>/dev/null || true
# Python
if command -v pip &>/dev/null; then
rm -rf /root/.cache/pip 2>/dev/null || true
fi
if command -v uv &>/dev/null; then
rm -rf /root/.cache/uv 2>/dev/null || true
fi
# Node.js npm
# Node.js
if command -v npm &>/dev/null; then
rm -rf /root/.npm/_cacache /root/.npm/_logs 2>/dev/null || true
fi
# Node.js yarn
#if command -v yarn &>/dev/null; then $STD yarn cache clean 2>/dev/null || true; fi
# Node.js pnpm
if command -v pnpm &>/dev/null; then $STD pnpm store prune 2>/dev/null || true; fi
# Go
if command -v go &>/dev/null; then $STD go clean -cache -modcache 2>/dev/null || true; fi
# Rust cargo
if command -v cargo &>/dev/null; then $STD cargo clean 2>/dev/null || true; fi
# Ruby gem
if command -v gem &>/dev/null; then $STD gem cleanup 2>/dev/null || true; fi
# Composer (PHP)
if command -v composer &>/dev/null; then $STD composer clear-cache 2>/dev/null || true; fi
if command -v journalctl &>/dev/null; then
$STD journalctl --vacuum-time=10m 2>/dev/null || true
if command -v yarn &>/dev/null; then
rm -rf /root/.cache/yarn /root/.yarn/cache 2>/dev/null || true
fi
if command -v pnpm &>/dev/null; then
pnpm store prune &>/dev/null || true
fi
# Go (only build cache, not modules)
if command -v go &>/dev/null; then
$STD go clean -cache 2>/dev/null || true
fi
# Rust (only registry cache, not build artifacts)
if command -v cargo &>/dev/null; then
rm -rf /root/.cargo/registry/cache /root/.cargo/.package-cache 2>/dev/null || true
fi
# Ruby
if command -v gem &>/dev/null; then
rm -rf /root/.gem/cache 2>/dev/null || true
fi
# PHP
if command -v composer &>/dev/null; then
rm -rf /root/.composer/cache 2>/dev/null || true
fi
msg_ok "Cleaned"
}
@ -954,14 +944,14 @@ function get_lxc_ip() {
get_current_ip() {
local ip
# Try direct interface lookup for eth0 FIRST (most reliable for LXC)
# Try direct interface lookup for eth0 FIRST (most reliable for LXC) - IPv4
ip=$(ip -4 addr show eth0 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1)
if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$ip"
return 0
fi
# Fallback: Try hostname -I
# Fallback: Try hostname -I (returns IPv4 first if available)
if command -v hostname >/dev/null 2>&1; then
ip=$(hostname -I 2>/dev/null | awk '{print $1}')
if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
@ -970,9 +960,9 @@ function get_lxc_ip() {
fi
fi
# Last resort: Use routing table
local targets=("8.8.8.8" "1.1.1.1" "default")
for target in "${targets[@]}"; do
# Try routing table with IPv4 targets
local ipv4_targets=("8.8.8.8" "1.1.1.1" "default")
for target in "${ipv4_targets[@]}"; do
if [[ "$target" == "default" ]]; then
ip=$(ip route get 1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')
else
@ -984,6 +974,32 @@ function get_lxc_ip() {
fi
done
# IPv6 fallback: Try direct interface lookup for eth0
ip=$(ip -6 addr show eth0 scope global 2>/dev/null | awk '/inet6 / {print $2}' | cut -d/ -f1 | head -n1)
if [[ -n "$ip" && "$ip" =~ : ]]; then
echo "$ip"
return 0
fi
# IPv6 fallback: Try hostname -I for IPv6
if command -v hostname >/dev/null 2>&1; then
ip=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E ':' | head -n1)
if [[ -n "$ip" && "$ip" =~ : ]]; then
echo "$ip"
return 0
fi
fi
# IPv6 fallback: Use routing table with IPv6 targets
local ipv6_targets=("2001:4860:4860::8888" "2606:4700:4700::1111")
for target in "${ipv6_targets[@]}"; do
ip=$(ip -6 route get "$target" 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')
if [[ -n "$ip" && "$ip" =~ : ]]; then
echo "$ip"
return 0
fi
done
return 1
}