system overhaul and bug fixeds

- Replaced the fragile upstream script installer with native Deb822 repository injection and automated GPG keyring management in `jellyfin.sh`. Eliminated external dependencies, checksums, and interactive flags for guaranteed non-interactive support across Bullseye/Bookworm/Trixie.
- Upgraded the NVMe module (`modules/extras/system/system.sh`) to perform multi-drive scanning with dynamic `lsblk` parsing. Replaced single-disk detection logic with a `while read` loop to capture all devices, displaying formatted SMART health diagnostics (Critical Warning, Temperature, Percentage Used).
- Overhauled the 'System Information' TUI into a multi-device dashboard featuring standalone GPU/Driver hierarchies and dynamic storage mapping. Added new globals (`DISPLAY_SERVER`, `STORAGE_SUMMARY`) and comprehensive arrays for Network/Wi-Fi interface indexing in `modules/utils.sh`.
- Redesigned the graphics stack layout to fix multi-GPU text clipping and unified Mesa version prompting logic. Integrated post-install package telemetry to display live versions in the completion screen, separating planning visualization from installation decision points in `modules/gpu.sh`.
- Fixed non-free-firmware conceptual documentation bugs and expanded Backports descriptions with hardware-focused educational text. Added non-free repository safeguards for Trixie/Bullseye compatibility under "Firmware & Wireless Drivers".
- Refactored repository logic in modules/repos.sh to eliminate dead code (redundant default_text variables) and strict-hardcoded layout behaviors, standardizing dialog geometry to a clean matrix.
- Updated README.md
This commit is contained in:
stornic56
2026-06-16 19:59:15 -05:00
committed by GitHub
parent 63ef2e7343
commit 3a652c28e6
9 changed files with 343 additions and 93 deletions
+8
View File
@@ -24,6 +24,14 @@ _quick_install_bullseye() {
install_firmware_bullseye() {
echo -e "${YELLOW}Installing firmware-linux-nonfree (Bullseye)...${NC}"
# ── Safeguard: non-free repos must be enabled ──
if ! grep -qr "non-free" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null; then
_msg "Error" "Error: No 'non-free' repositories were detected.\n\
Please first run the 'Configure repositories' option in the\n\
main menu to install proprietary firmwares." 10 65
return 1
fi
if is_installed "firmware-linux-nonfree"; then
echo "firmware-linux-nonfree already installed."
return
+32 -26
View File
@@ -1,32 +1,38 @@
# jellyfin.sh — Jellyfin Media Server installation
# jellyfin.sh — Jellyfin Media Server installation (native repo)
install_jellyfin() {
local tmpdir="/tmp/jellyfin_install"
mkdir -p "${tmpdir}"
local ver
ver=$(apt-cache policy jellyfin 2>/dev/null | awk 'NR==3 {print $2; exit}')
_run_cmd "Jellyfin" "curl -sSL -o ${tmpdir}/install-debuntu.sh https://repo.jellyfin.org/install-debuntu.sh" "Downloading Jellyfin repository script..."
_run_cmd "Jellyfin" "curl -sSL -o ${tmpdir}/install-debuntu.sh.sha256sum https://repo.jellyfin.org/install-debuntu.sh.sha256sum" "Downloading checksum..."
if _confirm "Install: Jellyfin" "Install Jellyfin Media Server
Repository: repo.jellyfin.org/debian
Version: ${ver:-unknown}"; then
if [ ! -s "${tmpdir}/install-debuntu.sh" ] || [ ! -s "${tmpdir}/install-debuntu.sh.sha256sum" ]; then
echo -e "${RED}[-]${NC} Download failed: script or checksum is empty or missing."
rm -rf "${tmpdir}"
return 1
# 1. Prerequisites
! is_installed "curl" && _run_install "curl"
! is_installed "gpg" && _run_install "gpg"
sudo install -d -m 0755 /etc/apt/keyrings
# 2. GPG key
echo -e "${GREEN}[+]${NC} Adding Jellyfin GPG key..."
curl -fsSL "https://repo.jellyfin.org/jellyfin_team.gpg.key" \
| sudo gpg --dearmor -o /etc/apt/keyrings/jellyfin.gpg
# 3. Deb822 .sources file
echo -e "${GREEN}[+]${NC} Adding Jellyfin repository..."
sudo tee /etc/apt/sources.list.d/jellyfin.sources > /dev/null << EOF
Types: deb
URIs: https://repo.jellyfin.org/debian
Suites: ${DEBIAN_CODENAME}
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/jellyfin.gpg
EOF
# 4. Update + install
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
_run_cmd "Jellyfin" "sudo DEBIAN_FRONTEND=noninteractive apt install -y jellyfin" "Installing Jellyfin..."
echo -e "${GREEN}Jellyfin Server installed. Web interface available at http://localhost:8096${NC}"
fi
echo -e "${GREEN}[+]${NC} Verifying checksum..."
if ! (cd "${tmpdir}" && sha256sum -c install-debuntu.sh.sha256sum); then
echo -e "${RED}[-]${NC} Checksum verification failed. The downloaded script may be corrupted."
rm -rf "${tmpdir}"
return 1
fi
echo -e "${GREEN}[+]${NC} Running Jellyfin repository setup..."
if ! sudo bash "${tmpdir}/install-debuntu.sh"; then
echo -e "${RED}[-]${NC} Jellyfin installation failed."
rm -rf "${tmpdir}"
return 1
fi
rm -rf "${tmpdir}"
echo -e "${GREEN}Jellyfin Server installed. Web interface available at http://localhost:8096${NC}"
}
+33 -12
View File
@@ -214,23 +214,44 @@ _cat_general() {
nvme-cli)
if ! lsblk -d -o TRAN 2>/dev/null | grep -q "^nvme$"; then
echo "No NVMe controller detected. Skipping."
break
continue
fi
if ! is_installed "nvme-cli"; then
_run_cmd "nvme-cli" "sudo apt install -y nvme-cli" "Installing nvme-cli..."
fi
local nvme_dev
nvme_dev=$(lsblk -d -o NAME,TRAN 2>/dev/null | awk '/nvme/ {print $1; exit}')
if [ -n "$nvme_dev" ] && [ -e "/dev/${nvme_dev}" ]; then
if _confirm "NVMe Health" "Run smart-log on /dev/${nvme_dev}?"; then
local nvme_devs=()
while read -r dev; do
nvme_devs+=("$dev")
done < <(lsblk -d -o NAME,TRAN 2>/dev/null | awk '$2 == "nvme" {print $1}')
if [ ${#nvme_devs[@]} -eq 0 ]; then
echo "No NVMe block devices found for health check."
continue
fi
local dev_list=""
local dev
for dev in "${nvme_devs[@]}"; do
[ -n "$dev_list" ] && dev_list+=", "
dev_list+="/dev/${dev}"
done
if _confirm "NVMe Health" "Run smart-log on ${#nvme_devs[@]} NVMe device(s): ${dev_list}?"; then
echo ""
for dev in "${nvme_devs[@]}"; do
local cw="" temp="" pu=""
while IFS= read -r line; do
case "$line" in
*critical_warning*) cw="${line##*: }" ;;
*temperature*) temp="${line##*: }" ;;
*percentage_used*) pu="${line##*: }" ;;
esac
done < <(sudo nvme smart-log "/dev/${dev}" 2>/dev/null || true)
echo -e "${YELLOW}━━━ /dev/${dev} ━━━${NC}"
echo -e " ${GREEN}Critical Warning:${NC} ${cw:-N/A}"
echo -e " ${GREEN}Temperature:${NC} ${temp:-N/A}"
echo -e " ${GREEN}Percentage Used:${NC} ${pu:-N/A}"
echo ""
sudo nvme smart-log "/dev/${nvme_dev}"
echo ""
echo "Press [ENTER] to continue..."
read -r
fi
else
echo "No NVMe device found for health check."
done
echo "Press [ENTER] to continue..."
read -r
fi
;;
*)
+15 -2
View File
@@ -3,6 +3,14 @@
install_firmware() {
echo -e "${YELLOW}Base firmware check...${NC}"
# ── Safeguard: non-free repos must be enabled ──
if ! grep -qr "non-free" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null; then
_msg "Error" "Error: No 'non-free' repositories were detected.\n\
Please first run the 'Configure repositories' option in the\n\
main menu to install proprietary firmwares." 10 65
return 1
fi
local fw_pkg="firmware-linux-nonfree"
local fw_bpo
fw_bpo=$(apt-cache madison "$fw_pkg" 2>/dev/null | \
@@ -28,8 +36,13 @@ install_firmware() {
local msg="firmware-linux-nonfree provides hardware drivers for:\n"
msg+=" WiFi, Bluetooth, GPU, audio, webcams, and more.\n\n"
if [ -n "$fw_bpo" ]; then
msg+=" Backports: ${fw_bpo} (newer, recommended)\n"
msg+=" Stable: ${fw_stable}\n\n"
msg+=" ● Stable: ${fw_stable}\n"
msg+=" Ultra tested, but may lack support for\n"
msg+=" very recent hardware.\n\n"
msg+=" ● Backports: ${fw_bpo} (Recommended)\n"
msg+=" Updated firmware for modern hardware from\n"
msg+=" 2025/2026: recent GPUs (Intel Arc, Radeon,\n"
msg+=" NVIDIA), new processors, Wi-Fi 6E / Wi-Fi 7.\n\n"
msg+="Choose version:"
if _confirm_custom "Firmware" "$msg" "Backports" "Stable"; then
_run_cmd "Firmware" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $fw_pkg" "Installing firmware from backports..."
+34 -20
View File
@@ -16,11 +16,13 @@ install_gpu_drivers() {
info+="Components:\n"
info+=" Mesa (OpenGL / Vulkan / VA-API)\n"
if [ "$GPU_TYPE" != "unknown" ]; then
info+=" GPU firmware for ${GPU_DESC}\n"
info+=" GPU firmware\n"
fi
info+=" Monitoring tools (nvtop, vainfo, ...)"
if ! _confirm "Graphics Stack" "$info"; then
_msg "Graphics Stack" "$info" 16 70
if ! _confirm "Graphics Stack" "Proceed with the graphics stack setup?"; then
echo "Skipping Graphics Stack."
return
fi
@@ -66,21 +68,15 @@ install_gpu_drivers() {
fi
# ── Detectable GPU: build plan ──
local ref_ver
ref_ver=$(apt-cache policy mesa-vulkan-drivers 2>/dev/null | awk 'NR==3 {print $2; exit}')
local ref_bpo_ver
ref_bpo_ver=$(apt-cache madison mesa-vulkan-drivers 2>/dev/null | \
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1)
local comp_line="Components: Vulkan, OpenGL, GLX, EGL, VA-API (64-bit)"
local src_line="Source: Debian Stable"
[ -n "$ref_bpo_ver" ] && [ "$(is_backports_enabled)" == "true" ] && src_line="Source: Debian ${DEBIAN_CODENAME^}-Backports"
local plan="GPUs detected: ${GPU_DESC}\n\n"
plan+="${src_line}\n"
plan+="Mesa ${ref_bpo_ver:-$ref_ver}\n"
plan+="${comp_line}\n\n"
plan+="Components:\n"
local plan=""
local gpu_count=0
while IFS= read -r gpu_line; do
gpu_count=$((gpu_count + 1))
local desc
desc=$(echo "$gpu_line" | sed -E 's/.*: //; s/ *\(rev.*//')
plan+=" GPU ${gpu_count}: ${desc}\n"
done < <(lspci -nn | grep -E "VGA|3D" || true)
plan+="\nComponents:\n"
if $HAS_INTEL; then
local _gen; _gen=$(get_intel_generation)
local _va; [ "$_gen" = "gen7-" ] && _va="i965-va-driver-shaders" || _va="intel-media-va-driver-non-free"
@@ -90,10 +86,13 @@ install_gpu_drivers() {
plan+=" [+] AMD firmware (firmware-amd-graphics)\n"
fi
if $HAS_NVIDIA; then
plan+=" [+] NVIDIA driver (details in next step)\n"
plan+=" [+] NVIDIA driver\n"
fi
plan+=" [+] Mesa (version selected in next step)\n"
if ! _confirm "Graphics Stack — ${GPU_DESC}" "$plan" 14 70; then
_msg "Graphics Stack — Plan" "$plan" 16 70
if ! _confirm "Graphics Stack" "Install the components shown above?"; then
echo "Skipping Graphics Stack."
return
fi
@@ -140,6 +139,11 @@ install_gpu_drivers() {
# ── Mesa (once) ──
_install_mesa_backports
# ── Refresh GPU_VERSION after Mesa install ──
local mesa_ver
mesa_ver=$(dpkg -l libgl1-mesa-dri 2>/dev/null | awk '/^ii/ {print $3; exit}' | sed 's/-.*//')
[ -n "$mesa_ver" ] && GPU_VERSION="Mesa ${mesa_ver}"
# ── Vendor-specific tools ──
if $HAS_INTEL; then
offer_intel_tools
@@ -151,5 +155,15 @@ install_gpu_drivers() {
offer_generic_tools
fi
echo -e "${GREEN}Graphics stack setup complete.${NC}"
# ── Build summary ──
local summary=""
summary+="Mesa: ${GPU_VERSION:-not available}\n"
if $HAS_NVIDIA; then
local nv_mode="${NVIDIA_DRIVER_MODE:-unknown}"
summary+="NVIDIA: ${nv_mode}\n"
fi
summary+="Firmware: installed for detected GPUs\n"
summary+="Tools: installed per vendor selection"
_msg "Graphics Stack — Complete" "$summary" 12 65
}
+27 -5
View File
@@ -273,6 +273,15 @@ configure_repos() {
return 1
fi
# ── Informational banner ──
_msg "Repositories" \
"This section will automatically enable the 'contrib' and 'non-free'\n\
branches in your official Debian repositories. (The 'non-free-firmware'\n\
branch is already enabled by default in Debian 12 and 13.)\n\n\
This is CRUCIAL for obtaining proprietary software packages and\n\
essential hardware drivers, including NVIDIA graphics drivers,\n\
Wi-Fi firmware, and CPU microcode." 14 70
# Detect current state
local current_format
current_format=$(detect_repo_format)
@@ -288,12 +297,19 @@ configure_repos() {
echo "Current format: ${current_format:-none}"
echo "Backports: $bp_status (location: $bp_location)"
# Choose format (only Trixie gets the choice)
# ── Format selection dialog (only Trixie gets the choice) ──
local use_deb822=false
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
local default_text="no"
[ "$current_format" = "deb822" ] && default_text="yes"
if whiptail --title "Repository Format" --defaultno --yesno "Use deb822 format (modern .sources)?" 8 60; then
if whiptail --title "Repository Format" --defaultno --yesno \
"Do you want to migrate your repositories to the new
DEB822 (.sources) format?
DEB822 is the modern, structured Debian standard. It won't
harm your system, and the script will handle the transition
safely if you accept.
NOTE: 'NO' (default) is recommended to maintain the classic
linear format as it comes pre-configured in Debian 13 (Trixie)." 14 70; then
use_deb822=true
fi
elif [ "$current_format" = "deb822" ]; then
@@ -302,7 +318,13 @@ configure_repos() {
# Choose backports
local enable_backports=false
if _confirm "Backports" "Enable backports repository?\n\nProvides newer kernel, drivers, Mesa."; then
if _confirm "Backports" "Do you want to enable the official Debian Backports repository?\n\n\
Backports provides newer, selectively updated packages from the\n\
next Debian testing branch, recompiled to run stably on your\n\
current system.\n\n\
This is HIGHLY RECOMMENDED if you have modern hardware, as it\n\
delivers newer Linux Kernels, updated display drivers, and modern\n\
Mesa versions without compromising overall system stability." 15 70; then
enable_backports=true
fi
+98
View File
@@ -16,6 +16,8 @@ HAS_NVIDIA=false
HAS_AMD=false
HAS_INTEL=false
KERNEL_VERSION=""
DISPLAY_SERVER="unknown"
STORAGE_SUMMARY=""
WIFI_CHIPSET=""
# --------------------------
@@ -252,6 +254,17 @@ WIFI_CHIPSET=""
WIFI_DESC=""
ETH_DESC=""
declare -a ETH_NAMES=()
declare -a ETH_DESCS=()
declare -a ETH_STATES=()
declare -a ETH_IPS=()
declare -a WIFI_NAMES=()
declare -a WIFI_DESCS=()
declare -a WIFI_STATES=()
declare -a WIFI_IPS=()
declare -a WIFI_SSIDS=()
detect_network() {
local eth_line
eth_line=$(lspci -nn | grep -i 'Ethernet controller' | head -n1) || true
@@ -265,6 +278,91 @@ detect_network() {
WIFI_CHIPSET="$wifi_line"
WIFI_DESC=$(echo "$wifi_line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
fi
# ── Safeguard: if ip is not installed, skip runtime parsing ──
if ! command -v ip &>/dev/null; then
return
fi
local iface state ip4 ssid
while IFS= read -r line; do
iface=$(echo "$line" | awk -F': ' '{print $2}' | sed 's/@.*//')
state=$(echo "$line" | awk '{print $9}')
case "$iface" in
eth*|enp*|ens*|enx*|eno*)
ip4=$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}')
ETH_NAMES+=("$iface")
ETH_STATES+=("$state")
ETH_IPS+=("${ip4:-}")
ETH_DESCS+=("${ETH_DESC:-}")
;;
wl*|wlp*|wlo*)
ip4=$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}')
ssid=""
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
WIFI_NAMES+=("$iface")
WIFI_STATES+=("$state")
WIFI_IPS+=("${ip4:-}")
WIFI_SSIDS+=("${ssid:-}")
WIFI_DESCS+=("${WIFI_DESC:-}")
;;
esac
done < <(ip -o link show 2>/dev/null)
}
# ---------------------------------------
# Display Server detection (Wayland / X11 / tty)
# ---------------------------------------
detect_displayserver() {
local st="${XDG_SESSION_TYPE:-}"
case "$st" in
wayland) DISPLAY_SERVER="Wayland" ;;
x11) DISPLAY_SERVER="X11" ;;
tty) DISPLAY_SERVER="none (tty)" ;;
*)
if [ -n "${WAYLAND_DISPLAY:-}" ]; then
DISPLAY_SERVER="Wayland"
elif [ -n "${DISPLAY:-}" ]; then
DISPLAY_SERVER="X11"
else
DISPLAY_SERVER="unknown"
fi
;;
esac
}
# ---------------------------------------
# Storage summary via lsblk (NVMe / SSD / HDD)
# ---------------------------------------
detect_storage() {
local parts=()
local name size rota type
while read -r name size rota; do
[ "$name" = "NAME" ] && continue
if echo "$name" | grep -q "nvme"; then
type="NVMe"
elif [ "$rota" = "1" ]; then
type="HDD"
else
type="SSD"
fi
parts+=("${size} ${type}")
done < <(lsblk -d -o NAME,SIZE,ROTA 2>/dev/null || true)
if [ ${#parts[@]} -eq 0 ]; then
STORAGE_SUMMARY="No disks detected"
return
fi
local result=""
local p
for p in "${parts[@]}"; do
[ -n "$result" ] && result+=" + "
result+="$p"
done
STORAGE_SUMMARY="$result"
}
# ---------------------------------------