13 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
DragonSlayer_14andClaude Sonnet 5 950eb5d361 Refactor: Verschachtelung im Ollama-Speicherort-Dialog reduziert
Der whiptail-Zweig verschachtelte vier Ebenen tief und verteilte drei
identische chosen="$default_path"-Zuweisungen über if/else-Paare, um
eine einzige lineare Entscheidung abzubilden. Die Ja/Nein-Abfrage und
der Eingabedialog folgen jetzt beide dem Guard-Clause-Muster
(if [[ -z "$chosen" ]]; then ... fi), das bereits für den CLI-Fallback
weiter unten in derselben Funktion verwendet wird.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 21:33:48 +02:00
DragonSlayer_14andClaude Sonnet 5 9278241dd0 Refactor: Ja/Nein-Abfrage in gemeinsame Hilfsfunktion ausgelagert
prompt_target_user und prompt_ollama_models_path implementierten die
gleiche CLI-Ja/Nein-Abfrage (read + Trim + Regex-Prüfung) unabhängig
voneinander. Beide Kopien waren bereits leicht auseinandergelaufen
(unterschiedliches Fallback-Zeichen, unterschiedliche Regex-
Reihenfolge). confirm_yes_no() bündelt die Logik an einer Stelle.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 21:32:42 +02:00
DragonSlayer_14andClaude Sonnet 5 1fa3770e6e Fix: ESC im Ollama-Speicherort-Dialog fällt auf Standardpfad zurück
whiptail liefert bei ESC den Exit-Code 255, der bisher wie ein
explizites "Nein" (Exit-Code 1) behandelt und in den Eingabedialog für
einen eigenen Pfad geleitet wurde. Das widersprach dem direkt
folgenden Eingabedialog, in dem ESC/Abbruch stattdessen den
Standardpfad übernimmt. ESC verhält sich jetzt in beiden Dialogen
gleich.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 21:31:53 +02:00
DragonSlayer_14andClaude Sonnet 5 775b03e9de Fix: Trimmen der Ja/Nein-Antwort per xargs durch sed ersetzt
xargs interpretiert Anführungszeichen/Backslashes in der Eingabe und
schlägt bei ungültiger Eingabe mit leerer Ausgabe fehl. Das ließ eine
eigentlich verneinende Antwort fälschlich als "Ja" (Standardpfad)
durchgehen. sed wird bereits an allen anderen Trim-Stellen in dieser
Funktion verwendet und kennt dieses Fehlverhalten nicht.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 21:31:38 +02:00
DragonSlayer_14andClaude Sonnet 5 d9ec12dba3 Feat: Bestätigungsabfrage vor Ollama-Speicherort-Dialog hinzufügen
prompt_ollama_models_path() fragt jetzt zuerst per Ja/Nein, ob der
konfigurierte Standard-Speicherort (OLLAMA_MODELS_DEFAULT) verwendet werden
soll - analog zum bestehenden Muster in tui_prompt_target_user(). Nur bei
"Eigenen Pfad angeben" erscheint der Eingabedialog, vorbelegt mit genau
diesem Standardpfad. Gilt für whiptail-TUI und den CLI-Fallback gleichermaßen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017WMUd2fGsPCtTCVQkSS5TA
2026-09-06 21:15:29 +02:00
13 changed files with 372 additions and 34 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) ├── stages/ # Sequenziell und modular ausführbare Phasen (00 bis 11)
│ ├── 00-preflight.sh # Systemvoraussetzungen, Root/User-Erkennung, Internetverbindung │ ├── 00-preflight.sh # Systemvoraussetzungen, Root/User-Erkennung, Internetverbindung
│ ├── 01-apt-unstable.sh # Deb822-Quellen, Keyrings, Pinning, apt-listbugs, dist-upgrade │ ├── 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 │ ├── 03-bootloader.sh # GRUB Kernel-Parameter, Vimix-Theme, Plymouth Solar
│ ├── 04-packages.sh # Installation der thematischen Paketlisten │ ├── 04-packages.sh # Installation der thematischen Paketlisten
│ ├── 05-fonts.sh # Download & Installation von Coding- & Nerd-Fonts │ ├── 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 │ ├── 07-skel-and-user.sh # /etc/skel Vorlagen, ZSH-Shell-Setzen, Dotfiles-Sync
│ ├── 08-flatpaks.sh # Flathub Setup, Flatpak-Paketlisten-Installation │ ├── 08-flatpaks.sh # Flathub Setup, Flatpak-Paketlisten-Installation
│ ├── 09-apps.sh # Spotify, Waydroid, OpenDeck, Desktop-Starter, MIME-Types │ ├── 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 │ │ └── preferences.d/ # Pinning-Konfigurationen
│ ├── etc/ │ ├── etc/
│ │ ├── environment.d/ # Globale Umgebungsvariablen (Raytracing, Upscaling) │ │ ├── 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) │ │ └── 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 │ └── usr/share/applications/ # Desktop-Starter-Dateien
├── README.md # Projektdokumentation für Endanwender ├── README.md # Projektdokumentation für Endanwender
└── LICENSE # MIT-Lizenz └── LICENSE # MIT-Lizenz
@@ -91,6 +93,7 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F
source "$SCRIPT_DIR/../lib/utils.sh" source "$SCRIPT_DIR/../lib/utils.sh"
setup_err_trap 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: - Verwende für temporäre Verzeichnisse immer `mktemp -d` und stelle sicher, dass am Skriptende oder bei Fehlern aufgeräumt wird:
```bash ```bash
TMP_DIR="$(mktemp -d)" 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_error "Nachricht"`: Rote Fehlermeldung (`[ERROR]`).
- `log_step "Titel"`: Hervorgehobener Abschnitts-Header. - `log_step "Titel"`: Hervorgehobener Abschnitts-Header.
- `log_substep "Titel"`: Eingerückter Unterabschnitt. - `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. - `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. - `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. - `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 │ ├── sources.list.d/ # debian-unstable.sources, xanmod.sources
│ └── preferences.d/ # Pinning-Konfigurationen (unstable, xanmod) │ └── preferences.d/ # Pinning-Konfigurationen (unstable, xanmod)
├── etc/ ├── 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 │ └── 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) └── 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 ## 🎮 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 ### CPU P-State & Kernel-Parameter
In `stages/03-bootloader.sh` wird der CPU-Hersteller automatisch ermittelt und in `/etc/default/grub` eingetragen: In `stages/03-bootloader.sh` wird der CPU-Hersteller automatisch ermittelt und in `/etc/default/grub` eingetragen:
- **AMD CPUs**: `amd_pstate=active` - **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) # 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% 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 rpi-imager
shellcheck shellcheck
sl sl
systemd-oomd
systemd-timesyncd systemd-timesyncd
tar tar
tealdeer tealdeer
+3
View File
@@ -2,6 +2,7 @@
# config/packages/03-gaming.list - Gaming tools, Vulkan drivers, Wine & Emulation # config/packages/03-gaming.list - Gaming tools, Vulkan drivers, Wine & Emulation
# ============================================================================== # ==============================================================================
corectrl
gameconqueror gameconqueror
gamemode gamemode
gamescope gamescope
@@ -17,6 +18,8 @@ protontricks
radeontop radeontop
steam-installer steam-installer
steam-devices steam-devices
vkbasalt
vkbasalt:i386
vulkan-tools vulkan-tools
wine wine
winetricks winetricks
+10
View File
@@ -23,7 +23,17 @@ GRUB_TIMEOUT_STYLE="menu"
# Shell & Userland # Shell & Userland
DEFAULT_SHELL="zsh" 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 # 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_MODELS_DEFAULT="/mnt/Data/Software/ollama/models"
OLLAMA_FLASH_ATTENTION="1" OLLAMA_FLASH_ATTENTION="1"
OLLAMA_KV_CACHE_TYPE="q8_0" OLLAMA_KV_CACHE_TYPE="q8_0"
+1 -1
View File
@@ -1,5 +1,5 @@
Types: deb Types: deb
URIs: http://deb.xanmod.org URIs: http://deb.xanmod.org
Suites: releases Suites: sid
Components: main Components: main
Signed-By: /etc/apt/keyrings/xanmod-archive-keyring.gpg 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
+139 -17
View File
@@ -58,15 +58,101 @@ log_substep() {
# Error trap handler # Error trap handler
setup_err_trap() { 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 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() { error_handler() {
local exit_code="$1" local exit_code="$1"
local line_no="$2" local line_no="$2"
local bash_command="$3" local bash_command="$3"
log_error "Command failed with exit code $exit_code at line $line_no: '$bash_command'" 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" exit "$exit_code"
;;
esac
} }
# Root permission check # Root permission check
@@ -135,6 +221,23 @@ run_whiptail() {
fi fi
} }
# Ask a yes/no question on the CLI. Returns 0 for yes, 1 for no.
# On read failure (e.g. closed stdin), falls back to default_answer.
# Usage: confirm_yes_no "<prompt>" "<y|n default answer>" "$tty_in" "$tty_out"
confirm_yes_no() {
local prompt="$1"
local default_answer="$2"
local tty_in="$3"
local tty_out="$4"
local answer=""
read -r -p "$prompt" answer < "$tty_in" > "$tty_out" 2>&1 || answer="$default_answer"
answer="$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' <<< "$answer")"
if [[ -z "$answer" ]]; then
answer="$default_answer"
fi
[[ "$answer" =~ ^[YyJj] ]]
}
# Determine and prompt for the non-root target user # Determine and prompt for the non-root target user
prompt_target_user() { prompt_target_user() {
if [[ -n "${TARGET_USER:-}" ]]; then if [[ -n "${TARGET_USER:-}" ]]; then
@@ -173,9 +276,7 @@ prompt_target_user() {
if [[ -n "$candidate" && "$candidate" != "root" ]]; then if [[ -n "$candidate" && "$candidate" != "root" ]]; then
printf "\n%bTarget User Detection:%b\n" "${CLR_CYAN}" "${CLR_RESET}" > "$tty_out" printf "\n%bTarget User Detection:%b\n" "${CLR_CYAN}" "${CLR_RESET}" > "$tty_out"
printf "Detected target user: %b%s%b\n" "${CLR_BOLD}" "$candidate" "${CLR_RESET}" > "$tty_out" printf "Detected target user: %b%s%b\n" "${CLR_BOLD}" "$candidate" "${CLR_RESET}" > "$tty_out"
local answer="" if confirm_yes_no "Use target user '$candidate'? [Y/n]: " "y" "$tty_in" "$tty_out"; then
read -r -p "Use target user '$candidate'? [Y/n]: " answer < "$tty_in" > "$tty_out" 2>&1 || answer="y"
if [[ -z "$answer" || "$answer" =~ ^[YyJj] ]]; then
chosen="$candidate" chosen="$candidate"
fi fi
fi fi
@@ -240,7 +341,12 @@ prompt_ollama_models_path() {
return 0 return 0
fi 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 chosen=""
local is_interactive=0 local is_interactive=0
if { [[ -t 0 ]] || has_tty; } && [[ "${DEBIAN_FRONTEND:-}" != "noninteractive" && "${CI:-}" != "1" && "${AUTO_CONFIRM:-}" != "1" ]]; then if { [[ -t 0 ]] || has_tty; } && [[ "${DEBIAN_FRONTEND:-}" != "noninteractive" && "${CI:-}" != "1" && "${AUTO_CONFIRM:-}" != "1" ]]; then
@@ -255,40 +361,56 @@ prompt_ollama_models_path() {
tty_out="/dev/stderr" tty_out="/dev/stderr"
fi fi
# If whiptail is available and running on an active terminal, use whiptail dialog # If whiptail is available and running on an active terminal, first ask
# 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 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$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 Ollama default,
# consistent with the inputbox fallback below where an
# empty or cancelled dialog also keeps its own default
# instead of asking again.
chosen="$ollama_default_path"
fi
if [[ -z "$chosen" ]]; then
local tui_tmp local tui_tmp
tui_tmp="$(mktemp)" tui_tmp="$(mktemp)"
if run_whiptail --output-fd 3 --title "Ollama KI-Modelle Speicherort" \ if run_whiptail --output-fd 3 --title "Ollama KI-Modelle Speicherort" \
--inputbox "Bitte gib den Speicherort für die Ollama KI-Modelle an:" \ --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 3> "$tui_tmp"; then
local tui_input chosen="$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' < "$tui_tmp")"
tui_input="$(sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' < "$tui_tmp")"
if [[ -n "$tui_input" ]]; then
chosen="$tui_input"
else
chosen="$default_path"
fi
fi fi
rm -f "$tui_tmp" rm -f "$tui_tmp"
[[ -z "$chosen" ]] && chosen="$custom_path_suggestion"
fi
fi fi
# CLI fallback if whiptail was not used or failed # CLI fallback if whiptail was not used or failed
if [[ -z "$chosen" ]]; then if [[ -z "$chosen" ]]; then
printf "\n%bOllama KI-Modelle Speicherort:%b\n" "${CLR_CYAN}" "${CLR_RESET}" > "$tty_out" 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="$ollama_default_path"
else
local input_path="" 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:]]*$//')" input_path="$(echo "$input_path" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
if [[ -n "$input_path" ]]; then if [[ -n "$input_path" ]]; then
chosen="$input_path" chosen="$input_path"
else else
chosen="$default_path" chosen="$custom_path_suggestion"
fi
fi fi
fi fi
else else
chosen="$default_path" chosen="$ollama_default_path"
fi fi
export OLLAMA_MODELS="$chosen" 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 done
fi 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" create_timeshift_snapshot "Stage 02: Post-kernel and hardware tuning" "O"
log_success "Stage 02: Kernel and Hardware Tuning completed successfully!" 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 if getent group ollama >/dev/null 2>&1; then
usermod -aG ollama "$TARGET_USER" 2>/dev/null || true usermod -aG ollama "$TARGET_USER" 2>/dev/null || true
fi 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!" log_success "Stage 06: System services configuration completed successfully!"