8 Commits
Author SHA1 Message Date
DragonSlayer_14andClaude Sonnet 5 4b8299fede Fix: XanMod-Repo-Suite "releases" existiert nicht mehr
deb.xanmod.org/dists/releases liefert 404; das Repository ist mittlerweile
pro Debian-Codename organisiert (sid, trixie, bookworm, ...). Da dieses
Framework Debian Unstable (Sid) als Zielsystem hat, wird jetzt direkt die
Suite "sid" verwendet (per curl gegen deb.xanmod.org verifiziert).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 23:01:05 +02:00
DragonSlayer_14andClaude Sonnet 5 7296489c11 Feature: Optionale Verlegung des Mesa/DXVK-Shader-Caches
Neue Variable SHADER_CACHE_DIR in config/setup.conf erlaubt es, den
Mesa- (RADV/OpenGL) und DXVK-Shader-Cache (Wine/Proton) auf einen
separaten Speicherort zu verlegen, um Nachcompilierungs-Ruckler nach
Neustarts zu vermeiden. Standardmäßig leer, damit kein hartkodierter
Pfad (z. B. /mnt/Data) vorausgesetzt wird - ohne Angabe bleiben Mesa
und DXVK bei ihren eigenen, überall vorhandenen Cache-Pfaden.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 22:53:36 +02:00
DragonSlayer_14andClaude Sonnet 5 7932bb2482 Feature: vkBasalt Vulkan-Postprocessing integriert
Rollt vkBasalt (inkl. 32-Bit-Variante für Proton/Wine) mit einer
vorkonfigurierten Contrast-Adaptive-Sharpening-Config aus. Der MangoHud-
Overlay zeigt den Aktivierungsstatus mit an; Aktivierung erfolgt pro
Spiel über die Steam-Launch-Option ENABLE_VKBASALT=1.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 22:52:36 +02:00
DragonSlayer_14andClaude Sonnet 5 0cc710f997 Feature: sched-ext Gaming-Scheduler (scx_lavd) aktiviert
Installiert scx-scheds aus dem bereits konfigurierten XanMod-Repository
und aktiviert den für Gaming/interaktive Desktop-Workloads gebauten
Latency-criticality Aware Virtual Deadline Scheduler im Autopilot-Modus.
Benötigt einen Kernel mit CONFIG_SCHED_CLASS_EXT (bei XanMod bereits
aktiv); nach frischer Kernel-Installation ggf. Neustart nötig.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 22:51:29 +02:00
DragonSlayer_14andClaude Sonnet 5 fec46ef46f Feature: systemd-oomd gegen Einfrieren bei Speicherdruck aktiviert
Ergänzt das bestehende zram-Swap um einen modernen, cgroup-v2/PSI-
basierten Out-of-Memory-Schutz, um Systemfreezes bei gleichzeitiger
Speicher-/Swap-Auslastung (z. B. Spiel + Discord + Browser) zu
verhindern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 22:50:54 +02:00
DragonSlayer_14andClaude Sonnet 5 287e4d815b Feature: GameMode-Tuning, MangoHud-Default & CoreCtrl für Gaming-Setup
Deployt eine getunte /etc/gamemode.ini (Performance-Governor, Renice,
I/O-Priorität, AMD-GPU-Performance-Level) und ergänzt den Zielbenutzer
um die Gruppen render/gamemode. MangoHud erhält ein vorkonfiguriertes
Overlay über den bestehenden Skel-Sync. CoreCtrl wird installiert und
per PolicyKit-Regel ohne wiederholte Passwortabfrage für sudo-Mitglieder
freigegeben.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 22:23:29 +02:00
DragonSlayer_14andClaude Sonnet 5 c1f3851086 Feature: Bei fehlgeschlagenem Befehl Wiederholen/Ignorieren/Abbrechen abfragen
Der ERR-Trap fragt den Benutzer nun interaktiv, wie mit einem
fehlgeschlagenen Befehl verfahren werden soll, statt die Installation
sofort abzubrechen. Zusätzlich aktiviert setup_err_trap jetzt
errtrace/functrace, damit Fehler auch innerhalb von lib/*.sh-Funktionen
abgefangen werden statt das Skript stillschweigend zu beenden.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 21:54:47 +02:00
DragonSlayer_14andClaude Sonnet 5 0bf2e81063 Fix: Ollama-eigenen Standardpfad statt /mnt/Data als Vorschlag anbieten
Bisher wurde in allen drei Dialogvarianten (whiptail-Yesno, whiptail-
Inputbox, CLI-Fallback) derselbe konfigurierte Pfad
(/mnt/Data/Software/ollama/models) sowohl als "Standard" beworben als
auch als vorausgefüllter Eingabewert verwendet - der tatsächliche
Ollama-Standardspeicherort kam nie zum Zug.

prompt_ollama_models_path() unterscheidet jetzt zwischen dem echten
Ollama-Standardpfad (/usr/share/ollama/.ollama/models, verwendet vom
offiziellen Installationsskript / systemd-Dienst) und dem in
OLLAMA_MODELS_DEFAULT konfigurierten Pfadvorschlag. Letzterer wird nur
noch als Vorbelegung im Eingabefeld angezeigt, nachdem der Standardpfad
explizit abgelehnt wurde.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 21:37:27 +02:00
13 changed files with 330 additions and 23 deletions
+8 -3
View File
@@ -40,11 +40,11 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F
├── stages/ # Sequenziell und modular ausführbare Phasen (00 bis 11)
│ ├── 00-preflight.sh # Systemvoraussetzungen, Root/User-Erkennung, Internetverbindung
│ ├── 01-apt-unstable.sh # Deb822-Quellen, Keyrings, Pinning, apt-listbugs, dist-upgrade
│ ├── 02-kernel-hardware.sh # XanMod-Kernel, CPU P-State, Microcode, auto-cpufreq
│ ├── 02-kernel-hardware.sh # XanMod-Kernel, CPU P-State, Microcode, auto-cpufreq, Shader-Cache-Pfad
│ ├── 03-bootloader.sh # GRUB Kernel-Parameter, Vimix-Theme, Plymouth Solar
│ ├── 04-packages.sh # Installation der thematischen Paketlisten
│ ├── 05-fonts.sh # Download & Installation von Coding- & Nerd-Fonts
│ ├── 06-services.sh # Aktivierung von AppArmor, Docker, Libvirt, zram, Ollama
│ ├── 06-services.sh # Aktivierung von AppArmor, Docker, Libvirt, zram, Ollama, GameMode/CoreCtrl, systemd-oomd, scx-Scheduler
│ ├── 07-skel-and-user.sh # /etc/skel Vorlagen, ZSH-Shell-Setzen, Dotfiles-Sync
│ ├── 08-flatpaks.sh # Flathub Setup, Flatpak-Paketlisten-Installation
│ ├── 09-apps.sh # Spotify, Waydroid, OpenDeck, Desktop-Starter, MIME-Types
@@ -56,8 +56,10 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F
│ │ └── preferences.d/ # Pinning-Konfigurationen
│ ├── etc/
│ │ ├── environment.d/ # Globale Umgebungsvariablen (Raytracing, Upscaling)
│ │ ├── gamemode.ini # GameMode Performance-Daemon Defaults (Governor, Renice, GPU)
│ │ ├── polkit-1/rules.d/ # 90-corectrl.rules (passwortlose CoreCtrl-Freigabe für sudo-Gruppe)
│ │ └── profile.d/ # Globale Profil-Skripte (z. B. XDG User Dirs Update)
│ ├── skel/ # Vorlagen für /etc/skel (.zshrc, Dokumentvorlagen)
│ ├── skel/ # Vorlagen für /etc/skel (.zshrc, .config/MangoHud, .config/vkBasalt, Dokumentvorlagen)
│ └── usr/share/applications/ # Desktop-Starter-Dateien
├── README.md # Projektdokumentation für Endanwender
└── LICENSE # MIT-Lizenz
@@ -91,6 +93,7 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F
source "$SCRIPT_DIR/../lib/utils.sh"
setup_err_trap
```
- `setup_err_trap` aktiviert `errtrace`/`functrace`, damit Fehler auch innerhalb von `lib/*.sh`-Funktionen abgefangen werden, und registriert `error_handler` als ERR-Trap. Schlägt ein Befehl fehl, wird der Benutzer interaktiv gefragt, ob der Befehl **wiederholt**, **ignoriert** oder die **Installation abgebrochen** werden soll (`ask_retry_ignore_abort`). In nicht-interaktiven Läufen (`CI=1`, `DEBIAN_FRONTEND=noninteractive`, `AUTO_CONFIRM=1`, keine TTY) wird immer automatisch abgebrochen, wie zuvor.
- Verwende für temporäre Verzeichnisse immer `mktemp -d` und stelle sicher, dass am Skriptende oder bei Fehlern aufgeräumt wird:
```bash
TMP_DIR="$(mktemp -d)"
@@ -123,6 +126,8 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F
- `log_error "Nachricht"`: Rote Fehlermeldung (`[ERROR]`).
- `log_step "Titel"`: Hervorgehobener Abschnitts-Header.
- `log_substep "Titel"`: Eingerückter Unterabschnitt.
- `setup_err_trap`: Aktiviert `errtrace`/`functrace` und registriert `error_handler` als ERR-Trap für das gesamte Skript (inkl. `lib/*.sh`-Funktionen).
- `error_handler` / `ask_retry_ignore_abort` / `resume_after_error`: Zentrale Fehlerbehandlung. Bei einem fehlgeschlagenen Befehl wird interaktiv nach Wiederholen/Ignorieren/Abbrechen gefragt; nicht-interaktiv wird immer abgebrochen.
- `require_root`: Bricht ab, wenn das Skript nicht mit Root-Rechten ausgeführt wird.
- `command_exists "tool"`: Prüft, ob ein Befehl im Pfad verfügbar ist.
- `prompt_target_user`: Erkennt `$SUDO_USER` oder fragt interaktiv nach dem Zielbenutzer.
+24 -2
View File
@@ -109,9 +109,11 @@ Installiere nur bestimmte Phasen (z. B. nur Paketlisten und Schriften):
│ ├── sources.list.d/ # debian-unstable.sources, xanmod.sources
│ └── preferences.d/ # Pinning-Konfigurationen (unstable, xanmod)
├── etc/
│ ├── environment.d/ # 99-raytracing.conf, 99-upscaling.conf
│ ├── environment.d/ # 99-raytracing.conf, 99-upscaling.conf (99-shader-cache.conf wird optional zur Laufzeit generiert)
│ ├── gamemode.ini # GameMode Performance-Daemon Defaults
│ ├── polkit-1/rules.d/ # 90-corectrl.rules (passwortlose CoreCtrl-Freigabe für sudo-Gruppe)
│ └── profile.d/ # Bereinigte System-Profile-Skripte
├── skel/ # .zshrc, .config/hypr, Templates für Dokumente & Skripte
├── skel/ # .zshrc, .config/hypr, .config/MangoHud, .config/vkBasalt, Templates für Dokumente & Skripte
└── usr/share/applications/ # Desktop-Dateien (z. B. Spotify)
```
@@ -144,6 +146,23 @@ Installiere nur bestimmte Phasen (z. B. nur Paketlisten und Schriften):
## 🎮 Gaming & Performance-Optimierungen
### GameMode, MangoHud & CoreCtrl
- **GameMode**: `stages/06-services.sh` rollt eine getunte `/etc/gamemode.ini` aus (`desiredgov=performance`, Renice, I/O-Priorität, AMD-GPU-Performance-Level `high`) und fügt den Zielbenutzer automatisch den Gruppen `gamemode` (Renice/Core-Parking) und `render` (Vulkan/GPU-Compute) hinzu.
- **MangoHud**: `data/skel/.config/MangoHud/MangoHud.conf` liefert ein vorkonfiguriertes Overlay (FPS, Frametime, CPU/GPU-Temperatur & -Takt, VRAM/RAM, GameMode-Indikator), das über `stages/07-skel-and-user.sh` automatisch für neue und bestehende Benutzer bereitgestellt wird. Umschalten mit `Shift+F12` (Position mit `Shift+F11`).
- **CoreCtrl**: Für Fankurven, Power-States und Undervolting von AMD-CPU/GPU. Eine PolicyKit-Regel (`90-corectrl.rules`) erlaubt Mitgliedern der `sudo`-Gruppe den Start ohne wiederholte Passwortabfrage.
### systemd-oomd (Out-of-Memory-Schutz)
- Wird aktiviert, um Einfrieren des Systems bei gleichzeitiger Speicher-/Swap-Auslastung (Spiel + Discord + Browser) zu verhindern ergänzt das bestehende zram-Swap.
### Sched-ext Gaming-Scheduler
- **sched-ext (`scx-scheds`)**: `stages/06-services.sh` installiert das Paket aus dem bereits konfigurierten XanMod-Repository und aktiviert den Scheduler `scx_lavd` (Latency-criticality Aware Virtual Deadline speziell für Gaming/interaktive Desktop-Workloads) im `--autopilot`-Modus über `/etc/default/scx` und `scx.service`. Benötigt einen Kernel mit `CONFIG_SCHED_CLASS_EXT` (bei XanMod bereits aktiv); nach einer frischen Kernel-Installation ist ggf. ein Neustart nötig.
### vkBasalt (Vulkan-Postprocessing)
- ReShade-ähnliche Vulkan-Postprocessing-Shader (Contrast Adaptive Sharpening als Standard) mit vorkonfigurierter `~/.config/vkBasalt/vkBasalt.conf`. Aktivierung pro Spiel über die Steam-Launch-Option `ENABLE_VKBASALT=1 %command%`; Status wird von MangoHud mit angezeigt.
### Persistenter Shader-Cache (optional)
- Standardmäßig bleiben Mesa (RADV/OpenGL) und DXVK (Wine/Proton) bei ihren eigenen Cache-Pfaden (`~/.cache/mesa_shader_cache`, `~/.cache/dxvk`). Wird `SHADER_CACHE_DIR` in `config/setup.conf` gesetzt (z. B. auf eine separate/schnelle Festplatte), verlegt `stages/02-kernel-hardware.sh` beide Caches dorthin, um Nachcompilierungs-Ruckler nach Neustarts zu vermeiden.
### CPU P-State & Kernel-Parameter
In `stages/03-bootloader.sh` wird der CPU-Hersteller automatisch ermittelt und in `/etc/default/grub` eingetragen:
- **AMD CPUs**: `amd_pstate=active`
@@ -157,6 +176,9 @@ gamemoderun gamescope -W 2560 -H 1440 --force-grab-cursor --hdr-enabled --adapti
# Raytracing für DX12 Titel (RADV / Mesa)
RADV_PERFTEST=gpl,rt,ngg_streamout VKD3D_CONFIG=dxr,dxr11 DXVK_ASYNC=1 AMD_VULKAN_ICD=RADV gamemoderun gamescope -W 2560 -H 1440 --force-grab-cursor --hdr-enabled --adaptive-sync -f -o 240 -r 240 -- mangohud %command%
# Mit vkBasalt-Postprocessing (Schärfung via Contrast Adaptive Sharpening)
ENABLE_VKBASALT=1 gamemoderun gamescope -W 2560 -H 1440 --force-grab-cursor --hdr-enabled --adaptive-sync -f -o 240 -r 240 -- mangohud %command%
```
---
+1
View File
@@ -69,6 +69,7 @@ ripgrep
rpi-imager
shellcheck
sl
systemd-oomd
systemd-timesyncd
tar
tealdeer
+3
View File
@@ -2,6 +2,7 @@
# config/packages/03-gaming.list - Gaming tools, Vulkan drivers, Wine & Emulation
# ==============================================================================
corectrl
gameconqueror
gamemode
gamescope
@@ -17,6 +18,8 @@ protontricks
radeontop
steam-installer
steam-devices
vkbasalt
vkbasalt:i386
vulkan-tools
wine
winetricks
+10
View File
@@ -23,7 +23,17 @@ GRUB_TIMEOUT_STYLE="menu"
# Shell & Userland
DEFAULT_SHELL="zsh"
# Gaming: Persistent Shader Cache (Mesa & DXVK)
# Optional relocation of the shader/pipeline cache onto separate/bulk storage.
# Leave empty to keep Mesa's and DXVK's own default cache locations
# (~/.cache/mesa_shader_cache, ~/.cache/dxvk) - recommended unless you have a
# specific reason (small root disk, dedicated fast scratch drive, ...).
# Example: SHADER_CACHE_DIR="/mnt/Data/Software/mesa_shader_cache"
SHADER_CACHE_DIR=""
# Ollama AI Configuration
# Suggested custom models path, pre-filled only if the user declines
# Ollama's own default storage location (/usr/share/ollama/.ollama/models).
OLLAMA_MODELS_DEFAULT="/mnt/Data/Software/ollama/models"
OLLAMA_FLASH_ATTENTION="1"
OLLAMA_KV_CACHE_TYPE="q8_0"
+1 -1
View File
@@ -1,5 +1,5 @@
Types: deb
URIs: http://deb.xanmod.org
Suites: releases
Suites: sid
Components: main
Signed-By: /etc/apt/keyrings/xanmod-archive-keyring.gpg
+34
View File
@@ -0,0 +1,34 @@
# ==============================================================================
# data/etc/gamemode.ini - GameMode performance daemon defaults
# ==============================================================================
# Deployed to /etc/gamemode.ini by stages/06-services.sh
# Full reference: /usr/share/gamemode/gamemode.ini
[general]
; Use the "performance" CPU governor while a game is running instead of
; "powersave"/"ondemand", restoring the previous governor once it exits.
desiredgov=performance
; Renice game processes for smoother frame pacing (0-20, applied as a negated
; nice value). Requires the target user to be a member of the "gamemode"
; group, which the setup framework adds automatically.
renice=5
; Lower I/O priority class while gaming (0 = highest Best-Effort priority).
ioprio=0
; Keep the screen from blanking/locking while a game has focus.
inhibit_screensaver=1
[gpu]
; Apply AMD/NVIDIA GPU performance-level optimisations while gaming.
apply_gpu_optimisations=accept-responsibility
gpu_device=0
; AMD: force the "high" DPM performance level during GameMode sessions
; (requires an up-to-date amdgpu kernel module).
amd_performance_level=high
; NVIDIA-specific PowerMizer tuning (nv_powermizer_mode, nv_core_clock_mhz_offset,
; nv_mem_clock_mhz_offset) requires the "coolbits" Xorg option and is not
; configured by default, since this setup targets AMD/Intel GPUs.
@@ -0,0 +1,10 @@
// Allow members of the "sudo" administrative group to start/stop CoreCtrl's
// privileged helper without an interactive PolicyKit password prompt.
// Deployed by stages/06-services.sh.
polkit.addRule(function(action, subject) {
if ((action.id == "org.corectrl.helper.init" ||
action.id == "org.corectrl.helperkiller.init") &&
subject.isInGroup("sudo")) {
return polkit.Result.YES;
}
});
+35
View File
@@ -0,0 +1,35 @@
### MangoHud default overlay configuration
### Deployed to ~/.config/MangoHud/MangoHud.conf via stages/07-skel-and-user.sh
### Full reference: https://github.com/flightlessmango/MangoHud/blob/master/data/MangoHud.conf
# Toggle the overlay on/off with Shift+F12, move it with Shift+F11
toggle_hud=Shift_L+F12
toggle_hud_position=Shift_L+F11
# Performance metrics
fps
frametime
frame_timing
cpu_stats
cpu_temp
cpu_power
gpu_stats
gpu_temp
gpu_power
gpu_core_clock
gpu_mem_clock
vram
ram
io_read
io_write
# GameMode / vkBasalt indicators
gamemode
vkbasalt
# Presentation
position=top-left
background_alpha=0.4
font_size=20
round_corners=6
table_columns=3
+18
View File
@@ -0,0 +1,18 @@
### vkBasalt default post-processing configuration
### Deployed to ~/.config/vkBasalt/vkBasalt.conf via stages/07-skel-and-user.sh
### Full reference: https://github.com/DadSchoorse/vkBasalt
###
### Only active for games launched with ENABLE_VKBASALT=1, e.g. as a Steam
### launch option: ENABLE_VKBASALT=1 %command%
# Effect chain to apply, in order
effects = cas
# Contrast Adaptive Sharpening strength (0.0 - 1.0)
casSharpness = 0.4
# Apply the effect chain immediately without needing to press toggleKey first
enableOnLaunch = True
# Key to toggle all effects on/off at runtime
toggleKey = Home
+106 -15
View File
@@ -58,15 +58,101 @@ log_substep() {
# Error trap handler
setup_err_trap() {
# Required so the ERR trap also fires for failures inside sourced
# lib/*.sh functions (errtrace) and nested function calls (functrace),
# not just for top-level commands in the stage script itself.
set -o errtrace
set -o functrace
trap 'error_handler $? $LINENO "$BASH_COMMAND"' ERR
}
# Re-arms 'set -e' for the *next* command only, via a self-removing DEBUG
# trap. Bash normally terminates the script right after an ERR trap when
# errexit is set, no matter what the trap does - the only way to make the
# script actually resume past the failed line is to have errexit disabled
# at the moment the trap returns. Must be the very last statement executed
# on the "resume" path (no trailing 'return'/'break'/...): any further
# command run inside error_handler itself would consume the DEBUG trap's
# one-shot reset before control ever gets back to the failed line.
resume_after_error() {
set +e
trap 'set -e; trap - DEBUG' DEBUG
}
# Ask the user what to do about a failed command.
# Echoes one of: r (retry), i (ignore), a (abort). Defaults to "a" when
# not running interactively (piped install, CI, DEBIAN_FRONTEND=noninteractive,
# AUTO_CONFIRM=1) or when the prompt can't be read, so unattended installs
# keep failing hard exactly like before this feature existed.
ask_retry_ignore_abort() {
local is_interactive=0
if { [[ -t 0 ]] || has_tty; } && [[ "${DEBIAN_FRONTEND:-}" != "noninteractive" && "${CI:-}" != "1" && "${AUTO_CONFIRM:-}" != "1" ]]; then
is_interactive=1
fi
if [[ "$is_interactive" -ne 1 ]]; then
echo "a"
return 0
fi
local tty_in="/dev/tty"
local tty_out="/dev/tty"
if ! has_tty; then
tty_in="/dev/stdin"
tty_out="/dev/stderr"
fi
local prompt answer=""
prompt="$(printf "%b[W]iederholen%b / %b[i]gnorieren%b / %b[a]bbrechen%b (Standard: a): " \
"$CLR_BOLD" "$CLR_RESET" "$CLR_BOLD" "$CLR_RESET" "$CLR_BOLD" "$CLR_RESET")"
read -r -p "$prompt" answer < "$tty_in" > "$tty_out" 2>&1 || answer="a"
answer="$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' <<< "$answer")"
case "$answer" in
[Ww]*) echo "r" ;;
[Ii]*) echo "i" ;;
*) echo "a" ;;
esac
}
error_handler() {
local exit_code="$1"
local line_no="$2"
local bash_command="$3"
log_error "Command failed with exit code $exit_code at line $line_no: '$bash_command'"
local choice
choice="$(ask_retry_ignore_abort)"
case "$choice" in
r)
# Bare shell keywords (return/exit/break/continue) can't be
# meaningfully re-run via eval - they'd just unwind the current
# function instead of redoing any actual work. Treat these like
# "ignore" instead of silently aborting on a nonsensical retry.
if [[ "$bash_command" =~ ^(return|exit|break|continue)([[:space:]]|$) ]]; then
log_warn "'$bash_command' kann nicht wiederholt werden - Fehler wird ignoriert."
resume_after_error
else
log_info "Wiederhole: $bash_command"
if eval "$bash_command"; then
log_success "Wiederholung erfolgreich, Installation wird fortgesetzt."
resume_after_error
else
error_handler "$?" "$line_no" "$bash_command"
fi
fi
;;
i)
log_warn "Fehler wird ignoriert, Installation wird fortgesetzt: $bash_command"
resume_after_error
;;
*)
log_error "Installation abgebrochen."
exit "$exit_code"
;;
esac
}
# Root permission check
@@ -255,7 +341,12 @@ prompt_ollama_models_path() {
return 0
fi
local default_path="${OLLAMA_MODELS_DEFAULT:-/mnt/Data/Software/ollama/models}"
# Ollama's own default storage location (used by the official install
# script / systemd service, which runs as the "ollama" user).
local ollama_default_path="/usr/share/ollama/.ollama/models"
# Suggested custom path, only ever pre-filled once the user has
# explicitly declined the Ollama default above.
local custom_path_suggestion="${OLLAMA_MODELS_DEFAULT:-/mnt/Data/Software/ollama/models}"
local chosen=""
local is_interactive=0
if { [[ -t 0 ]] || has_tty; } && [[ "${DEBIAN_FRONTEND:-}" != "noninteractive" && "${CI:-}" != "1" && "${AUTO_CONFIRM:-}" != "1" ]]; then
@@ -271,20 +362,20 @@ prompt_ollama_models_path() {
fi
# If whiptail is available and running on an active terminal, first ask
# whether the configured default path should be used, and only show
# the free-text path dialog (pre-filled with that default) if not.
# whether Ollama's own default path should be used, and only show the
# free-text path dialog (pre-filled with the custom suggestion) if not.
if command_exists whiptail && has_tty; then
local yesno_status=0
run_whiptail --title "Ollama KI-Modelle Speicherort" \
--yes-button "Standard verwenden" --no-button "Eigenen Pfad angeben" \
--yesno "Standard-Speicherort für Ollama-Modelle:\n\n$default_path\n\nMöchtest du diesen Speicherort verwenden?" \
--yesno "Standard-Speicherort für Ollama-Modelle:\n\n$ollama_default_path\n\nMöchtest du diesen Speicherort verwenden?" \
12 70 || yesno_status=$?
if [[ "$yesno_status" -eq 0 || "$yesno_status" -eq 255 ]]; then
# Yes, or ESC/Cancel (255) - use the configured default,
# Yes, or ESC/Cancel (255) - use the Ollama default,
# consistent with the inputbox fallback below where an
# empty or cancelled dialog also keeps the default instead
# of asking again.
chosen="$default_path"
# empty or cancelled dialog also keeps its own default
# instead of asking again.
chosen="$ollama_default_path"
fi
if [[ -z "$chosen" ]]; then
@@ -292,34 +383,34 @@ prompt_ollama_models_path() {
tui_tmp="$(mktemp)"
if run_whiptail --output-fd 3 --title "Ollama KI-Modelle Speicherort" \
--inputbox "Bitte gib den Speicherort für die Ollama KI-Modelle an:" \
10 70 "$default_path" \
10 70 "$custom_path_suggestion" \
3> "$tui_tmp"; then
chosen="$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' < "$tui_tmp")"
fi
rm -f "$tui_tmp"
[[ -z "$chosen" ]] && chosen="$default_path"
[[ -z "$chosen" ]] && chosen="$custom_path_suggestion"
fi
fi
# CLI fallback if whiptail was not used or failed
if [[ -z "$chosen" ]]; then
printf "\n%bOllama KI-Modelle Speicherort:%b\n" "${CLR_CYAN}" "${CLR_RESET}" > "$tty_out"
printf "Standard-Pfad: %b%s%b\n" "${CLR_BOLD}" "$default_path" "${CLR_RESET}" > "$tty_out"
printf "Standard-Pfad: %b%s%b\n" "${CLR_BOLD}" "$ollama_default_path" "${CLR_RESET}" > "$tty_out"
if confirm_yes_no "Standard-Speicherort verwenden? [J/n]: " "j" "$tty_in" "$tty_out"; then
chosen="$default_path"
chosen="$ollama_default_path"
else
local input_path=""
read -r -p "Speicherort für Ollama-Modelle eingeben [$default_path]: " input_path < "$tty_in" > "$tty_out" 2>&1 || true
read -r -p "Speicherort für Ollama-Modelle eingeben [$custom_path_suggestion]: " input_path < "$tty_in" > "$tty_out" 2>&1 || true
input_path="$(echo "$input_path" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
if [[ -n "$input_path" ]]; then
chosen="$input_path"
else
chosen="$default_path"
chosen="$custom_path_suggestion"
fi
fi
fi
else
chosen="$default_path"
chosen="$ollama_default_path"
fi
export OLLAMA_MODELS="$chosen"
+18
View File
@@ -120,6 +120,24 @@ if compgen -G "$SCRIPT_DIR/data/etc/environment.d/*.conf" > /dev/null; then
done
fi
# 6. Persistent Shader Cache Location (Mesa & DXVK) - optional relocation
if [[ -n "${SHADER_CACHE_DIR:-}" ]]; then
log_substep "Configuring custom Mesa/DXVK shader cache location..."
TARGET_USER="${TARGET_USER:-$(prompt_target_user)}"
mkdir -p "$SHADER_CACHE_DIR"
chown -R "$TARGET_USER:$TARGET_USER" "$SHADER_CACHE_DIR"
cat <<EOF > /etc/environment.d/99-shader-cache.conf
# Persistent Mesa (RADV/OpenGL) & DXVK (Wine/Proton) shader/pipeline cache,
# relocated off the system disk to avoid re-compilation stutter after reboots.
MESA_SHADER_CACHE_DIR=$SHADER_CACHE_DIR
DXVK_STATE_CACHE_PATH=$SHADER_CACHE_DIR
EOF
chmod 0644 /etc/environment.d/99-shader-cache.conf
log_success "Shader cache directory set to $SHADER_CACHE_DIR"
else
log_info "SHADER_CACHE_DIR not set - keeping Mesa's and DXVK's own default shader cache locations."
fi
create_timeshift_snapshot "Stage 02: Post-kernel and hardware tuning" "O"
log_success "Stage 02: Kernel and Hardware Tuning completed successfully!"
+61 -1
View File
@@ -162,6 +162,66 @@ usermod -aG sudo,docker,netdev "$TARGET_USER"
if getent group ollama >/dev/null 2>&1; then
usermod -aG ollama "$TARGET_USER" 2>/dev/null || true
fi
log_success "Target user $TARGET_USER added to sudo, docker, netdev and ollama groups."
# "render" (GPU compute/Vulkan access) is created by Debian's udev sysusers
# config and is always present; "gamemode" only exists once the gamemode
# package is installed (stage 04), so it is added conditionally.
if getent group render >/dev/null 2>&1; then
usermod -aG render "$TARGET_USER" 2>/dev/null || true
fi
if getent group gamemode >/dev/null 2>&1; then
usermod -aG gamemode "$TARGET_USER" 2>/dev/null || true
fi
log_success "Target user $TARGET_USER added to sudo, docker, netdev, ollama, render and gamemode groups."
# 9. GameMode Performance Daemon & CoreCtrl Configuration
log_substep "Deploying GameMode performance configuration..."
if [[ -f "$SCRIPT_DIR/data/etc/gamemode.ini" ]]; then
backup_file_or_dir "/etc/gamemode.ini"
cp "$SCRIPT_DIR/data/etc/gamemode.ini" /etc/gamemode.ini
chmod 0644 /etc/gamemode.ini
log_success "GameMode configuration deployed to /etc/gamemode.ini."
fi
log_substep "Configuring passwordless CoreCtrl access for administrative users..."
if [[ -f "$SCRIPT_DIR/data/etc/polkit-1/rules.d/90-corectrl.rules" ]]; then
mkdir -p /etc/polkit-1/rules.d
cp "$SCRIPT_DIR/data/etc/polkit-1/rules.d/90-corectrl.rules" /etc/polkit-1/rules.d/90-corectrl.rules
chmod 0644 /etc/polkit-1/rules.d/90-corectrl.rules
log_success "CoreCtrl PolicyKit rule installed for the 'sudo' group."
fi
# 10. systemd-oomd Out-of-Memory Protection
log_substep "Enabling systemd-oomd out-of-memory protection..."
if command_exists systemctl; then
systemctl enable --now systemd-oomd.service 2>/dev/null || log_warn "Could not enable systemd-oomd.service."
log_success "systemd-oomd enabled (protects against freezes under heavy memory/swap pressure)."
fi
# 11. Sched-ext (scx) Gaming Scheduler
log_substep "Configuring sched-ext (scx) gaming scheduler..."
apt_ensure_keyrings_dir
apt_add_keyring_from_url "https://dl.xanmod.org/archive.key" "xanmod-archive-keyring.gpg" || true
if [[ -f "$SCRIPT_DIR/data/apt/sources.list.d/xanmod.sources" ]]; then
apt_install_sources_file "$SCRIPT_DIR/data/apt/sources.list.d/xanmod.sources" "xanmod.sources"
fi
apt_update
if DEBIAN_FRONTEND=noninteractive apt-get install -y scx-scheds 2>/dev/null; then
if [[ -f /etc/default/scx ]]; then
# scx_lavd (Latency-criticality Aware Virtual Deadline) is purpose-built
# for gaming/interactive desktop workloads; --autopilot lets it balance
# performance vs. powersave automatically based on system load.
sed -i 's|^SCX_SCHEDULER=.*|SCX_SCHEDULER=scx_lavd|' /etc/default/scx
grep -q '^SCX_SCHEDULER=' /etc/default/scx || echo "SCX_SCHEDULER=scx_lavd" >> /etc/default/scx
sed -i "s|^#\?SCX_FLAGS=.*|SCX_FLAGS='--autopilot'|" /etc/default/scx
grep -q '^SCX_FLAGS=' /etc/default/scx || echo "SCX_FLAGS='--autopilot'" >> /etc/default/scx
fi
if command_exists systemctl; then
systemctl daemon-reload 2>/dev/null || true
systemctl enable --now scx.service 2>/dev/null || log_warn "scx.service could not be started - a reboot into a sched_ext-capable kernel (e.g. XanMod) may be required."
fi
log_success "sched-ext gaming scheduler (scx_lavd) configured and enabled."
else
log_warn "Could not install scx-scheds. Skipping sched-ext scheduler configuration."
fi
log_success "Stage 06: System services configuration completed successfully!"