refactor mod configurator (#222)
* refactor mod configurator * ci: add apt-get update before install in test-release and weekly-patch-test workflows --------- Co-authored-by: Meliox <na> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
parent
e44ad6400a
commit
96b8a1277e
@ -3,19 +3,19 @@
|
|||||||
# pve-mod-configure - Interactive configuration tool for pve-mod
|
# pve-mod-configure - Interactive configuration tool for pve-mod
|
||||||
# Detects hardware, asks the user which features to enable, writes
|
# Detects hardware, asks the user which features to enable, writes
|
||||||
# /etc/pve-mod/pve-mod.conf, and applies patches to PVE system files.
|
# /etc/pve-mod/pve-mod.conf, and applies patches to PVE system files.
|
||||||
|
#
|
||||||
|
# Module-specific logic lives in /usr/lib/pve-mod/configure.d/<mod>.sh,
|
||||||
|
# sourced at startup. Each module file provides the standard four-function
|
||||||
|
# API: <mod>_defaults, <mod>_load_conf, <mod>_configure, <mod>_write_conf.
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
CONF_FILE="/etc/pve-mod/pve-mod.conf"
|
CONF_FILE="/etc/pve-mod/pve-mod.conf"
|
||||||
CONFD_DIR="/etc/pve-mod/conf.d"
|
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"
|
APPLY_PATCHES="/usr/lib/pve-mod/apply-patches.sh"
|
||||||
REVERT_PATCHES="/usr/lib/pve-mod/revert-patches.sh"
|
REVERT_PATCHES="/usr/lib/pve-mod/revert-patches.sh"
|
||||||
NODES_PM="/usr/share/perl5/PVE/API2/Nodes.pm"
|
NODES_PM="/usr/share/perl5/PVE/API2/Nodes.pm"
|
||||||
|
|
||||||
KNOWN_CPU_SENSORS=("coretemp-isa-" "k10temp-pci-")
|
|
||||||
|
|
||||||
#region helpers
|
#region helpers
|
||||||
msgb() { echo -e "\e[1m${1}\e[0m"; }
|
msgb() { echo -e "\e[1m${1}\e[0m"; }
|
||||||
info() { echo -e "\e[0;32m[info] ${1}\e[0m"; }
|
info() { echo -e "\e[0;32m[info] ${1}\e[0m"; }
|
||||||
@ -31,10 +31,18 @@ mod_status() {
|
|||||||
local val="$1" on_label="${2:-[enabled]}" off_label="${3:-[disabled]}"
|
local val="$1" on_label="${2:-[enabled]}" off_label="${3:-[disabled]}"
|
||||||
[[ "$val" == "1" ]] && echo -e "\e[0;32m${on_label}\e[0m" || echo -e "\e[0;33m${off_label}\e[0m"
|
[[ "$val" == "1" ]] && echo -e "\e[0;32m${on_label}\e[0m" || echo -e "\e[0;33m${off_label}\e[0m"
|
||||||
}
|
}
|
||||||
|
#endregion helpers
|
||||||
|
|
||||||
_load_conf() {
|
# Source all module configure scripts. Override CONFIGURE_D_DIR for testing.
|
||||||
# Load main config (module toggles + pve_trigger)
|
CONFIGURE_D_DIR="${PVE_MOD_CONFIGURE_D:-/usr/lib/pve-mod/configure.d}"
|
||||||
if [[ -f "$CONF_FILE" ]]; then
|
for _f in "${CONFIGURE_D_DIR}"/*.sh; do
|
||||||
|
[[ -f "$_f" ]] || continue
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "$_f"
|
||||||
|
done; unset _f
|
||||||
|
|
||||||
|
_load_main_conf() {
|
||||||
|
[[ -f "$CONF_FILE" ]] || return 0
|
||||||
local section="" line key val
|
local section="" line key val
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
case "$line" in
|
case "$line" in
|
||||||
@ -49,418 +57,10 @@ _load_conf() {
|
|||||||
pve_trigger.enabled) PVE_TRIGGER_ENABLED="$val" ;;
|
pve_trigger.enabled) PVE_TRIGGER_ENABLED="$val" ;;
|
||||||
esac
|
esac
|
||||||
done < "$CONF_FILE"
|
done < "$CONF_FILE"
|
||||||
fi
|
|
||||||
|
|
||||||
# Load node_info mod config
|
|
||||||
[[ -f "$NODE_INFO_CONF" ]] || return 0
|
|
||||||
local in_debug=0 line key val section=""
|
|
||||||
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() {
|
write_main_conf() {
|
||||||
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
|
|
||||||
|
|
||||||
# Write JSON devices file for debug/cache use by the Perl collector
|
|
||||||
local json="["
|
|
||||||
local first=1
|
|
||||||
while IFS= read -r line; do
|
|
||||||
# Parse: "card0 Intel Alderlake_n (Gen12) pci:vendor=8086,device=46D0,card=0"
|
|
||||||
if [[ "$line" =~ ^(card[0-9]+)[[:space:]]+(.+[^[:space:]])[[:space:]]+(pci:[^[:space:]]+) ]]; then
|
|
||||||
local card="${BASH_REMATCH[1]}"
|
|
||||||
local name="${BASH_REMATCH[2]}"
|
|
||||||
local path="${BASH_REMATCH[3]}"
|
|
||||||
name="${name%"${name##*[![:space:]]}"}" # rtrim
|
|
||||||
[[ "$first" -eq 0 ]] && json+=","
|
|
||||||
json+="{\"card\":\"$card\",\"name\":\"$name\",\"path\":\"$path\",\"drm_path\":\"/dev/dri/$card\"}"
|
|
||||||
first=0
|
|
||||||
fi
|
|
||||||
done <<< "$intelCards"
|
|
||||||
json+="]"
|
|
||||||
echo "$json" > "$DEBUG_INTEL_FILE"
|
|
||||||
info "Intel GPU device list saved to $DEBUG_INTEL_FILE"
|
|
||||||
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
|
|
||||||
|
|
||||||
if [[ "$ENABLE_SYSTEM_INFO" -eq 1 ]]; then
|
|
||||||
local cache_dir="/var/lib/pve-mod"
|
|
||||||
mkdir -p "$cache_dir"
|
|
||||||
local cache_file="${cache_dir}/dmidecode-type${SYSTEM_INFO_TYPE}.txt"
|
|
||||||
dmidecode -t "$SYSTEM_INFO_TYPE" > "$cache_file" 2>/dev/null || true
|
|
||||||
chmod 644 "$cache_file"
|
|
||||||
info "DMI data cached to $cache_file"
|
|
||||||
fi
|
|
||||||
#endregion System info
|
|
||||||
}
|
|
||||||
#endregion node-info wizard
|
|
||||||
|
|
||||||
#region write config
|
|
||||||
write_config() {
|
|
||||||
mkdir -p "$(dirname "$CONF_FILE")" "$CONFD_DIR"
|
mkdir -p "$(dirname "$CONF_FILE")" "$CONFD_DIR"
|
||||||
|
|
||||||
# Main config: which mods are enabled + global trigger/service settings.
|
|
||||||
cat > "$CONF_FILE" <<EOF
|
cat > "$CONF_FILE" <<EOF
|
||||||
# pve-mod main configuration file
|
# pve-mod main configuration file
|
||||||
# Managed by pve-mod-configure. Re-run to update.
|
# Managed by pve-mod-configure. Re-run to update.
|
||||||
@ -476,67 +76,7 @@ nag_screen=${MOD_NAG_SCREEN}
|
|||||||
enabled=${PVE_TRIGGER_ENABLED}
|
enabled=${PVE_TRIGGER_ENABLED}
|
||||||
EOF
|
EOF
|
||||||
info "Main configuration saved to $CONF_FILE"
|
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}
|
|
||||||
intel_output_file=${DEBUG_INTEL_OUTPUT_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() {
|
main() {
|
||||||
# ── Welcome banner ────────────────────────────────────────────────────────
|
# ── Welcome banner ────────────────────────────────────────────────────────
|
||||||
@ -568,25 +108,12 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Initialize all config variables with safe defaults ────────────────────
|
# ── Initialize all config variables with safe defaults ────────────────────
|
||||||
MOD_NODE_INFO=0; MOD_NAG_SCREEN=0
|
MOD_NODE_INFO=0; MOD_NAG_SCREEN=0; PVE_TRIGGER_ENABLED=0
|
||||||
LM_SENSORS_ENABLED=0
|
node_info_defaults
|
||||||
ENABLE_CPU=0; CPU_TEMP_TARGET="Core"
|
nag_screen_defaults
|
||||||
ENABLE_RAM_TEMP=0; ENABLE_HDD_TEMP=0; ENABLE_NVME_TEMP=0
|
_load_main_conf
|
||||||
ENABLE_FAN_SPEED=0; DISPLAY_ZERO_SPEED_FANS=0; TEMP_UNIT="C"
|
node_info_load_conf
|
||||||
ENABLE_INTEL_GPU_INFO=0; ENABLE_NVIDIA_GPU_INFO=0; ENABLE_AMD_GPU_INFO=0
|
nag_screen_load_conf
|
||||||
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.json"
|
|
||||||
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 ────────────────────────────────────────────
|
# ── Module / feature selection ────────────────────────────────────────────
|
||||||
# Existing settings are loaded above; the user picks ONE option to (re)configure
|
# Existing settings are loaded above; the user picks ONE option to (re)configure
|
||||||
@ -608,7 +135,7 @@ main() {
|
|||||||
else
|
else
|
||||||
MOD_NODE_INFO=1; patching_needed=1
|
MOD_NODE_INFO=1; patching_needed=1
|
||||||
msgb "\n=== Node Info Configuration ==="
|
msgb "\n=== Node Info Configuration ==="
|
||||||
configure_node_info
|
node_info_configure
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
@ -618,6 +145,7 @@ main() {
|
|||||||
else
|
else
|
||||||
MOD_NAG_SCREEN=1; patching_needed=1
|
MOD_NAG_SCREEN=1; patching_needed=1
|
||||||
info "Subscription nag screen removal will be applied."
|
info "Subscription nag screen removal will be applied."
|
||||||
|
nag_screen_configure
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
3)
|
3)
|
||||||
@ -633,7 +161,7 @@ main() {
|
|||||||
|
|
||||||
# ── Write config and apply/revert ─────────────────────────────────────────
|
# ── Write config and apply/revert ─────────────────────────────────────────
|
||||||
# For mods with patches: apply if being enabled, revert if being disabled.
|
# For mods with patches: apply if being enabled, revert if being disabled.
|
||||||
# Option 3 (pve_trigger) has no patches — write_config is sufficient.
|
# Option 3 (pve_trigger) has no patches — write_main_conf is sufficient.
|
||||||
if [[ "$patching_needed" == "1" ]]; then
|
if [[ "$patching_needed" == "1" ]]; then
|
||||||
msgb "\n=== Applying patches ==="
|
msgb "\n=== Applying patches ==="
|
||||||
if ! "$APPLY_PATCHES" "$selected_mod"; then
|
if ! "$APPLY_PATCHES" "$selected_mod"; then
|
||||||
@ -645,7 +173,9 @@ main() {
|
|||||||
err "Could not revert all patches for $selected_mod. Configuration was not updated."
|
err "Could not revert all patches for $selected_mod. Configuration was not updated."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
write_config
|
write_main_conf
|
||||||
|
node_info_write_conf
|
||||||
|
nag_screen_write_conf
|
||||||
|
|
||||||
msgb "\n=== Done ==="
|
msgb "\n=== Done ==="
|
||||||
info "pve-mod is configured and active."
|
info "pve-mod is configured and active."
|
||||||
|
|||||||
@ -102,6 +102,12 @@ emit_install_rules() {
|
|||||||
emit_install 644 "$rel_mod/$mod.conf" "etc/pve-mod/conf.d/$mod.conf"
|
emit_install 644 "$rel_mod/$mod.conf" "etc/pve-mod/conf.d/$mod.conf"
|
||||||
emit_install 644 "$rel_mod/$mod.conf" "usr/share/pve-mod/conf.d/$mod.conf.default"
|
emit_install 644 "$rel_mod/$mod.conf" "usr/share/pve-mod/conf.d/$mod.conf.default"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 4. Per-module configure script.
|
||||||
|
local configure_script="$mod_dir/$mod.configure.sh"
|
||||||
|
if [[ -f "$configure_script" ]]; then
|
||||||
|
emit_install 755 "$rel_mod/$mod.configure.sh" "usr/lib/pve-mod/configure.d/$mod.sh"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_conffiles() {
|
emit_conffiles() {
|
||||||
|
|||||||
29
src/nag_screen/nag_screen.configure.sh
Normal file
29
src/nag_screen/nag_screen.configure.sh
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# nag_screen.configure.sh - Configure module for pve-mod nag_screen
|
||||||
|
#
|
||||||
|
# Sourced by pve-mod-configure. Requires CONFD_DIR to be defined in the
|
||||||
|
# calling script before this file is sourced.
|
||||||
|
#
|
||||||
|
# Provides the standard four-function module API:
|
||||||
|
# nag_screen_defaults — no-op (nag_screen has no tunable variables)
|
||||||
|
# nag_screen_load_conf — no-op (no tunable settings to load)
|
||||||
|
# nag_screen_configure — no-op (no interactive configuration needed)
|
||||||
|
# nag_screen_write_conf — write placeholder /etc/pve-mod/conf.d/nag_screen.conf
|
||||||
|
|
||||||
|
NAG_SCREEN_CONF="${CONFD_DIR}/nag_screen.conf"
|
||||||
|
|
||||||
|
nag_screen_defaults() { :; }
|
||||||
|
nag_screen_load_conf() { :; }
|
||||||
|
nag_screen_configure() { :; }
|
||||||
|
|
||||||
|
nag_screen_write_conf() {
|
||||||
|
# Only write the placeholder if it does not already exist; it has no
|
||||||
|
# machine-managed values so there is nothing to update on re-runs.
|
||||||
|
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
|
||||||
|
}
|
||||||
483
src/node_info/node_info.configure.sh
Normal file
483
src/node_info/node_info.configure.sh
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# node_info.configure.sh - Configure module for pve-mod node_info
|
||||||
|
#
|
||||||
|
# Sourced by pve-mod-configure. Requires CONFD_DIR and the helper functions
|
||||||
|
# (info, warn, err, ask, msgb) to be defined in the calling script before
|
||||||
|
# this file is sourced.
|
||||||
|
#
|
||||||
|
# Provides the standard four-function module API:
|
||||||
|
# node_info_defaults — set all variables to safe defaults
|
||||||
|
# node_info_load_conf — parse /etc/pve-mod/conf.d/node_info.conf
|
||||||
|
# node_info_configure — interactive hardware-detection wizard
|
||||||
|
# node_info_write_conf — write /etc/pve-mod/conf.d/node_info.conf
|
||||||
|
|
||||||
|
NODE_INFO_CONF="${CONFD_DIR}/node_info.conf"
|
||||||
|
KNOWN_CPU_SENSORS=("coretemp-isa-" "k10temp-pci-")
|
||||||
|
|
||||||
|
# --- utilities ---------------------------------------------------------------
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- standard API ------------------------------------------------------------
|
||||||
|
|
||||||
|
node_info_defaults() {
|
||||||
|
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
|
||||||
|
DEBUG_LM_SENSORS=0; DEBUG_LM_SENSORS_FILE="/tmp/sensors-output.json"
|
||||||
|
DEBUG_INTEL=0; DEBUG_INTEL_FILE="/tmp/intel-gpu-devices.json"
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
node_info_load_conf() {
|
||||||
|
[[ -f "$NODE_INFO_CONF" ]] || return 0
|
||||||
|
local line key val section=""
|
||||||
|
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
|
||||||
|
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.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.enabled) ENABLE_UPS="$val" ;;
|
||||||
|
ups.device_name) UPS_DEVICE_NAME="$val" ;;
|
||||||
|
system_info.enabled) ENABLE_SYSTEM_INFO="$val" ;;
|
||||||
|
system_info.type) SYSTEM_INFO_TYPE="$val" ;;
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
#region node-info wizard
|
||||||
|
node_info_configure() {
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Write JSON devices file for debug/cache use by the Perl collector
|
||||||
|
local json="["
|
||||||
|
local first=1
|
||||||
|
while IFS= read -r line; do
|
||||||
|
# Parse: "card0 Intel Alderlake_n (Gen12) pci:vendor=8086,device=46D0,card=0"
|
||||||
|
if [[ "$line" =~ ^(card[0-9]+)[[:space:]]+(.+[^[:space:]])[[:space:]]+(pci:[^[:space:]]+) ]]; then
|
||||||
|
local card="${BASH_REMATCH[1]}"
|
||||||
|
local name="${BASH_REMATCH[2]}"
|
||||||
|
local path="${BASH_REMATCH[3]}"
|
||||||
|
name="${name%"${name##*[![:space:]]}"}" # rtrim
|
||||||
|
[[ "$first" -eq 0 ]] && json+=","
|
||||||
|
json+="{\"card\":\"$card\",\"name\":\"$name\",\"path\":\"$path\",\"drm_path\":\"/dev/dri/$card\"}"
|
||||||
|
first=0
|
||||||
|
fi
|
||||||
|
done <<< "$intelCards"
|
||||||
|
json+="]"
|
||||||
|
echo "$json" > "$DEBUG_INTEL_FILE"
|
||||||
|
info "Intel GPU device list saved to $DEBUG_INTEL_FILE"
|
||||||
|
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
|
||||||
|
|
||||||
|
if [[ "$ENABLE_SYSTEM_INFO" -eq 1 ]]; then
|
||||||
|
local cache_dir="/var/lib/pve-mod"
|
||||||
|
mkdir -p "$cache_dir"
|
||||||
|
local cache_file="${cache_dir}/dmidecode-type${SYSTEM_INFO_TYPE}.txt"
|
||||||
|
dmidecode -t "$SYSTEM_INFO_TYPE" > "$cache_file" 2>/dev/null || true
|
||||||
|
chmod 644 "$cache_file"
|
||||||
|
info "DMI data cached to $cache_file"
|
||||||
|
fi
|
||||||
|
#endregion System info
|
||||||
|
}
|
||||||
|
#endregion node-info wizard
|
||||||
|
|
||||||
|
node_info_write_conf() {
|
||||||
|
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}
|
||||||
|
intel_output_file=${DEBUG_INTEL_OUTPUT_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"
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user