mirror of
https://github.com/XuehaiPan/nvitop.git
synced 2026-05-15 14:15:55 -06:00
feat(install-nvidia-driver): support open kernel-module driver packages
This commit is contained in:
parent
2f68dd269d
commit
6399e087f1
3 changed files with 197 additions and 16 deletions
|
|
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Added
|
||||
|
||||
- Add `nvidia-ml-py` 13.595.45 to support list.
|
||||
- Add support for open kernel-module driver packages (e.g., `nvidia-driver-595-open`) in `install-nvidia-driver.sh` with new `--proprietary` and `--open` flags by [@XuehaiPan](https://github.com/XuehaiPan).
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -128,8 +128,9 @@ git clone --depth=1 https://github.com/XuehaiPan/nvitop.git && cd nvitop
|
|||
# Optional for SSH users
|
||||
sudo chvt 3 # or use keyboard shortcut: Ctrl-LeftAlt-F3
|
||||
|
||||
bash install-nvidia-driver.sh --package=nvidia-driver-470 # install the R470 driver from ppa:graphics-drivers
|
||||
bash install-nvidia-driver.sh --package=nvidia-driver-595 # install the R595 driver from ppa:graphics-drivers
|
||||
bash install-nvidia-driver.sh --latest # install the latest driver from ppa:graphics-drivers
|
||||
bash install-nvidia-driver.sh --latest --open # install the latest open-kernel-module driver
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
#
|
||||
# Usage: bash install-nvidia-driver.sh [--package=PKG] [--upgrade-only] [--latest] [--dry-run] [--yes] [--help]
|
||||
# Usage: bash install-nvidia-driver.sh [--package=PKG] [--upgrade-only] [--latest]
|
||||
# [--proprietary | --open] [--dry-run] [--yes] [--help]
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# bash install-nvidia-driver.sh
|
||||
# bash install-nvidia-driver.sh --package=nvidia-driver-470
|
||||
# bash install-nvidia-driver.sh --package=nvidia-driver-595
|
||||
# bash install-nvidia-driver.sh --package=nvidia-driver-595-open
|
||||
# bash install-nvidia-driver.sh --upgrade-only
|
||||
# bash install-nvidia-driver.sh --latest
|
||||
# bash install-nvidia-driver.sh --latest --open
|
||||
#
|
||||
# ==============================================================================
|
||||
# This file is part of nvitop, the interactive NVIDIA-GPU process viewer.
|
||||
|
|
@ -28,7 +31,7 @@
|
|||
# limitations under the License.
|
||||
# ==============================================================================
|
||||
|
||||
# shellcheck disable=SC2016,SC2312
|
||||
# shellcheck disable=SC2016,SC2310,SC2312
|
||||
|
||||
set -u
|
||||
set -e
|
||||
|
|
@ -66,16 +69,22 @@ tty_green="$(tty_mkbold 32)"
|
|||
tty_yellow="$(tty_mkbold 33)"
|
||||
tty_white="$(tty_mkbold 37)"
|
||||
tty_bold="$(tty_mkbold 39)"
|
||||
tty_dim="$(tty_escape 90)"
|
||||
tty_reset="$(tty_escape 0)"
|
||||
|
||||
function usage() {
|
||||
cat <<EOS
|
||||
Usage: bash $(basename "$0") [--package=PKG] [--upgrade-only] [--latest] [--dry-run] [--yes] [--help]
|
||||
Usage: bash $(basename "$0") [--package=PKG] [--upgrade-only] [--latest]
|
||||
[--proprietary | --open] [--dry-run] [--yes] [--help]
|
||||
|
||||
Options:
|
||||
--package PKG Install the specified driver package. (e.g. ${tty_bold}nvidia-driver-470${tty_reset})
|
||||
--package PKG Install the specified driver package. (e.g. ${tty_bold}nvidia-driver-595${tty_reset} or ${tty_bold}nvidia-driver-595-open${tty_reset})
|
||||
--upgrade-only Keep the installed NVIDIA driver package and only upgrade the package version.
|
||||
--latest Upgrade to the latest NVIDIA driver, the old driver package may be removed.
|
||||
--proprietary Prefer the proprietary kernel-module flavor (e.g. ${tty_bold}nvidia-driver-595${tty_reset}).
|
||||
--open Prefer the open kernel-module flavor (e.g. ${tty_bold}nvidia-driver-595-open${tty_reset}).
|
||||
If neither flag is set, the installed driver's flavor is preserved
|
||||
(proprietary on fresh hosts).
|
||||
--dry-run, -n List all available NVIDIA driver packages and exit.
|
||||
--yes, -y Do not ask for confirmation.
|
||||
--help, -h Show this help and exit.
|
||||
|
|
@ -83,9 +92,11 @@ Options:
|
|||
Examples:
|
||||
|
||||
bash $(basename "$0")
|
||||
bash $(basename "$0") --package=nvidia-driver-470
|
||||
bash $(basename "$0") --package=nvidia-driver-595
|
||||
bash $(basename "$0") --package=nvidia-driver-595-open
|
||||
bash $(basename "$0") --upgrade-only
|
||||
bash $(basename "$0") --latest
|
||||
bash $(basename "$0") --latest --open
|
||||
|
||||
${tty_yellow}NOTE:${tty_reset} During the install process, the script will offload the NVIDIA kernel modules. Please terminate the
|
||||
processes that are using the NVIDIA GPUs, e.g., \`watch nvidia-smi\`, \`nvitop\`, and the GNOME Display Manager.
|
||||
|
|
@ -98,6 +109,8 @@ EOS
|
|||
REQUESTED_DRIVER=''
|
||||
UPGRADE_ONLY=''
|
||||
LATEST=''
|
||||
FLAVOR='' # '', 'proprietary', or 'open'
|
||||
FLAVOR_EXPLICIT='' # set when the user explicitly passed --proprietary or --open
|
||||
DRY_RUN=''
|
||||
YES=''
|
||||
unset HAVE_SUDO_ACCESS
|
||||
|
|
@ -124,6 +137,20 @@ while [[ "$#" -gt 0 ]]; do
|
|||
fi
|
||||
LATEST=1
|
||||
;;
|
||||
--proprietary)
|
||||
if [[ "${FLAVOR}" == 'open' ]]; then
|
||||
abort 'Both option `--proprietary` and `--open` are set.'
|
||||
fi
|
||||
FLAVOR='proprietary'
|
||||
FLAVOR_EXPLICIT=1
|
||||
;;
|
||||
--open)
|
||||
if [[ "${FLAVOR}" == 'proprietary' ]]; then
|
||||
abort 'Both option `--proprietary` and `--open` are set.'
|
||||
fi
|
||||
FLAVOR='open'
|
||||
FLAVOR_EXPLICIT=1
|
||||
;;
|
||||
--dry-run | -n)
|
||||
DRY_RUN=1
|
||||
HAVE_SUDO_ACCESS=1
|
||||
|
|
@ -143,6 +170,9 @@ while [[ "$#" -gt 0 ]]; do
|
|||
esac
|
||||
done
|
||||
|
||||
# Default flavor when neither --proprietary nor --open is given.
|
||||
: "${FLAVOR:=proprietary}"
|
||||
|
||||
### Functions ######################################################################################
|
||||
|
||||
function apt-list-packages() {
|
||||
|
|
@ -154,7 +184,7 @@ function apt-list-nvidia-packages() {
|
|||
local packages
|
||||
packages="$(
|
||||
apt-list-packages |
|
||||
awk '$2 ~ /nvidia.*-([0-9]+)(:.*)?$/ { print $2 }' |
|
||||
awk '$2 ~ /nvidia.*-([0-9]+)(-open)?(:.*)?$/ { print $2 }' |
|
||||
sort
|
||||
)"
|
||||
echo "${packages//$'\n'/ }"
|
||||
|
|
@ -164,6 +194,44 @@ function apt-installed-version() {
|
|||
apt-cache policy "$1" | grep -F 'Installed' | awk '{ print $2 }'
|
||||
}
|
||||
|
||||
function driver-major() {
|
||||
# nvidia-driver-595 -> 595
|
||||
# nvidia-driver-595-open -> 595
|
||||
local d="${1#nvidia-driver-}"
|
||||
echo "${d%-open}"
|
||||
}
|
||||
|
||||
function driver-flavor() {
|
||||
# nvidia-driver-595 -> proprietary
|
||||
# nvidia-driver-595-open -> open
|
||||
if [[ "$1" == *-open ]]; then
|
||||
echo 'open'
|
||||
else
|
||||
echo 'proprietary'
|
||||
fi
|
||||
}
|
||||
|
||||
function toggle-open-suffix() {
|
||||
# nvidia-driver-595 -> nvidia-driver-595-open
|
||||
# nvidia-driver-595-open -> nvidia-driver-595
|
||||
if [[ "$1" == *-open ]]; then
|
||||
echo "${1%-open}"
|
||||
else
|
||||
echo "$1-open"
|
||||
fi
|
||||
}
|
||||
|
||||
function driver-available() {
|
||||
# Predicate: is "$1" present in the global AVAILABLE_DRIVERS array?
|
||||
local d
|
||||
for d in "${AVAILABLE_DRIVERS[@]}"; do
|
||||
if [[ "${d}" == "$1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
function apt-candidate-version() {
|
||||
apt-cache policy "$1" | grep -F 'Candidate' | awk '{ print $2 }'
|
||||
}
|
||||
|
|
@ -339,7 +407,7 @@ fi
|
|||
# shellcheck disable=SC2207
|
||||
AVAILABLE_DRIVERS=($(
|
||||
apt-cache search --names-only nvidia-driver |
|
||||
awk '$1 ~ /^nvidia-driver-([0-9]+)$/ { print $1 }' |
|
||||
awk '$1 ~ /^nvidia-driver-([0-9]+)(-open)?$/ { print $1 }' |
|
||||
sort -V
|
||||
))
|
||||
|
||||
|
|
@ -347,22 +415,80 @@ if [[ "${#AVAILABLE_DRIVERS[@]}" -eq 0 ]]; then
|
|||
abort "No available drivers found from APT."
|
||||
fi
|
||||
|
||||
LATEST_DRIVER="${AVAILABLE_DRIVERS[-1]}"
|
||||
LATEST_DRIVER_VERSION="$(apt-candidate-version "${LATEST_DRIVER}")"
|
||||
# `sort -V` orders `nvidia-driver-595` before `nvidia-driver-595-open`, so picking
|
||||
# `${AVAILABLE_DRIVERS[-1]}` would silently flip the default to open. Pick per-flavor instead.
|
||||
LATEST_PROPRIETARY_DRIVER=''
|
||||
LATEST_OPEN_DRIVER=''
|
||||
for driver in "${AVAILABLE_DRIVERS[@]}"; do
|
||||
if [[ "$(driver-flavor "${driver}")" == 'open' ]]; then
|
||||
LATEST_OPEN_DRIVER="${driver}"
|
||||
else
|
||||
LATEST_PROPRIETARY_DRIVER="${driver}"
|
||||
fi
|
||||
done
|
||||
|
||||
INSTALLED_DRIVER="$(apt-list-packages | awk '$2 ~ /nvidia-driver-([0-9]+)$/ { print $2 }')"
|
||||
INSTALLED_DRIVER="$(apt-list-packages | awk '$2 ~ /nvidia-driver-([0-9]+)(-open)?$/ { print $2 }')"
|
||||
if [[ -n "${INSTALLED_DRIVER}" ]]; then
|
||||
INSTALLED_DRIVER_VERSION="$(apt-installed-version "${INSTALLED_DRIVER}")"
|
||||
INSTALLED_DRIVER_CANDIDATE_VERSION="$(apt-candidate-version "${INSTALLED_DRIVER}")"
|
||||
INSTALLED_FLAVOR="$(driver-flavor "${INSTALLED_DRIVER}")"
|
||||
else
|
||||
INSTALLED_DRIVER_VERSION=''
|
||||
INSTALLED_DRIVER_CANDIDATE_VERSION=''
|
||||
INSTALLED_FLAVOR=''
|
||||
fi
|
||||
|
||||
# Effective flavor for picking LATEST_DRIVER: explicit `--proprietary`/`--open` wins; otherwise
|
||||
# preserve the installed driver's flavor; fresh hosts fall through to the `FLAVOR` default.
|
||||
EFFECTIVE_FLAVOR="${FLAVOR}"
|
||||
if [[ -z "${FLAVOR_EXPLICIT}" && -n "${INSTALLED_FLAVOR}" ]]; then
|
||||
EFFECTIVE_FLAVOR="${INSTALLED_FLAVOR}"
|
||||
fi
|
||||
|
||||
if [[ "${EFFECTIVE_FLAVOR}" == 'open' ]]; then
|
||||
LATEST_DRIVER="${LATEST_OPEN_DRIVER}"
|
||||
LATEST_FALLBACK="${LATEST_PROPRIETARY_DRIVER}"
|
||||
else
|
||||
LATEST_DRIVER="${LATEST_PROPRIETARY_DRIVER}"
|
||||
LATEST_FALLBACK="${LATEST_OPEN_DRIVER}"
|
||||
fi
|
||||
# Resolution-time fallback only matters when the script needs LATEST_DRIVER to compute
|
||||
# REQUESTED_DRIVER. An explicit `--package=PKG` is the user's authoritative override and is
|
||||
# allowed through even when the preserved flavor has no APT candidates.
|
||||
if [[ -z "${LATEST_DRIVER}" && -z "${REQUESTED_DRIVER}" ]]; then
|
||||
if [[ -n "${FLAVOR_EXPLICIT}" ]]; then
|
||||
abort "No \`${EFFECTIVE_FLAVOR}\` driver candidates available from APT. Drop \`--${FLAVOR}\`, run \`sudo apt-get update\` to refresh the package cache, or pass \`--package=PKG\` to override."
|
||||
fi
|
||||
if [[ -n "${INSTALLED_DRIVER}" ]]; then
|
||||
# Never silently switch flavor on an installed system: falling back to the opposite
|
||||
# kernel-module flavor would be a root-level migration the user did not ask for.
|
||||
if [[ "${EFFECTIVE_FLAVOR}" == 'open' ]]; then
|
||||
opposite_flavor='proprietary'
|
||||
else
|
||||
opposite_flavor='open'
|
||||
fi
|
||||
abort "No \`${EFFECTIVE_FLAVOR}\` driver candidates available from APT to upgrade \`${INSTALLED_DRIVER}\`. Run \`sudo apt-get update\` to refresh the cache, pass \`--${opposite_flavor}\` to switch flavors explicitly, or pass \`--package=PKG\` to override."
|
||||
fi
|
||||
# Fresh-install fallback: pick whichever flavor the PPA publishes rather than refusing.
|
||||
warn "No \`${EFFECTIVE_FLAVOR}\` driver candidates available; falling back to \`${LATEST_FALLBACK}\` ($(driver-flavor "${LATEST_FALLBACK}") flavor)."
|
||||
LATEST_DRIVER="${LATEST_FALLBACK}"
|
||||
fi
|
||||
LATEST_DRIVER_VERSION="$(apt-candidate-version "${LATEST_DRIVER}")"
|
||||
|
||||
if [[ -z "${REQUESTED_DRIVER}" ]]; then
|
||||
if [[ -n "${LATEST}" || -z "${INSTALLED_DRIVER}" ]]; then
|
||||
REQUESTED_DRIVER="${LATEST_DRIVER}"
|
||||
REQUESTED_DRIVER_VERSION="${LATEST_DRIVER_VERSION}"
|
||||
elif [[ -n "${FLAVOR_EXPLICIT}" && "${INSTALLED_FLAVOR}" != "${FLAVOR}" ]]; then
|
||||
# Standalone `--open` / `--proprietary` (no `--latest`, no `--package`) on an
|
||||
# opposite-flavor install: switch to the same-major counterpart, e.g.
|
||||
# `--open` on `nvidia-driver-595` -> `nvidia-driver-595-open`.
|
||||
counterpart="$(toggle-open-suffix "${INSTALLED_DRIVER}")"
|
||||
if ! driver-available "${counterpart}"; then
|
||||
abort "Cannot switch \`${INSTALLED_DRIVER}\` to ${FLAVOR} flavor: \`${counterpart}\` is not available from APT. Pass \`--latest\` to switch to the latest ${FLAVOR} branch instead."
|
||||
fi
|
||||
REQUESTED_DRIVER="${counterpart}"
|
||||
REQUESTED_DRIVER_VERSION="$(apt-candidate-version "${REQUESTED_DRIVER}")"
|
||||
else
|
||||
REQUESTED_DRIVER="${INSTALLED_DRIVER}"
|
||||
REQUESTED_DRIVER_VERSION="${INSTALLED_DRIVER_CANDIDATE_VERSION}"
|
||||
|
|
@ -372,14 +498,52 @@ else
|
|||
if [[ -z "${REQUESTED_DRIVER_VERSION}" ]]; then
|
||||
abort "Unable to locate package ${REQUESTED_DRIVER}."
|
||||
fi
|
||||
requested_flavor="$(driver-flavor "${REQUESTED_DRIVER}")"
|
||||
if [[ -n "${FLAVOR_EXPLICIT}" && "${requested_flavor}" != "${FLAVOR}" ]]; then
|
||||
suggested="$(toggle-open-suffix "${REQUESTED_DRIVER}")"
|
||||
conflict_msg="Option \`--${FLAVOR}\` conflicts with package \`${REQUESTED_DRIVER}\` (${requested_flavor} flavor)."
|
||||
if driver-available "${suggested}"; then
|
||||
conflict_msg+=" Did you mean \`${suggested}\`?"
|
||||
fi
|
||||
abort "${conflict_msg}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# `--upgrade-only` promises to keep the installed driver package, so reject any combination that
|
||||
# would change the package name (including a flavor flag that rewrote `REQUESTED_DRIVER` to the
|
||||
# counterpart, or an explicit `--package=` pointing at a different driver). Without this guard the
|
||||
# later install path would purge the existing NVIDIA stack and reinstall the new package — a
|
||||
# root-level system change masquerading as an upgrade.
|
||||
if [[ -n "${UPGRADE_ONLY}" && -n "${INSTALLED_DRIVER}" && "${INSTALLED_DRIVER}" != "${REQUESTED_DRIVER}" ]]; then
|
||||
abort "Option \`--upgrade-only\` cannot change the driver package from \`${INSTALLED_DRIVER}\` to \`${REQUESTED_DRIVER}\`. Drop \`--upgrade-only\` to switch packages."
|
||||
fi
|
||||
|
||||
ohai "Available NVIDIA drivers:"
|
||||
for driver in "${AVAILABLE_DRIVERS[@]}"; do
|
||||
flavor="$(driver-flavor "${driver}")"
|
||||
prefix=" "
|
||||
if [[ "${driver}" == "${REQUESTED_DRIVER}" ]]; then
|
||||
prefix="--> "
|
||||
fi
|
||||
|
||||
# Each flavor's branch tip gets a flavor-explicit annotation so "latest" cannot be confused
|
||||
# with the user's effective `--latest` target under flavor preservation.
|
||||
suffix=''
|
||||
if [[ "${driver}" == "${LATEST_PROPRIETARY_DRIVER}" ]]; then
|
||||
suffix=' (latest proprietary)'
|
||||
elif [[ "${driver}" == "${LATEST_OPEN_DRIVER}" ]]; then
|
||||
suffix=' (latest open)'
|
||||
fi
|
||||
|
||||
# Dim other-flavor rows: picking one would require a purge+reinstall flavor switch. The
|
||||
# REQUESTED_DRIVER row is exempt so the `--> ` arrow keeps priority on a deliberate switch.
|
||||
dim=''
|
||||
if [[ -n "${INSTALLED_FLAVOR}" &&
|
||||
"${flavor}" != "${INSTALLED_FLAVOR}" &&
|
||||
"${driver}" != "${REQUESTED_DRIVER}" ]]; then
|
||||
dim=1
|
||||
fi
|
||||
|
||||
if [[ "${driver}" == "${INSTALLED_DRIVER}" ]]; then
|
||||
if [[ "${driver}" != "${REQUESTED_DRIVER}" ]]; then
|
||||
prefix="<-- "
|
||||
|
|
@ -397,10 +561,12 @@ for driver in "${AVAILABLE_DRIVERS[@]}"; do
|
|||
else
|
||||
echo "${prefix}${tty_bold}${driver} [${INSTALLED_DRIVER_VERSION}]${tty_reset} ${tty_yellow}[installed]${tty_reset} (upgradable to [${INSTALLED_DRIVER_CANDIDATE_VERSION}])"
|
||||
fi
|
||||
elif [[ -n "${dim}" ]]; then
|
||||
echo "${prefix}${tty_dim}${driver} [$(apt-candidate-version "${driver}")]${suffix}${tty_reset}"
|
||||
elif [[ "${driver}" == "${LATEST_DRIVER}" ]]; then
|
||||
echo "${prefix}${tty_green}${driver} [${LATEST_DRIVER_VERSION}]${tty_reset} (latest)"
|
||||
echo "${prefix}${tty_green}${driver} [${LATEST_DRIVER_VERSION}]${tty_reset}${suffix}"
|
||||
else
|
||||
echo "${prefix}${driver} [$(apt-candidate-version "${driver}")]"
|
||||
echo "${prefix}${driver} [$(apt-candidate-version "${driver}")]${suffix}"
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
@ -422,12 +588,24 @@ echo
|
|||
|
||||
if [[ -z "${INSTALLED_DRIVER}" ]]; then
|
||||
ohai "Install the NVIDIA driver ${REQUESTED_DRIVER} [${REQUESTED_DRIVER_VERSION}]."
|
||||
elif [[ "${REQUESTED_DRIVER#nvidia-driver-}" -ge "${INSTALLED_DRIVER#nvidia-driver-}" ]]; then
|
||||
elif [[ "$(driver-major "${REQUESTED_DRIVER}")" -ge "$(driver-major "${INSTALLED_DRIVER}")" ]]; then
|
||||
ohai "Upgrade the NVIDIA driver from ${INSTALLED_DRIVER} [${INSTALLED_DRIVER_VERSION}] to ${REQUESTED_DRIVER} [${REQUESTED_DRIVER_VERSION}]."
|
||||
else
|
||||
ohai "Downgrade the NVIDIA driver from ${INSTALLED_DRIVER} [${INSTALLED_DRIVER_VERSION}] to ${REQUESTED_DRIVER} [${REQUESTED_DRIVER_VERSION}]."
|
||||
fi
|
||||
|
||||
REQUESTED_FLAVOR="$(driver-flavor "${REQUESTED_DRIVER}")"
|
||||
if [[ -n "${INSTALLED_FLAVOR}" && "${INSTALLED_FLAVOR}" != "${REQUESTED_FLAVOR}" ]]; then
|
||||
ohai "Switching kernel-module flavor from ${INSTALLED_FLAVOR} to ${REQUESTED_FLAVOR}."
|
||||
fi
|
||||
|
||||
# Preflight the install plan before any teardown so an unsatisfiable APT transaction aborts
|
||||
# while the existing driver is still working. `--allow-change-held-packages` lets the simulate
|
||||
# plan past the existing apt-mark holds (the real `apt-mark unhold` runs in the teardown block).
|
||||
if [[ -n "${INSTALLED_DRIVER}" && "${INSTALLED_DRIVER}" != "${REQUESTED_DRIVER}" ]]; then
|
||||
exec_cmd "sudo apt-get install --simulate --allow-change-held-packages --yes ${REQUESTED_DRIVER}"
|
||||
fi
|
||||
|
||||
DM_SERVICES=()
|
||||
if [[ -n "$(sudo lsof -t /dev/nvidia* 2>/dev/null || true)" ]]; then
|
||||
for dm in gdm3 lightdm; do
|
||||
|
|
@ -504,7 +682,8 @@ if [[ -n "${INSTALLED_DRIVER}" ]]; then
|
|||
# Upgrade the existing driver packages
|
||||
exec_cmd "sudo apt-get install --only-upgrade --yes ${NVIDIA_PACKAGES}"
|
||||
else
|
||||
# Uninstall the existing driver packages
|
||||
# The install plan was already validated above with `apt-get install --simulate` (before
|
||||
# any destructive teardown), so this purge is safe to run.
|
||||
exec_cmd "sudo apt-get purge --yes ${NVIDIA_PACKAGES}"
|
||||
fi
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue