diff --git a/.gitattributes b/.gitattributes index da7f4fe..d40969f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ -*.sh linguist-language=Rust - +*.sh text eol=lf linguist-language=Shell diff --git a/.github/workflows/shell-checks.yml b/.github/workflows/shell-checks.yml new file mode 100644 index 0000000..5655989 --- /dev/null +++ b/.github/workflows/shell-checks.yml @@ -0,0 +1,26 @@ +name: Shell checks + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Check Bash syntax + run: bash -n install-nvidia-cuda.sh + + - name: Install ShellCheck + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends --yes shellcheck + + - name: Run ShellCheck + run: shellcheck install-nvidia-cuda.sh diff --git a/README.md b/README.md index bff5fe4..d6976de 100644 --- a/README.md +++ b/README.md @@ -1,94 +1,120 @@ -# nvidia-driver -NVIDIA Driver + CUDA Toolkit Installer for Debian 12/13 +# NVIDIA Driver + CUDA Toolkit Installer -This script installs **NVIDIA GPU drivers** and the **CUDA Toolkit** on **Debian 12 (Bookworm)** and **Debian 13 (Trixie)** — automatically and reliably. -It uses Debian’s own packages (APT-first, no NVIDIA repo by default) for a stable, Debian-managed setup. +[![Shell checks](https://github.com/dennishilk/nvidia-driver/actions/workflows/shell-checks.yml/badge.svg)](https://github.com/dennishilk/nvidia-driver/actions/workflows/shell-checks.yml) ---- +Interactive, APT-first installer for NVIDIA drivers and the optional CUDA Toolkit on Debian 12 (Bookworm) and Debian 13 (Trixie). -## ✨ Features -- ✅ Auto-detects Debian **12/13** and **amd64/arm64** architecture -- ✅ Installs build tools: `build-essential`, `dkms`, `linux-headers-$(uname -r)` -- ✅ Installs CUDA via the Debian package: `nvidia-cuda-toolkit` -- ✅ Optionally blacklists **nouveau** to avoid conflicts -- ✅ Warns if **Secure Boot** is enabled +The recommended paths use Debian's own packages. The script does not add NVIDIA repositories, force an Xorg configuration, kill package-manager processes, or delete APT lock files. +## Supported systems -🛡️ Secure Boot +- Debian 12 or 13 +- `amd64` or `arm64` +- An NVIDIA PCI display device +- Root access +- APT sources with `main contrib non-free non-free-firmware` -If Secure Boot is enabled, DKMS may fail to load unsigned modules. Options: +The advanced NVIDIA `.run` installer is available only on `amd64` and is intentionally not recommended for normal Debian installations. -Disable Secure Boot in firmware, or +## Features -Enroll a Machine Owner Key (MOK) and sign the module. +- Installs `nvidia-driver` from Debian stable or an already configured backports suite +- Installs the Debian `nvidia-cuda-toolkit` package on request +- Installs both the architecture header metapackage and exact running-kernel headers when available +- Understands classic `.list` files and modern deb822 `.sources` files +- Detects Secure Boot when `mokutil` is available and explains MOK enrollment +- Can switch back to nouveau or remove installed `nvidia-*` packages through APT +- Fetches current `.run` installer metadata from NVIDIA instead of using a stale hardcoded version +- Logs output to `/var/log/nvidia-optimizer.log` -The script prints a note when Secure Boot appears enabled. +## Installation +```bash +git clone https://github.com/dennishilk/nvidia-driver.git +cd nvidia-driver +chmod +x install-nvidia-cuda.sh +sudo ./install-nvidia-cuda.sh +``` -🚫 Nouveau (Open-Source Driver) +Choose one of the five menu actions: -The script blacklists nouveau to prevent conflicts: +1. Install the Debian stable driver (recommended) +2. Install the driver from an already enabled Debian backports suite +3. Remove NVIDIA packages and enable nouveau +4. Remove NVIDIA packages and clean unused dependencies +5. Install NVIDIA's `.run` driver (advanced, `amd64` only) -Config: /etc/modprobe.d/blacklist-nouveau.conf +After a driver change, reboot and verify: -Rebuilds initramfs automatically +```bash +nvidia-smi +nvcc --version # only when the CUDA Toolkit was installed +``` -If you prefer to keep nouveau, remove that file and run sudo update-initramfs -u. +## APT source requirements +The script accepts both `/etc/apt/sources.list` entries and deb822 files such as `/etc/apt/sources.list.d/debian.sources`. -🧰 Troubleshooting +For example, a classic Debian 13 source line contains: -Black screen or login loop: Likely driver conflict or Secure Boot. Boot to recovery/TTY, remove conflicting drivers, verify blacklist, check mokutil --sb-state. +```text +deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware +``` -DKMS build fails: Ensure headers match the running kernel: +Replace `trixie` with `bookworm` on Debian 12. Backports option 2 additionally expects `${VERSION_CODENAME}-backports`, such as `trixie-backports`. -uname -r -apt-cache policy linux-headers-$(uname -r) +## Secure Boot + +With Secure Boot enabled, the NVIDIA DKMS module may not load until its Machine Owner Key is enrolled. If Debian created `/var/lib/dkms/mok.pub`, enroll it with: -Unable to locate package cuda: Debian repos do not ship the `cuda` meta-package. Use `nvidia-cuda-toolkit` (this script does) or add NVIDIA’s CUDA repo explicitly. +```bash +sudo mokutil --import /var/lib/dkms/mok.pub +``` +Then reboot and complete enrollment in the firmware's MOK Manager. If `mokutil` is missing, install the Debian package of the same name first. -nvidia-smi not found: Ensure driver packages are installed and reboot if needed. +## Troubleshooting +### `Unable to locate package nvidia-cuda-toolkit` -🧩 Uninstall +The Debian package is named `nvidia-cuda-toolkit`, not `cuda`. Confirm that `non-free` is enabled, then refresh APT: -To remove CUDA & drivers: +```bash +sudo apt update +apt-cache policy nvidia-cuda-toolkit +``` -sudo apt remove --purge 'nvidia-cuda-toolkit*' 'nvidia*' -sudo rm -f /etc/modprobe.d/blacklist-nouveau.conf -sudo update-initramfs -u -sudo apt autoremove -y -sudo reboot +### DKMS build fails +Check whether headers exist for the running kernel: + +```bash +uname -r +apt-cache policy "linux-headers-$(uname -r)" +``` +If only the newer architecture header metapackage was available, reboot into the newly installed Debian kernel and run the driver installation again. -## 📦 Installation +### Black screen or login loop -1. Clone the repository or download the script: - git clone https://github.com/dennishilk/nvidia-driver.git - - cd nvidia-driver - -3. Make the script executable: - chmod +x install-nvidia-cuda.sh +From a recovery shell or TTY, inspect: -4. Run with root privileges: - sudo ./install-nvidia-cuda.sh +```bash +cat /var/log/nvidia-optimizer.log +dkms status +sudo mokutil --sb-state +``` -5. Reboot to load the NVIDIA kernel module: - sudo reboot +Secure Boot, a failed DKMS build, or an old manually installed `.run` driver are the usual causes. -6. Check after reboot: - nvidia-smi - nvcc --version +## Uninstall or return to nouveau - Buy Me A Coffee +Run the script again and choose option 3 or 4. Cleanup is performed through APT; the script does not manually erase `/var/lib/dkms` or user-owned NVIDIA configuration files. +## License and warranty +MIT License. See [LICENSE](LICENSE). -No Warranty Disclaimer +The software is provided "as is", without warranty of any kind. Use it at your own risk; the author is not responsible for damage, data loss, or other issues caused by its use. -The software in this repository is provided "as is", without warranty of any kind. -I make no guarantees regarding the functionality, correctness, or suitability of this code for any purpose. -Use it at your own risk. I am not responsible for any damages, data loss, or issues that may arise from using this software. +Buy Me A Coffee diff --git a/install-nvidia-cuda.sh b/install-nvidia-cuda.sh index 57c3a78..692df1a 100644 --- a/install-nvidia-cuda.sh +++ b/install-nvidia-cuda.sh @@ -1,20 +1,19 @@ #!/usr/bin/env bash # ============================================================ -# NVIDIA Driver + (optional) CUDA Toolkit for Debian 13 (Trixie) +# NVIDIA Driver + (optional) CUDA Toolkit for Debian 12/13 # "Debian-clean" edition (APT-first, no mixed installer by default) # Author: Dennis Hilk -# Version: 1.2.0 +# Version: 1.3.0 # # Features: # - Strict mode + logging -# - Safe APT/dpkg lock handling (no blind killing) +# - Safe APT/dpkg lock handling (never kills package managers or removes locks) # - Detect NVIDIA GPU -# - Checks non-free + non-free-firmware APT sources +# - Checks .list and deb822 .sources files for required APT components # - Stable driver install (Debian repo) or Backports install # - Optional CUDA Toolkit (Debian package) # - Nouveau enable, full clean remove # - Secure Boot + Wayland hints -# - Uses /etc/X11/xorg.conf.d (modular) instead of patching xorg.conf # ============================================================ set -Eeuo pipefail @@ -23,6 +22,7 @@ set -Eeuo pipefail # Logging # ---------------------------- LOGFILE="/var/log/nvidia-optimizer.log" +SCRIPT_VERSION="1.3.0" mkdir -p "$(dirname "$LOGFILE")" exec > >(tee -a "$LOGFILE") 2>&1 @@ -62,9 +62,9 @@ if [[ ${EUID:-0} -ne 0 ]]; then die "Please run as root: sudo $0" fi -clear +clear 2>/dev/null || true echo -e "${CYAN}──────────────────────────────────────────────────────────" -echo -e " 🧠 NVIDIA Driver + CUDA Toolkit (Debian 13) v1.2.0" +echo -e " 🧠 NVIDIA Driver + CUDA Toolkit (Debian 12/13) v${SCRIPT_VERSION}" echo -e "──────────────────────────────────────────────────────────${NC}" echo -e "Log file: ${YELLOW}${LOGFILE}${NC}" echo @@ -75,10 +75,12 @@ echo need_cmd uname need_cmd grep need_cmd sed -need_cmd lspci +need_cmd awk need_cmd apt need_cmd dpkg +need_cmd dpkg-query need_cmd apt-cache +need_cmd pgrep need_cmd tee # ---------------------------- @@ -88,11 +90,35 @@ KERNEL="$(uname -r)" SESSION="${XDG_SESSION_TYPE:-unknown}" ARCH="$(dpkg --print-architecture)" SECURE_BOOT_ENABLED=0 +CODENAME="unknown" +DEBIAN_VERSION="unknown" + +if [[ ! -r /etc/os-release ]]; then + die "Cannot identify the operating system: /etc/os-release is missing." +fi + +# shellcheck disable=SC1091 +. /etc/os-release +[[ "${ID:-}" == "debian" ]] || die "Unsupported distribution: ${PRETTY_NAME:-${ID:-unknown}}. This script supports Debian only." + +DEBIAN_VERSION="${VERSION_ID:-unknown}" +CODENAME="${VERSION_CODENAME:-unknown}" +case "${DEBIAN_VERSION}" in + 12|12.*|13|13.*) ;; + *) die "Unsupported Debian version: ${DEBIAN_VERSION}. Supported releases: Debian 12 and 13." ;; +esac + +case "${ARCH}" in + amd64|arm64) ;; + *) die "Unsupported architecture: ${ARCH}. Supported architectures: amd64 and arm64." ;; +esac -info "Kernel: ${KERNEL}" -info "Session: ${SESSION}" +info "Debian: ${DEBIAN_VERSION} (${CODENAME})" +info "Architecture: ${ARCH}" +info "Kernel: ${KERNEL}" +info "Session: ${SESSION}" if [[ "$SESSION" == "wayland" ]]; then - warn "Wayland session detected. Xorg config tweaks may be ignored (depends on DE)." + info "Wayland session detected." fi # Secure Boot hint (best-effort) @@ -101,95 +127,109 @@ if command -v mokutil >/dev/null 2>&1; then SECURE_BOOT_ENABLED=1 warn "Secure Boot appears ENABLED. Unsigned NVIDIA modules may fail to load." warn "If the driver does not load: disable Secure Boot or enroll/sign modules (MOK)." - warn "Tip: update-secureboot-policy --enroll-key (requires secureboot-policy package)." fi fi echo # ---------------------------- -# NVIDIA GPU detection +# NVIDIA GPU detection (lspci first, sysfs fallback for minimal systems) # ---------------------------- -GPU="$(lspci | grep -E "VGA|3D" | grep -i nvidia || true)" +detect_nvidia_gpu() { + if command -v lspci >/dev/null 2>&1; then + lspci | grep -Ei 'VGA|3D|Display' | grep -i nvidia || true + return + fi + + local device vendor class + for device in /sys/bus/pci/devices/*; do + [[ -r "${device}/vendor" && -r "${device}/class" ]] || continue + vendor="$(<"${device}/vendor")" + class="$(<"${device}/class")" + if [[ "${vendor,,}" == "0x10de" && "${class,,}" == 0x03* ]]; then + printf 'NVIDIA PCI display device %s (class %s)\n' "${device##*/}" "${class}" + fi + done +} + +GPU="$(detect_nvidia_gpu)" [[ -n "$GPU" ]] || die "No NVIDIA GPU detected." ok "NVIDIA GPU detected:" echo "$GPU" echo # ---------------------------- -# Debian release / codename +# APT sources sanity (non-free + non-free-firmware) # ---------------------------- -CODENAME="unknown" -if [[ -r /etc/os-release ]]; then - # shellcheck disable=SC1091 - . /etc/os-release - CODENAME="${VERSION_CODENAME:-${CODENAME}}" -fi +collect_apt_source_files() { + APT_SOURCE_FILES=() + [[ -r /etc/apt/sources.list ]] && APT_SOURCE_FILES+=(/etc/apt/sources.list) + + local file + shopt -s nullglob + for file in /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources; do + [[ -r "${file}" ]] && APT_SOURCE_FILES+=("${file}") + done + shopt -u nullglob +} -info "Debian codename: ${CODENAME}" +apt_source_text() { + (( ${#APT_SOURCE_FILES[@]} > 0 )) || return 1 + sed -e '/^[[:space:]]*#/d' -e '/^[[:space:]]*$/d' "${APT_SOURCE_FILES[@]}" 2>/dev/null +} + +has_apt_source_token() { + local token="$1" + apt_source_text | grep -Eq "(^|[[:space:]])${token}([[:space:]]|$)" +} -# ---------------------------- -# APT sources sanity (non-free + non-free-firmware) -# ---------------------------- check_nonfree_sources() { - # Debian 12/13 typically need: main contrib non-free non-free-firmware - local sources=() - [[ -f /etc/apt/sources.list ]] && sources+=("/etc/apt/sources.list") - if compgen -G "/etc/apt/sources.list.d/*.list" >/dev/null; then - sources+=(/etc/apt/sources.list.d/*.list) + if (( ${#APT_SOURCE_FILES[@]} == 0 )); then + warn "No readable APT source files found." + warn "Checked /etc/apt/sources.list and /etc/apt/sources.list.d/*.{list,sources}." + return 1 fi - if (( ${#sources[@]} == 0 )); then - warn "No APT source files found in /etc/apt/sources.list or /etc/apt/sources.list.d." + if ! has_apt_source_token "non-free"; then + warn "APT sources do not seem to include: non-free" + warn "Enable it in your .list or deb822 .sources configuration." return 1 fi - local all_text - all_text="$(cat "${sources[@]}" 2>/dev/null || true)" - - if ! echo "$all_text" | grep -Eq '^[[:space:]]*deb[[:space:]].*(non-free)'; then - warn "APT sources do not seem to include: non-free" - warn "Enable it in your sources.list (recommended for NVIDIA)." + if ! has_apt_source_token "contrib"; then + warn "APT sources do not seem to include: contrib" + warn "Enable it in your .list or deb822 .sources configuration." return 1 fi - if ! echo "$all_text" | grep -Eq '^[[:space:]]*deb[[:space:]].*(non-free-firmware)'; then + if ! has_apt_source_token "non-free-firmware"; then warn "APT sources do not seem to include: non-free-firmware" - warn "Debian 13 typically needs it for firmware packages." + warn "Debian 12/13 use it for firmware packages." return 1 fi return 0 } +APT_SOURCE_FILES=() +collect_apt_source_files + if ! check_nonfree_sources; then echo warn "Fix your APT sources first, then re-run this script." - echo "Example (Debian 13 Trixie):" - echo " deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware" - echo " deb http://security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware" - echo " deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware" + echo "Example for ${CODENAME}:" + echo " deb http://deb.debian.org/debian ${CODENAME} main contrib non-free non-free-firmware" + echo " deb http://security.debian.org/debian-security ${CODENAME}-security main contrib non-free non-free-firmware" + echo " deb http://deb.debian.org/debian ${CODENAME}-updates main contrib non-free non-free-firmware" echo die "APT sources missing required components." fi -ok "APT sources look good (non-free + non-free-firmware detected)." +ok "APT sources look good (contrib + non-free + non-free-firmware detected)." echo has_suite_sources() { local suite="$1" - local sources=() - [[ -f /etc/apt/sources.list ]] && sources+=("/etc/apt/sources.list") - if compgen -G "/etc/apt/sources.list.d/*.list" >/dev/null; then - sources+=(/etc/apt/sources.list.d/*.list) - fi - - if (( ${#sources[@]} == 0 )); then - return 1 - fi - - local all_text - all_text="$(cat "${sources[@]}" 2>/dev/null || true)" - echo "$all_text" | grep -Eq "^[[:space:]]*deb[[:space:]].*\\b${suite}\\b" + has_apt_source_token "${suite}" } # ---------------------------- @@ -200,18 +240,11 @@ check_locks() { local timeout=120 local waited=0 - while pgrep -x apt >/dev/null 2>&1 || pgrep -x dpkg >/dev/null 2>&1; do + while pgrep -x apt >/dev/null 2>&1 || + pgrep -x apt-get >/dev/null 2>&1 || + pgrep -x dpkg >/dev/null 2>&1; do if (( waited >= timeout )); then - warn "APT/dpkg still running after ${timeout}s." - warn "Killing package manager processes can BREAK your system." - if confirm "Do you want to attempt killing apt/dpkg anyway?"; then - warn "Attempting to kill apt/dpkg..." - pkill -9 apt 2>/dev/null || true - pkill -9 dpkg 2>/dev/null || true - break - else - die "Please wait until apt/dpkg finishes, then re-run." - fi + die "APT/dpkg is still running after ${timeout}s. Let it finish, then re-run this script." fi echo -ne "${YELLOW}⏳ Waiting for package manager... (${waited}s)\r${NC}" sleep 3 @@ -219,17 +252,7 @@ check_locks() { done echo - # Do NOT rm lock files blindly unless user confirms (can be dangerous) - if [[ -e /var/lib/dpkg/lock-frontend || -e /var/lib/dpkg/lock || -e /var/cache/apt/archives/lock ]]; then - warn "Lock files detected." - warn "Removing lock files while apt is running can corrupt dpkg state." - if confirm "Remove lock files now? (only do this if you are sure apt is NOT running)"; then - rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock || true - ok "Lock files removed." - else - warn "Keeping lock files." - fi - fi + ok "No active APT/dpkg process detected." } # ---------------------------- @@ -243,35 +266,6 @@ else fi echo -# ---------------------------- -# Xorg config (modular) -# ---------------------------- -ensure_xorg_conf_d() { - mkdir -p /etc/X11/xorg.conf.d -} - -write_xorg_driver_snippet() { - # $1: driver name - local driver="$1" - ensure_xorg_conf_d - cat > /etc/X11/xorg.conf.d/10-gpu-driver.conf </dev/null 2>&1; then + packages+=("${header_meta}") + else + warn "No architecture header metapackage found: ${header_meta}" fi + if apt-cache show "linux-headers-${KERNEL}" >/dev/null 2>&1; then packages+=("linux-headers-${KERNEL}") else warn "No exact headers for running kernel found: linux-headers-${KERNEL}" - warn "Consider rebooting into the newest kernel or installing linux-headers-${ARCH}." + warn "The ${header_meta} metapackage will install headers for Debian's current kernel." + warn "Reboot into that kernel before expecting the NVIDIA DKMS module to load." fi apt install -y --no-install-recommends "${packages[@]}" } @@ -313,32 +313,29 @@ unblacklist_nouveau() { # NVIDIA remove/clean # ---------------------------- remove_nvidia() { - local installed - installed="$(dpkg-query -W -f='${Package}\n' 'nvidia-*' 2>/dev/null || true)" - if [[ -n "${installed}" ]]; then - warn "Installed NVIDIA-related packages that may be removed:" - echo "${installed}" - warn "This includes CUDA-related packages that match nvidia-*." + local installed=() + mapfile -t installed < <( + dpkg-query -W -f='${binary:Package}\t${db:Status-Status}\n' 2>/dev/null | + awk '$2 == "installed" && $1 ~ /^nvidia-/ { print $1 }' + ) + + if (( ${#installed[@]} > 0 )); then + warn "Installed nvidia-* packages that will be removed:" + printf ' %s\n' "${installed[@]}" + progress "Purging NVIDIA packages" + apt purge -y "${installed[@]}" else - info "No installed NVIDIA-related packages detected." + info "No installed nvidia-* packages detected." fi - progress "Purging NVIDIA packages" - apt purge -y 'nvidia-*' || true - progress "Autoremoving unused deps" - apt autoremove -y || true + apt autoremove -y - progress "Cleaning DKMS remnants (best-effort)" - rm -rf /var/lib/dkms/nvidia* 2>/dev/null || true - - progress "Removing old modprobe snippets (best-effort)" - rm -f /etc/modprobe.d/nvidia*.conf 2>/dev/null || true + unblacklist_nouveau progress "Updating initramfs" update-initramfs -u - remove_xorg_driver_snippet ok "NVIDIA removed." } @@ -350,6 +347,9 @@ install_cuda_toolkit_debian() { warn "Note: This may not be the newest CUDA version, but it is Debian-managed and stable." warn "If you need the newest CUDA, consider NVIDIA's official repo:" warn "https://developer.nvidia.com/cuda-downloads (use with caution on Debian)." + if ! apt-cache show nvidia-cuda-toolkit >/dev/null 2>&1; then + die "nvidia-cuda-toolkit is unavailable. Verify that non-free is enabled and apt update succeeded." + fi apt install -y nvidia-cuda-toolkit ok "CUDA Toolkit installed (Debian package)." echo @@ -377,33 +377,18 @@ check_locks handle_secure_boot() { if (( SECURE_BOOT_ENABLED == 1 )); then warn "Secure Boot is enabled. NVIDIA DKMS modules may require MOK enrollment." - if confirm "Install secureboot-policy and enroll MOK now?"; then - apt update - apt install -y secureboot-policy kmod - if command -v update-secureboot-policy >/dev/null 2>&1; then - update-secureboot-policy --enroll-key || true - else - warn "update-secureboot-policy not found. Please enroll MOK manually." - fi - warn "You may be prompted to set a MOK password and reboot to enroll." + warn "Debian DKMS normally stores its enrollment certificate at /var/lib/dkms/mok.pub." + warn "After installation, import it with mokutil --import /var/lib/dkms/mok.pub, then reboot and enroll it in MOK Manager." + if ! confirm "Continue with Secure Boot enabled?"; then + die "Aborted." fi fi } -should_write_xorg_snippet() { - if [[ "${SESSION}" == "wayland" || "${SESSION}" == "unknown" ]]; then - warn "Wayland/unknown session detected. Xorg snippets may be ignored." - confirm "Write Xorg driver snippet anyway?" - return $? - fi - return 0 -} - case "${CHOICE}" in 1) info "Installing NVIDIA driver from Debian stable repo..." handle_secure_boot - remove_nvidia unblacklist_nouveau install_common_deps @@ -414,17 +399,12 @@ case "${CHOICE}" in progress "Updating initramfs" update-initramfs -u - if should_write_xorg_snippet; then - write_xorg_driver_snippet "nvidia" - fi - ok "Driver installation finished (Debian stable repo)." ;; 2) info "Installing NVIDIA driver from Debian backports..." handle_secure_boot - remove_nvidia unblacklist_nouveau install_common_deps @@ -449,10 +429,6 @@ case "${CHOICE}" in progress "Updating initramfs" update-initramfs -u - if should_write_xorg_snippet; then - write_xorg_driver_snippet "nvidia" - fi - ok "Driver installation finished (backports)." ;; @@ -463,24 +439,16 @@ case "${CHOICE}" in progress "Installing nouveau Xorg driver" apt install -y xserver-xorg-video-nouveau - unblacklist_nouveau progress "Updating initramfs" update-initramfs -u - if should_write_xorg_snippet; then - write_xorg_driver_snippet "nouveau" - fi - ok "Nouveau enabled." ;; 4) info "Removing NVIDIA driver and cleaning system..." remove_nvidia - - # Prefer modesetting: no explicit snippet needed - remove_xorg_driver_snippet - ok "System cleaned. Using default modesetting (no forced Xorg driver)." + ok "System cleaned. Nouveau is no longer blacklisted by this script." ;; 5) @@ -490,6 +458,8 @@ case "${CHOICE}" in die "Aborted." fi + [[ "${ARCH}" == "amd64" ]] || die "The advanced .run installer option currently supports amd64 only." + need_cmd curl need_cmd wget @@ -503,24 +473,20 @@ case "${CHOICE}" in handle_secure_boot remove_nvidia - unblacklist_nouveau install_common_deps mkdir -p /root/nvidia-install cd /root/nvidia-install - warn "Fetching latest driver version (best-effort)..." - # Keep a safe fallback; API endpoints can change. - LATEST="$(curl -fsSL https://api.nvidia.com/v1/driver-latest-version/linux 2>/dev/null | grep -oP '"version":"\K[0-9.]+' || true)" - if [[ -z "${LATEST}" ]]; then - LATEST="580.95.05" - warn "Could not fetch latest version. Using fallback: ${LATEST}" - else - ok "Latest NVIDIA version detected: ${LATEST}" - fi + warn "Fetching NVIDIA's current Linux x86_64 driver metadata..." + LATEST_LINE="$(curl -fsSL https://download.nvidia.com/XFree86/Linux-x86_64/latest.txt)" || die "Could not fetch NVIDIA driver metadata." + read -r LATEST RUN_PATH _ <<<"${LATEST_LINE}" + [[ "${LATEST}" =~ ^[0-9]+(\.[0-9]+)+$ ]] || die "NVIDIA returned an invalid driver version: ${LATEST:-empty}" + [[ "${RUN_PATH}" == "${LATEST}/NVIDIA-Linux-x86_64-${LATEST}.run" ]] || die "NVIDIA returned an unexpected download path." + ok "Latest NVIDIA version detected: ${LATEST}" progress "Downloading NVIDIA-Linux-x86_64-${LATEST}.run" - wget -O NVIDIA-Linux.run "https://us.download.nvidia.com/XFree86/Linux-x86_64/${LATEST}/NVIDIA-Linux-x86_64-${LATEST}.run" + wget -O NVIDIA-Linux.run "https://download.nvidia.com/XFree86/Linux-x86_64/${RUN_PATH}" chmod +x NVIDIA-Linux.run @@ -535,10 +501,6 @@ case "${CHOICE}" in progress "Updating initramfs" update-initramfs -u - if should_write_xorg_snippet; then - write_xorg_driver_snippet "nvidia" - fi - ok ".run driver installation finished (advanced)." ;;