From 3e96906d6e1753041b7c6eda6d3c8a869d41e799 Mon Sep 17 00:00:00 2001 From: stornic56 <71296607+stornic56@users.noreply.github.com> Date: Fri, 19 Jun 2026 22:32:50 -0500 Subject: [PATCH] firmware & wireless refactor + extrepo Migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Created standalone modules/bluetooth.sh for `_install_bluetooth_stack()` with desktop-aware frontend selection (bluedevil/KDE, blueman/XFCE/other). Extracted from `firmware.sh`, reducing it from 438 to 369 lines. - Added `detect_desktop_environment()` and `detect_audio_server()` functions in `utils.sh` with new globals `DESKTOP_ENV=""` and `AUDIO_SERVER=""`. - New `found_active_wifi` flag detects Qualcomm Atheros AR9485 PCI chips without loaded firmware, displaying `(no driver — install firmware)` instead of silently disappearing. Auto-installs `firmware-atheros + firmware-linux-nonfree` after Firmware & Wireless Setup. - New `is_nvidia_blackwell()` detects GPUs in ranges `0x2900–0x29BF` and `0x2B80–0x31FF`. Added `_enable_cuda_repo()` helper for extrepo-based CUDA installation with APT pinning. DKMS verification blocks added to all `_install_nvidia_*` functions. - Standardized repository enablement across 7 modules using `_enable_*_repo()` helpers: - `internet.sh`: Firefox/Floorp/LibreWolf, Pale Moon, Tailscale, Mullvad VPN/Browser, ProtonVPN - `jellyfin.sh`, `programming.sh` (VSCodium), `java.sh` (Temurin) - New `extras/office/office.sh`: OnlyOffice + LibreOffice with language detection - The main script was reduced from 233 to 137 lines. Created new `modules/sysinfo.sh` (97 lines) for `_show_sysinfo()`. Source chain: `utils.sh → sysinfo.sh → sudo_config.sh → repos → firmware.sh → bluetooth.sh → gpu.sh → kernel.sh → gaming.sh → extras.sh → zram.sh → java.sh`. - Renamed menu to `"Firmware, Wireless & Bluetooth"`. Translated NTP dialog (English), basic programs install message, and NVIDIA 32-bit legacy messages. --- debianito.sh | 98 +---------- modules/bluetooth.sh | 72 ++++++++ modules/bullseye/extras.sh | 2 +- modules/bullseye/legacy.sh | 19 ++- modules/extras.sh | 14 +- modules/extras/dev/jellyfin.sh | 37 ++-- modules/extras/internet/internet.sh | 195 +++++++++++++--------- modules/extras/java.sh | 36 ++-- modules/extras/office/office.sh | 87 ++++++++++ modules/extras/programming/programming.sh | 42 ++--- modules/firmware.sh | 65 +++++++- modules/gpu/_helpers.sh | 16 ++ modules/gpu/nvidia.sh | 91 +++++++++- modules/sysinfo.sh | 99 +++++++++++ modules/utils.sh | 37 +++- 15 files changed, 638 insertions(+), 272 deletions(-) create mode 100644 modules/bluetooth.sh create mode 100644 modules/extras/office/office.sh create mode 100644 modules/sysinfo.sh diff --git a/debianito.sh b/debianito.sh index bde3403..1a2ed46 100644 --- a/debianito.sh +++ b/debianito.sh @@ -16,10 +16,12 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MODULES_DIR="${SCRIPT_DIR}/modules" source "${MODULES_DIR}/utils.sh" +[ -f "${MODULES_DIR}/sysinfo.sh" ] && source "${MODULES_DIR}/sysinfo.sh" source "${MODULES_DIR}/sudo_config.sh" source "${MODULES_DIR}/repos/repo_detect.sh" source "${MODULES_DIR}/repos.sh" -[ -f "${MODULES_DIR}/firmware.sh" ] && source "${MODULES_DIR}/firmware.sh" +[ -f "${MODULES_DIR}/firmware.sh" ] && source "${MODULES_DIR}/firmware.sh" +[ -f "${MODULES_DIR}/bluetooth.sh" ] && source "${MODULES_DIR}/bluetooth.sh" [ -f "${MODULES_DIR}/gpu.sh" ] && source "${MODULES_DIR}/gpu.sh" [ -f "${MODULES_DIR}/kernel.sh" ] && source "${MODULES_DIR}/kernel.sh" [ -f "${MODULES_DIR}/gaming.sh" ] && source "${MODULES_DIR}/gaming.sh" @@ -53,7 +55,7 @@ main_menu() { "1" "System Info" \ "2" "User Privileges & Feedback" \ "3" "Configure repositories" \ - "4" "Firmware & Wireless Drivers" \ + "4" "Firmware, Wireless & Bluetooth" \ "5" "Graphics Drivers & Mesa Stack" \ "6" "Backports Kernel" \ "7" "Gaming Setup" \ @@ -112,96 +114,6 @@ kernels. Use the stable kernel provided by Bullseye." 10 60 done } -_show_sysinfo() { - local msg="" - - # ── OS Block ── - msg+="OS: ${DEBIAN_VERSION} (${DEBIAN_CODENAME})\n" - msg+="Kernel: ${KERNEL_VERSION}\n" - msg+="Display: ${DISPLAY_SERVER}\n" - msg+="\n" - - # ── Hardware Block ── - msg+="CPU: ${CPU_SUMMARY}\n" - msg+="RAM: ${RAM_SUMMARY}\n" - msg+="Storage: ${STORAGE_SUMMARY}\n" - msg+="\n" - - # ── GPU Block ── - local found_gpu=false - if command -v lspci &>/dev/null; then - local gpu_count=0 - while IFS= read -r gpu_line; do - found_gpu=true - gpu_count=$((gpu_count + 1)) - local desc - desc=$(echo "$gpu_line" | sed -E 's/.*: //; s/ *\(rev.*//') - - if echo "$gpu_line" | grep -qi "nvidia"; then - local nv_ver="" - nv_ver=$(nvidia-smi --query-gpu=driver_version --format=csv,noheader 2>/dev/null | head -1) - [ -z "$nv_ver" ] && nv_ver=$(dpkg -l nvidia-driver 2>/dev/null | awk '/^ii/ {print $3}' | sed 's/-.*//') - msg+="GPU ${gpu_count}: ${desc}\n" - msg+=" Driver: ${nv_ver:+NVIDIA }${nv_ver:-not installed}\n" - else - local mesa_ver="" - mesa_ver=$(dpkg -l libgl1-mesa-dri 2>/dev/null | awk '/^ii/ {print $3; exit}' | sed 's/-.*//') - msg+="GPU ${gpu_count}: ${desc}\n" - msg+=" Driver: ${mesa_ver:+Mesa }${mesa_ver:-unknown}\n" - fi - done < <(lspci -nn | grep -E "VGA|3D" || true) - fi - - if ! $found_gpu; then - msg+="GPU: No GPU detected\n" - fi - msg+="\n" - - # ── Network Block ── - msg+="─── Network ───\n" - local has_network=false - local i - - if ! command -v ip &>/dev/null; then - msg+="(install iproute2 for interface details)\n" - else - for i in "${!ETH_NAMES[@]}"; do - has_network=true - local e_iface="${ETH_NAMES[$i]}" - local e_desc="${ETH_DESCS[$i]:-$ETH_DESC}" - local e_state="${ETH_STATES[$i]}" - local e_ip4="${ETH_IPS[$i]}" - if [ "$e_state" = "UP" ]; then - msg+="${e_iface}: ${e_desc}\n ↑ ${e_ip4:-no IP}\n" - else - msg+="${e_iface}: ${e_desc}\n ↓\n" - fi - done - - for i in "${!WIFI_NAMES[@]}"; do - has_network=true - local w_iface="${WIFI_NAMES[$i]}" - local w_desc="${WIFI_DESCS[$i]:-$WIFI_DESC}" - local w_state="${WIFI_STATES[$i]}" - local w_ip4="${WIFI_IPS[$i]}" - local w_ssid="${WIFI_SSIDS[$i]}" - if [ "$w_state" = "UP" ]; then - msg+="${w_iface}: ${w_desc}\n ↑ ${w_ip4:-no IP}" - [ -n "$w_ssid" ] && msg+=" \"${w_ssid}\"" - msg+="\n" - else - msg+="${w_iface}: ${w_desc}\n ↓\n" - fi - done - - if ! $has_network; then - msg+="No active interfaces detected\n" - fi - fi - - _msg "System Information" "$msg" 22 76 -} - check_root check_sudo check_system_time @@ -214,6 +126,8 @@ detect_gpu detect_network detect_displayserver detect_storage +detect_desktop_environment +detect_audio_server # ── Bullseye-specific init (archive phase) ── if [ "$DEBIAN_VERSION" = "11" ] && type check_bullseye_archive_phase &>/dev/null; then diff --git a/modules/bluetooth.sh b/modules/bluetooth.sh new file mode 100644 index 0000000..14a93d0 --- /dev/null +++ b/modules/bluetooth.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +# modules/bluetooth.sh +# Requires: modules/utils.sh (globals + helpers), modules/firmware.sh (PCI_BT_DEVS, USB_BT_DEVS, USB_WIFI_DEVS) + +_install_bluetooth_stack() { + local has_bt=false + [ ${#PCI_BT_DEVS[@]} -gt 0 ] && has_bt=true + [ ${#USB_BT_DEVS[@]} -gt 0 ] && has_bt=true + if ! $has_bt; then + for dev in "${USB_WIFI_DEVS[@]}"; do + if echo "$dev" | grep -qi 'bluetooth'; then + has_bt=true; break + fi + done + fi + if ! $has_bt; then + echo " → No Bluetooth hardware detected, skipping." + return + fi + + if is_installed bluez && is_installed bluez-utils; then + echo " → Bluetooth stack already installed." + service_enable_only=true + fi + + if [ ! ${service_enable_only:-false} = true ]; then + local bt_pkgs=() + ! is_installed bluez && bt_pkgs+=(bluez) + ! is_installed bluez-utils && bt_pkgs+=(bluez-utils) + ! is_installed bluez-obexd && bt_pkgs+=(bluez-obexd) + if [ ${#bt_pkgs[@]} -gt 0 ]; then + _run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y ${bt_pkgs[*]}" "Installing Bluetooth stack..." + fi + fi + + if command -v rfkill &>/dev/null; then + if rfkill list bluetooth 2>/dev/null | grep -q "Soft blocked: yes"; then + echo " → Unblocking Bluetooth (rfkill)..." + sudo rfkill unblock bluetooth + fi + fi + + case "${DESKTOP_ENV:-other}" in + kde) + if ! is_installed bluedevil; then + _run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y bluedevil" "Installing bluedevil..." + fi + if [ "${AUDIO_SERVER:-}" = "pipewire" ]; then + ! is_installed pipewire-pulse && _run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y pipewire-pulse" "Installing pipewire-pulse..." + ! is_installed wireplumber && _run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y wireplumber" "Installing wireplumber..." + fi + ;; + gnome) + echo " → GNOME Bluetooth support already in gnome-control-center." + ;; + xfce|other) + if ! is_installed blueman; then + _run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y blueman" "Installing blueman..." + fi + ;; + esac + + if ! systemctl is-enabled bluetooth &>/dev/null 2>&1; then + sudo systemctl enable bluetooth 2>/dev/null || true + fi + if ! systemctl is-active bluetooth &>/dev/null 2>&1; then + sudo systemctl start bluetooth 2>/dev/null || true + fi + + _msg "Bluetooth Setup" "Bluetooth stack installed.\n\nA session restart or reboot is\nrecommended to load the desktop\napplets and tray icons." 10 60 +} diff --git a/modules/bullseye/extras.sh b/modules/bullseye/extras.sh index 9b5962e..3c9dda4 100644 --- a/modules/bullseye/extras.sh +++ b/modules/bullseye/extras.sh @@ -5,7 +5,7 @@ # ── Essential Pack (Bullseye) ── _quick_install_bullseye() { _msg "Essential Pack — Bullseye" \ - "Instalar programas básicos:\n\n\ + "Install basic programs:\n\n\ - Compression (zip, unrar, p7zip-full)\n\ - System tools (htop, inxi, neofetch, bpytop)\n\ - VLC media player\n\ diff --git a/modules/bullseye/legacy.sh b/modules/bullseye/legacy.sh index a18f0c4..24cd191 100644 --- a/modules/bullseye/legacy.sh +++ b/modules/bullseye/legacy.sh @@ -95,16 +95,29 @@ install_nvidia_bullseye() { local nv32_ver nv32_ver=$(apt-cache policy "$nv32_pkg" 2>/dev/null | awk 'NR==3 {print $2; exit}') if [ -n "$nv32_ver" ] && [ "$nv32_ver" != "(none)" ]; then - echo "Instalando compatibilidad 32-bit para ${nv_pkg}..." + echo "Installing 32-bit compatibility for ${nv_pkg}..." _run_cmd "NVIDIA 32-bit" "sudo apt install -y $nv32_pkg" \ - "Instalando librerías NVIDIA 32-bit..." + "Installing NVIDIA 32-bit libraries..." else - echo "No hay paquete 32-bit disponible para ${nv_pkg} en Bullseye." + echo "No 32-bit compatibility package available for ${nv_pkg} on Bullseye." fi fi NVIDIA_DRIVER_MODE="stable" echo -e "${GREEN}Driver NVIDIA ${nv_pkg} instalado. Requiere reinicio.${NC}" + + echo "" + echo "──────────────────────────────────────────────" + echo "Verifying DKMS module compilation:" + if command -v dkms &>/dev/null; then + dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" + else + echo "(dkms not installed)" + fi + echo "" + echo "If the line ends with 'installed' → module is OK." + echo "Otherwise check: dmesg | grep nvidia" + echo "──────────────────────────────────────────────" } # --------------------------------------------------------------------------- diff --git a/modules/extras.sh b/modules/extras.sh index 13af6d2..50f9b7b 100644 --- a/modules/extras.sh +++ b/modules/extras.sh @@ -39,9 +39,10 @@ install_extras() { "7" "Servers & Dev Tools" \ "8" "Security & Networking" \ "9" "Software Centers" \ - "10" "System Tools" \ - "11" "Fetch / System Info" \ - "12" "Back to main menu" \ + "10" "Office & Productivity" \ + "11" "System Tools" \ + "12" "Fetch / System Info" \ + "13" "Back to main menu" \ 3>&1 1>&2 2>&3) [ -z "$cat_choice" ] && return @@ -58,9 +59,10 @@ install_extras() { 7) _cat_dev ;; 8) _cat_security ;; 9) _cat_software_centers ;; - 10) _cat_general ;; - 11) _cat_fetch ;; - 12) return ;; + 10) _cat_office ;; + 11) _cat_general ;; + 12) _cat_fetch ;; + 13) return ;; esac clear done diff --git a/modules/extras/dev/jellyfin.sh b/modules/extras/dev/jellyfin.sh index 5d3f60f..5ca9f0f 100644 --- a/modules/extras/dev/jellyfin.sh +++ b/modules/extras/dev/jellyfin.sh @@ -1,4 +1,15 @@ -# jellyfin.sh — Jellyfin Media Server installation (native repo) +#!/usr/bin/env bash +# jellyfin.sh — Jellyfin Media Server installation (extrepo) + +_enable_jellyfin_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_jellyfin.sources ]; then + if ! command -v extrepo &>/dev/null; then + _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." + fi + _run_cmd "Jellyfin" "sudo extrepo enable jellyfin" "Enabling Jellyfin repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} install_jellyfin() { local ver @@ -8,29 +19,7 @@ install_jellyfin() { Repository: repo.jellyfin.org/debian Version: ${ver:-unknown}"; then - # 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..." + _enable_jellyfin_repo _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}" diff --git a/modules/extras/internet/internet.sh b/modules/extras/internet/internet.sh index d0fced6..56c16f6 100644 --- a/modules/extras/internet/internet.sh +++ b/modules/extras/internet/internet.sh @@ -1,6 +1,78 @@ #!/usr/bin/env bash -# internet.sh — Browsers, email, VPN (was _cat_browsers, now includes riseup-vpn) +# internet.sh — Browsers, email, VPN +# extrepo-powered: mozilla, floorp, palemoon, librewolf, tailscale, mullvad, protonvpn +# ── Helpers extrepo ── +_ensure_extrepo() { + if ! command -v extrepo &>/dev/null; then + _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." + fi +} + +_enable_mozilla_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_mozilla.sources ]; then + _ensure_extrepo + _run_cmd "Mozilla" "sudo extrepo enable mozilla" "Enabling Mozilla repository..." + fi + if [ ! -f /etc/apt/preferences.d/mozilla ]; then + sudo tee /etc/apt/preferences.d/mozilla > /dev/null << 'EOF' +Package: * +Pin: origin packages.mozilla.org +Pin-Priority: 1000 +EOF + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +_enable_floorp_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_floorp.sources ]; then + _ensure_extrepo + _run_cmd "Floorp" "sudo extrepo enable floorp" "Enabling Floorp repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +_enable_palemoon_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_palemoon.sources ]; then + _ensure_extrepo + _run_cmd "Pale Moon" "sudo extrepo enable palemoon" "Enabling Pale Moon repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +_enable_librewolf_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_librewolf.sources ]; then + _ensure_extrepo + _run_cmd "LibreWolf" "sudo extrepo enable librewolf" "Enabling LibreWolf repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +_enable_tailscale_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_tailscale.sources ]; then + _ensure_extrepo + _run_cmd "Tailscale" "sudo extrepo enable tailscale" "Enabling Tailscale repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +_enable_mullvad_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_mullvad.sources ]; then + _ensure_extrepo + _run_cmd "Mullvad" "sudo extrepo enable mullvad" "Enabling Mullvad repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +_enable_protonvpn_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_protonvpn.sources ]; then + _ensure_extrepo + _run_cmd "ProtonVPN" "sudo extrepo enable protonvpn" "Enabling ProtonVPN repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +# ── Categories ── _cat_internet() { local headless=false _is_headless && headless=true @@ -16,12 +88,17 @@ _cat_internet() { local floorp_state; floorp_state=$(_state "floorp") local konqueror_state; konqueror_state=$(_state "konqueror") local librewolf_state; librewolf_state=$(_state "librewolf") + local palemoon_state; palemoon_state=$(_state "palemoon") local privacybrowser_state; privacybrowser_state=$(_state "privacybrowser") local qutebrowser_state; qutebrowser_state=$(_state "qutebrowser") local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn") local thunderbird_state; thunderbird_state=$(_state "thunderbird") local torbrowser_state; torbrowser_state=$(_state "torbrowser-launcher") local w3m_state; w3m_state=$(_state "w3m") + local tailscale_state; tailscale_state=$(_state "tailscale") + local mullvad_state; mullvad_state=$(_state "mullvad-vpn") + local mullvadbrowser_state; mullvadbrowser_state=$(_state "mullvad-browser") + local protonvpn_state; protonvpn_state=$(_state "protonvpn") local choices choices=$(whiptail --title "Internet" --checklist \ @@ -32,15 +109,20 @@ _cat_internet() { "epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$epiphany_state" \ "falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$falkon_state" \ "firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state" \ - "floorp" "Firefox-based browser (external repo)" "$floorp_state" \ + "floorp" "Firefox-based browser (extrepo)$(_inst floorp)" "$floorp_state" \ "konqueror" "KDE file manager / web browser$(_inst konqueror)" "$konqueror_state" \ - "librewolf" "Privacy-focused Firefox fork$(_inst librewolf)" "$librewolf_state" \ + "librewolf" "Privacy-focused Firefox fork (extrepo)$(_inst librewolf)" "$librewolf_state" \ + "palemoon" "Classic Firefox-derived browser (extrepo)" "$palemoon_state" \ "privacybrowser" "Privacy-focused web browser$(_inst privacybrowser)" "$privacybrowser_state" \ "qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$qutebrowser_state" \ - "riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" \ + "riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" \ "thunderbird" "Email client$(_inst thunderbird)" "$thunderbird_state" \ "torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$torbrowser_state" \ "w3m" "Text-mode browser + deps (w3m-img)$(_inst w3m)" "$w3m_state" \ + "tailscale" "Zero-config VPN & mesh networking$(_inst tailscale)" "$tailscale_state" \ + "mullvad-vpn" "Mullvad VPN client (WireGuard)$(_inst mullvad-vpn)" "$mullvad_state" \ + "mullvad-browser" "Mullvad privacy browser$(_inst mullvad-browser)" "$mullvadbrowser_state" \ + "protonvpn" "ProtonVPN client$(_inst protonvpn)" "$protonvpn_state" \ 3>&1 1>&2 2>&3) clear @@ -54,38 +136,39 @@ _cat_internet() { install_firefox_mozilla ;; floorp) - if ! is_installed "floorp"; then - echo "Setting up Floorp repository..." - ! is_installed "curl" && _run_install curl - ! is_installed "gpg" && _run_install gpg - sudo install -d -m 0755 /etc/apt/keyrings - curl -fsSL https://ppa.floorp.app/KEY.gpg | \ - sudo gpg --dearmor -o /usr/share/keyrings/Floorp.gpg - sudo curl -sS --compressed -o /etc/apt/sources.list.d/Floorp.list \ - 'https://ppa.floorp.app/Floorp.list' - sudo tee /etc/apt/preferences.d/floorp > /dev/null << EOF -Package: * -Pin: origin ppa.floorp.app -Pin-Priority: 1000 -EOF - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." - _run_install floorp - echo -e "${GREEN}Floorp installed.${NC}" - else - echo "Floorp already installed." - fi + _enable_floorp_repo + _run_install floorp + echo -e "${GREEN}Floorp installed.${NC}" ;; librewolf) - if ! is_installed "librewolf"; then - echo "Installing LibreWolf..." - install_backports_or_stable extrepo - sudo extrepo enable librewolf 2>/dev/null || true - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." - _run_install librewolf - echo -e "${GREEN}LibreWolf installed.${NC}" - else - echo "LibreWolf already installed." - fi + _enable_librewolf_repo + _run_install librewolf + echo -e "${GREEN}LibreWolf installed.${NC}" + ;; + palemoon) + _enable_palemoon_repo + _run_install palemoon + echo -e "${GREEN}Pale Moon installed.${NC}" + ;; + tailscale) + _enable_tailscale_repo + _run_install tailscale + echo -e "${GREEN}Tailscale installed.${NC}" + ;; + mullvad-vpn) + _enable_mullvad_repo + _run_install mullvad-vpn + echo -e "${GREEN}Mullvad VPN installed.${NC}" + ;; + mullvad-browser) + _enable_mullvad_repo + _run_install mullvad-browser + echo -e "${GREEN}Mullvad Browser installed.${NC}" + ;; + protonvpn) + _enable_protonvpn_repo + _run_install protonvpn + echo -e "${GREEN}ProtonVPN installed.${NC}" ;; riseup-vpn) install_backports_or_stable riseup-vpn @@ -125,57 +208,17 @@ install_firefox_mozilla() { return fi - echo "Setting up Mozilla APT repository for Firefox..." - if is_installed "firefox-esr"; then if _confirm "Firefox ESR" "Firefox ESR is installed.\nRemove it before installing Mozilla Firefox?"; then echo "Removing Firefox ESR..." sudo apt remove -y firefox-esr else echo "Keeping Firefox ESR." + return fi fi - ! is_installed "wget" && _run_install wget - ! is_installed "gpg" && _run_install gpg - - sudo install -d -m 0755 /etc/apt/keyrings - - wget -q https://packages.mozilla.org/apt/repo-signing-key.gpg -O- | \ - sudo tee /etc/apt/keyrings/packages.mozilla.org.asc > /dev/null - - local fp - fp=$(gpg -n -q --import --import-options import-show \ - /etc/apt/keyrings/packages.mozilla.org.asc 2>/dev/null | \ - awk '/pub/{getline; gsub(/^ +| +$/,""); print}') - if [ "$fp" != "35BAA0B33E9EB396F59CA838C0BA5CE6DC6315A3" ]; then - echo -e "${YELLOW}Warning: Mozilla key fingerprint does not match expected value.${NC}" - fi - - local use_deb822=false - [ -f /etc/apt/sources.list.d/debian.sources ] && use_deb822=true - - if $use_deb822; then - sudo tee /etc/apt/sources.list.d/mozilla.sources > /dev/null << EOF -Types: deb -URIs: https://packages.mozilla.org/apt -Suites: mozilla -Components: main -Signed-By: /etc/apt/keyrings/packages.mozilla.org.asc -EOF - else - echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" | \ - sudo tee /etc/apt/sources.list.d/mozilla.list > /dev/null - fi - - sudo tee /etc/apt/preferences.d/mozilla > /dev/null << EOF -Package: * -Pin: origin packages.mozilla.org -Pin-Priority: 1000 -EOF - - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." + _enable_mozilla_repo _run_install firefox - echo -e "${GREEN}Firefox (Mozilla) installed.${NC}" } diff --git a/modules/extras/java.sh b/modules/extras/java.sh index 8054a7e..4343e6e 100644 --- a/modules/extras/java.sh +++ b/modules/extras/java.sh @@ -1,28 +1,16 @@ #!/usr/bin/env bash -# java.sh — Adoptium Temurin repository setup and Java version selectors +# java.sh — Adoptium Temurin repository setup (extrepo) and Java version selectors # License GPL v3 -_ensure_adoptium_repo() { - [ -f /etc/apt/sources.list.d/adoptium.list ] && return 0 - - local deps=() - ! is_installed "wget" && deps+=("wget") - ! is_installed "apt-transport-https" && deps+=("apt-transport-https") - ! is_installed "gpg" && deps+=("gpg") - [ ${#deps[@]} -gt 0 ] && _run_install_batch "${deps[@]}" - - wget -qO - "https://packages.adoptium.net/artifactory/api/gpg/key/public" \ - | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/adoptium.gpg 2>/dev/null - - local codename - codename=$(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) - echo "deb https://packages.adoptium.net/artifactory/deb ${codename} main" \ - | sudo tee /etc/apt/sources.list.d/adoptium.list > /dev/null - - sudo apt update \ - -o Dir::Etc::sourcelist=/etc/apt/sources.list.d/adoptium.list \ - -o Dir::Etc::sourceparts="-" \ - 2>/dev/null || true +_enable_temurin_repo() { + if [ -f /etc/apt/sources.list.d/extrepo_temurin.sources ]; then + return 0 + fi + if ! command -v extrepo &>/dev/null; then + _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." + fi + _run_cmd "Temurin" "sudo extrepo enable temurin" "Enabling Adoptium Temurin repository..." + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." } _install_gaming_java() { @@ -34,7 +22,7 @@ _install_gaming_java() { "21" "Java 21 — For modern Minecraft >= 1.20.5 & 1.21+" \ 3>&1 1>&2 2>&3) [ -z "$ver" ] && { echo "No Java version selected."; return; } - _ensure_adoptium_repo + _enable_temurin_repo _run_install "temurin-${ver}-jre" } @@ -47,7 +35,7 @@ _install_dev_java() { "25" "Java 25 LTS Development Kit" \ 3>&1 1>&2 2>&3) [ -z "$ver" ] && { echo "No JDK version selected."; return; } - _ensure_adoptium_repo + _enable_temurin_repo _run_install "temurin-${ver}-jdk" } diff --git a/modules/extras/office/office.sh b/modules/extras/office/office.sh new file mode 100644 index 0000000..40f6d8a --- /dev/null +++ b/modules/extras/office/office.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# office.sh — Office & Productivity (OnlyOffice via extrepo, LibreOffice backports) +# License GPL v3 + +# ── OnlyOffice ── +_enable_onlyoffice_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_onlyoffice-desktopeditors.sources ]; then + if ! command -v extrepo &>/dev/null; then + _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." + fi + _run_cmd "OnlyOffice" "sudo extrepo enable onlyoffice-desktopeditors" "Enabling OnlyOffice repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + +install_onlyoffice() { + local ver + ver=$(apt-cache policy onlyoffice-desktopeditors 2>/dev/null | awk 'NR==3 {print $2; exit}') + + if _confirm "Install: OnlyOffice" "Install OnlyOffice Desktop Editors +Repository: download.onlyoffice.com +Version: ${ver:-unknown}"; then + _enable_onlyoffice_repo + _run_cmd "OnlyOffice" "sudo DEBIAN_FRONTEND=noninteractive apt install -y onlyoffice-desktopeditors" "Installing OnlyOffice..." + echo -e "${GREEN}OnlyOffice installed.${NC}" + fi +} + +# ── LibreOffice (backports) ── +install_libreoffice_bpo() { + if [ "$DEBIAN_VERSION" != "12" ] && [ "$DEBIAN_VERSION" != "13" ]; then + _msg "LibreOffice" "LibreOffice backports only available on Debian 12+." + return + fi + + local sys_lang + sys_lang=$(echo "${LANG:-en}" | cut -c1-2 | tr '[:upper:]' '[:lower:]') + + local lang_pkg="" + if [ "$sys_lang" != "en" ]; then + local candidate="libreoffice-l10n-${sys_lang}" + if apt-cache show "$candidate" &>/dev/null 2>&1; then + lang_pkg="$candidate" + fi + fi + + local ver + ver=$(apt-cache policy libreoffice 2>/dev/null | awk 'NR==3 {print $2; exit}') + local bpo_ver + bpo_ver=$(apt-cache madison libreoffice 2>/dev/null | grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1) + + local msg="Install LibreOffice?\n\n" + msg+=" Stable: ${ver:-unknown}\n" + msg+=" Backports: ${bpo_ver:-unavailable}\n" + [ -n "$lang_pkg" ] && msg+=" Language: ${lang_pkg}\n" + + if _confirm "LibreOffice" "$msg"; then + local pkgs="libreoffice${lang_pkg:+ $lang_pkg}" + if [ -n "$bpo_ver" ]; then + _run_cmd "LibreOffice" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $pkgs" \ + "Installing LibreOffice from backports..." + else + _run_cmd "LibreOffice" "sudo apt install -y $pkgs" \ + "Installing LibreOffice from stable..." + fi + echo -e "${GREEN}LibreOffice installed.${NC}" + fi +} + +_cat_office() { + local choices + choices=$(whiptail --title "Office & Productivity" --checklist \ + "Select office applications${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \ + "onlyoffice" "OnlyOffice Desktop Editors (extrepo)" OFF \ + "libreoffice" "LibreOffice (backports on Bookworm/Trixie)" OFF \ + 3>&1 1>&2 2>&3) + + [ -z "$choices" ] && return + local cleaned; cleaned=$(echo "$choices" | tr -d '"') + + for pkg in $cleaned; do + case $pkg in + onlyoffice) install_onlyoffice ;; + libreoffice) install_libreoffice_bpo ;; + esac + done +} diff --git a/modules/extras/programming/programming.sh b/modules/extras/programming/programming.sh index 18e58f2..fa8619a 100644 --- a/modules/extras/programming/programming.sh +++ b/modules/extras/programming/programming.sh @@ -35,7 +35,7 @@ _cat_programming() { "gedit" "GNOME text editor$(_inst gedit)" "$gedit_state" \ "geany" "Lightweight IDE$(_inst geany)" "$geany_state" \ "gnome-text-editor" "GNOME modern text editor$(_inst gnome-text-editor)" "$gte_state" \ - "vscodium" "VS Code open-source (external repo)$(_inst codium)" "$codium_state" \ + "vscodium" "VS Code open-source (extrepo)$(_inst codium)" "$codium_state" \ 3>&1 1>&2 2>&3) clear @@ -65,41 +65,23 @@ _cat_programming() { echo -e "${GREEN}Programming applications installed.${NC}" } +_enable_vscodium_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_vscodium.sources ]; then + if ! command -v extrepo &>/dev/null; then + _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." + fi + _run_cmd "VSCodium" "sudo extrepo enable vscodium" "Enabling VSCodium repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + install_vscodium() { if command -v codium &>/dev/null; then echo "VSCodium is already installed." return fi - echo "Setting up VSCodium repository..." - - ! is_installed "wget" && _run_install wget - ! is_installed "gpg" && _run_install gpg - - sudo install -d -m 0755 /usr/share/keyrings - - wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg \ - | gpg --dearmor \ - | sudo dd of=/usr/share/keyrings/vscodium-archive-keyring.gpg 2>/dev/null - - local use_deb822=false - [ -f /etc/apt/sources.list.d/debian.sources ] && use_deb822=true - - if $use_deb822; then - sudo tee /etc/apt/sources.list.d/vscodium.sources > /dev/null << 'EOF' -Types: deb -URIs: https://download.vscodium.com/debs -Suites: vscodium -Components: main -Architectures: amd64 arm64 -Signed-by: /usr/share/keyrings/vscodium-archive-keyring.gpg -EOF - else - echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/vscodium-archive-keyring.gpg] https://download.vscodium.com/debs vscodium main" \ - | sudo tee /etc/apt/sources.list.d/vscodium.list > /dev/null - fi - - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." + _enable_vscodium_repo _run_install codium echo -e "${GREEN}VSCodium installed.${NC}" diff --git a/modules/firmware.sh b/modules/firmware.sh index c662098..03d1aa8 100644 --- a/modules/firmware.sh +++ b/modules/firmware.sh @@ -3,6 +3,8 @@ # ── Global arrays ── PCI_NET_DEVS=() USB_WIFI_DEVS=() +PCI_BT_DEVS=() +USB_BT_DEVS=() _DETECTED_FW_PKGS=() _FW_PLAN_HW_LINES=() _FW_PLAN_PKG_LINES=() @@ -24,6 +26,20 @@ _detect_all_network_devices() { fi done < <(lsusb 2>/dev/null || true) + PCI_BT_DEVS=() + while IFS= read -r line; do + PCI_BT_DEVS+=("$line") + done < <(lspci -nn 2>/dev/null | grep -i 'Bluetooth controller' || true) + + USB_BT_DEVS=() + while IFS= read -r line; do + if echo "$line" | grep -qi 'bluetooth'; then + if ! echo "$line" | grep -qiE 'wireless|wifi|802\.11|wlan'; then + USB_BT_DEVS+=("$line") + fi + fi + done < <(lsusb 2>/dev/null || true) + _FW_PLAN_HW_LINES=() for dev in "${PCI_NET_DEVS[@]}"; do local desc dev_type @@ -39,7 +55,17 @@ _detect_all_network_devices() { local desc desc=$(echo "$dev" | sed 's/^.*ID //') _FW_PLAN_HW_LINES+=(" \xe2\x97\x8f ${desc} (USB)") + done + for dev in "${PCI_BT_DEVS[@]}"; do + local desc + desc=$(echo "$dev" | sed -E 's/^[^ ]+ [^:]+: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev.*\)//') + _FW_PLAN_HW_LINES+=(" \xe2\x97\x8f ${desc} (Bluetooth PCI)") + done + for dev in "${USB_BT_DEVS[@]}"; do + local desc + desc=$(echo "$dev" | sed 's/^.*ID //') + _FW_PLAN_HW_LINES+=(" \xe2\x97\x8f ${desc} (Bluetooth USB)") done } @@ -144,10 +170,42 @@ _build_firmware_plan() { plan+="${line}\n" done + local has_bt=false + [ ${#PCI_BT_DEVS[@]} -gt 0 ] && has_bt=true + [ ${#USB_BT_DEVS[@]} -gt 0 ] && has_bt=true + if ! $has_bt; then + for dev in "${USB_WIFI_DEVS[@]}"; do + if echo "$dev" | grep -qi 'bluetooth'; then + has_bt=true; break + fi + done + fi + + plan+="\nBluetooth:\n" + if $has_bt; then + if is_installed bluez; then + plan+=" [+] bluez (already installed)\n" + else + plan+=" [+] bluez + bluez-utils + bluez-obexd (base stack)\n" + fi + case "${DESKTOP_ENV:-other}" in + kde) plan+=" [+] bluedevil (KDE applet)\n" + if [ "${AUDIO_SERVER:-}" = "pipewire" ]; then + plan+=" → pipewire-pulse + wireplumber (if missing)\n" + fi + ;; + gnome) plan+=" (already in gnome-control-center)\n" ;; + *) plan+=" [+] blueman (GTK Bluetooth manager)\n" ;; + esac + plan+=" → Bluetooth service will be enabled\n" + else + plan+=" (no Bluetooth hardware detected)\n" + fi + plan+="\nInstallation order:\n" plan+=" 1. Base firmware (firmware-linux-nonfree)\n" plan+=" 2. Network firmware (realtek, iwlwifi, ...)\n" - plan+=" 3. Broadcom wireless (if detected)\n" + plan+=" 3. Broadcom / Bluetooth firmware\n" echo -e "$plan" } @@ -303,6 +361,9 @@ main menu to install proprietary firmwares." 10 65 # 6. Broadcom wireless handler _handle_wireless - # 7. Summary + # 7. Bluetooth stack + _install_bluetooth_stack + + # 8. Summary echo -e "${GREEN}Network & firmware setup complete.${NC}" } diff --git a/modules/gpu/_helpers.sh b/modules/gpu/_helpers.sh index c163bc9..b3de3f3 100644 --- a/modules/gpu/_helpers.sh +++ b/modules/gpu/_helpers.sh @@ -67,6 +67,22 @@ is_nvidia_pascal() { echo false } +is_nvidia_blackwell() { + local dev_id + dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | grep -oP '10de:\K[0-9a-fA-F]+' | head -n1) + [ -z "$dev_id" ] && { echo false; return; } + + local dev_int + dev_int=$((16#${dev_id,,})) + + # Blackwell (GB20x) rango bajo: 0x2900 – 0x29BF + if [ "$dev_int" -ge $((16#2900)) ] && [ "$dev_int" -le $((16#29BF)) ]; then echo true; return; fi + # Blackwell (GB20x) rango alto: 0x2B80 – 0x31FF + if [ "$dev_int" -ge $((16#2B80)) ] && [ "$dev_int" -le $((16#31FF)) ]; then echo true; return; fi + + echo false +} + _install_mesa_backports() { if [ "$(is_backports_enabled)" != "true" ]; then install_mesa_stable diff --git a/modules/gpu/nvidia.sh b/modules/gpu/nvidia.sh index 8b7febf..4fc663c 100644 --- a/modules/gpu/nvidia.sh +++ b/modules/gpu/nvidia.sh @@ -13,6 +13,16 @@ install_nvidia_driver() { local is_kepler; is_kepler=$(is_nvidia_kepler) local is_maxwell; is_maxwell=$(is_nvidia_maxwell) local is_pascal; is_pascal=$(is_nvidia_pascal) + local is_blackwell; is_blackwell=$(is_nvidia_blackwell) + + # ── Blackwell: v550 no soporta GB20x → CUDA repo v590 ── + if [ "$DEBIAN_CODENAME" = "trixie" ] && [ "$is_blackwell" = "true" ]; then + _msg "NVIDIA Blackwell" \ + "Your GPU is NVIDIA Blackwell architecture.\n\nDebian 13's nvidia-driver (v550) does not\nsupport Blackwell GPUs.\n\n\ +The script will enable the official NVIDIA CUDA\nrepository and install the v590 production branch,\nwhich fully supports Blackwell (GB20x)." 14 65 + _install_nvidia_cuda_repo + return + fi # ── Veto: Kepler en Trixie no tiene driver disponible ── if [ "$is_kepler" = "true" ] && [ "$DEBIAN_CODENAME" = "trixie" ]; then @@ -48,6 +58,22 @@ install_nvidia_driver() { fi } +# ------------------------------------------------------------------- +# Shared helper: enable NVIDIA CUDA repo via extrepo +# ------------------------------------------------------------------- +_enable_cuda_repo() { + if [ ! -f /etc/apt/sources.list.d/extrepo_nvidia-cuda.sources ] && \ + ! grep -qr 'developer.download.nvidia.com' /etc/apt/sources.list.d/ 2>/dev/null; then + if ! command -v extrepo &>/dev/null; then + _run_cmd "extrepo" "sudo apt install -y extrepo" "Installing extrepo..." + fi + _run_cmd "CUDA Repo" \ + "sudo extrepo enable nvidia-cuda" \ + "Enabling official NVIDIA CUDA repository..." + fi + _run_cmd "APT Update" "sudo apt update" "Updating package lists..." +} + # ------------------------------------------------------------------- # CASE A: Trixie + Backports Kernel → Official CUDA Repo (Pinned v590) # ------------------------------------------------------------------- @@ -74,20 +100,15 @@ _install_nvidia_cuda_repo() { return 1 fi - # Step 1: Download & install CUDA keyring - _run_cmd "CUDA Keyring" \ - "wget -q https://developer.download.nvidia.com/compute/cuda/repos/debian13/x86_64/cuda-keyring_1.1-1_all.deb -O /tmp/cuda-keyring.deb && sudo dpkg -i /tmp/cuda-keyring.deb && rm -f /tmp/cuda-keyring.deb" \ - "Downloading and installing official CUDA keyring..." + # Step 1: Enable CUDA repo via extrepo + _enable_cuda_repo # Step 2: Create APT pinning to lock v590 _run_cmd "APT Pinning" \ 'printf "%s\n" "Package: *nvidia*" "Package: *cuda*" "Package: libcuda1" "Package: firmware-nvidia-gsp" "Pin: version 590.*" "Pin-Priority: 1001" | sudo tee /etc/apt/preferences.d/block-nvidia > /dev/null' \ "Creating APT pinning to lock NVIDIA to v590 branch..." - # Step 3: Update package lists - _run_cmd "APT Update" "sudo apt update" "Updating package lists..." - - # Step 4: Build version-locked package list + # Step 3: Build version-locked package list local pkgs=( "cuda-drivers=590.48.01-1" "libcuda1=590.48.01-1" @@ -127,13 +148,26 @@ _install_nvidia_cuda_repo() { _run_cmd "NVIDIA CUDA" "sudo apt install -y ${pkgs[*]}" \ "Installing NVIDIA Production Driver v590.48.01..." - # Step 5: Hold critical packages + # Step 4: Hold critical packages _run_cmd "Package Hold" \ "sudo apt-mark hold cuda-drivers libcuda1 firmware-nvidia-gsp" \ "Locking v590 packages to prevent accidental upgrades..." NVIDIA_DRIVER_MODE="cuda-repo" echo -e "${GREEN}NVIDIA Production Driver v590 installed from CUDA repo. Reboot required.${NC}" + + echo "" + echo "──────────────────────────────────────────────" + echo "Verifying DKMS module compilation:" + if command -v dkms &>/dev/null; then + dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" + else + echo "(dkms not installed)" + fi + echo "" + echo "If the line ends with 'installed' → module is OK." + echo "Otherwise check: dmesg | grep nvidia" + echo "──────────────────────────────────────────────" } # ------------------------------------------------------------------- @@ -187,6 +221,19 @@ _install_nvidia_bookworm_bpo() { NVIDIA_DRIVER_MODE="backports" echo -e "${GREEN}NVIDIA driver installed from backports. Reboot required.${NC}" + + echo "" + echo "──────────────────────────────────────────────" + echo "Verifying DKMS module compilation:" + if command -v dkms &>/dev/null; then + dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" + else + echo "(dkms not installed)" + fi + echo "" + echo "If the line ends with 'installed' → module is OK." + echo "Otherwise check: dmesg | grep nvidia" + echo "──────────────────────────────────────────────" } # ------------------------------------------------------------------- @@ -241,6 +288,19 @@ _install_nvidia_bookworm_kepler() { NVIDIA_DRIVER_MODE="${NVIDIA_DRIVER_MODE:-stable}" echo -e "${GREEN}Kepler driver (${nv_pkg}) installed. Reboot required.${NC}" + + echo "" + echo "──────────────────────────────────────────────" + echo "Verifying DKMS module compilation:" + if command -v dkms &>/dev/null; then + dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" + else + echo "(dkms not installed)" + fi + echo "" + echo "If the line ends with 'installed' → module is OK." + echo "Otherwise check: dmesg | grep nvidia" + echo "──────────────────────────────────────────────" } # ------------------------------------------------------------------- @@ -327,4 +387,17 @@ _install_nvidia_standard() { fi echo -e "${GREEN}NVIDIA driver installed. Reboot required.${NC}" + + echo "" + echo "──────────────────────────────────────────────" + echo "Verifying DKMS module compilation:" + if command -v dkms &>/dev/null; then + dkms status 2>/dev/null | grep nvidia || echo "(no nvidia DKMS module found)" + else + echo "(dkms not installed)" + fi + echo "" + echo "If the line ends with 'installed' → module is OK." + echo "Otherwise check: dmesg | grep nvidia" + echo "──────────────────────────────────────────────" } diff --git a/modules/sysinfo.sh b/modules/sysinfo.sh new file mode 100644 index 0000000..d741d07 --- /dev/null +++ b/modules/sysinfo.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +_show_sysinfo() { + local msg="" + + # ── OS Block ── + msg+="OS: ${DEBIAN_VERSION} (${DEBIAN_CODENAME})\n" + msg+="Kernel: ${KERNEL_VERSION}\n" + msg+="Display: ${DISPLAY_SERVER}\n" + msg+="\n" + + # ── Hardware Block ── + msg+="CPU: ${CPU_SUMMARY}\n" + msg+="RAM: ${RAM_SUMMARY}\n" + msg+="Storage: ${STORAGE_SUMMARY}\n" + msg+="\n" + + # ── GPU Block ── + local found_gpu=false + if command -v lspci &>/dev/null; then + local gpu_count=0 + while IFS= read -r gpu_line; do + found_gpu=true + gpu_count=$((gpu_count + 1)) + local desc + desc=$(echo "$gpu_line" | sed -E 's/.*: //; s/ *\(rev.*//') + + if echo "$gpu_line" | grep -qi "nvidia"; then + local nv_ver="" + nv_ver=$(nvidia-smi --query-gpu=driver_version --format=csv,noheader 2>/dev/null | head -1) + [ -z "$nv_ver" ] && nv_ver=$(dpkg -l nvidia-driver 2>/dev/null | awk '/^ii/ {print $3}' | sed 's/-.*//') + msg+="GPU ${gpu_count}: ${desc}\n" + msg+=" Driver: ${nv_ver:+NVIDIA }${nv_ver:-not installed}\n" + else + local mesa_ver="" + mesa_ver=$(dpkg -l libgl1-mesa-dri 2>/dev/null | awk '/^ii/ {print $3; exit}' | sed 's/-.*//') + msg+="GPU ${gpu_count}: ${desc}\n" + msg+=" Driver: ${mesa_ver:+Mesa }${mesa_ver:-unknown}\n" + fi + done < <(lspci -nn | grep -E "VGA|3D" || true) + fi + + if ! $found_gpu; then + msg+="GPU: No GPU detected\n" + fi + msg+="\n" + + # ── Network Block ── + msg+="─── Network ───\n" + local has_network=false + local i + + if ! command -v ip &>/dev/null; then + msg+="(install iproute2 for interface details)\n" + else + for i in "${!ETH_NAMES[@]}"; do + has_network=true + local e_iface="${ETH_NAMES[$i]}" + local e_desc="${ETH_DESCS[$i]:-$ETH_DESC}" + local e_state="${ETH_STATES[$i]}" + local e_ip4="${ETH_IPS[$i]}" + if [ "$e_state" = "UP" ]; then + msg+="${e_iface}: ${e_desc}\n ↑ ${e_ip4:-no IP}\n" + else + msg+="${e_iface}: ${e_desc}\n ↓\n" + fi + done + + local found_active_wifi=false + for i in "${!WIFI_NAMES[@]}"; do + found_active_wifi=true + has_network=true + local w_iface="${WIFI_NAMES[$i]}" + local w_desc="${WIFI_DESCS[$i]:-$WIFI_DESC}" + local w_state="${WIFI_STATES[$i]}" + local w_ip4="${WIFI_IPS[$i]}" + local w_ssid="${WIFI_SSIDS[$i]}" + if [ "$w_state" = "UP" ]; then + msg+="${w_iface}: ${w_desc}\n ↑ ${w_ip4:-no IP}" + [ -n "$w_ssid" ] && msg+=" \"${w_ssid}\"" + msg+="\n" + else + msg+="${w_iface}: ${w_desc}\n ↓\n" + fi + done + + if ! $found_active_wifi && [ -n "$WIFI_DESC" ]; then + has_network=true + msg+="WiFi: ${WIFI_DESC}\n" + msg+=" (no driver — install firmware)\n" + fi + + if ! $has_network; then + msg+="No active interfaces detected\n" + fi + fi + + _msg "System Information" "$msg" 22 76 +} diff --git a/modules/utils.sh b/modules/utils.sh index ed527a2..3faca42 100644 --- a/modules/utils.sh +++ b/modules/utils.sh @@ -19,6 +19,8 @@ KERNEL_VERSION="" DISPLAY_SERVER="unknown" STORAGE_SUMMARY="" WIFI_CHIPSET="" +DESKTOP_ENV="" +AUDIO_SERVER="" # -------------------------- # Pre-flight checks @@ -47,11 +49,11 @@ check_system_time() { local year year=$(date +%Y) if [ "$year" -lt 2026 ]; then - local msg="Se ha detectado que la fecha/hora de su sistema está desconfigurada\n" - msg+="($(date '+%Y-%m-%d %H:%M')), lo que impedirá que los repositorios\n" - msg+="de Debian funcionen correctamente.\n\n" - msg+="¿Desea que el script intente sincronizar la hora automáticamente\n" - msg+="mediante la red (NTP) y configurar timedatectl?" + local msg="System date/time appears to be incorrect\n" + msg+="($(date '+%Y-%m-%d %H:%M')). This will prevent Debian\n" + msg+="repositories from working properly.\n\n" + msg+="Attempt automatic NTP synchronization?\n" + msg+="(requires network access and timedatectl)" if _confirm "System Date" "$msg"; then sync_system_time local new_year @@ -365,6 +367,31 @@ detect_storage() { STORAGE_SUMMARY="$result" } +# --------------------------------------- +# Desktop environment detection +# --------------------------------------- +detect_desktop_environment() { + case "${XDG_CURRENT_DESKTOP:-}" in + *GNOME*) DESKTOP_ENV="gnome" ;; + *KDE*) DESKTOP_ENV="kde" ;; + *XFCE*) DESKTOP_ENV="xfce" ;; + *) DESKTOP_ENV="other" ;; + esac +} + +# --------------------------------------- +# Audio server detection (PipeWire / PulseAudio) +# --------------------------------------- +detect_audio_server() { + if command -v pw-cli &>/dev/null && pw-cli info &>/dev/null 2>&1; then + AUDIO_SERVER="pipewire" + elif command -v pactl &>/dev/null; then + AUDIO_SERVER="pulseaudio" + else + AUDIO_SERVER="none" + fi +} + # --------------------------------------- # Intel HD Graphics generation detection # ---------------------------------------