PVE-mods/src/Scripts/pve-mod-configure
2026-06-13 19:45:18 +02:00

581 lines
24 KiB
Bash

#!/usr/bin/env bash
#
# pve-mod-configure - Interactive configuration tool for pve-mod
# Detects hardware, asks the user which features to enable, writes
# /etc/pve-mod/pve-mod.conf, and applies patches to PVE system files.
set -euo pipefail
CONF_FILE="/etc/pve-mod/pve-mod.conf"
CONFD_DIR="/etc/pve-mod/conf.d"
NODE_INFO_CONF="${CONFD_DIR}/node_info.conf"
NAG_SCREEN_CONF="${CONFD_DIR}/nag_screen.conf"
APPLY_PATCHES="/usr/lib/pve-mod/apply-patches.sh"
NODES_PM="/usr/share/perl5/PVE/API2/Nodes.pm"
KNOWN_CPU_SENSORS=("coretemp-isa-" "k10temp-pci-")
#region helpers
msgb() { echo -e "\e[1m${1}\e[0m"; }
info() { echo -e "\e[0;32m[info] ${1}\e[0m"; }
warn() { echo -e "\e[0;33m[warning] ${1}\e[0m"; }
err() { echo -e "\e[0;31m[error] ${1}\e[0m"; exit 1; }
ask() {
local prompt="$1" response
read -r -p $'\n\e[1;36m'"${prompt}:"$'\e[0m ' response
echo "$response"
}
bool() { [[ "$1" == true ]] && echo 1 || echo 0; }
_load_conf() {
[[ -f "$NODE_INFO_CONF" ]] || return 0
local in_debug=0 line key val
while IFS= read -r line; do
case "$line" in
'#'*|'') continue ;;
'['*']') section="${line#[}"; section="${section%]}"; continue ;;
esac
[[ "$line" == *=* ]] || continue
key="${line%%=*}"; val="${line#*=}"
case "${section}.${key}" in
# [modules]
modules.node_info) MOD_NODE_INFO="$val" ;;
modules.nag_screen) MOD_NAG_SCREEN="$val" ;;
# [gpu]
gpu.intel_enabled) ENABLE_INTEL_GPU_INFO="$val" ;;
gpu.nvidia_enabled) ENABLE_NVIDIA_GPU_INFO="$val" ;;
gpu.amd_enabled) ENABLE_AMD_GPU_INFO="$val" ;;
gpu.gpu_history) ENABLE_GPU_HISTORY="$val" ;;
# [lm_sensors]
lm_sensors.enabled) LM_SENSORS_ENABLED="$val" ;;
lm_sensors.enable_cpu) ENABLE_CPU="$val" ;;
lm_sensors.cpu_temp_target) CPU_TEMP_TARGET="$val" ;;
lm_sensors.enable_ram_temp) ENABLE_RAM_TEMP="$val" ;;
lm_sensors.enable_hdd_temp) ENABLE_HDD_TEMP="$val" ;;
lm_sensors.enable_nvme_temp) ENABLE_NVME_TEMP="$val" ;;
lm_sensors.enable_fan_speed) ENABLE_FAN_SPEED="$val" ;;
lm_sensors.display_zero_speed_fans) DISPLAY_ZERO_SPEED_FANS="$val" ;;
lm_sensors.temp_unit) TEMP_UNIT="$val" ;;
# [ups]
ups.enabled) ENABLE_UPS="$val" ;;
ups.device_name) UPS_DEVICE_NAME="$val" ;;
# [system_info]
system_info.enabled) ENABLE_SYSTEM_INFO="$val" ;;
system_info.type) SYSTEM_INFO_TYPE="$val" ;;
# [pve_trigger]
pve_trigger.enabled) PVE_TRIGGER_ENABLED="$val" ;;
# [debug]
debug.lm_sensors_mode) DEBUG_LM_SENSORS="$val" ;;
debug.lm_sensors_output_file) DEBUG_LM_SENSORS_FILE="$val" ;;
debug.intel_mode) DEBUG_INTEL="$val" ;;
debug.intel_devices_file) DEBUG_INTEL_FILE="$val" ;;
debug.intel_output_file) DEBUG_INTEL_OUTPUT_FILE="$val" ;;
debug.nvidia_mode) DEBUG_NVIDIA="$val" ;;
debug.nvidia_devices_file) DEBUG_NVIDIA_DEVICES_FILE="$val" ;;
debug.nvidia_output_file) DEBUG_NVIDIA_OUTPUT_FILE="$val" ;;
debug.amd_mode) DEBUG_AMD="$val" ;;
debug.amd_devices_file) DEBUG_AMD_FILE="$val" ;;
debug.ups_mode) DEBUG_UPS="$val" ;;
debug.ups_output_file) DEBUG_UPS_FILE="$val" ;;
debug.log_enabled) DEBUG_LOG="$val" ;;
debug.log_file) DEBUG_LOG_FILE="$val" ;;
esac
done < "$NODE_INFO_CONF"
}
#endregion helpers
sanitize_sensors_output() {
local input="$1"
echo "$input" | perl -0777 -pe '
s/ERROR:.+\s(\w+):\s(.+)/"$1": 0.000,/g;
s/ERROR:.+\s(\w+)!/"$1": 0.000,/g;
s/,\s*(\})/$1/g;
s/\bNaN\b/null/g;
s/"SODIMM"\s*:\s*\{\s*"temp(\d+)_input"/"SODIMM $1": {\n "temp$1_input"/g;
s/"([^"]*Fan[^"]*)"\s*:\s*\{\s*"fan(\d+)_input"/"$1 $2": {\n "fan$2_input"/g;
' | python3 -m json.tool 2>/dev/null || echo "$input"
}
_check_or_install_tool() {
local cmd="$1" pkg="$2" description="$3"
if command -v "$cmd" &>/dev/null; then
info "$description is installed."
return 0
fi
local choice
choice=$(ask "$description is not installed. Install it now? (y/N)")
case "$choice" in
[yY])
apt-get update -qq
apt-get install -y "$pkg"
command -v "$cmd" &>/dev/null && { info "$description installed."; return 0; } || \
{ warn "$description installation failed. Section will be skipped."; return 1; }
;;
*)
info "Skipping $description."
return 1
;;
esac
}
_check_nvidia_tool() {
if command -v nvidia-smi &>/dev/null; then
info "nvidia-smi is installed."
return 0
fi
warn "nvidia-smi not found. NVIDIA monitoring requires NVIDIA drivers (not installable via apt)."
return 1
}
#region node-info wizard
configure_node_info() {
# Initialize all variables to off
LM_SENSORS_ENABLED=0
ENABLE_CPU=0; CPU_TEMP_TARGET="Core"
ENABLE_RAM_TEMP=0; ENABLE_HDD_TEMP=0; ENABLE_NVME_TEMP=0
ENABLE_FAN_SPEED=0; DISPLAY_ZERO_SPEED_FANS=0; TEMP_UNIT="C"
ENABLE_INTEL_GPU_INFO=0; ENABLE_NVIDIA_GPU_INFO=0; ENABLE_AMD_GPU_INFO=0
ENABLE_GPU_HISTORY=0
ENABLE_UPS=0; UPS_DEVICE_NAME="ups@localhost"
ENABLE_SYSTEM_INFO=0; SYSTEM_INFO_TYPE=1
local lm_sensors_ok=false
local sensors_detected=false
if [[ "$DEBUG_LM_SENSORS" -eq 1 && -f "$DEBUG_LM_SENSORS_FILE" ]]; then
info "[debug] Using sensor data from $DEBUG_LM_SENSORS_FILE"
lm_sensors_ok=true; LM_SENSORS_ENABLED=1
else
_check_or_install_tool sensors lm-sensors "lm-sensors" && lm_sensors_ok=true && LM_SENSORS_ENABLED=1
fi
if [[ "$lm_sensors_ok" == true ]]; then
local sensorsOutput
if [[ "$DEBUG_LM_SENSORS" -eq 1 ]]; then
sensorsOutput=$(cat "$DEBUG_LM_SENSORS_FILE")
else
sensorsOutput=$(sensors -j 2>/dev/null) || true
fi
local trimmedSensorsOutput
trimmedSensorsOutput=$(echo "$sensorsOutput" | tr -d '[:space:]')
if [[ -z "$trimmedSensorsOutput" || "$trimmedSensorsOutput" == "{}" ]]; then
warn "lm-sensors is installed but reported no sensors."
warn "No kernel sensor drivers appear to be loaded."
warn "Run 'sensors-detect' and load the suggested modules, then re-run this configurator."
warn "lm-sensors output is the foundation for this mod. Mod cannot be enabled without it."
exit 0
lm_sensors_ok=false
LM_SENSORS_ENABLED=0
fi
fi
if [[ "$lm_sensors_ok" == true ]]; then
local sanitisedSensorsOutput
sanitisedSensorsOutput=$(sanitize_sensors_output "$sensorsOutput")
#region CPU
msgb "\n=== Detecting CPU temperature sensors ==="
local cpuList="" cpuCount=0
for pattern in "${KNOWN_CPU_SENSORS[@]}"; do
local found_cpus
found_cpus=$(echo "$sanitisedSensorsOutput" | grep -o "\"${pattern}[^\"]*\"" || true | sed 's/"//g')
if [[ -n "$found_cpus" ]]; then
while read -r sensor; do
[[ -z "$sensor" ]] && continue
cpuCount=$((cpuCount + 1))
cpuList="${cpuList:+$cpuList,}$sensor"
ENABLE_CPU=1
done <<< "$found_cpus"
fi
done
if [[ "$ENABLE_CPU" -eq 1 ]]; then
info "Detected CPU sensors ($cpuCount): $cpuList"
sensors_detected=true
while true; do
local choice
choice=$(ask "Display temperatures for all cores [C] or average per CPU [a]? (C/a)")
case "$choice" in
[cC]|"") CPU_TEMP_TARGET="Core"; info "Showing per-core temperatures."; break ;;
[aA]) CPU_TEMP_TARGET="Package"; info "Showing average per-CPU temperature."; break ;;
*) warn "Invalid input, choose C or a." ;;
esac
done
else
warn "No CPU temperature sensors found."
fi
#endregion CPU
#region RAM
msgb "\n=== Detecting RAM temperature sensors ==="
local ramCount
ramCount=$(grep -c '"SODIMM[^"]*"' <<<"$sanitisedSensorsOutput" || true)
if [[ "$ramCount" -gt 0 ]]; then
info "Detected $ramCount RAM sensor(s)."
ENABLE_RAM_TEMP=1; sensors_detected=true
else
warn "No RAM temperature sensors found."
fi
#endregion RAM
#region HDD/SSD
msgb "\n=== Detecting HDD/SSD temperature sensors ==="
local hddList
hddList=$(echo "$sanitisedSensorsOutput" | grep -o '"drivetemp-scsi[^"]*"' | sed 's/"//g' | wc -l || true)
if [[ "$hddList" -gt 0 ]]; then
info "Detected $hddList HDD/SSD sensor(s)."
ENABLE_HDD_TEMP=1; sensors_detected=true
else
warn "No HDD/SSD temperature sensors found. (Requires kernel module 'drivetemp'.)"
fi
#endregion HDD/SSD
#region NVMe
msgb "\n=== Detecting NVMe temperature sensors ==="
local nvmeCount
nvmeCount=$(echo "$sanitisedSensorsOutput" | grep -c '"nvme[^"]*"' || true)
if [[ "$nvmeCount" -gt 0 ]]; then
info "Detected $nvmeCount NVMe sensor(s)."
ENABLE_NVME_TEMP=1; sensors_detected=true
else
warn "No NVMe temperature sensors found."
fi
#endregion NVMe
#region Fans
msgb "\n=== Detecting fan speed sensors ==="
local fanCount
fanCount=$(grep -c 'fan[0-9]\+_input' <<<"$sanitisedSensorsOutput" || true)
if [[ "$fanCount" -gt 0 ]]; then
info "Detected $fanCount fan speed reading(s)."
ENABLE_FAN_SPEED=1; sensors_detected=true
local choice
choice=$(ask "Display fans reporting zero speed? (Y/n)")
case "$choice" in
[nN]) DISPLAY_ZERO_SPEED_FANS=0; info "Zero-speed fans will be hidden." ;;
*) DISPLAY_ZERO_SPEED_FANS=1; info "Zero-speed fans will be shown." ;;
esac
else
warn "No fan speed sensors found."
fi
#endregion Fans
#region Temperature unit
if [[ "$sensors_detected" == true ]]; then
msgb "\n=== Temperature unit ==="
local unit
unit=$(ask "Display temperatures in Celsius [C] or Fahrenheit [f]? (C/f)")
case "$unit" in
[fF]) TEMP_UNIT="F"; info "Using Fahrenheit." ;;
*) TEMP_UNIT="C"; info "Using Celsius." ;;
esac
fi
#endregion Temperature unit
fi
#region Intel GPU
msgb "\n=== Detecting Intel GPU ==="
local intelCards=""
if [[ "$DEBUG_INTEL" -eq 1 && -f "$DEBUG_INTEL_FILE" ]]; then
info "[debug] Using Intel GPU data from $DEBUG_INTEL_FILE"
intelCards=$(cat "$DEBUG_INTEL_FILE")
if [[ -n "$intelCards" ]]; then
info "Intel GPU(s) detected (debug):"
echo "$intelCards" | while IFS= read -r line; do echo " $line"; done
if [[ -f "$DEBUG_INTEL_OUTPUT_FILE" ]]; then
info "[debug] Intel GPU stats output file found at $DEBUG_INTEL_OUTPUT_FILE"
ENABLE_INTEL_GPU_INFO=1
else
warn "[debug] Intel GPU stats output file not found at $DEBUG_INTEL_OUTPUT_FILE. GPU stats graphs will be empty."
fi
else
warn "No Intel GPUs in debug file."
fi
elif _check_or_install_tool intel_gpu_top intel-gpu-tools "Intel GPU tools (intel-gpu-tools)"; then
intelCards=$(intel_gpu_top -L 2>/dev/null | grep -E '^card[0-9]+' || true)
if [[ -n "$intelCards" ]]; then
info "Intel GPU(s) detected:"
echo "$intelCards" | while IFS= read -r line; do echo " $line"; done
ENABLE_INTEL_GPU_INFO=1
else
warn "No Intel GPUs detected by intel_gpu_top."
fi
fi
#endregion Intel GPU
#region NVIDIA GPU
msgb "\n=== Detecting NVIDIA GPU ==="
if [[ "$DEBUG_NVIDIA" -eq 1 && -f "$DEBUG_NVIDIA_DEVICES_FILE" ]]; then
info "[debug] Using NVIDIA GPU data from $DEBUG_NVIDIA_DEVICES_FILE"
local nvidiaCards
nvidiaCards=$(cat "$DEBUG_NVIDIA_DEVICES_FILE")
if [[ -n "$nvidiaCards" ]]; then
info "NVIDIA GPU(s) detected (debug):"
echo "$nvidiaCards" | while IFS= read -r line; do echo " $line"; done
if [[ -f "$DEBUG_NVIDIA_OUTPUT_FILE" ]]; then
info "[debug] NVIDIA GPU stats output file found at $DEBUG_NVIDIA_OUTPUT_FILE"
ENABLE_NVIDIA_GPU_INFO=1
else
warn "[debug] NVIDIA GPU stats output file not found at $DEBUG_NVIDIA_OUTPUT_FILE. GPU stats graphs will be empty."
fi
else
warn "No NVIDIA GPUs in debug file."
fi
elif _check_nvidia_tool; then
local nvidiaCards
nvidiaCards=$(nvidia-smi -L 2>/dev/null || true)
if [[ -n "$nvidiaCards" ]]; then
info "NVIDIA GPU(s) detected:"
echo "$nvidiaCards" | while IFS= read -r line; do echo " $line"; done
ENABLE_NVIDIA_GPU_INFO=1
else
warn "No NVIDIA GPUs detected by nvidia-smi."
fi
fi
#endregion NVIDIA GPU
#region AMD GPU (placeholder)
ENABLE_AMD_GPU_INFO=0
#endregion AMD GPU
#region GPU history
if [[ "$ENABLE_INTEL_GPU_INFO" -eq 1 || "$ENABLE_NVIDIA_GPU_INFO" -eq 1 ]]; then
msgb "\n=== GPU Historical Data ==="
local choice
choice=$(ask "Store historical GPU data for graphs? (y/N)")
case "$choice" in
[yY]) ENABLE_GPU_HISTORY=1; info "Historical GPU data will be stored." ;;
*) info "Historical GPU data disabled." ;;
esac
fi
#endregion GPU history
#region UPS
msgb "\n=== UPS Information ==="
local choiceUPS
choiceUPS=$(ask "Enable UPS information? (y/N)")
case "$choiceUPS" in
[yY])
local upsConn modelName upsOutput
upsConn=$(ask "Enter UPS connection string (e.g. upsname@hostname[:port])")
if [[ "$DEBUG_UPS" -eq 1 ]]; then
if [[ -f "$DEBUG_UPS_FILE" ]]; then
info "[debug] Using UPS data from $DEBUG_UPS_FILE"
else
warn "[debug] Debug mode for UPS is enabled but file not found at $DEBUG_UPS_FILE."
fi
upsOutput=$(cat "$DEBUG_UPS_FILE" || true)
ENABLE_UPS=1
elif _check_or_install_tool upsc nut-client "Network UPS Tools (upsc)" && [[ -n "$upsConn" ]]; then
upsOutput=$(upsc "$upsConn" 2>/dev/null || true)
else
warn "Could not connect to UPS at '$upsConn'. UPS info will be disabled."
fi
if [[ -n "$upsOutput" ]]; then
modelName=$(echo "$upsOutput" | grep "device.model:" | cut -d: -f2- | xargs)
ENABLE_UPS=1
UPS_DEVICE_NAME="$upsConn"
info "Connected to UPS: $modelName at $upsConn"
else
warn "Could not connect to UPS at '$upsConn'. UPS info will be disabled."
ENABLE_UPS=0
fi
;;
*) info "UPS information disabled." ;;
esac
#endregion UPS
#region System info
msgb "\n=== System Information ==="
echo " type 1) System information (manufacturer, product, serial)"
dmidecode -t 1 2>/dev/null | awk -F': ' '/Manufacturer|Product Name|Serial Number/ {print " "$0}' || true
echo " type 2) Baseboard/Motherboard information"
dmidecode -t 2 2>/dev/null | awk -F': ' '/Manufacturer|Product Name|Serial Number/ {print " "$0}' || true
local choiceSys
choiceSys=$(ask "Enable system information? (1/2/n)")
case "$choiceSys" in
1|"") ENABLE_SYSTEM_INFO=1; SYSTEM_INFO_TYPE=1; info "System information (type 1) will be shown." ;;
2) ENABLE_SYSTEM_INFO=1; SYSTEM_INFO_TYPE=2; info "Baseboard information (type 2) will be shown." ;;
[nN]) info "System information disabled." ;;
*) warn "Invalid selection. Defaulting to type 1."; ENABLE_SYSTEM_INFO=1; SYSTEM_INFO_TYPE=1 ;;
esac
#endregion System info
}
#endregion node-info wizard
#region write config
write_config() {
mkdir -p "$(dirname "$CONF_FILE")" "$CONFD_DIR"
# Main config: which mods are enabled + global trigger/service settings.
cat > "$CONF_FILE" <<EOF
# pve-mod main configuration file
# Managed by pve-mod-configure. Re-run to update.
#
# This file only declares which mods are enabled. Each mod keeps its own
# settings in ${CONFD_DIR}/<mod>.conf
[modules]
node_info=${MOD_NODE_INFO}
nag_screen=${MOD_NAG_SCREEN}
[pve_trigger]
enabled=${PVE_TRIGGER_ENABLED}
EOF
info "Main configuration saved to $CONF_FILE"
# node_info mod config.
cat > "$NODE_INFO_CONF" <<EOF
# pve-mod :: node_info mod configuration
# Managed by pve-mod-configure. Re-run to update.
[gpu]
intel_enabled=${ENABLE_INTEL_GPU_INFO}
nvidia_enabled=${ENABLE_NVIDIA_GPU_INFO}
amd_enabled=${ENABLE_AMD_GPU_INFO}
gpu_history=${ENABLE_GPU_HISTORY}
[lm_sensors]
enabled=${LM_SENSORS_ENABLED}
enable_cpu=${ENABLE_CPU}
cpu_temp_target=${CPU_TEMP_TARGET}
enable_ram_temp=${ENABLE_RAM_TEMP}
enable_hdd_temp=${ENABLE_HDD_TEMP}
enable_nvme_temp=${ENABLE_NVME_TEMP}
enable_fan_speed=${ENABLE_FAN_SPEED}
display_zero_speed_fans=${DISPLAY_ZERO_SPEED_FANS}
temp_unit=${TEMP_UNIT}
[ups]
enabled=${ENABLE_UPS}
device_name=${UPS_DEVICE_NAME}
[system_info]
enabled=${ENABLE_SYSTEM_INFO}
type=${SYSTEM_INFO_TYPE}
# Debug mode: when a collector's mode is 1, the real tool is not required.
# Data is read from the file path instead. Useful for development/testing.
[debug]
lm_sensors_mode=${DEBUG_LM_SENSORS}
lm_sensors_output_file=${DEBUG_LM_SENSORS_FILE}
intel_mode=${DEBUG_INTEL}
intel_devices_file=${DEBUG_INTEL_FILE}
nvidia_mode=${DEBUG_NVIDIA}
nvidia_devices_file=${DEBUG_NVIDIA_DEVICES_FILE}
nvidia_output_file=${DEBUG_NVIDIA_OUTPUT_FILE}
amd_mode=${DEBUG_AMD}
amd_devices_file=${DEBUG_AMD_FILE}
ups_mode=${DEBUG_UPS}
ups_output_file=${DEBUG_UPS_FILE}
log_enabled=${DEBUG_LOG}
log_file=${DEBUG_LOG_FILE}
EOF
info "node_info configuration saved to $NODE_INFO_CONF"
# nag_screen mod config (placeholder; no tunable settings).
if [[ ! -f "$NAG_SCREEN_CONF" ]]; then
cat > "$NAG_SCREEN_CONF" <<EOF
# pve-mod :: nag_screen mod configuration
# The nag-screen mod has no tunable settings; this file is a placeholder
# kept for consistency with the per-mod conf.d layout.
EOF
fi
}
#endregion write config
main() {
# ── Welcome banner ────────────────────────────────────────────────────────
local _version
_version=$(dpkg-query -W -f='${Version}' pve-mod 2>/dev/null || echo "unknown")
echo -e "\e[1;34m"
echo " ██████╗ ██╗ ██╗███████╗ ███╗ ███╗ ██████╗ ██████╗ ███████╗"
echo " ██╔══██╗██║ ██║██╔════╝ ████╗ ████║██╔═══██╗██╔══██╗██╔════╝"
echo " ██████╔╝██║ ██║█████╗ ██╔████╔██║██║ ██║██║ ██║███████╗"
echo " ██╔═══╝ ╚██╗ ██╔╝██╔══╝ ██║╚██╔╝██║██║ ██║██║ ██║╚════██║"
echo " ██║ ╚████╔╝ ███████╗ ██║ ╚═╝ ██║╚██████╔╝██████╔╝███████║"
echo " ╚═╝ ╚═══╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝"
echo -e "\e[0m"
echo -e "\e[1m PVE-mods Configurator \e[0;36mv${_version}\e[0m"
echo -e " Proxmox VE enhancement suite — hardware monitoring, GPU info & more\n"
# ── Root check ────────────────────────────────────────────────────────────
[[ $EUID -eq 0 ]] || err "This script must be run as root."
# ── Prerequisite check ────────────────────────────────────────────────────
if [[ ! -x "$APPLY_PATCHES" ]]; then
err "pve-mod is not installed (cannot find $APPLY_PATCHES).\nInstall it first: dpkg -i pve-mod_*.deb"
fi
# ── Legacy installation check ─────────────────────────────────────────────
if grep -qF '$res->{sensorsJSONOutput}' "$NODES_PM" 2>/dev/null || \
grep -qF '$res->{systemInfo}' "$NODES_PM" 2>/dev/null; then
err "A legacy pve-mod bash-script installation was detected in Nodes.pm.\nRemove it first:\n bash /path/to/pve-mod-gui-sensors.sh uninstall"
fi
# ── Initialize all config variables with safe defaults ────────────────────
MOD_NODE_INFO=0; MOD_NAG_SCREEN=0
LM_SENSORS_ENABLED=0
ENABLE_CPU=0; CPU_TEMP_TARGET="Core"
ENABLE_RAM_TEMP=0; ENABLE_HDD_TEMP=0; ENABLE_NVME_TEMP=0
ENABLE_FAN_SPEED=0; DISPLAY_ZERO_SPEED_FANS=0; TEMP_UNIT="C"
ENABLE_INTEL_GPU_INFO=0; ENABLE_NVIDIA_GPU_INFO=0; ENABLE_AMD_GPU_INFO=0
ENABLE_GPU_HISTORY=0
ENABLE_UPS=0; UPS_DEVICE_NAME="ups@localhost"
ENABLE_SYSTEM_INFO=0; SYSTEM_INFO_TYPE=1
PVE_TRIGGER_ENABLED=0
DEBUG_LM_SENSORS=0; DEBUG_LM_SENSORS_FILE="/tmp/sensors-output.json"
DEBUG_INTEL=0; DEBUG_INTEL_FILE="/tmp/intel-gpu-devices.txt"
DEBUG_INTEL_OUTPUT_FILE="/tmp/intel-gpu-top-output.txt"
DEBUG_NVIDIA=0; DEBUG_NVIDIA_OUTPUT_FILE="/tmp/nvidia-smi-output.csv"
DEBUG_NVIDIA_DEVICES_FILE="/tmp/nvidia-smi-devices.csv"
DEBUG_AMD=0; DEBUG_AMD_FILE="/tmp/amd-gpu-devices.json"
DEBUG_UPS=0; DEBUG_UPS_FILE="/tmp/ups-output.json"
DEBUG_LOG=0; DEBUG_LOG_FILE="/tmp/pve-mod-debug.log"
_load_conf
# ── Module / feature selection ────────────────────────────────────────────
# Existing settings are loaded above; the user picks ONE option to (re)configure
# this run, and all other options retain their previously saved values.
msgb "\n=== pve-mod Module Selection ==="
echo "Available options (select one):"
echo " [1] Node Info — sensor readings, GPU stats, UPS, system information"
echo " [2] Nag Screen — remove Proxmox subscription nag screen"
echo " [3] Auto re-patch on PVE upgrade — automatically re-apply patches when"
echo " pve-manager is upgraded"
echo " [n] None / cancel"
local modChoice
modChoice=$(ask "Select an option to enable (1/2/3/n)")
case "$modChoice" in
1)
MOD_NODE_INFO=1
msgb "\n=== Node Info Configuration ==="
configure_node_info
;;
2)
MOD_NAG_SCREEN=1
msgb "\n=== Nag Screen ==="
info "Subscription nag screen removal will be applied."
;;
3)
PVE_TRIGGER_ENABLED=1
info "Auto re-patching on PVE upgrade enabled."
;;
[nN]) info "No option selected. Exiting."; exit 0 ;;
*) warn "Invalid selection. Exiting."; exit 0 ;;
esac
# ── Write config and apply ────────────────────────────────────────────────
write_config
msgb "\n=== Applying patches ==="
"$APPLY_PATCHES"
msgb "\n=== Done ==="
info "pve-mod is configured and active."
info "Clear your browser cache to see the changes."
}
main