chore: add maintenance scripts and update editor preference
- Add scripts/cleanup.sh for package cleanup (dry-run/apply modes) - Add scripts/nvidia-recovery.sh for broken GUI recovery - Update AGENTS.md with new script references - Change default editor from vim to nvim in bashrc Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
@@ -14,6 +14,10 @@ This repository manages the infrastructure, configuration, and maintenance for M
|
||||
|------|---------|
|
||||
| Apply Configuration | `ansible-playbook ansible/workstation.yml` |
|
||||
| System Maintenance | `bash scripts/maintenance.sh` |
|
||||
| Package Cleanup (dry-run) | `bash scripts/cleanup.sh --check` |
|
||||
| Package Cleanup (apply) | `bash scripts/cleanup.sh --apply` |
|
||||
| NVIDIA Recovery (broken GUI) | `bash scripts/nvidia-recovery.sh --apply` |
|
||||
| **Post-recovery** | **Reboot required to restore GUI login** |
|
||||
| Verify Ansible | `ansible-playbook ansible/workstation.yml --check` |
|
||||
|
||||
## Standards
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ alias k='kubectl'
|
||||
alias main='bash {{ workspace_root }}/scripts/maintenance.sh'
|
||||
|
||||
# Environment
|
||||
export EDITOR='vim'
|
||||
export EDITOR='nvim'
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# saTway indicators
|
||||
|
||||
Executable
+372
@@ -0,0 +1,372 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Workstation Package Cleanup Script
|
||||
# Version: 1.0.0
|
||||
# Target: mw-pfeddersheim-workstation
|
||||
# Purpose: Remove identified cleanup candidates and log for verification
|
||||
|
||||
MODE="apply"
|
||||
if [[ "${1:-}" == "--check" ]]; then
|
||||
MODE="check"
|
||||
echo "=== Running in CHECK mode (dry-run, no packages removed) ==="
|
||||
elif [[ "${1:-}" == "--help" ]]; then
|
||||
echo "Usage: $0 [--check | --apply | --help]"
|
||||
echo " --check Dry-run: show what would be removed (default)"
|
||||
echo " --apply Actually remove packages"
|
||||
echo " --help Show this help"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Ensure log directory exists
|
||||
mkdir -p "$HOME/logs" 2>/dev/null || true
|
||||
LOCAL_LOG="$HOME/logs/cleanup-$(date +%Y%m%d-%H%M%S).log"
|
||||
BOLD=$(tput bold 2>/dev/null || true)
|
||||
RED=$(tput setaf 1 2>/dev/null || true)
|
||||
GREEN=$(tput setaf 2 2>/dev/null || true)
|
||||
RESET=$(tput sgr0 2>/dev/null || true)
|
||||
|
||||
log() { echo -e "$*" | tee -a "$LOCAL_LOG"; }
|
||||
section() { log ""; log "${BOLD}--- $1 ---${RESET}"; }
|
||||
|
||||
echo "" | tee -a "$LOCAL_LOG"
|
||||
log "============================================="
|
||||
log " Workstation Package Cleanup"
|
||||
log " Mode: $MODE | Date: $(date)"
|
||||
log " Log: $LOCAL_LOG"
|
||||
log "============================================="
|
||||
|
||||
# Track totals
|
||||
TOTAL_CANDIDATES=0
|
||||
TOTAL_REMOVED=0
|
||||
TOTAL_ERRORS=0
|
||||
SKIPPED=0
|
||||
|
||||
# Helper: add package to candidate list file
|
||||
add_candidates() {
|
||||
local category="$1"
|
||||
shift
|
||||
echo "$@" >> "$HOME/logs/.cleanup-candidates-${category}.txt"
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 1. PRE-FLIGHT CHECKS
|
||||
# ============================================================
|
||||
section "Pre-flight Checks"
|
||||
|
||||
# Verify pacman is available
|
||||
if ! command -v pacman &> /dev/null; then
|
||||
log "${RED}ERROR: pacman not found. This script must be run on Arch/Manjaro.${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check disk space (need room for transaction)
|
||||
DISK_PCT=$(df / | awk 'NR==2 {gsub(/%/,"",$5); print $5}')
|
||||
if [[ "$DISK_PCT" -gt 95 ]]; then
|
||||
log "${RED}WARNING: Disk usage at ${DISK_PCT}%. Consider freeing space first.${RESET}"
|
||||
fi
|
||||
DISK_AVAIL=$(df -h / | awk 'NR==2 {print $4}')
|
||||
log "Disk available: $DISK_AVAIL"
|
||||
|
||||
# Check for existing packages (only list ones that are installed)
|
||||
log "Scanning for installed cleanup candidates..."
|
||||
|
||||
# ============================================================
|
||||
# 2. OLD MULTIMEDIA PACKAGES
|
||||
# ============================================================
|
||||
section "[1/7] Old Multimedia Packages"
|
||||
|
||||
CANDIDATES=()
|
||||
# Old ffmpeg version
|
||||
if pacman -Qe ffmpeg4.4 &>/dev/null || pacman -Q ffmpeg4.4 &>/dev/null; then
|
||||
CANDIDATES+=(ffmpeg4.4)
|
||||
fi
|
||||
|
||||
# VLC plugins (keep base vlc)
|
||||
while IFS= read -r pkg; do
|
||||
[[ "$pkg" == "vlc" ]] && continue # skip base vlc
|
||||
CANDIDATES+=("$pkg")
|
||||
done < <(pacman -Qq 2>/dev/null | grep -E '^vlc-' || true)
|
||||
|
||||
TOTAL_CANDIDATES=$((TOTAL_CANDIDATES + ${#CANDIDATES[@]}))
|
||||
log "Found ${#CANDIDATES[@]} multimedia candidates: ${CANDIDATES[*]:0:5}..."
|
||||
|
||||
if [[ ${#CANDIDATES[@]} -gt 0 ]]; then
|
||||
log "Candidates: ${CANDIDATES[*]}"
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would run: sudo pacman -Rns --noconfirm ${CANDIDATES[*]}"
|
||||
else
|
||||
sudo pacman -Rns --noconfirm "${CANDIDATES[@]}" 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ${#CANDIDATES[@]}))
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 3. INACTIVE NVIDIA/MHWHD DRIVERS
|
||||
# ============================================================
|
||||
section "[2/7] Inactive NVIDIA Drivers (mhwd-nvidia-*)"
|
||||
|
||||
CANDIDATES=()
|
||||
while IFS= read -r pkg; do
|
||||
[[ -n "$pkg" ]] && CANDIDATES+=("$pkg")
|
||||
done < <(pacman -Qq 2>/dev/null | grep -E '^mhwd-nvidia-' || true)
|
||||
|
||||
TOTAL_CANDIDATES=$((TOTAL_CANDIDATES + ${#CANDIDATES[@]}))
|
||||
if [[ ${#CANDIDATES[@]} -gt 0 ]]; then
|
||||
log "Found ${#CANDIDATES[@]} mhwd-nvidia candidates: ${CANDIDATES[*]}"
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would run: sudo pacman -Rns --noconfirm ${CANDIDATES[*]}"
|
||||
else
|
||||
sudo pacman -Rns --noconfirm "${CANDIDATES[@]}" 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ${#CANDIDATES[@]}))
|
||||
fi
|
||||
else
|
||||
log "No mhwd-nvidia packages found."
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 4. OLD KERNELS
|
||||
# ============================================================
|
||||
section "[3/7] Old Kernel Packages"
|
||||
|
||||
CANDIDATES=()
|
||||
# linux618 and linux70 (keep current running kernel and its modules)
|
||||
CURRENT_KERNEL=$(uname -r)
|
||||
KMVR="${CURRENT_KERNEL%-MANJARO}" # 6.18.33-1
|
||||
KMJ="${KMVR%%.*}" # 6
|
||||
KMREST="${KMVR#*.}" # 18.33-1
|
||||
KMN="${KMREST%%.*}" # 18
|
||||
CURRENT_KERNEL_PKG="linux${KMJ}${KMN}" # linux618
|
||||
log "Current running kernel: $CURRENT_KERNEL (package: $CURRENT_KERNEL_PKG)"
|
||||
|
||||
for kernel in linux618 linux70; do
|
||||
# Skip if this is the running kernel package
|
||||
if [[ "$kernel" == "linux${CURRENT_KERNEL_PKG}" ]]; then
|
||||
log "Skipping $kernel — this is the running kernel."
|
||||
continue
|
||||
fi
|
||||
if pacman -Q "$kernel" &>/dev/null; then
|
||||
CANDIDATES+=("$kernel")
|
||||
# Also remove its modules/headers/etc (but not nvidia/r8168 for running kernel — already skipped above)
|
||||
while IFS= read -r pkg; do
|
||||
[[ -n "$pkg" ]] && CANDIDATES+=("$pkg")
|
||||
done < <(pacman -Qq 2>/dev/null | grep -E "^${kernel}-" || true)
|
||||
fi
|
||||
done
|
||||
|
||||
TOTAL_CANDIDATES=$((TOTAL_CANDIDATES + ${#CANDIDATES[@]}))
|
||||
if [[ ${#CANDIDATES[@]} -gt 0 ]]; then
|
||||
log "Found ${#CANDIDATES[@]} kernel candidates: ${CANDIDATES[*]}"
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would run: sudo pacman -Rns --noconfirm ${CANDIDATES[*]}"
|
||||
else
|
||||
sudo pacman -Rns --noconfirm "${CANDIDATES[@]}" 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ${#CANDIDATES[@]}))
|
||||
fi
|
||||
else
|
||||
log "No old kernel packages found."
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 5. lib32 PACKAGES
|
||||
# ============================================================
|
||||
section "[4/7] lib32 Packages"
|
||||
|
||||
CANDIDATES=()
|
||||
while IFS= read -r pkg; do
|
||||
[[ -n "$pkg" ]] && CANDIDATES+=("$pkg")
|
||||
done < <(pacman -Qq 2>/dev/null | grep -E '^lib32-' || true)
|
||||
|
||||
TOTAL_CANDIDATES=$((TOTAL_CANDIDATES + ${#CANDIDATES[@]}))
|
||||
log "Found ${#CANDIDATES[@]} lib32 packages"
|
||||
|
||||
if [[ ${#CANDIDATES[@]} -gt 0 ]]; then
|
||||
# List first 10, then total
|
||||
log "First 10 candidates: ${CANDIDATES[*]:0:10}..."
|
||||
log "Total: ${#CANDIDATES[@]} lib32 packages"
|
||||
|
||||
# Interactive: ask user if they want to remove lib32 packages
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would run: sudo pacman -Rns --noconfirm ${CANDIDATES[*]}"
|
||||
else
|
||||
log "${BOLD}This will remove ALL ${#CANDIDATES[@]} lib32 packages.${RESET}"
|
||||
log "Only remove if you don't run 32-bit applications (games, wine, etc.)"
|
||||
read -rp "Remove all lib32 packages? [y/N] " confirm
|
||||
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
||||
sudo pacman -Rns --noconfirm "${CANDIDATES[@]}" 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ${#CANDIDATES[@]}))
|
||||
else
|
||||
log "SKIPPED lib32 removal."
|
||||
SKIPPED=$((SKIPPED + ${#CANDIDATES[@]}))
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 6. REDUNDANT FONTS (Nerd Font variants)
|
||||
# ============================================================
|
||||
section "[5/7] Redundant Font Packages"
|
||||
|
||||
CANDIDATES=()
|
||||
# Nerd Font packages (keep the one in active use)
|
||||
while IFS= read -r pkg; do
|
||||
[[ -n "$pkg" ]] && CANDIDATES+=("$pkg")
|
||||
done < <(pacman -Qq 2>/dev/null | grep -iE 'nerd-font' || true)
|
||||
|
||||
# Also check for duplicate font collections
|
||||
while IFS= read -r pkg; do
|
||||
[[ -n "$pkg" ]] && CANDIDATES+=("$pkg")
|
||||
done < <(pacman -Qq 2>/dev/null | grep -iE 'ttf-(jetbrains|iosevka|fira|hack|noto)' || true)
|
||||
|
||||
TOTAL_CANDIDATES=$((TOTAL_CANDIDATES + ${#CANDIDATES[@]}))
|
||||
if [[ ${#CANDIDATES[@]} -gt 0 ]]; then
|
||||
log "Found ${#CANDIDATES[@]} font candidates:"
|
||||
for pkg in "${CANDIDATES[@]}"; do
|
||||
log " - $pkg"
|
||||
done
|
||||
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would show above packages for manual review"
|
||||
else
|
||||
log "${RED}CRITICAL: Review font packages carefully - removing wrong fonts can break UI.${RESET}"
|
||||
read -rp "Remove these ${#CANDIDATES[@]} font packages? [y/N] " confirm
|
||||
if [[ "$confirm" =~ ^[Yy]$ ]]; then
|
||||
sudo pacman -Rns --noconfirm "${CANDIDATES[@]}" 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ${#CANDIDATES[@]}))
|
||||
else
|
||||
log "SKIPPED font removal."
|
||||
SKIPPED=$((SKIPPED + ${#CANDIDATES[@]}))
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log "No redundant font packages found."
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 7. BROWSERS (keep current active, remove extras)
|
||||
# ============================================================
|
||||
section "[6/7] Browser Packages"
|
||||
|
||||
CANDIDATES=()
|
||||
# Check which browsers are installed
|
||||
BROWSERS=()
|
||||
for browser in firefox chromium google-chrome firefox-developer-edition brave-bin microsoft-edge; do
|
||||
if pacman -Q "$browser" &>/dev/null; then
|
||||
BROWSERS+=("$browser")
|
||||
fi
|
||||
done
|
||||
|
||||
log "Installed browsers: ${BROWSERS[*]}"
|
||||
log "${BOLD}Recommended: Keep firefox-developer-edition + one other${RESET}"
|
||||
|
||||
if [[ ${#BROWSERS[@]} -gt 2 ]]; then
|
||||
# Suggest removal of non-essential browsers
|
||||
SUGGESTED_REMOVAL=()
|
||||
for b in "${BROWSERS[@]}"; do
|
||||
# Keep firefox-developer-edition and chromium/google-chrome
|
||||
if [[ "$b" != "firefox-developer-edition" && "$b" != "chromium" && "$b" != "google-chrome" ]]; then
|
||||
SUGGESTED_REMOVAL+=("$b")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#SUGGESTED_REMOVAL[@]} -gt 0 ]]; then
|
||||
CANDIDATES=("${SUGGESTED_REMOVAL[@]}")
|
||||
TOTAL_CANDIDATES=$((TOTAL_CANDIDATES + ${#CANDIDATES[@]}))
|
||||
log "Suggested removal: ${CANDIDATES[*]}"
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would run: sudo pacman -Rns --noconfirm ${CANDIDATES[*]}"
|
||||
else
|
||||
sudo pacman -Rns --noconfirm "${CANDIDATES[@]}" 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ${#CANDIDATES[@]}))
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log "Browser count is manageable (${#BROWSERS[@]}). No action needed."
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 8. UNUSED PYTHON PACKAGES
|
||||
# ============================================================
|
||||
section "[7/7] Unused Python GUI Packages"
|
||||
|
||||
CANDIDATES=()
|
||||
PYTHON_CANDIDATES=(
|
||||
wxpython
|
||||
wxpython-gtk3
|
||||
pyqt5
|
||||
pyqt5-sip
|
||||
pyqt6
|
||||
pyqt6-sip
|
||||
fluidity
|
||||
tk
|
||||
tkinter
|
||||
python-tk
|
||||
)
|
||||
|
||||
for pkg in "${PYTHON_CANDIDATES[@]}"; do
|
||||
if pacman -Q "$pkg" &>/dev/null; then
|
||||
CANDIDATES+=("$pkg")
|
||||
fi
|
||||
done
|
||||
|
||||
TOTAL_CANDIDATES=$((TOTAL_CANDIDATES + ${#CANDIDATES[@]}))
|
||||
if [[ ${#CANDIDATES[@]} -gt 0 ]]; then
|
||||
log "Found ${#CANDIDATES[@]} Python GUI candidates: ${CANDIDATES[*]}"
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would run: sudo pacman -Rns --noconfirm ${CANDIDATES[*]}"
|
||||
else
|
||||
sudo pacman -Rns --noconfirm "${CANDIDATES[@]}" 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ${#CANDIDATES[@]}))
|
||||
fi
|
||||
else
|
||||
log "No unused Python GUI packages found."
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# CLEANUP ORPHANS & CACHE
|
||||
# ============================================================
|
||||
section "Post-Cleanup: Orphans & Cache"
|
||||
|
||||
log "Finding orphaned dependencies..."
|
||||
ORPHANS=$(pacman -Qtdq 2>/dev/null || true)
|
||||
if [[ -n "$ORPHANS" ]]; then
|
||||
ORPHAN_COUNT=$(echo "$ORPHANS" | wc -l)
|
||||
log "Found $ORPHAN_COUNT orphaned packages"
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "DRY-RUN: Would run: sudo pacman -Rns --noconfirm $(echo $ORPHANS)"
|
||||
else
|
||||
sudo pacman -Rns --noconfirm $ORPHANS 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
TOTAL_REMOVED=$((TOTAL_REMOVED + ORPHAN_COUNT))
|
||||
fi
|
||||
else
|
||||
log "No orphaned packages found."
|
||||
fi
|
||||
|
||||
log "Cleaning pacman cache (keep last 2 versions)..."
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
CACHE_SIZE=$(du -sh /var/cache/pacman/pkg/ 2>/dev/null | cut -f1)
|
||||
log "Cache size: $CACHE_SIZE"
|
||||
log "DRY-RUN: Would run: sudo paccache -rk2"
|
||||
else
|
||||
sudo paccache -rk2 2>&1 | tee -a "$LOCAL_LOG" || true
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# SUMMARY
|
||||
# ============================================================
|
||||
section "Cleanup Summary"
|
||||
|
||||
FINAL_DISK=$(df -h / | awk 'NR==2 {print $4}')
|
||||
log "Disk space available after cleanup: $FINAL_DISK"
|
||||
log "Total candidates identified: $TOTAL_CANDIDATES"
|
||||
log "Packages removed: $TOTAL_REMOVED"
|
||||
log "Packages skipped: $SKIPPED"
|
||||
log "Log saved to: $LOCAL_LOG"
|
||||
|
||||
log ""
|
||||
log "============================================="
|
||||
log " Cleanup Complete"
|
||||
log "============================================="
|
||||
|
||||
# Cleanup temp files
|
||||
rm -f "$HOME/logs/.cleanup-candidates-"*.txt 2>/dev/null || true
|
||||
Executable
+230
@@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# NVIDIA Kernel Module Recovery Script
|
||||
# Purpose: Reinstall nvidia-580xx-dkms and rebuild kernel module after package cleanup removed it
|
||||
# Target: mw-pfeddersheim-workstation (Manjaro, NVIDIA GPU)
|
||||
|
||||
MODE="apply"
|
||||
if [[ "${1:-}" == "--check" ]]; then
|
||||
MODE="check"
|
||||
echo "=== Running in CHECK mode (diagnostic only, no changes) ==="
|
||||
elif [[ "${1:-}" == "--help" ]]; then
|
||||
echo "Usage: $0 [--check | --apply | --help]"
|
||||
echo " --check Diagnose and show what would be done"
|
||||
echo " --apply Reinstall nvidia-580xx-dkms and rebuild module (requires sudo)"
|
||||
echo " --help Show this help"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "$HOME/logs" 2>/dev/null || true
|
||||
LOCAL_LOG="$HOME/logs/nvidia-recovery-$(date +%Y%m%d-%H%M%S).log"
|
||||
BOLD=$(tput bold 2>/dev/null || true)
|
||||
RED=$(tput setaf 1 2>/dev/null || true)
|
||||
GREEN=$(tput setaf 2 2>/dev/null || true)
|
||||
YELLOW=$(tput setaf 3 2>/dev/null || true)
|
||||
RESET=$(tput sgr0 2>/dev/null || true)
|
||||
|
||||
log() { echo -e "$*" | tee -a "$LOCAL_LOG"; }
|
||||
section() { log ""; log "${BOLD}--- $1 ---${RESET}"; }
|
||||
|
||||
echo "" | tee -a "$LOCAL_LOG"
|
||||
log "============================================="
|
||||
log " NVIDIA Kernel Module Recovery"
|
||||
log " Date: $(date)"
|
||||
log " Log: $LOCAL_LOG"
|
||||
log "============================================="
|
||||
|
||||
# ============================================================
|
||||
# 1. DIAGNOSTICS
|
||||
# ============================================================
|
||||
section "Diagnostic"
|
||||
|
||||
# Get current kernel
|
||||
RUNNING_KERNEL=$(uname -r)
|
||||
log "Running kernel: $RED$RUNNING_KERNEL$RESET"
|
||||
|
||||
KERNEL_VERSION="${RUNNING_KERNEL%-MANJARO}" # 6.18.33-1
|
||||
KERNEL_MAJOR="${KERNEL_VERSION%%.*}" # 6
|
||||
KERNEL_MINOR="${KERNEL_VERSION#*.}" # 18.33-1
|
||||
KERNEL_MINOR="${KERNEL_MINOR%%.*}" # 18
|
||||
KERNEL_PKG="linux${KERNEL_MAJOR}${KERNEL_MINOR}" # linux618
|
||||
log "Kernel package: $KERNEL_PKG"
|
||||
|
||||
# Check if nvidia module exists
|
||||
MODULE_PATH="/usr/lib/modules/$RUNNING_KERNEL/extra/modules/nvidia.ko.zst"
|
||||
MODULE_PATH2="/usr/lib/modules/$RUNNING_KERNEL/extra/nvidia.ko.zst"
|
||||
MODULE_PATH3="/usr/lib/modules/$RUNNING_KERNEL/updates/dkms/nvidia.ko.zst"
|
||||
MODULE_PATH4="/usr/lib/modules/$RUNNING_KERNEL/updates/nvidia.ko.zst"
|
||||
MODULE_PATH5="/usr/lib/modules/$RUNNING_KERNEL/kernel/drivers/gpu/drm/nvidia/nvidia.ko.zst"
|
||||
|
||||
MODULE_FOUND=false
|
||||
if [[ -f "$MODULE_PATH" ]] || [[ -f "$MODULE_PATH2" ]] || [[ -f "$MODULE_PATH3" ]] || [[ -f "$MODULE_PATH4" ]] || [[ -f "$MODULE_PATH5" ]]; then
|
||||
MODULE_FOUND=true
|
||||
log "${GREEN}NVIDIA module found at $MODULE_PATH3$RESET"
|
||||
else
|
||||
log "${RED}NVIDIA module MISSING for kernel $RUNNING_KERNEL$RESET"
|
||||
fi
|
||||
|
||||
# Check nvidia-utils
|
||||
if command -v nvidia-smi &>/dev/null; then
|
||||
log "${GREEN}nvidia-smi: available$RESET"
|
||||
else
|
||||
log "${RED}nvidia-smi: not found$RESET"
|
||||
fi
|
||||
|
||||
# Check DKMS
|
||||
if command -v dkms &>/dev/null; then
|
||||
log "${GREEN}dkms: available$RESET"
|
||||
else
|
||||
log "${RED}dkms: not found$RESET"
|
||||
fi
|
||||
|
||||
# Check if nvidia-580xx-dkms is installed
|
||||
if pacman -Q nvidia-580xx-dkms &>/dev/null; then
|
||||
DKMS_INSTALLED=true
|
||||
log "${GREEN}nvidia-580xx-dkms: installed$(pacman -Qi nvidia-580xx-dkms 2>/dev/null | grep Version)"
|
||||
else
|
||||
DKMS_INSTALLED=false
|
||||
log "${RED}nvidia-580xx-dkms: NOT installed$RESET"
|
||||
fi
|
||||
|
||||
# Check if nvidia-utils is installed
|
||||
if pacman -Q nvidia-utils &>/dev/null; then
|
||||
log "${GREEN}nvidia-utils: installed"
|
||||
else
|
||||
log "${RED}nvidia-utils: NOT installed$RESET"
|
||||
fi
|
||||
|
||||
# Check modules-load config
|
||||
if [[ -f /etc/modules-load.d/mhwd-gpu.conf ]]; then
|
||||
log "modules-load config: /etc/modules-load.d/mhwd-gpu.conf exists"
|
||||
log " Entries: $(grep -v '^#\|^$' /etc/modules-load.d/mhwd-gpu.conf | tr '\n' ' ')"
|
||||
else
|
||||
log "${RED}No mhwd-gpu.conf found$RESET"
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# 2. CHECK DEPENDENCIES
|
||||
# ============================================================
|
||||
section "Dependency Check"
|
||||
|
||||
MISSING=()
|
||||
if ! command -v dkms &>/dev/null; then
|
||||
MISSING+=(dkms)
|
||||
fi
|
||||
if ! command -v mkinitcpio &>/dev/null; then
|
||||
MISSING+=(mkinitcpio)
|
||||
fi
|
||||
|
||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||
log "${RED}Missing base tools: ${MISSING[*]}$RESET"
|
||||
log "These will be installed as part of the fix."
|
||||
fi
|
||||
|
||||
# Check available disk space
|
||||
DISK_AVAIL=$(df -h / | awk 'NR==2 {print $4}')
|
||||
log "Disk available: $DISK_AVAIL"
|
||||
|
||||
# ============================================================
|
||||
# 3. APPLY FIX
|
||||
# ============================================================
|
||||
section "Applying Fix"
|
||||
|
||||
if [[ "$MODE" == "check" ]]; then
|
||||
log "${BOLD}DRY-RUN MODE${RESET}"
|
||||
log "Would execute:"
|
||||
log " sudo pacman -Rns --noconfirm nvidia-utils # remove conflicting non-580xx driver"
|
||||
log " sudo pacman -S --needed nvidia-580xx-dkms nvidia-580xx-utils"
|
||||
log " sudo pacman -S --needed linux618-headers # kernel headers for DKMS"
|
||||
log " sudo dkms autoinstall"
|
||||
log " sudo mkinitcpio -P"
|
||||
log " sudo reboot"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Confirm before destructive action
|
||||
log "${BOLD}This will reinstall the NVIDIA kernel module driver.$RESET"
|
||||
log "The system will reboot automatically."
|
||||
read -rp "Continue? [y/N] " confirm
|
||||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||||
log "ABORTED by user."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Step 1: Resolve driver conflict, install 580xx suite
|
||||
log "[1/5] Resolving NVIDIA driver conflict and installing 580xx suite..."
|
||||
# Check if newer nvidia-utils conflicts with 580xx-dkms
|
||||
if pacman -Q nvidia-utils &>/dev/null && ! pacman -Q nvidia-580xx-utils &>/dev/null; then
|
||||
log "Conflict: nvidia-utils (non-580xx) installed alongside nvidia-580xx-dkms."
|
||||
log "Removing conflicting nvidia-utils, installing nvidia-580xx-utils..."
|
||||
sudo pacman -Rns --noconfirm nvidia-utils 2>&1 | tee -a "$LOCAL_LOG"
|
||||
sudo pacman -S --needed --noconfirm nvidia-580xx-dkms nvidia-580xx-utils 2>&1 | tee -a "$LOCAL_LOG"
|
||||
else
|
||||
sudo pacman -S --needed --noconfirm nvidia-580xx-dkms nvidia-580xx-utils 2>&1 | tee -a "$LOCAL_LOG"
|
||||
fi
|
||||
|
||||
# Step 2: Ensure kernel headers are available for DKMS
|
||||
log "[1b/4] Checking kernel headers for DKMS..."
|
||||
KERNEL_HEADERS="${KERNEL_PKG}-headers"
|
||||
if pacman -Q "$KERNEL_HEADERS" &>/dev/null; then
|
||||
log "${GREEN}Kernel headers ($KERNEL_HEADERS) already installed.$RESET"
|
||||
else
|
||||
log "Installing $KERNEL_HEADERS for DKMS..."
|
||||
sudo pacman -S --needed --noconfirm "$KERNEL_HEADERS" 2>&1 | tee -a "$LOCAL_LOG"
|
||||
fi
|
||||
|
||||
# Step 3: Rebuild DKMS module for current kernel
|
||||
log "[2/5] Rebuilding DKMS module for kernel $RUNNING_KERNEL..."
|
||||
sudo dkms autoinstall 2>&1 | tee -a "$LOCAL_LOG"
|
||||
|
||||
# Step 3: Verify module was created
|
||||
log "[3/5] Verifying module..."
|
||||
if [[ -f "$MODULE_PATH" ]] || [[ -f "$MODULE_PATH2" ]] || [[ -f "$MODULE_PATH3" ]] || [[ -f "$MODULE_PATH4" ]] || [[ -f "$MODULE_PATH5" ]]; then
|
||||
log "${GREEN}Module verified!$RESET"
|
||||
# Show module details
|
||||
modinfo_output=$(modinfo nvidia 2>/dev/null || echo "modinfo failed")
|
||||
log " $modinfo_output"
|
||||
else
|
||||
log "${RED}WARNING: Module file not found after DKMS build.$RESET"
|
||||
# Detect version for manual build
|
||||
DKMS_VERSION=$(pacman -Qi nvidia-580xx-dkms 2>/dev/null | grep Version | awk '{print $2}' | cut -d- -f1)
|
||||
[[ -z "$DKMS_VERSION" ]] && DKMS_VERSION="580.159.04"
|
||||
log "Attempting manual build (version: $DKMS_VERSION)..."
|
||||
sudo dkms build -m nvidia -v "$DKMS_VERSION" -k "$RUNNING_KERNEL" 2>&1 | tee -a "$LOCAL_LOG"
|
||||
sudo dkms install -m nvidia -v "$DKMS_VERSION" -k "$RUNNING_KERNEL" 2>&1 | tee -a "$LOCAL_LOG"
|
||||
fi
|
||||
|
||||
# Step 4: Rebuild initramfs
|
||||
log "[4/5] Rebuilding initramfs..."
|
||||
sudo mkinitcpio -P 2>&1 | tee -a "$LOCAL_LOG"
|
||||
|
||||
# ============================================================
|
||||
# 4. VERIFICATION
|
||||
# ============================================================
|
||||
section "Post-Recovery Verification"
|
||||
|
||||
log "Checking module loading..."
|
||||
if sudo modprobe nvidia 2>&1; then
|
||||
log "${GREEN}nvidia module loaded successfully$RESET"
|
||||
else
|
||||
log "${YELLOW}modprobe nvidia failed - module will be loaded at next boot$RESET"
|
||||
fi
|
||||
|
||||
# Detect 580xx version for manual DKMS fallback
|
||||
DKMS_VERSION=$(pacman -Qi nvidia-580xx-dkms 2>/dev/null | grep Version | awk '{print $2}' | cut -d- -f1 || echo "580.159.04")
|
||||
|
||||
# Manual DKMS fallback uses DKMS_VERSION variable
|
||||
|
||||
log ""
|
||||
log "${BOLD}Recovery complete!${RESET}"
|
||||
log ""
|
||||
log "Before rebooting, verify:"
|
||||
log " 1. Module exists: ls /usr/lib/modules/$(uname -r)/extra/nvidia*"
|
||||
log " 2. nvidia-smi works: sudo nvidia-smi"
|
||||
log ""
|
||||
log "Then reboot:"
|
||||
log " sudo reboot"
|
||||
log ""
|
||||
log "Log saved to: $LOCAL_LOG"
|
||||
log "============================================="
|
||||
Reference in New Issue
Block a user