mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-05-14 21:15:01 +00:00
update beta ProxMenux 1.2.1.1-beta
This commit is contained in:
@@ -1,37 +1,30 @@
|
||||
#!/bin/bash
|
||||
# ==========================================================
|
||||
# ProxMenux - Complete Post-Installation Script with Registration
|
||||
# ProxMenux - Automated Post-Install Script
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : (GPL-3.0) (https://github.com/MacRimi/ProxMenux/blob/main/LICENSE)
|
||||
# License : GPL-3.0
|
||||
# https://github.com/MacRimi/ProxMenux/blob/main/LICENSE
|
||||
# Version : 1.0
|
||||
# Last Updated: 06/07/2025
|
||||
# ==========================================================
|
||||
# Description:
|
||||
# Applies a curated set of 13 safe optimizations to a fresh
|
||||
# Proxmox VE host without prompts. Every change is registered
|
||||
# in installed_tools.json so it can be reversed later from the
|
||||
# Uninstall Optimizations menu.
|
||||
#
|
||||
# The script performs system optimizations including:
|
||||
# - Repository configuration and system upgrades
|
||||
# - Subscription banner removal and UI enhancements
|
||||
# - Advanced memory management and kernel optimizations
|
||||
# - Network stack tuning and security hardening
|
||||
# - Storage optimizations including log2ram for SSD protection
|
||||
# - System limits increases and entropy generation improvements
|
||||
# - Journald and logrotate optimizations for better log management
|
||||
# - Security enhancements including RPC disabling and time synchronization
|
||||
# - Bash environment customization and system monitoring setup
|
||||
# Features:
|
||||
# - Zero-interaction baseline: repos, upgrade, banner, APT
|
||||
# IPv4, skip translations, kernel limits, memory tuning,
|
||||
# kernel-panic behaviour, network stack tuning, bashrc,
|
||||
# Log2RAM (SSD-aware), journald, logrotate, persistent NIC names.
|
||||
# - Hardware-aware: auto-detects SSD/NVMe for Log2RAM and sizes
|
||||
# its ramdisk according to host RAM (128M/256M/512M).
|
||||
# - Registration: tracks each tool in installed_tools.json.
|
||||
# - Rollback: every tool has a reverse function in uninstall-tools.sh.
|
||||
#
|
||||
# Key Features:
|
||||
# - Zero-interaction automation: Runs completely unattended
|
||||
# - Intelligent hardware detection: Automatically detects SSD/NVMe for log2ram
|
||||
# - RAM-aware configurations: Adjusts settings based on available system memory
|
||||
# - Comprehensive error handling: Robust installation with fallback mechanisms
|
||||
# - Registration system: Tracks installed optimizations for easy management
|
||||
# - Reboot management: Intelligently handles reboot requirements
|
||||
# - Translation support: Multi-language compatible through ProxMenux framework
|
||||
# - Rollback compatibility: All optimizations can be reversed using the uninstall script
|
||||
#
|
||||
# This script is based on the post-install script cutotomizable
|
||||
# Shares the function library with customizable_post_install.sh.
|
||||
# ==========================================================
|
||||
|
||||
|
||||
@@ -55,17 +48,49 @@ RAM_SIZE_GB=$(( $(vmstat -s | grep -i "total memory" | xargs | cut -d" " -f 1) /
|
||||
NECESSARY_REBOOT=0
|
||||
export SCRIPT_TITLE="ProxMenux Optimization Post-Installation"
|
||||
|
||||
# Sprint 12A: identify which post-install flow is calling register_tool.
|
||||
# auto_post_install.sh always emits source=auto; customizable sets "custom".
|
||||
# The detector uses this to know which function to compare against and
|
||||
# which one to re-run when applying an update (preserves user's choice
|
||||
# between the auto and the custom flow of the same tool).
|
||||
SCRIPT_SOURCE="auto"
|
||||
|
||||
# ==========================================================
|
||||
# Tool registration system
|
||||
ensure_tools_json() {
|
||||
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
|
||||
}
|
||||
|
||||
# Sprint 12A: register_tool accepts (key, state, version, source).
|
||||
# key — tool identifier (existing)
|
||||
# state — true/false (existing)
|
||||
# version — defaults to "1.0"; each function declares its own version as
|
||||
# `local FUNC_VERSION="X.Y"` on the first line and passes
|
||||
# "$FUNC_VERSION" here. We use a `local` variable rather than a
|
||||
# `# version:` comment because bash's `declare -f` strips
|
||||
# comments — so a comment-based version was lost when the
|
||||
# update wrapper sourced the script and re-ran the function.
|
||||
# source — defaults to $SCRIPT_SOURCE (auto/custom) so the detector
|
||||
# knows which flow to compare against and which to re-run on
|
||||
# update.
|
||||
# On install (state=true) the entry becomes a structured object
|
||||
# {installed: true, version: "X.Y", source: "auto"|"custom"}
|
||||
# On uninstall (state=false) we keep the legacy boolean false so the rest
|
||||
# of the pipeline (uninstall-tools.sh, frontend) keeps working.
|
||||
register_tool() {
|
||||
local tool="$1"
|
||||
local state="$2"
|
||||
local version="${3:-1.0}"
|
||||
local source="${4:-${SCRIPT_SOURCE:-unknown}}"
|
||||
ensure_tools_json
|
||||
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
|
||||
if [[ "$state" == "true" ]]; then
|
||||
jq --arg t "$tool" --arg ver "$version" --arg src "$source" \
|
||||
'.[$t]={"installed": true, "version": $ver, "source": $src}' \
|
||||
"$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
|
||||
else
|
||||
jq --arg t "$tool" '.[$t]=false' \
|
||||
"$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +191,8 @@ remove_subscription_banner() {
|
||||
|
||||
|
||||
configure_time_sync() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Detect timezone from public IP and enable systemd time sync (NTP).
|
||||
msg_info2 "$(translate "Configuring system time settings...")"
|
||||
|
||||
this_ip=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null)
|
||||
@@ -174,20 +201,30 @@ configure_time_sync() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
timezone=$(curl -s --connect-timeout 10 "https://ipapi.co/${this_ip}/timezone" 2>/dev/null)
|
||||
timezone=$(curl -s --connect-timeout 10 "https://ipapi.co/${this_ip}/timezone" 2>/dev/null | tr -d '[:space:]')
|
||||
if [ -z "$timezone" ] || [ "$timezone" = "undefined" ]; then
|
||||
msg_warn "$(translate "Failed to determine timezone from IP address - keeping current timezone settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Validate against the system's IANA timezone database before applying.
|
||||
# ipapi.co can return rate-limit JSON, an error string, or stale data; the
|
||||
# previous code accepted anything that wasn't literally "undefined" and
|
||||
# passed it straight to `timedatectl set-timezone`, which silently kept
|
||||
# the old TZ on a bad value.
|
||||
if ! timedatectl list-timezones 2>/dev/null | grep -Fxq "$timezone"; then
|
||||
msg_warn "$(translate "API returned an invalid timezone") ($timezone) - $(translate "keeping current settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Found timezone $timezone for IP $this_ip")"
|
||||
|
||||
|
||||
if timedatectl set-timezone "$timezone"; then
|
||||
msg_ok "$(translate "Timezone set to $timezone")"
|
||||
|
||||
if timedatectl set-ntp true; then
|
||||
msg_ok "$(translate "Time settings configured - Timezone:") $timezone"
|
||||
register_tool "time_sync" true
|
||||
register_tool "time_sync" true "$FUNC_VERSION"
|
||||
|
||||
systemctl restart postfix 2>/dev/null || true
|
||||
else
|
||||
@@ -204,17 +241,20 @@ configure_time_sync() {
|
||||
# ==========================================================
|
||||
|
||||
skip_apt_languages() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Stop APT from downloading translation files to speed up updates.
|
||||
msg_info "$(translate "Configuring APT to skip downloading additional languages...")"
|
||||
cat > /etc/apt/apt.conf.d/99-disable-translations <<'EOF'
|
||||
Acquire::Languages "none";
|
||||
EOF
|
||||
msg_ok "$(translate "APT configured to skip additional languages")"
|
||||
register_tool "apt_languages" true
|
||||
register_tool "apt_languages" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
optimize_journald() {
|
||||
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Cap journald size, raise rate limit and force info-level logging so the log viewer and Fail2Ban work.
|
||||
if [ -f /etc/log2ram.conf ] || [ -d /var/log.hdd ]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -254,18 +294,20 @@ EOF
|
||||
journalctl --rotate > /dev/null 2>&1
|
||||
|
||||
msg_ok "$(translate "Journald optimized - Max size: 64M")"
|
||||
register_tool "journald" true
|
||||
register_tool "journald" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
optimize_logrotate() {
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Replace logrotate.conf with a Log2RAM-friendly profile (daily rotation, copytruncate).
|
||||
msg_info "$(translate "Optimizing logrotate configuration...")"
|
||||
local logrotate_conf="/etc/logrotate.conf"
|
||||
local backup_conf="${logrotate_conf}.bak"
|
||||
|
||||
if ! grep -q "# ProxMenux optimized configuration" "$logrotate_conf"; then
|
||||
cp "$logrotate_conf" "$backup_conf"
|
||||
cat <<EOF > "$logrotate_conf"
|
||||
|
||||
cp -n "$logrotate_conf" "$backup_conf" 2>/dev/null || true
|
||||
|
||||
cat <<EOF > "$logrotate_conf"
|
||||
# ProxMenux optimized configuration (Log2RAM-friendly)
|
||||
daily
|
||||
su root adm
|
||||
@@ -279,15 +321,16 @@ create 0640 root adm
|
||||
copytruncate
|
||||
include /etc/logrotate.d
|
||||
EOF
|
||||
systemctl restart logrotate > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
systemctl restart logrotate > /dev/null 2>&1
|
||||
|
||||
msg_ok "$(translate "Logrotate optimization completed")"
|
||||
register_tool "logrotate" true
|
||||
register_tool "logrotate" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
increase_system_limits() {
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Raise inotify watches, file descriptors, process keys and PID limits to enterprise levels.
|
||||
msg_info "$(translate "Increasing various system limits...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -355,11 +398,13 @@ fs.aio-max-nr = 1048576
|
||||
EOF
|
||||
|
||||
msg_ok "$(translate "System limits increase completed.")"
|
||||
register_tool "system_limits" true
|
||||
register_tool "system_limits" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
optimize_memory_settings() {
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Tune swappiness, dirty page ratios, overcommit and compaction proactiveness for VM hosts.
|
||||
msg_info "$(translate "Optimizing memory settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -377,11 +422,13 @@ EOF
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Memory optimization completed.")"
|
||||
register_tool "memory_settings" true
|
||||
register_tool "memory_settings" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
configure_kernel_panic() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Auto-reboot on kernel panic / oops / hardlockup; write crash dumps to /var/crash.
|
||||
msg_info "$(translate "Configuring kernel panic behavior")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -394,22 +441,26 @@ kernel.hardlockup_panic = 1
|
||||
EOF
|
||||
|
||||
msg_ok "$(translate "Kernel panic behavior configuration completed")"
|
||||
register_tool "kernel_panic" true
|
||||
register_tool "kernel_panic" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
force_apt_ipv4() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Force APT to use IPv4 to avoid stalls on hosts with broken IPv6 connectivity.
|
||||
msg_info "$(translate "Configuring APT to use IPv4...")"
|
||||
|
||||
|
||||
echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99-force-ipv4
|
||||
|
||||
|
||||
msg_ok "$(translate "APT IPv4 configuration completed")"
|
||||
register_tool "apt_ipv4" true
|
||||
register_tool "apt_ipv4" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
# ==========================================================
|
||||
|
||||
apply_network_optimizations() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Tune TCP buffers, somaxconn, IPv4 hardening and disable rp_filter on fw bridges (PVE 9 compatible).
|
||||
msg_info "$(translate "Optimizing network settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -484,7 +535,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Network optimization completed")"
|
||||
register_tool "network_optimization" true
|
||||
register_tool "network_optimization" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -495,6 +546,8 @@ EOF
|
||||
|
||||
# ==========================================================
|
||||
customize_bashrc() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Inject the ProxMenux core bashrc block (aliases, prompt, history) into root's .bashrc, idempotent via begin/end markers.
|
||||
msg_info "$(translate "Customizing bashrc for root user...")"
|
||||
local bashrc="/root/.bashrc"
|
||||
local bash_profile="/root/.bash_profile"
|
||||
@@ -532,7 +585,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Bashrc customization completed")"
|
||||
register_tool "bashrc_custom" true
|
||||
register_tool "bashrc_custom" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -547,11 +600,14 @@ EOF
|
||||
|
||||
|
||||
install_log2ram_auto() {
|
||||
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Install Log2RAM with size auto-tuned to host RAM (128M/256M/512M); SSD/M.2 detection skips on rotational disks.
|
||||
# ── Reinstall detection ─────────────────────────────────────────────────
|
||||
# If log2ram was previously installed by ProxMenux (register_tool "log2ram" true),
|
||||
# skip hardware detection and reinstall directly — no prompts, transparent to user.
|
||||
if [[ -f "$TOOLS_JSON" ]] && jq -e '.log2ram == true' "$TOOLS_JSON" >/dev/null 2>&1; then
|
||||
# If log2ram was previously installed by ProxMenux, skip hardware detection
|
||||
# and reinstall directly — no prompts, transparent to user. Sprint 12A:
|
||||
# also matches the new structured form `{"installed": true, ...}` written by
|
||||
# the updated register_tool, in addition to the legacy boolean true entry.
|
||||
if [[ -f "$TOOLS_JSON" ]] && jq -e '.log2ram == true or .log2ram.installed == true' "$TOOLS_JSON" >/dev/null 2>&1; then
|
||||
msg_ok "$(translate "Log2RAM already registered — updating to latest configuration")"
|
||||
else
|
||||
# ── First-time install: detect SSD/M.2 ─────────────────────────────────
|
||||
@@ -769,7 +825,7 @@ EOF
|
||||
msg_ok "$(translate "Journald configuration adjusted to") ${USE_MB}M (Log2RAM ${LOG2RAM_SIZE})"
|
||||
|
||||
|
||||
register_tool "log2ram" true
|
||||
register_tool "log2ram" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -783,6 +839,8 @@ EOF
|
||||
|
||||
|
||||
setup_persistent_network() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Pin NIC names to MAC addresses via systemd .link files so kernel updates don't shuffle interface names.
|
||||
local LINK_DIR="/etc/systemd/network"
|
||||
local BACKUP_DIR="/etc/systemd/network/backup-$(date +%Y%m%d-%H%M%S)"
|
||||
local pve_version
|
||||
@@ -791,6 +849,13 @@ setup_persistent_network() {
|
||||
msg_info "$(translate "Setting up persistent network interfaces")"
|
||||
sleep 2
|
||||
|
||||
# Same legacy-conflict warning as in customizable_post_install.sh.
|
||||
if [[ -f /etc/network/interfaces ]]; then
|
||||
if grep -qE '^[[:space:]]*allow-hotplug[[:space:]]' /etc/network/interfaces 2>/dev/null; then
|
||||
msg_warn "$(translate '/etc/network/interfaces uses allow-hotplug. Renaming interfaces via systemd .link can break that flow — review the file after reboot.')"
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$LINK_DIR"
|
||||
|
||||
if ls "$LINK_DIR"/*.link >/dev/null 2>&1; then
|
||||
@@ -833,7 +898,7 @@ EOF
|
||||
else
|
||||
msg_warn "$(translate "No physical interfaces found")"
|
||||
fi
|
||||
register_tool "persistent_network" true
|
||||
register_tool "persistent_network" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,50 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ==========================================================
|
||||
# ProxMenux - Customizable script settings for Proxmox post-installation
|
||||
# ProxMenux - Customizable Post-Install Script
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : (GPL-3.0) (https://github.com/MacRimi/ProxMenux/blob/main/LICENSE)
|
||||
# License : GPL-3.0
|
||||
# https://github.com/MacRimi/ProxMenux/blob/main/LICENSE
|
||||
# Version : 1.3
|
||||
# Last Updated: 30/06/2025
|
||||
# ==========================================================
|
||||
# Description:
|
||||
# This script automates post-installation configurations and optimizations
|
||||
# for Proxmox Virtual Environment (VE). It allows for a variety of system
|
||||
# customizations, including kernel optimizations, memory management, network
|
||||
# tweaks, and virtualization environment adjustments. The script facilitates
|
||||
# easy installation of useful tools and security enhancements, including
|
||||
# fail2ban, ZFS auto-snapshot, and more.
|
||||
# Interactive post-installation configurator for Proxmox VE.
|
||||
# Groups ~30 optimizations into 10 categories (Basic Settings,
|
||||
# System, Virtualization, Network, Storage, Security,
|
||||
# Customization, Monitoring, Performance, Optional) and presents
|
||||
# a checklist per category so the user picks exactly what to
|
||||
# apply. Every change is registered in installed_tools.json for
|
||||
# later reversal from Uninstall Optimizations.
|
||||
#
|
||||
# This script is based on the work of Adrian Jon Kriel from eXtremeSHOK.com,
|
||||
# and it was originally published as a post-installation script for Proxmox under the
|
||||
# BSD License.
|
||||
#
|
||||
# Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
|
||||
# Script updates can be found at: https://github.com/extremeshok/xshok-proxmox
|
||||
#
|
||||
# License: BSD (Berkeley Software Distribution)
|
||||
#
|
||||
# Additionally, this script incorporates elements from the
|
||||
# Proxmox VE Post Install script from Proxmox VE Helper-Scripts.
|
||||
#
|
||||
# Copyright (c) Proxmox VE Helper-Scripts Community
|
||||
# Script updates can be found at: https://github.com/community-scripts/ProxmoxVE
|
||||
#
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
#
|
||||
# Key features:
|
||||
# - Configures system memory and kernel settings for better performance.
|
||||
# - Enables IOMMU and VFIO for PCI passthrough and virtualization optimizations.
|
||||
# - Installs essential tools such as kernel headers, system utilities, and networking tools.
|
||||
# - Optimizes journald, achievement, and other system services for better efficiency.
|
||||
# - Enables guest agents for virtualization platforms such as KVM, VMware, and VirtualBox.
|
||||
# - Updates the system, adds correct repositories, and optimizes system features such as memory, network settings, and more.
|
||||
# - Provides a wide range of additional options for customization and optimization.
|
||||
# - Offers interactive selection of features using an easy-to-use menu-driven interface.
|
||||
# - And many more...
|
||||
# Features:
|
||||
# - Checklist UI per category (10 categories, ~30 tools total).
|
||||
# - Superset of the Automated script: includes the 13 baseline
|
||||
# optimizations plus opt-in items (IOMMU/VFIO, Fastfetch,
|
||||
# Figurine, Ceph repo, HA, AMD fixes, pigz, ZFS ARC, …).
|
||||
# - Idempotent: safe to run repeatedly.
|
||||
# - Registration + rollback: every tool has a reverse function
|
||||
# in uninstall-tools.sh.
|
||||
#
|
||||
# Credits:
|
||||
# Incorporates ideas and snippets originally published under BSD
|
||||
# by Adrian Jon Kriel (eXtremeSHOK) in xshok-proxmox, and elements
|
||||
# of the Proxmox VE Post Install script from the Proxmox VE
|
||||
# Helper-Scripts Community (MIT).
|
||||
# https://github.com/extremeshok/xshok-proxmox
|
||||
# https://github.com/community-scripts/ProxmoxVE
|
||||
# ==========================================================
|
||||
|
||||
|
||||
@@ -78,15 +67,36 @@ SCRIPT_TITLE="Customizable post-installation optimization script"
|
||||
|
||||
TOOLS_JSON="/usr/local/share/proxmenux/installed_tools.json"
|
||||
|
||||
# Sprint 12A: customizable_post_install.sh always emits source=custom so
|
||||
# the update detector knows to re-run the customizable flow (which asks
|
||||
# the user for parameters again) instead of the silent auto flow.
|
||||
SCRIPT_SOURCE="custom"
|
||||
|
||||
ensure_tools_json() {
|
||||
[ -f "$TOOLS_JSON" ] || echo "{}" > "$TOOLS_JSON"
|
||||
}
|
||||
|
||||
# Sprint 12A: register_tool accepts (key, state, version, source).
|
||||
# Each function declares `local FUNC_VERSION="X.Y"` on its first line and
|
||||
# passes "$FUNC_VERSION" here. We use `local` rather than a `# version:`
|
||||
# comment because bash's `declare -f` strips comments — comments would be
|
||||
# silently lost when the update wrapper sourced the script and re-ran a
|
||||
# function, leaving the registered version stuck at the default. See
|
||||
# auto_post_install.sh for the full contract.
|
||||
register_tool() {
|
||||
local tool="$1"
|
||||
local state="$2"
|
||||
local state="$2"
|
||||
local version="${3:-1.0}"
|
||||
local source="${4:-${SCRIPT_SOURCE:-unknown}}"
|
||||
ensure_tools_json
|
||||
jq --arg t "$tool" --argjson v "$state" '.[$t]=$v' "$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
|
||||
if [[ "$state" == "true" ]]; then
|
||||
jq --arg t "$tool" --arg ver "$version" --arg src "$source" \
|
||||
'.[$t]={"installed": true, "version": $ver, "source": $src}' \
|
||||
"$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
|
||||
else
|
||||
jq --arg t "$tool" '.[$t]=false' \
|
||||
"$TOOLS_JSON" > "$TOOLS_JSON.tmp" && mv "$TOOLS_JSON.tmp" "$TOOLS_JSON"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +129,8 @@ $(translate "Do you want to continue anyway?")" 13 70
|
||||
|
||||
|
||||
enable_kexec() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Install kexec-tools and add a Ctrl+Alt+K hotkey + systemd unit for fast reboots that skip BIOS/POST.
|
||||
msg_info2 "$(translate "Configuring kexec for quick reboots...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -179,7 +191,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_success "$(translate "kexec configured successfully. Use the command: reboot-quick")"
|
||||
register_tool "kexec" true
|
||||
register_tool "kexec" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -221,8 +233,10 @@ apt_upgrade() {
|
||||
|
||||
|
||||
optimize_journald() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Cap journald size, raise rate limit and force info-level logging so the log viewer and Fail2Ban work.
|
||||
msg_info2 "$(translate "Limiting size and optimizing journald")"
|
||||
NECESSARY_REBOOT=1
|
||||
NECESSARY_REBOOT=1
|
||||
local journald_conf="/etc/systemd/journald.conf"
|
||||
local config_changed=false
|
||||
|
||||
@@ -280,7 +294,7 @@ EOF
|
||||
journalctl --rotate > /dev/null 2>&1
|
||||
|
||||
msg_success "$(translate "Journald optimization completed")"
|
||||
register_tool "journald" true
|
||||
register_tool "journald" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -299,6 +313,8 @@ EOF
|
||||
|
||||
|
||||
configure_kernel_panic() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Auto-reboot on kernel panic / oops / hardlockup; write crash dumps to /var/crash.
|
||||
msg_info2 "$(translate "Configuring kernel panic behavior")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -320,7 +336,7 @@ EOF
|
||||
|
||||
|
||||
msg_ok "$(translate "Kernel panic configuration updated and applied")"
|
||||
register_tool "kernel_panic" true
|
||||
register_tool "kernel_panic" true "$FUNC_VERSION"
|
||||
msg_success "$(translate "Kernel panic behavior configuration completed")"
|
||||
}
|
||||
|
||||
@@ -333,6 +349,8 @@ EOF
|
||||
|
||||
|
||||
increase_system_limits() {
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Raise inotify watches, file descriptors, process keys and PID limits to enterprise levels.
|
||||
msg_info2 "$(translate "Increasing various system limits...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -418,7 +436,7 @@ fs.file-max = 2097152
|
||||
fs.aio-max-nr = 1048576"
|
||||
|
||||
msg_ok "$(translate "Max FS open files configuration created successfully")"
|
||||
register_tool "system_limits" true
|
||||
register_tool "system_limits" true "$FUNC_VERSION"
|
||||
msg_success "$(translate "System limits increase completed.")"
|
||||
}
|
||||
|
||||
@@ -431,6 +449,8 @@ fs.aio-max-nr = 1048576"
|
||||
|
||||
|
||||
skip_apt_languages() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Stop APT from downloading translation files to speed up updates.
|
||||
msg_info2 "$(translate "Configuring APT to skip downloading additional languages")"
|
||||
|
||||
# 1. Detect locale
|
||||
@@ -471,7 +491,7 @@ skip_apt_languages() {
|
||||
msg_ok "$(translate "APT language configuration updated")"
|
||||
fi
|
||||
|
||||
register_tool "apt_languages" true
|
||||
register_tool "apt_languages" true "$FUNC_VERSION"
|
||||
msg_success "$(translate "APT configured to skip downloading additional languages")"
|
||||
}
|
||||
|
||||
@@ -489,6 +509,8 @@ skip_apt_languages() {
|
||||
|
||||
|
||||
configure_time_sync() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Detect timezone from public IP and enable systemd time sync (NTP).
|
||||
msg_info2 "$(translate "Configuring system time settings...")"
|
||||
|
||||
this_ip=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null)
|
||||
@@ -497,20 +519,30 @@ configure_time_sync() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
timezone=$(curl -s --connect-timeout 10 "https://ipapi.co/${this_ip}/timezone" 2>/dev/null)
|
||||
timezone=$(curl -s --connect-timeout 10 "https://ipapi.co/${this_ip}/timezone" 2>/dev/null | tr -d '[:space:]')
|
||||
if [ -z "$timezone" ] || [ "$timezone" = "undefined" ]; then
|
||||
msg_warn "$(translate "Failed to determine timezone from IP address - keeping current timezone settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Validate against the system's IANA timezone database before applying.
|
||||
# ipapi.co can return rate-limit JSON, an error string, or stale data; the
|
||||
# previous code accepted anything that wasn't literally "undefined" and
|
||||
# passed it straight to `timedatectl set-timezone`, which silently kept
|
||||
# the old TZ on a bad value.
|
||||
if ! timedatectl list-timezones 2>/dev/null | grep -Fxq "$timezone"; then
|
||||
msg_warn "$(translate "API returned an invalid timezone") ($timezone) - $(translate "keeping current settings")"
|
||||
return 0
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Found timezone $timezone for IP $this_ip")"
|
||||
|
||||
|
||||
if timedatectl set-timezone "$timezone"; then
|
||||
msg_ok "$(translate "Timezone set to $timezone")"
|
||||
|
||||
if timedatectl set-ntp true; then
|
||||
msg_ok "$(translate "Time settings configured - Timezone:") $timezone"
|
||||
register_tool "time_sync" true
|
||||
register_tool "time_sync" true "$FUNC_VERSION"
|
||||
|
||||
systemctl restart postfix 2>/dev/null || true
|
||||
else
|
||||
@@ -583,6 +615,8 @@ configure_time_sync() {
|
||||
|
||||
|
||||
apply_amd_fixes() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Detect AMD EPYC/Ryzen CPUs and apply microcode + IOMMU + KVM-specific kernel boot params.
|
||||
msg_info2 "$(translate "Detecting AMD CPU and applying fixes if necessary...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -672,7 +706,7 @@ apply_amd_fixes() {
|
||||
fi
|
||||
|
||||
msg_success "$(translate "AMD CPU fixes applied successfully")"
|
||||
register_tool "amd_fixes" true
|
||||
register_tool "amd_fixes" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -687,6 +721,8 @@ apply_amd_fixes() {
|
||||
|
||||
|
||||
force_apt_ipv4() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Force APT to use IPv4 to avoid stalls on hosts with broken IPv6 connectivity.
|
||||
msg_info2 "$(translate "Configuring APT to use IPv4...")"
|
||||
|
||||
local config_file="/etc/apt/apt.conf.d/99-force-ipv4"
|
||||
@@ -701,7 +737,7 @@ force_apt_ipv4() {
|
||||
fi
|
||||
fi
|
||||
|
||||
register_tool "apt_ipv4" true
|
||||
register_tool "apt_ipv4" true "$FUNC_VERSION"
|
||||
msg_success "$(translate "APT IPv4 configuration completed")"
|
||||
}
|
||||
|
||||
@@ -716,6 +752,8 @@ force_apt_ipv4() {
|
||||
|
||||
|
||||
apply_network_optimizations() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Tune TCP buffers, somaxconn, IPv4 hardening and disable rp_filter on fw bridges (PVE 9 compatible).
|
||||
msg_info "$(translate "Optimizing network settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -742,6 +780,12 @@ net.ipv4.conf.default.secure_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
net.ipv4.conf.default.log_martians = 0
|
||||
|
||||
# rp_filter=2 (loose) instead of the kernel default 1 (strict). Loose
|
||||
# allows asymmetric routing typical of a Proxmox host with VMs on
|
||||
# multiple bridges — strict mode would drop legitimate VM traffic when
|
||||
# the reverse path differs. Trade-off: slightly weaker spoofing
|
||||
# protection from local LAN. Document this choice rather than the
|
||||
# default.
|
||||
net.ipv4.conf.all.rp_filter = 2
|
||||
net.ipv4.conf.default.rp_filter = 2
|
||||
|
||||
@@ -750,6 +794,11 @@ net.ipv4.icmp_echo_ignore_broadcasts = 1
|
||||
net.ipv4.icmp_ignore_bogus_error_responses = 1
|
||||
|
||||
# TCP/IP
|
||||
# Wider ephemeral port range than Debian's default 32768-60999 so
|
||||
# Proxmox hosts handing out NAT/forward ports for many VMs/CTs don't
|
||||
# run out under load. Privileged-port range (1-1023) is still protected
|
||||
# by capabilities — the kernel won't actually pick one for an
|
||||
# unprivileged ephemeral allocation.
|
||||
net.ipv4.ip_local_port_range = 1024 65535
|
||||
net.ipv4.tcp_mtu_probing = 1
|
||||
net.ipv4.tcp_rfc1337 = 1
|
||||
@@ -771,7 +820,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Network optimization completed")"
|
||||
register_tool "network_optimization" true
|
||||
register_tool "network_optimization" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -786,6 +835,8 @@ EOF
|
||||
|
||||
|
||||
install_openvswitch() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Install OpenVSwitch for software-defined networking inside VMs and containers.
|
||||
msg_info2 "$(translate "Installing OpenVSwitch for virtual internal network...")"
|
||||
|
||||
|
||||
@@ -813,6 +864,7 @@ install_openvswitch() {
|
||||
# Verify installation
|
||||
if command -v ovs-vsctl >/dev/null 2>&1; then
|
||||
msg_success "$(translate "OpenVSwitch is ready to use")"
|
||||
register_tool "openvswitch" true "$FUNC_VERSION"
|
||||
else
|
||||
msg_warn "$(translate "OpenVSwitch installation could not be verified")"
|
||||
fi
|
||||
@@ -829,6 +881,8 @@ install_openvswitch() {
|
||||
|
||||
|
||||
enable_tcp_fast_open() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Enable TCP Fast Open (clients + server) and BBR congestion control for better latency under load.
|
||||
msg_info2 "$(translate "Configuring TCP optimizations...")"
|
||||
|
||||
local bbr_conf="/etc/sysctl.d/99-kernel-bbr.conf"
|
||||
@@ -869,6 +923,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_success "$(translate "TCP optimizations configuration completed")"
|
||||
register_tool "tcp_optimizations" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -883,6 +938,8 @@ EOF
|
||||
|
||||
|
||||
install_ceph() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Install Ceph (client + server packages) for distributed RBD/CephFS storage; PVE 8/9 aware repo selection.
|
||||
msg_info2 "$(translate "Installing Ceph support...")"
|
||||
|
||||
|
||||
@@ -1043,8 +1100,11 @@ EOF
|
||||
msg_info2 "$(translate "You may need to run 'pveceph install' manually")"
|
||||
msg_success "$(translate "Ceph installation process finished with warnings")"
|
||||
fi
|
||||
|
||||
|
||||
# Track install in the registry so the Uninstall menu can offer
|
||||
# `apt purge ceph-*` + repo removal. Audit Tier 6 — `install_ceph` /
|
||||
# `enable_ha` sin `register_tool` ni uninstall.
|
||||
register_tool "ceph" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1060,6 +1120,8 @@ EOF
|
||||
|
||||
|
||||
optimize_zfs_arc() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Cap ZFS ARC to a sensible fraction of host RAM so VMs don't fight the kernel for memory.
|
||||
msg_info2 "$(translate "Optimizing ZFS ARC size according to available memory...")"
|
||||
|
||||
# Check if ZFS is installed
|
||||
@@ -1139,6 +1201,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_success "$(translate "ZFS ARC optimization completed")"
|
||||
register_tool "zfs_arc" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1151,6 +1214,8 @@ EOF
|
||||
|
||||
|
||||
install_zfs_auto_snapshot() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Install zfs-auto-snapshot with cron schedules for hourly/daily/weekly/monthly snapshots.
|
||||
msg_info2 "$(translate "Installing and configuring ZFS auto-snapshot...")"
|
||||
|
||||
# Check if zfs-auto-snapshot is already installed
|
||||
@@ -1171,6 +1236,7 @@ install_zfs_auto_snapshot() {
|
||||
config_zfs_auto_snapshot
|
||||
|
||||
msg_success "$(translate "ZFS auto-snapshot installation and configuration completed")"
|
||||
register_tool "zfs_auto_snapshot" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
config_zfs_auto_snapshot() {
|
||||
@@ -1238,6 +1304,8 @@ disable_rpc() {
|
||||
|
||||
|
||||
configure_pigz() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Replace gzip with pigz (parallel implementation) for faster vzdump backup compression.
|
||||
msg_info2 "$(translate "Configuring pigz as a faster replacement for gzip...")"
|
||||
|
||||
# Enable pigz in vzdump configuration
|
||||
@@ -1295,6 +1363,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_success "$(translate "pigz configuration completed")"
|
||||
register_tool "pigz" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1339,6 +1408,8 @@ EOF
|
||||
|
||||
|
||||
install_guest_agent() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Detect the host's hypervisor (qemu/vmware/hyperv/virtualbox) and install the matching guest agent.
|
||||
msg_info2 "$(translate "Detecting virtualization and installing guest agent...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -1366,6 +1437,11 @@ install_guest_agent() {
|
||||
msg_info "$(translate "Installing $guest_agent for $virt_env...")"
|
||||
if /usr/bin/env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confdef' install $guest_agent > /dev/null 2>&1; then
|
||||
msg_ok "$(translate "$guest_agent installed successfully")"
|
||||
# Persist which package was installed so the uninstaller knows
|
||||
# what to apt purge later (different per hypervisor).
|
||||
mkdir -p /usr/local/share/proxmenux 2>/dev/null
|
||||
echo "$guest_agent" > /usr/local/share/proxmenux/guest_agent.pkg
|
||||
register_tool "guest_agent" true "$FUNC_VERSION"
|
||||
else
|
||||
msg_error "$(translate "Failed to install $guest_agent")"
|
||||
fi
|
||||
@@ -1398,6 +1474,8 @@ install_guest_agent() {
|
||||
|
||||
|
||||
enable_vfio_iommu() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Enable IOMMU and load VFIO modules to allow GPU/PCI passthrough into VMs.
|
||||
msg_info2 "$(translate "Enabling IOMMU and configuring VFIO for PCI passthrough...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -1553,7 +1631,7 @@ enable_vfio_iommu() {
|
||||
fi
|
||||
|
||||
msg_success "$(translate "IOMMU and VFIO setup completed")"
|
||||
register_tool "vfio_iommu" true
|
||||
register_tool "vfio_iommu" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1570,6 +1648,8 @@ enable_vfio_iommu() {
|
||||
|
||||
|
||||
customize_bashrc() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Inject the ProxMenux core bashrc block (aliases, prompt, history) into root's .bashrc, idempotent via begin/end markers.
|
||||
msg_info2 "$(translate "Customizing bashrc for root user...")"
|
||||
|
||||
msg_info "$(translate "Customizing bashrc for root user...")"
|
||||
@@ -1609,7 +1689,7 @@ EOF
|
||||
fi
|
||||
|
||||
msg_ok "$(translate "Bashrc customization completed")"
|
||||
register_tool "bashrc_custom" true
|
||||
register_tool "bashrc_custom" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1667,36 +1747,34 @@ setup_motd() {
|
||||
|
||||
|
||||
optimize_logrotate() {
|
||||
msg_info2 "$(translate "Optimizing logrotate configuration...")"
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Replace logrotate.conf with a Log2RAM-friendly profile (daily rotation, copytruncate).
|
||||
msg_info2 "$(translate "Optimizing logrotate configuration...")"
|
||||
|
||||
local logrotate_conf="/etc/logrotate.conf"
|
||||
local backup_conf="${logrotate_conf}.bak"
|
||||
|
||||
cp -n "$logrotate_conf" "$backup_conf" 2>/dev/null || true
|
||||
|
||||
if grep -q "# ProxMenux optimized configuration" "$logrotate_conf"; then
|
||||
msg_ok "$(translate "Logrotate configuration already optimized.")"
|
||||
else
|
||||
cp "$logrotate_conf" "$backup_conf"
|
||||
|
||||
msg_info "$(translate "Applying optimized logrotate configuration...")"
|
||||
cat <<EOF > "$logrotate_conf"
|
||||
# ProxMenux optimized configuration
|
||||
msg_info "$(translate "Applying optimized logrotate configuration...")"
|
||||
cat <<EOF > "$logrotate_conf"
|
||||
# ProxMenux optimized configuration (Log2RAM-friendly)
|
||||
daily
|
||||
su root adm
|
||||
rotate 7
|
||||
create
|
||||
compress
|
||||
size 10M
|
||||
compress
|
||||
delaycompress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 root adm
|
||||
copytruncate
|
||||
|
||||
include /etc/logrotate.d
|
||||
EOF
|
||||
|
||||
systemctl restart logrotate > /dev/null 2>&1
|
||||
msg_ok "$(translate "Logrotate service restarted successfully")"
|
||||
fi
|
||||
register_tool "logrotate" true
|
||||
register_tool "logrotate" true "$FUNC_VERSION"
|
||||
msg_success "$(translate "Logrotate optimization completed")"
|
||||
}
|
||||
|
||||
@@ -1711,6 +1789,8 @@ EOF
|
||||
|
||||
|
||||
remove_subscription_banner() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Patch the Proxmox web UI to suppress the "no valid subscription" dialog (PVE 8 + 9 variants supported).
|
||||
local pve_version
|
||||
pve_version=$(pveversion 2>/dev/null | grep -oP 'pve-manager/\K[0-9]+' | head -1)
|
||||
|
||||
@@ -1726,7 +1806,7 @@ remove_subscription_banner() {
|
||||
|
||||
bash "$LOCAL_SCRIPTS/global/remove-banner-pve8.sh"
|
||||
fi
|
||||
register_tool "subscription_banner" true
|
||||
register_tool "subscription_banner" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1740,6 +1820,8 @@ remove_subscription_banner() {
|
||||
|
||||
|
||||
optimize_memory_settings() {
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Tune swappiness, dirty page ratios, overcommit and compaction proactiveness for VM hosts.
|
||||
msg_info2 "$(translate "Optimizing memory settings...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -1777,7 +1859,7 @@ EOF
|
||||
|
||||
msg_ok "$(translate "Memory settings optimized successfully")"
|
||||
msg_success "$(translate "Memory optimization completed.")"
|
||||
register_tool "memory_settings" true
|
||||
register_tool "memory_settings" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1791,10 +1873,19 @@ EOF
|
||||
|
||||
|
||||
optimize_vzdump() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Lift vzdump bandwidth/IO limits so backups run at the storage's real throughput.
|
||||
msg_info2 "$(translate "Optimizing vzdump backup speed...")"
|
||||
|
||||
local vzdump_conf="/etc/vzdump.conf"
|
||||
|
||||
# Backup the current config so the uninstall path can restore the
|
||||
# user's original values. The previous code edited in-place with no
|
||||
# backup; users with custom bwlimit/ionice lost them silently.
|
||||
if [[ -f "$vzdump_conf" && ! -f "${vzdump_conf}.bak" ]]; then
|
||||
cp -p "$vzdump_conf" "${vzdump_conf}.bak"
|
||||
fi
|
||||
|
||||
# Configure bandwidth limit
|
||||
msg_info "$(translate "Configuring bandwidth limit for vzdump...")"
|
||||
if ! grep -q "^bwlimit: 0" "$vzdump_conf"; then
|
||||
@@ -1812,6 +1903,7 @@ optimize_vzdump() {
|
||||
msg_ok "$(translate "I/O priority configured")"
|
||||
|
||||
msg_success "$(translate "vzdump backup speed optimization completed")"
|
||||
register_tool "vzdump_speed" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1825,12 +1917,17 @@ optimize_vzdump() {
|
||||
|
||||
|
||||
install_ovh_rtm() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Detect OVH-rented hardware via whois lookup and install OVH Real-Time Monitoring (no-op on non-OVH).
|
||||
msg_info2 "$(translate "Detecting if this is an OVH server and installing OVH RTM if necessary...")"
|
||||
|
||||
# Get the public IP and check if it belongs to OVH
|
||||
msg_info "$(translate "Checking if the server belongs to OVH...")"
|
||||
public_ip=$(curl -s ipinfo.io/ip)
|
||||
is_ovh=$(whois -h v4.whois.cymru.com " -t $public_ip" | tail -n 1 | cut -d'|' -f3 | grep -i "ovh")
|
||||
# `--` ends whois client option parsing so "-t IP" reaches the cymru server
|
||||
# as the query string. Previous form had a leading space inside the quotes
|
||||
# ("\" -t IP\"") that mangled the query and caused detection to never match.
|
||||
is_ovh=$(whois -h v4.whois.cymru.com -- "-t $public_ip" | tail -n 1 | cut -d'|' -f3 | grep -i "ovh")
|
||||
|
||||
if [ -n "$is_ovh" ]; then
|
||||
msg_ok "$(translate "OVH server detected")"
|
||||
@@ -1838,11 +1935,13 @@ install_ovh_rtm() {
|
||||
msg_info "$(translate "Installing OVH RTM (Real Time Monitoring)...")"
|
||||
if wget -qO - https://last-public-ovh-infra-yak.snap.mirrors.ovh.net/yak/archives/apply.sh | OVH_PUPPET_MANIFEST=distribyak/catalog/master/puppet/manifests/common/rtmv2.pp bash > /dev/null 2>&1; then
|
||||
msg_ok "$(translate "OVH RTM installed successfully")"
|
||||
register_tool "ovh_rtm" true "$FUNC_VERSION"
|
||||
else
|
||||
msg_error "$(translate "Failed to install OVH RTM")"
|
||||
fi
|
||||
else
|
||||
msg_ok "$(translate "Not an OVH server, skipping RTM installation")"
|
||||
fi
|
||||
msg_ok "$(translate "Server belongs to OVH")"
|
||||
msg_success "$(translate "OVH server detection and RTM installation process completed")"
|
||||
}
|
||||
|
||||
@@ -1854,6 +1953,8 @@ install_ovh_rtm() {
|
||||
|
||||
|
||||
enable_ha() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Enable the Proxmox HA stack (pve-ha-lrm, pve-ha-crm, corosync) for cluster failover.
|
||||
msg_info2 "$(translate "Enabling High Availability (HA) services...")"
|
||||
NECESSARY_REBOOT=1
|
||||
|
||||
@@ -1865,7 +1966,7 @@ enable_ha() {
|
||||
msg_ok "$(translate "High Availability services have been enabled successfully")"
|
||||
msg_success "$(translate "High Availability setup completed")"
|
||||
|
||||
|
||||
register_tool "ha" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -1879,6 +1980,8 @@ enable_ha() {
|
||||
|
||||
|
||||
configure_fastfetch() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Install Fastfetch system summary tool with the ProxMenux logo + status block as the SSH login banner.
|
||||
msg_info2 "$(translate "Installing and configuring Fastfetch...")"
|
||||
|
||||
|
||||
@@ -1900,8 +2003,17 @@ configure_fastfetch() {
|
||||
|
||||
|
||||
msg_info "$(translate "Downloading the latest Fastfetch release...")"
|
||||
local fastfetch_deb_url=$(curl -s https://api.github.com/repos/fastfetch-cli/fastfetch/releases/latest |
|
||||
jq -r '.assets[] | select(.name | test("fastfetch-linux-amd64.deb")) | .browser_download_url')
|
||||
# `--connect-timeout`/`--max-time` so a slow GitHub API call doesn't
|
||||
# hang the menu indefinitely. `FASTFETCH_PIN_TAG` env var lets the
|
||||
# caller pin to a known release if upstream introduces a breaking
|
||||
# change. Audit Tier 6 — recursos remotos sin pinning de versión.
|
||||
local fastfetch_deb_url=""
|
||||
if [[ -n "${FASTFETCH_PIN_TAG:-}" ]]; then
|
||||
fastfetch_deb_url="https://github.com/fastfetch-cli/fastfetch/releases/download/${FASTFETCH_PIN_TAG}/fastfetch-linux-amd64.deb"
|
||||
else
|
||||
fastfetch_deb_url=$(curl -s --connect-timeout 5 --max-time 15 https://api.github.com/repos/fastfetch-cli/fastfetch/releases/latest |
|
||||
jq -r '.assets[] | select(.name | test("fastfetch-linux-amd64.deb")) | .browser_download_url')
|
||||
fi
|
||||
|
||||
if [[ -z "$fastfetch_deb_url" ]]; then
|
||||
msg_error "$(translate "Failed to retrieve Fastfetch download URL.")"
|
||||
@@ -2070,7 +2182,7 @@ fi
|
||||
|
||||
msg_ok "$(translate "Fastfetch will start automatically in the console")"
|
||||
msg_success "$(translate "Fastfetch installation and configuration completed")"
|
||||
register_tool "fastfetch" true
|
||||
register_tool "fastfetch" true "$FUNC_VERSION"
|
||||
|
||||
}
|
||||
|
||||
@@ -2102,8 +2214,13 @@ register_tool "fastfetch" true
|
||||
|
||||
|
||||
configure_figurine() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Install Figurine (ASCII-art hostname banner) and wire it into the SSH login flow.
|
||||
msg_info2 "$(translate "Installing and configuring Figurine...")"
|
||||
local version="1.3.0"
|
||||
# `FIGURINE_VERSION` env var allows pinning to a specific release;
|
||||
# default tracks the last tested upstream tag. Audit Tier 6 —
|
||||
# recursos remotos sin pinning de versión.
|
||||
local version="${FIGURINE_VERSION:-1.3.0}"
|
||||
local file="figurine_linux_amd64_v${version}.tar.gz"
|
||||
local url="https://github.com/arsham/figurine/releases/download/v${version}/${file}"
|
||||
local temp_dir; temp_dir=$(mktemp -d)
|
||||
@@ -2190,7 +2307,7 @@ EOF
|
||||
msg_ok "$(translate "Aliases added to .bashrc")"
|
||||
|
||||
msg_success "$(translate "Figurine installation and configuration completed successfully.")"
|
||||
register_tool "figurine" true
|
||||
register_tool "figurine" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -2233,6 +2350,8 @@ update_pve_appliance_manager() {
|
||||
|
||||
|
||||
configure_log2ram() {
|
||||
local FUNC_VERSION="1.1"
|
||||
# description: Install Log2RAM with user-chosen RAM size; prompts for size and SSD/M.2 awareness before applying.
|
||||
msg_info2 "$(translate "Preparing Log2RAM configuration")"
|
||||
sleep 1
|
||||
|
||||
@@ -2311,7 +2430,14 @@ configure_log2ram() {
|
||||
fi
|
||||
|
||||
rm -rf /tmp/log2ram 2>/dev/null || true
|
||||
if ! git clone https://github.com/azlux/log2ram.git /tmp/log2ram >/dev/null 2>>/tmp/log2ram_install.log; then
|
||||
# Pin to a tested release — `master` could ship breaking changes
|
||||
# without notice. `LOG2RAM_TAG` env var lets the caller upgrade.
|
||||
local LOG2RAM_TAG="${LOG2RAM_TAG:-1.7.0}"
|
||||
if ! git clone --depth 1 --branch "$LOG2RAM_TAG" \
|
||||
https://github.com/azlux/log2ram.git /tmp/log2ram \
|
||||
>/dev/null 2>>/tmp/log2ram_install.log \
|
||||
&& ! git clone --depth 1 https://github.com/azlux/log2ram.git /tmp/log2ram \
|
||||
>/dev/null 2>>/tmp/log2ram_install.log; then
|
||||
msg_error "$(translate "Failed to clone log2ram repository. Check /tmp/log2ram_install.log")"
|
||||
return 1
|
||||
fi
|
||||
@@ -2452,7 +2578,7 @@ EOF
|
||||
systemctl restart rsyslog >/dev/null 2>&1 || true
|
||||
|
||||
msg_success "$(translate "Log2RAM installation and configuration completed successfully.")"
|
||||
register_tool "log2ram" true
|
||||
register_tool "log2ram" true "$FUNC_VERSION"
|
||||
}
|
||||
|
||||
|
||||
@@ -2470,6 +2596,8 @@ EOF
|
||||
|
||||
|
||||
setup_persistent_network() {
|
||||
local FUNC_VERSION="1.0"
|
||||
# description: Pin NIC names to MAC addresses via systemd .link files so kernel updates don't shuffle interface names.
|
||||
local LINK_DIR="/etc/systemd/network"
|
||||
local BACKUP_DIR="/etc/systemd/network/backup-$(date +%Y%m%d-%H%M%S)"
|
||||
local pve_version
|
||||
@@ -2478,8 +2606,20 @@ setup_persistent_network() {
|
||||
msg_info "$(translate "Setting up persistent network interfaces")"
|
||||
sleep 2
|
||||
|
||||
# Detect legacy `/etc/network/interfaces` setups that depend on the
|
||||
# default udev naming. If the file references `allow-hotplug` rules
|
||||
# or uses physical interface names directly, the .link rules below
|
||||
# could rename interfaces and break network on reboot. Warn loudly so
|
||||
# the user can review before continuing. Audit Tier 6 —
|
||||
# `setup_persistent_network` no detecta conflicto con legacy.
|
||||
if [[ -f /etc/network/interfaces ]]; then
|
||||
if grep -qE '^[[:space:]]*allow-hotplug[[:space:]]' /etc/network/interfaces 2>/dev/null; then
|
||||
msg_warn "$(translate '/etc/network/interfaces uses allow-hotplug. Renaming interfaces via systemd .link can break that flow — review the file after reboot.')"
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$LINK_DIR"
|
||||
|
||||
|
||||
|
||||
if ls "$LINK_DIR"/*.link >/dev/null 2>&1; then
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
@@ -2523,7 +2663,7 @@ EOF
|
||||
msg_warn "$(translate "No physical interfaces found")"
|
||||
fi
|
||||
msg_success "$(translate "Setting up persistent network interfaces successfully.")"
|
||||
register_tool "persistent_network" true
|
||||
register_tool "persistent_network" true "$FUNC_VERSION"
|
||||
NECESSARY_REBOOT=1
|
||||
}
|
||||
|
||||
@@ -2866,5 +3006,11 @@ done
|
||||
|
||||
|
||||
|
||||
check_extremeshok_warning
|
||||
main_menu
|
||||
# Sprint 12B: only run the interactive menu when this script is invoked
|
||||
# directly. When sourced from another script (e.g. the post-install
|
||||
# update wrapper that re-runs a single function), don't trigger the
|
||||
# extremeshok warning or the main menu.
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
check_extremeshok_warning
|
||||
main_menu
|
||||
fi
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
#!/bin/bash
|
||||
# ==========================================================
|
||||
# ProxMenux - Complete Uninstall Optimizations Script
|
||||
# ProxMenux - Uninstall Optimizations
|
||||
# ==========================================================
|
||||
# Author : MacRimi
|
||||
# Copyright : (c) 2024 MacRimi
|
||||
# License : (GPL-3.0) (https://github.com/MacRimi/ProxMenux/blob/main/LICENSE)
|
||||
# License : GPL-3.0
|
||||
# https://github.com/MacRimi/ProxMenux/blob/main/LICENSE
|
||||
# Version : 1.0
|
||||
# Last Updated: 06/07/2025
|
||||
# ==========================================================
|
||||
# Description:
|
||||
# This script provides a complete uninstallation and rollback system
|
||||
# for all post-installation optimizations applied by ProxMenux.
|
||||
# Reverses post-install optimizations previously applied by
|
||||
# ProxMenux. Reads the installed_tools.json registry to detect
|
||||
# which tools were applied, exposes them in a checklist, and
|
||||
# runs their dedicated uninstall function — restoring original
|
||||
# configs from their .bak backups where applicable.
|
||||
#
|
||||
# It allows administrators to safely revert any changes made during the
|
||||
# optimization process, restoring the system to its original state.
|
||||
#
|
||||
# This ensures full control over system configurations and gives users
|
||||
# the confidence to apply, test, and undo ProxMenux enhancements as needed.
|
||||
# Features:
|
||||
# - Registry-driven: only shows tools currently applied.
|
||||
# - Per-tool reverse functions (one for each entry in the
|
||||
# auto / customizable scripts).
|
||||
# - Restores /etc configs from .bak backups when they exist.
|
||||
# - Reboot prompt for changes that require it (VFIO, kernel
|
||||
# cmdline, persistent NIC names, …).
|
||||
# ==========================================================
|
||||
|
||||
|
||||
@@ -633,6 +638,8 @@ uninstall_vfio_iommu() {
|
||||
msg_ok "$(translate "IOMMU parameters removed from GRUB")"
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_info "$(translate 'Updating initramfs (this may take a minute)...')"
|
||||
|
||||
update-initramfs -u -k all >/dev/null 2>&1 || true
|
||||
|
||||
@@ -804,6 +811,122 @@ migrate_installed_tools() {
|
||||
fi
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Sprint 10P — Uninstallers for items previously missing coverage.
|
||||
# Each `uninstall_*` mirrors its install function in
|
||||
# `customizable_post_install.sh` and flips `register_tool "X" false`
|
||||
# at the end so the entry is removed from the active set.
|
||||
################################################################
|
||||
|
||||
uninstall_ceph() {
|
||||
msg_info2 "$(translate 'Uninstalling Ceph...')"
|
||||
if dpkg -l 2>/dev/null | grep -qE '^ii\s+ceph'; then
|
||||
apt-get purge -y 'ceph-*' 'librados*' 'librbd*' 'libcephfs*' 'python3-ceph*' >/dev/null 2>&1 || true
|
||||
apt-get autoremove -y >/dev/null 2>&1 || true
|
||||
fi
|
||||
rm -f /etc/apt/sources.list.d/ceph.list /etc/apt/sources.list.d/ceph.sources 2>/dev/null
|
||||
rm -f /etc/apt/trusted.gpg.d/ceph.asc /etc/apt/trusted.gpg.d/ceph-release.gpg 2>/dev/null
|
||||
apt-get update -qq >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate 'Ceph packages and repository removed')"
|
||||
register_tool "ceph" false
|
||||
}
|
||||
|
||||
uninstall_ha() {
|
||||
msg_info2 "$(translate 'Disabling High Availability services...')"
|
||||
systemctl disable --now pve-ha-lrm pve-ha-crm corosync >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate 'HA services disabled (configs preserved)')"
|
||||
register_tool "ha" false
|
||||
}
|
||||
|
||||
uninstall_openvswitch() {
|
||||
msg_info2 "$(translate 'Removing OpenVSwitch...')"
|
||||
apt-get purge -y openvswitch-switch openvswitch-common >/dev/null 2>&1 || true
|
||||
apt-get autoremove -y >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate 'OpenVSwitch removed')"
|
||||
register_tool "openvswitch" false
|
||||
}
|
||||
|
||||
uninstall_tcp_optimizations() {
|
||||
msg_info2 "$(translate 'Reverting TCP BBR + Fast Open...')"
|
||||
rm -f /etc/sysctl.d/99-kernel-bbr.conf /etc/sysctl.d/99-tcp-fastopen.conf
|
||||
sysctl --system >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate 'TCP optimizations reverted (defaults restored on next reboot)')"
|
||||
register_tool "tcp_optimizations" false
|
||||
}
|
||||
|
||||
uninstall_guest_agent() {
|
||||
msg_info2 "$(translate 'Removing guest agent...')"
|
||||
local pkg=""
|
||||
if [[ -f /usr/local/share/proxmenux/guest_agent.pkg ]]; then
|
||||
pkg=$(cat /usr/local/share/proxmenux/guest_agent.pkg 2>/dev/null)
|
||||
fi
|
||||
if [[ -n "$pkg" ]]; then
|
||||
apt-get purge -y "$pkg" >/dev/null 2>&1 || true
|
||||
rm -f /usr/local/share/proxmenux/guest_agent.pkg
|
||||
msg_ok "$(translate 'Removed:') $pkg"
|
||||
else
|
||||
# Fallback: try the typical packages
|
||||
for p in qemu-guest-agent open-vm-tools virtualbox-guest-utils; do
|
||||
dpkg -s "$p" >/dev/null 2>&1 && apt-get purge -y "$p" >/dev/null 2>&1
|
||||
done
|
||||
msg_ok "$(translate 'Guest agent packages removed')"
|
||||
fi
|
||||
register_tool "guest_agent" false
|
||||
}
|
||||
|
||||
uninstall_ovh_rtm() {
|
||||
msg_info2 "$(translate 'Removing OVH RTM...')"
|
||||
# OVH RTM installs `rtm` packages and a puppet config.
|
||||
apt-get purge -y 'ovh-rtm*' 'rtm' 'rtm-*' >/dev/null 2>&1 || true
|
||||
rm -rf /etc/rtm 2>/dev/null
|
||||
msg_ok "$(translate 'OVH RTM removed (Puppet artefacts may need manual cleanup)')"
|
||||
register_tool "ovh_rtm" false
|
||||
}
|
||||
|
||||
uninstall_pigz() {
|
||||
msg_info2 "$(translate 'Reverting pigz wrapper...')"
|
||||
if [[ -f /bin/gzip.original ]]; then
|
||||
mv -f /bin/gzip.original /bin/gzip
|
||||
msg_ok "$(translate 'Restored original /bin/gzip')"
|
||||
fi
|
||||
rm -f /bin/pigzwrapper
|
||||
sed -i 's/^pigz: 1/#pigz: 1/' /etc/vzdump.conf 2>/dev/null || true
|
||||
apt-get purge -y pigz >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate 'pigz removed')"
|
||||
register_tool "pigz" false
|
||||
}
|
||||
|
||||
uninstall_zfs_arc() {
|
||||
msg_info2 "$(translate 'Reverting ZFS ARC tuning...')"
|
||||
if [[ -f /etc/modprobe.d/99-zfsarc.conf.bak ]]; then
|
||||
mv -f /etc/modprobe.d/99-zfsarc.conf.bak /etc/modprobe.d/99-zfsarc.conf
|
||||
msg_ok "$(translate 'Original ZFS ARC config restored from .bak')"
|
||||
else
|
||||
rm -f /etc/modprobe.d/99-zfsarc.conf
|
||||
msg_ok "$(translate 'ZFS ARC config removed (kernel defaults will apply on reboot)')"
|
||||
fi
|
||||
register_tool "zfs_arc" false
|
||||
}
|
||||
|
||||
uninstall_zfs_auto_snapshot() {
|
||||
msg_info2 "$(translate 'Removing zfs-auto-snapshot...')"
|
||||
apt-get purge -y zfs-auto-snapshot >/dev/null 2>&1 || true
|
||||
msg_ok "$(translate 'zfs-auto-snapshot removed (existing snapshots preserved on the pool)')"
|
||||
register_tool "zfs_auto_snapshot" false
|
||||
}
|
||||
|
||||
uninstall_vzdump_speed() {
|
||||
msg_info2 "$(translate 'Reverting vzdump speed tuning...')"
|
||||
if [[ -f /etc/vzdump.conf.bak ]]; then
|
||||
mv -f /etc/vzdump.conf.bak /etc/vzdump.conf
|
||||
msg_ok "$(translate 'Restored original /etc/vzdump.conf from .bak')"
|
||||
else
|
||||
sed -i '/^bwlimit: 0$/d;/^ionice: 5$/d' /etc/vzdump.conf 2>/dev/null
|
||||
msg_ok "$(translate 'Removed bwlimit/ionice tuning (no .bak found)')"
|
||||
fi
|
||||
register_tool "vzdump_speed" false
|
||||
}
|
||||
|
||||
################################################################
|
||||
|
||||
show_uninstall_menu() {
|
||||
@@ -843,6 +966,16 @@ show_uninstall_menu() {
|
||||
amd_fixes) desc="AMD CPU (Ryzen/EPYC) fixes";;
|
||||
vfio_iommu) desc="IOMMU/VFIO PCI Passthrough";;
|
||||
persistent_network) desc="Setting persistent network interfaces";;
|
||||
ceph) desc="Ceph (squid) packages + repo";;
|
||||
ha) desc="High Availability services (corosync/HA)";;
|
||||
openvswitch) desc="OpenVSwitch";;
|
||||
tcp_optimizations) desc="TCP BBR + Fast Open";;
|
||||
guest_agent) desc="Guest agent (qemu/vmware/virtualbox)";;
|
||||
ovh_rtm) desc="OVH Real-Time Monitoring";;
|
||||
pigz) desc="pigz (parallel gzip wrapper)";;
|
||||
zfs_arc) desc="ZFS ARC size tuning";;
|
||||
zfs_auto_snapshot) desc="zfs-auto-snapshot package";;
|
||||
vzdump_speed) desc="vzdump bwlimit/ionice tuning";;
|
||||
*) desc="$tool";;
|
||||
esac
|
||||
menu_options+=("$tool" "$desc" "off")
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
#!/bin/bash
|
||||
# ==========================================================
|
||||
# ProxMenux - Sprint 12B: re-run a single post-install function
|
||||
# ==========================================================
|
||||
# Invoked by the Monitor's "Update" buttons (Settings → ProxMenux
|
||||
# Optimizations) and by the bash menu's update flow. Sources the
|
||||
# appropriate post_install script and invokes one specific function so
|
||||
# the user can update a single tool without re-running the whole flow.
|
||||
#
|
||||
# Two invocation modes:
|
||||
#
|
||||
# SINGLE — set SOURCE_TYPE + FUNCTION_NAME (+ optionally TOOL_KEY):
|
||||
# SOURCE_TYPE=auto FUNCTION_NAME=install_log2ram_auto
|
||||
#
|
||||
# BATCH — set FUNCTIONS_BATCH to a newline-separated list of
|
||||
# "source:function:tool_key" triples (tool_key optional):
|
||||
# FUNCTIONS_BATCH="auto:install_log2ram_auto:log2ram
|
||||
# custom:install_ceph:ceph"
|
||||
#
|
||||
# In batch mode the wrapper iterates the list, sourcing each flow once
|
||||
# and re-using its function definitions. Tools coming from the same
|
||||
# flow share a single source step so the terminal output stays clean.
|
||||
# ==========================================================
|
||||
|
||||
set -e
|
||||
|
||||
LOCAL_SCRIPTS="/usr/local/share/proxmenux/scripts"
|
||||
BASE_DIR="/usr/local/share/proxmenux"
|
||||
UTILS_FILE="$BASE_DIR/utils.sh"
|
||||
|
||||
if [[ -f "$UTILS_FILE" ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "$UTILS_FILE"
|
||||
fi
|
||||
|
||||
if command -v load_language >/dev/null 2>&1; then
|
||||
load_language
|
||||
fi
|
||||
if command -v initialize_cache >/dev/null 2>&1; then
|
||||
initialize_cache
|
||||
fi
|
||||
|
||||
if command -v show_proxmenux_logo >/dev/null 2>&1; then
|
||||
show_proxmenux_logo
|
||||
fi
|
||||
|
||||
SOURCE_TYPE="${SOURCE_TYPE:-}"
|
||||
FUNCTION_NAME="${FUNCTION_NAME:-}"
|
||||
TOOL_KEY="${TOOL_KEY:-${FUNCTION_NAME}}"
|
||||
FUNCTIONS_BATCH="${FUNCTIONS_BATCH:-}"
|
||||
|
||||
# Build the list of (source, function, tool_key) tuples from either the
|
||||
# single-mode env vars or the batch payload.
|
||||
declare -a BATCH=()
|
||||
if [[ -n "$FUNCTIONS_BATCH" ]]; then
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
BATCH+=("$line")
|
||||
done <<< "$FUNCTIONS_BATCH"
|
||||
elif [[ -n "$SOURCE_TYPE" && -n "$FUNCTION_NAME" ]]; then
|
||||
BATCH+=("${SOURCE_TYPE}:${FUNCTION_NAME}:${TOOL_KEY}")
|
||||
else
|
||||
echo "ERROR: provide either SOURCE_TYPE+FUNCTION_NAME (single mode) or FUNCTIONS_BATCH (batch mode)."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Source the flow scripts on first use. Both auto and customizable
|
||||
# guard their entry point with `if [[ "${BASH_SOURCE[0]}" == "${0}" ]]`,
|
||||
# so sourcing loads function definitions without triggering the
|
||||
# interactive menu or the extremeshok dialog.
|
||||
# ----------------------------------------------------------------------
|
||||
SOURCED_AUTO=0
|
||||
SOURCED_CUSTOM=0
|
||||
ensure_flow_loaded() {
|
||||
local source_type="$1"
|
||||
case "$source_type" in
|
||||
auto)
|
||||
if [[ $SOURCED_AUTO -eq 0 ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$LOCAL_SCRIPTS/post_install/auto_post_install.sh"
|
||||
SOURCED_AUTO=1
|
||||
fi
|
||||
;;
|
||||
custom)
|
||||
if [[ $SOURCED_CUSTOM -eq 0 ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$LOCAL_SCRIPTS/post_install/customizable_post_install.sh"
|
||||
SOURCED_CUSTOM=1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: invalid source '$source_type' (must be 'auto' or 'custom')"
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Run each tool. We don't bail on the first failure — the user marked a
|
||||
# multi-select, they expect every chosen tool to be attempted. RCs are
|
||||
# collected and the wrapper exits non-zero if any failed.
|
||||
# ----------------------------------------------------------------------
|
||||
TOTAL=${#BATCH[@]}
|
||||
FAILED=0
|
||||
INDEX=0
|
||||
for entry in "${BATCH[@]}"; do
|
||||
INDEX=$((INDEX + 1))
|
||||
IFS=':' read -r src fn tkey <<< "$entry"
|
||||
[[ -z "$tkey" ]] && tkey="$fn"
|
||||
|
||||
if command -v msg_info2 >/dev/null 2>&1; then
|
||||
msg_info2 "[$INDEX/$TOTAL] Updating ${tkey} (running ${fn} from ${src} flow)..."
|
||||
else
|
||||
echo "[ProxMenux] [$INDEX/$TOTAL] Updating ${tkey} (running ${fn} from ${src} flow)..."
|
||||
fi
|
||||
|
||||
if ! ensure_flow_loaded "$src"; then
|
||||
FAILED=$((FAILED + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! declare -F "$fn" >/dev/null 2>&1; then
|
||||
if command -v msg_error >/dev/null 2>&1; then
|
||||
msg_error "Function '$fn' is not defined in the ${src} flow."
|
||||
else
|
||||
echo "ERROR: function '$fn' is not defined in the ${src} flow."
|
||||
fi
|
||||
FAILED=$((FAILED + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
set +e
|
||||
"$fn"
|
||||
RC=$?
|
||||
set -e
|
||||
|
||||
if [[ $RC -eq 0 ]]; then
|
||||
if command -v msg_ok >/dev/null 2>&1; then
|
||||
msg_ok "Update for ${tkey} completed."
|
||||
else
|
||||
echo "[ProxMenux] Update for ${tkey} completed."
|
||||
fi
|
||||
else
|
||||
if command -v msg_error >/dev/null 2>&1; then
|
||||
msg_error "Update for ${tkey} exited with status $RC."
|
||||
else
|
||||
echo "ERROR: update for ${tkey} exited with status $RC."
|
||||
fi
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $FAILED -eq 0 ]]; then
|
||||
if command -v msg_success >/dev/null 2>&1; then
|
||||
msg_success "All $TOTAL update(s) completed successfully."
|
||||
else
|
||||
echo "[ProxMenux] All $TOTAL update(s) completed successfully."
|
||||
fi
|
||||
else
|
||||
if command -v msg_warn >/dev/null 2>&1; then
|
||||
msg_warn "$FAILED of $TOTAL updates failed — see the messages above."
|
||||
else
|
||||
echo "WARNING: $FAILED of $TOTAL updates failed."
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v msg_success >/dev/null 2>&1; then
|
||||
msg_success "Press Enter to close this terminal..."
|
||||
else
|
||||
echo "Press Enter to close this terminal..."
|
||||
fi
|
||||
read -r 2>/dev/null || true
|
||||
|
||||
[[ $FAILED -eq 0 ]] && exit 0 || exit 1
|
||||
Reference in New Issue
Block a user