Feat: Überarbeitet die Install Struktur

This commit is contained in:
2026-09-06 11:11:46 +02:00
parent 90dd188555
commit d424b5eed7
51 changed files with 2099 additions and 583 deletions
+2
View File
@@ -90,3 +90,5 @@ fabric.properties
# Built Visual Studio Code Extensions # Built Visual Studio Code Extensions
*.vsix *.vsix
.junie/plans
-15
View File
@@ -1,15 +0,0 @@
if [ "$(id -u)" -ne 0 ]; then
echo "❌ The Skript has to be run as root!"
exit 1
fi
# Update
apt update && apt upgrade -y
# Install first important Packages
apt install ca-certificates curl git gpg imagemagick lsb-release network-manager openssh-server rsync sudo wget
sudo usermod -aG sudo $USER
sudo usermod -aG sudo root
echo "Now, you have to relogin for the next scripts to work!"
-27
View File
@@ -1,27 +0,0 @@
if [ "$(id -u)" -ne 0 ]; then
echo "❌ The Skript has to be run as root!"
exit 1
fi
apt modernize-sources
# Add 32bit-Architecture
#dpkg --add-architecture i386
# Install gitea Keyrings
sudo curl https://gitea.creative-dragonslayer.de/api/packages/Linuxapps/debian/repository.key -o /etc/apt/keyrings/gitea-Linuxapps.asc
sudo curl https://gitea.creative-dragonslayer.de/api/packages/Mirror/debian/repository.key -o /etc/apt/keyrings/gitea-Mirror.asc
# Install my apt-sources
rm /etc/apt/sources.list
rm /etc/apt/sources.list~
rm /etc/apt/sources.list.bak
rm -r /etc/apt/sources.list.d
mkdir -p /etc/apt/sources.list.d
cp ./data/apt/sources.list.d/* /etc/apt/sources.list.d/
# Install my apt-pinning
rm -r /etc/apt/preferences.d
mkdir -p /etc/apt/preferences.d
cp ./data/apt/preferences.d/* /etc/apt/preferences.d/
apt update
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
sh <(curl -L https://raw.githubusercontent.com/LinuxBeginnings/Debian-Hyprland/main/auto-install.sh)
-132
View File
@@ -1,132 +0,0 @@
#!/bin/bash
if [ "$(id -u)" -ne 0 ]; then
echo "❌ The Skript has to be run as root!"
exit 1
fi
# Install XanModKernel
wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -vo /etc/apt/keyrings/xanmod-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/xanmod-release.list
apt update && apt install linux-xanmod-x64v3
# Install apt-Packages
apt install -y 7zip
apt install -y adb amberol apparmor apparmor-notify apparmor-profiles apparmor-profiles-extra apparmor-utils aptitude apt-listbugs apt-listchanges
apt install -y baobab bat bleachbit blueman bluetooth bluez bruno btop
apt install -y cava clamav clamav-daemon clamav-docs clamav-freshclam codium command-not-found cpupower-gui cryptomator
apt install -y dconf-editor debian-goodies
apt install -y easyeffects
apt install -y fastfetch ffmpeg file-roller firmware-linux firmware-linux-nonfree firmware-misc-nonfree flameshot flatpak flatseal floorp fragments fzf
apt install -y gameconqueror gamemode gamescope gimp glances gnome-calculator gnome-decoder gnome-disk-utility gnome-firmware gnome-font-viewer gnome-keyring gnome-logs gnome-snapshot gnome-system-monitor gnome-text-editor gparted grim
apt install -y htop hunspell hunspell-de-de-frami
apt install -y impression input-remapper irqbalance
# j
apt install -y keepassxc
apt install -y libreoffice libreoffice-gtk4 libreoffice-l10n-de localsend loupe lsd
apt install -y man mangoapp mangohud mesa-utils mesa-vulkan-drivers vulkan-tools
apt install -y network-manager-gnome nodejs nwg-displays nwg-look
apt install -y obfuscate openrgb
apt install -y pipewire pipewire-pulse plymouth plymouth-themes prismlauncher protontricks
# q
apt install -y radeontop remmina resources rfkill ripgrep rpi-imager
apt install -y sddm simple-scan sl slurp speech-dispatcher steam-devices swappy swaybg systemd-timesyncd
apt install -y tar tealdeer timeshift thunar topgrade tree
apt install -y unrar unzip
apt install -y vesktop vlc vlc-data vlc-l10n vlc-plugin-access-extra vlc-plugin-base vlc-plugin-notify vlc-plugin-pipewire vlc-plugin-qt vlc-plugin-video-output
apt install -y wayland-utils wine winetricks wireplumber wl-clipboard
apt install -y xdg-user-dirs
apt install -y yazi
apt install -y zram-tools zsh
# TODO PDF-Editor finden
# Enable Services
sudo systemctl enable apparmor
sudo systemctl start apparmor
# Set Default Apps
xdg-mime default org.gnome.Loupe.desktop image/jpeg
xdg-mime default org.gnome.Loupe.desktop image/png
xdg-mime default io.bassi.Amberol.desktop audio/mpeg
xdg-mime default io.bassi.Amberol.desktop audio/x-wav
xdg-mime default io.bassi.Amberol.desktop audio/flac
xdg-mime default io.bassi.Amberol.desktop audio/ogg
xdg-mime default org.gnome.TextEditor.desktop text/plain
xdg-mime default org.gnome.TextEditor.desktop text/x-log
xdg-mime default org.gnome.TextEditor.desktop text/markdown
# Set plymout-Theme
sudo plymouth-set-default-theme -R solar
sudo update-initramfs -u
sudo update-grub
# Add flathub
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
# Install Docker
# Add Docker's official GPG key:
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Install Spotify
curl -sS https://download.spotify.com/debian/pubkey_5384CE82BA52C83A.asc | gpg --dearmor --yes -o /etc/apt/trusted.gpg.d/spotify.gpg
echo "deb https://repository.spotify.com stable non-free" | tee /etc/apt/sources.list.d/spotify.list
apt update && apt install spotify-client
cp ./data/usr/share/applications/* /usr/share/applications
# Install Waydroid
curl -s https://repo.waydro.id | bash
apt install waydroid
systemctl enable --now waydroid-container
# Ollama
curl -fsSL https://ollama.com/install.sh | sh
# TODO Anpassen des Speicherorts der Models
# OpenDeck
curl -sSL https://raw.githubusercontent.com/nekename/OpenDeck/main/install_opendeck.sh | bash
# AM - AppImage - Application Manager
curl -s -Lo ~/AM-INSTALLER https://raw.githubusercontent.com/ivan-hc/AM/main/AM-INSTALLER && chmod a+x ~/AM-INSTALLER && ~/AM-INSTALLER && rm ~/AM-INSTALLER
# auto-cpufreq
git clone https://github.com/AdnanHodzic/auto-cpufreq.git
cd auto-cpufreq && sudo ./auto-cpufreq-installer
auto-cpufreq --install
# Qemu, Virtual Machine Install
if [ $(grep -Eoc '(vmx|svm)' /proc/cpuinfo) -gt 0 ]; then
apt install -y qemu-system-x86 qemu-utils libvirt-daemon-system libvirt-clients virt-manager
systemctl enable --now libvirtd.service
usermod -aG libvirt "$USER"
virsh net-start default
virsh net-autostart default
else
echo "No virtualisation Support. Check BIOS for Intel VT-x, Intel Virtualization Technology, AMD-V, or SVM Mode."
fi
# RUN Linutil
curl -fsSL https://christitus.com/linux | sh
-80
View File
@@ -1,80 +0,0 @@
#!/bin/bash
GRUB_CFG="/etc/default/grub"
GRUB_TIMEOUT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_CMDLINE_LINUX_DEFAULT_BASE="quiet splash apparmor=1 usbcore.autosuspend=-1 vt.global_cursor_default=0 loglevel=3 rd.luks.options=discard plymouth.ignore-serial-consoles threadirqs"
GRUB_CMDLINE_LINUX="rcutree.rcu_idle_gp_delay=1"
GRUB_THEME_DIR="/usr/share/debian-gaming/grub/grub2-themes"
# CPU-Treiber automatisch erkennen und hinzufügen
CPU_VENDOR=$(lscpu | grep -oP 'Vendor ID:\s*\K.*' | tr -d ' ')
CPU_MODEL=$(lscpu | grep -oP 'Model name:\s*\K.*' | head -c 20)
echo "Erkannte CPU: $CPU_MODEL ($CPU_VENDOR)"
case "$CPU_VENDOR" in
"AuthenticAMD")
CPU_PARAM="amd_pstate=active"
echo "AMD CPU erkannt → amd_pstate=active wird hinzugefügt"
;;
"GenuineIntel")
CPU_PARAM="intel_pstate=active"
echo "Intel CPU erkannt → intel_pstate=active wird hinzugefügt"
;;
*)
CPU_PARAM=""
echo "⚠️ Unbekannter CPU-Hersteller ($CPU_VENDOR) kein pstate-Parameter"
;;
esac
# CPU-Parameter anhängen, falls vorhanden
if [ -n "$CPU_PARAM" ]; then
# Prüfen ob Parameter bereits existiert (idempotent machen)
if ! echo "$GRUB_CMDLINE_LINUX_DEFAULT_BASE" | grep -q "amd_pstate\|intel_pstate"; then
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT_BASE $CPU_PARAM"
fi
else
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT_BASE"
fi
# Root-Check
if [ "$(id -u)" -ne 0 ]; then
echo "❌ Das Script muss als root ausgeführt werden!"
exit 1
fi
# Backup erstellen
cp "$GRUB_CFG" "$GRUB_CFG.bak"
echo "✅ Backup erstellt: $GRUB_CFG.bak"
# GRUB-Parameter setzen (sed mit Exit-Code-Handling für nicht-existente Keys)
sed -i "s|^GRUB_TIMEOUT=.*|GRUB_TIMEOUT=$GRUB_TIMEOUT|" "$GRUB_CFG"
sed -i "s|^GRUB_TIMEOUT_STYLE=.*|GRUB_TIMEOUT_STYLE=$GRUB_TIMEOUT_STYLE|" "$GRUB_CFG"
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$GRUB_CMDLINE_LINUX_DEFAULT\"|" "$GRUB_CFG"
sed -i "s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\"$GRUB_CMDLINE_LINUX\"|" "$GRUB_CFG"
# Falls Parameter nicht existierten, nachhaken (falls sed nichts geändert hat)
grep -q '^GRUB_TIMEOUT=' "$GRUB_CFG" || echo "GRUB_TIMEOUT=$GRUB_TIMEOUT" >> "$GRUB_CFG"
grep -q '^GRUB_TIMEOUT_STYLE=' "$GRUB_CFG" || echo "GRUB_TIMEOUT_STYLE=$GRUB_TIMEOUT_STYLE" >> "$GRUB_CFG"
grep -q '^GRUB_CMDLINE_LINUX_DEFAULT=' "$GRUB_CFG" || echo "GRUB_CMDLINE_LINUX_DEFAULT=\"$GRUB_CMDLINE_LINUX_DEFAULT\"" >> "$GRUB_CFG"
grep -q '^GRUB_CMDLINE_LINUX=' "$GRUB_CFG" || echo "GRUB_CMDLINE_LINUX=\"$GRUB_CMDLINE_LINUX\"" >> "$GRUB_CFG"
# GRUB-Theme installieren
mkdir -p "$GRUB_THEME_DIR"
if [ ! -d "$GRUB_THEME_DIR/.git" ]; then
git clone https://github.com/vinceliuice/grub2-themes.git "$GRUB_THEME_DIR"
"$GRUB_THEME_DIR/install.sh" -b -t vimix
else
echo "✅ Theme bereits installiert, wird aktualisiert..."
cd "$GRUB_THEME_DIR" && git pull
"./install.sh" -b -t vimix
fi
# GRUB aktualisieren
sudo update-grub
echo "✅ GRUB-Konfiguration aktualisiert!"
echo "📝 Neue Kernel-Parameter: $GRUB_CMDLINE_LINUX_DEFAULT"
-37
View File
@@ -1,37 +0,0 @@
#!/bin/bash
HOME="$(getent passwd $SUDO_USER | cut -d: -f6)"
DEFAULT_USR_FOLDER="/usr/share/debian-gaming/home"
if [ "$(id -u)" -ne 0 ]; then
echo "❌ The Skript has to be run as root!"
exit 1
fi
# Copy my profile.d
mkdir -p /etc/profile.d
cp ./data/etc/profile.d/* /etc/profile.d/
mkdir -p $DEFAULT_USR_FOLDER
# Copy Zsh-Files
cp ./data/home/zshrc $DEFAULT_USR_FOLDER/zshrc
grep -q '^source /etc/profile' /etc/zsh/zprofile || echo 'source /etc/profile' >> /etc/zsh/zprofile
# copy config folder
cp -r $HOME/.config $DEFAULT_USR_FOLDER/.config
# copy templates
cp -r ./data/home/templates $DEFAULT_USR_FOLDER/templates
# set zsh as default shell
USER_ENTRY=$(getent passwd "$USER")
cp /etc/passwd /etc/passwd.bak
if grep -q "^$USER:" /etc/passwd; then
sed -i "/^$USER:/s|[^:]*$|/bin/zsh|" /etc/passwd
else
UPDATED_ENTRY=$(echo "$USER_ENTRY" | awk -F: -v OFS=: '{ $NF="/bin/zsh"; print }')
echo "$UPDATED_ENTRY" >>/etc/passwd
fi
-29
View File
@@ -1,29 +0,0 @@
#!/bin/bash
FONT_DIR=/usr/share/fonts
if [ "$(id -u)" -ne 0 ]; then
echo "❌ The Skript has to be run as root!"
exit 1
fi
# Install Jetbrains Mono Nerd Font
wget -q https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.tar.xz
mkdir -p $FONT_DIR/JetBrainsMonoNerd
tar -xJkf JetBrainsMono.tar.xz -C $FONT_DIR/JetBrainsMonoNerd
# Install Fantasque Mono Nerd Font
wget -q https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/FantasqueSansMono.zip
mkdir -p $FONT_DIR/FantasqueSansMonoNerd
unzip -o -q "FantasqueSansMono.zip" -d "$FONT_DIR/FantasqueSansMonoNerd"
# Install Victor Mono Font
wget -q https://rubjo.github.io/victor-mono/VictorMonoAll.zip
mkdir -p $FONT_DIR/VictorMono
unzip -o -q "VictorMonoAll.zip" -d "$FONT_DIR/VictorMono"
fc-cache -v
if [ -d "JetBrainsMono.tar.xz" ]; then
rm -r JetBrainsMono.tar.xz 2>&1 | tee -a "$LOG"
fi
-36
View File
@@ -1,36 +0,0 @@
#!/bin/bash
# Betterbird als Standard-Mail-Programm setzen
flatpak install eu.betterbird.Betterbird -y # TODO Durch Melia ersetzen
xdg-mime default org.betterbird.Betterbird.desktop x-scheme-handler/mailto
# Alpaca
flatpak install flathub com.jeffser.Alpaca -y
# Web App Hub
flatpak install flathub org.pvermeer.WebAppHub -y
# Musescore
flatpak install flathub org.musescore.MuseScore -y
# Fluffychat (Matrix)
flatpak install flathub im.fluffychat.Fluffychat -y
# Flatsweep
flatpak install flathub io.github.giantpinkrobots.flatsweep -y
# Steam
flatpak install flathub com.valvesoftware.Steam -y
# Heroic
flatpak install flathub com.heroicgameslauncher.hgl -y
# Lutris
flatpak install flathub net.lutris.Lutris -y
# Gamescope
flatpak install flathub org.freedesktop.Platform.VulkanLayer.gamescope -y
# MangoHud
flatpak install flathub org.freedesktop.Platform.VulkanLayer.MangoHud -y
# GE-Proton
flatpak install flathub com.valvesoftware.Steam.CompatibilityTool.Proton-GE -y
# Proton Up-QT
flatpak install flathub net.davidotek.pupgui2 -y
# Scopebuddy GUI
flatpak install flathub io.github.rfrench3.scopebuddy-gui -y
+201
View File
@@ -0,0 +1,201 @@
# AGENTS.md — Richtlinien und Architektur-Leitfaden für KI-Agenten
Dieses Dokument enthält Richtlinien, Architekturstandards, Konventionen und Arbeitsanweisungen für KI-Agenten und Entwickler, die an diesem Repository arbeiten oder es warten.
---
## 1. Projektübersicht
Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-Framework für **Debian GNU/Linux Unstable (Sid)** mit:
- **Hyprland** (Wayland-Compositor) und Waybar-Desktopumgebung
- **XanMod-Kernel** (main/edge) mit CPU P-State-Tuning (AMD/Intel) und `auto-cpufreq`
- **Bootloader & Splash**: GRUB-Konfiguration mit Vimix-Theme und Plymouth Solar-Splash
- **Gaming & Multimedia**: MangoHud, Gamescope, Lutris, Steam, Wine, Pro-Audio via PipeWire
- **Virtualisierung & Container**: QEMU/KVM, Libvirt, Docker, Waydroid
- **Paket- und Anwendungsmanagement**: Deb822-Quellen, APT-Pinning, Flatpaks (Flathub), isolierte Schriften-Installation
---
## 2. Projekt- und Verzeichnisstruktur
```
.
├── setup.sh # Zentraler Orchestrator (CLI Flags & whiptail TUI)
├── lib/ # Wiederverwendbare Funktionsbibliotheken
│ ├── utils.sh # Logging, Error-Traps, Benutzer- und Pfadermittlung, Backups
│ ├── apt.sh # Deb822-Quellen, Keyrings (/etc/apt/keyrings), APT-Pinning, Paketinstallation
│ └── tui.sh # Whiptail-TUI-Menüs und Dialoge
├── config/ # Konfigurationsdateien & Paketlisten
│ ├── setup.conf # Globale Umgebungsvariablen und Standardwerte
│ └── packages/ # Thematisch gegliederte Paketlisten (*.list)
│ ├── 01-base.list # Basiswerkzeuge, Firmware, Microcode
│ ├── 02-desktop.list # Hyprland, Waybar, SDDM, XDG-Portale, PipeWire
│ ├── 03-gaming.list # Steam-Devices, Lutris, Gamescope, MangoHud, Wine
│ ├── 04-virtualization.list # QEMU, KVM, Libvirt, Bridge-Tools
│ ├── 05-multimedia.list # VLC, Amberol, GIMP, Loupe, LibreOffice
│ └── 06-flatpaks.list # Flathub App-IDs
├── stages/ # Sequenziell und modular ausführbare Phasen (00 bis 09)
│ ├── 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
│ ├── 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
│ ├── 07-skel-and-user.sh # /etc/skel Vorlagen, ZSH-Shell-Setzen, Dotfiles-Sync
│ ├── 08-flatpaks-apps.sh # Flathub Setup, Flatpaks, Spotify, Waydroid, MIME-Types
│ └── 09-hyprland.sh # LinuxBeginnings Debian-Hyprland Auto-Installer
├── data/ # Statische Konfigurationsdateien & Vorlagen
│ ├── apt/
│ │ ├── sources.list.d/ # Deb822-Quellen (debian-unstable.sources, xanmod.sources)
│ │ └── preferences.d/ # Pinning-Konfigurationen
│ ├── etc/
│ │ ├── environment.d/ # Globale Umgebungsvariablen (Raytracing, Upscaling)
│ │ └── profile.d/ # Globale Profil-Skripte (z. B. XDG User Dirs Update)
│ ├── skel/ # Vorlagen für /etc/skel (.zshrc, Dokumentvorlagen)
│ └── usr/share/applications/ # Desktop-Starter-Dateien
├── README.md # Projektdokumentation für Endanwender
└── LICENSE # MIT-Lizenz
```
---
## 3. Architekturprinzipien und Entwicklungsrichtlinien
### 3.1 Idempotenz (Mehrfache Ausführbarkeit)
- Jedes Skript und jede Phase muss **vollständig idempotent** sein: Die wiederholte Ausführung darf keine Fehler erzeugen und keine doppelten Konfigurationseinträge hinterlassen.
- Verwende vor dem Hinzufügen von Zeilen zu Konfigurationsdateien Prüfungen (z. B. `grep -q`) oder nutze saubere Konfigurationsverzeichnisse (`.d/`-Verzeichnisse).
### 3.2 Strikte Trennung von Root- und Benutzerrechten
- Die Skripte laufen grundsätzlich mit Root-Rechten (`sudo ./setup.sh`).
- **Niemals** Benutzerkonfigurationen unter `/root/` ablegen, wenn sie für den Desktop-Benutzer gedacht sind.
- Der Zielbenutzer wird in `$TARGET_USER` gespeichert (ermittelt über `prompt_target_user` in `lib/utils.sh`).
- Befehle im Kontext des regulären Benutzers **müssen** über `run_as_user "<befehl>"` ausgeführt werden.
- Das Home-Verzeichnis des Zielbenutzers muss über `get_target_home "$TARGET_USER"` ermittelt werden.
### 3.3 Fehlerbehandlung und Shell-Standards
- Alle Bash-Skripte **müssen** mit folgenden Flags starten:
```bash
#!/usr/bin/env bash
set -euo pipefail
```
- Binde `lib/utils.sh` ein und rufe `setup_err_trap` am Anfang jedes Skripts auf:
```bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/utils.sh
source "$SCRIPT_DIR/../lib/utils.sh"
setup_err_trap
```
- 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)"
trap 'rm -rf "$TMP_DIR"' EXIT
```
### 3.4 Dateisicherungen (Backups)
- Modifiziere bestehende Konfigurationsdateien (z. B. in `/etc/default/grub` oder `/etc/apt/`) nie ohne vorheriges Backup.
- Nutze die Bibliotheksfunktion `backup_file "$DATEIPFAD"`. Diese erstellt Backups im Format `<datei>.backup_YYYYMMDD_HHMMSS`.
### 3.5 Debian-Standards & APT-Hygiene
- **Deb822-Format**: Neue Paketquellen ausschließlich im Deb822-Format (`.sources`) unter `/etc/apt/sources.list.d/` ablegen.
- **Keyrings**: GPG-Schlüsselbunde gehören nach `/etc/apt/keyrings/` mit Rechten `644`. Das veraltete `apt-key` darf **nicht** verwendet werden.
- **Pinning**: APT-Prioritäten in `/etc/apt/preferences.d/` verwalten.
- **Nicht-interaktive Paketinstallation**: APT-Befehle müssen immer `DEBIAN_FRONTEND=noninteractive` und `-y` bzw. `--no-install-recommends` (sofern passend) verwenden. Verwende bevorzugt die Wrapper in `lib/apt.sh` (`safe_apt_update`, `install_packages_from_file`).
### 3.6 Keine gefährlichen Login-Hooks & Shell-Verwaltung
- **Keine Live-Downloads** (`curl | sh` / `wget | bash`) in `/etc/profile.d/` oder Login-Skripten.
- Dotfiles und Vorlagen gehören nach `/etc/skel/` und werden bei Bedarf einmalig für bestehende Nutzer synchronisiert (`stages/07-skel-and-user.sh`).
- Ändere Login-Shells niemals durch direkte Bearbeitung von `/etc/passwd` via `sed` oder `awk`, sondern ausschließlich über `chsh -s "$(command -v zsh)" "$TARGET_USER"`.
---
## 4. Hilfsbibliotheken (`lib/`)
### `lib/utils.sh`
- `log_info "Nachricht"`: Blaue Info-Meldung.
- `log_success "Nachricht"`: Grüne Erfolgsmeldung (`[✓]`).
- `log_warn "Nachricht"`: Gelbe Warnung (`[WARN]`).
- `log_error "Nachricht"`: Rote Fehlermeldung (`[ERROR]`).
- `log_step "Titel"`: Hervorgehobener Abschnitts-Header.
- `log_substep "Titel"`: Eingerückter Unterabschnitt.
- `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.
- `get_target_home [username]`: Gibt den absoluten Pfad des Home-Verzeichnisses des Nutzers zurück.
- `run_as_user "command"`: Führt einen Befehl als `$TARGET_USER` via `su - "$TARGET_USER" -c ...` aus.
- `backup_file "filepath"`: Erstellt ein Backup einer Datei mit Zeitstempel.
### `lib/apt.sh`
- `safe_apt_update`: Führt ein abgesichertes `apt-get update` durch.
- `install_apt_keyring "name" "url"`: Lädt einen GPG-Schlüssel herunter, de-armort ihn sauber und speichert ihn in `/etc/apt/keyrings/<name>.gpg`.
- `install_packages_from_file "filepath"`: Liest eine `.list`-Datei ein (ignoriert Kommentare `#` und Leerzeilen) und installiert alle Pakete via `apt-get install -y`.
### `lib/tui.sh`
- `tui_show_stage_selection`: Zeigt ein `whiptail` Checklist-Menü zur interaktiven Auswahl der auszuführenden Phasen.
---
## 5. Arbeitsanweisungen für Modifikationen
### Neue Phase (Stage) hinzufügen
1. Erstelle eine neue Datei `stages/XX-<name>.sh` (nummeriert nach Reihenfolge, mit `chmod +x`).
2. Nutze das Standard-Template:
```bash
#!/usr/bin/env bash
# ==============================================================================
# stages/XX-<name>.sh - Kurzbeschreibung der Phase
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/utils.sh
source "$SCRIPT_DIR/../lib/utils.sh"
setup_err_trap
require_root
log_step "Stage XX: <Name der Phase>"
TARGET_USER="${TARGET_USER:-$(prompt_target_user)}"
TARGET_HOME="$(get_target_home "$TARGET_USER")"
# Implementierung (idempotent) ...
log_success "Stage XX abgeschlossen."
```
3. Registriere die neue Phase im Orchestrator `setup.sh` (Hilfetext `show_help`, Validierung in `run_stages`).
4. Ergänze die Phase im TUI-Auswahlmenü in `lib/tui.sh`.
5. Aktualisiere `README.md`.
### Paketlisten anpassen
- Paketdateien liegen unter `config/packages/<kategorie>.list`.
- Jede Zeile enthält genau einen Paketnamen.
- Kommentare beginnen mit `#`. Leerzeilen sind erlaubt.
### Vorlagen und Skel-Dateien hinzufügen
- Konfigurationsvorlagen für neue Benutzer gehören in `data/skel/`.
- Dateivorlagen für den Dateimanager (XDG Templates) gehören nach `data/skel/Templates/`.
---
## 6. Verifikation & Qualitätssicherung
Bevor Änderungen eingecheckt oder abgeschlossen werden:
1. **ShellCheck ausführen**:
Alle Bash-Skripte auf statische Fehler und Warnungen prüfen:
```bash
shellcheck setup.sh lib/*.sh stages/*.sh
```
2. **Dry-Run Validierung**:
Sicherstellen, dass der Orchestrator im Simulationsmodus funktioniert:
```bash
./setup.sh --dry-run --stages 00,01,02
```
3. **Syntaxprüfung**:
```bash
bash -n setup.sh
for f in lib/*.sh stages/*.sh; do bash -n "$f"; done
```
4. **Pfad- und Berechtigungskonsistenz**:
Prüfen, dass keine absoluten Pfade auf Benutzerverzeichnisse (`/home/...`) hartcodiert sind.
+115 -56
View File
@@ -1,71 +1,130 @@
# Setup # Debian Unstable (Sid) & Hyprland Setup Framework
## Übersicht Ein modulares, sicheres und erweiterbares Framework zur automatisierten Einrichtung von **Debian GNU/Linux Unstable (Sid)** mit Hyprland Desktop, XanMod-Kernel, Hardware-Tuning und thematisch gegliederten Anwendungen.
Dieses Repository enthält Skripte um ein Linux System mit Hyprland und diversen Programmen aufzusetzen. ---
Die entsprechenden Skripte befinden sich in den Branches zur jeweiligen Distribution.
Der Hauptbranch ist für ein aktuelles Debian-System gedacht! ## 🚀 Schnellstart
## Anforderungen ### 1. Interaktiver TUI-Modus (Empfohlen)
Starte das grafische Terminal-Menü (`whiptail`) zur flexiblen Auswahl einzelner Module:
Um die Skripte in diesem Repository auszuführen, stelle sicher, dass die folgenden Voraussetzungen erfüllt sind:
- Die Skripte sind als bash-Skripte konzipiert.
- Für die Skripte muss der richtige Branch der jewiligen Distribution ausgewählt werden.
- Daten werden vor der Ausführung nicht gesichert. Datenverlust möglich!
## Nutzung
1. Klone das Repository:
```bash ```bash
git clone https://gitea.creative-dragonslayer.de/Scripts/Setup.git sudo ./setup.sh
``` ```
2. Wechsle in den richtigen Branch.
3. Navigiere in das Verzeichnis `Setup`, um die ausführbaren Dateien und Ressourcen zu finden.
4. Folge den spezifischen Anweisungen in einzelnen Dateien oder Skripten für die korrekte Ausführung.
## Nach der Nutzung ### 2. Vollautomatischer CLI-Modus
### Für AMD-CPUs Führe alle Phasen (`00` bis `09`) ohne Interaktion aus:
#### Game-Launchparameter
```bash ```bash
GLOBAL — All games: sudo ./setup.sh --all
RADV_PERFTEST=gpl,rt DXVK_ASYNC=1 VKD3D_CONFIG=dxr,dxr11 MESA_VK_WSI_PRESENT_MODE=mailbox gamemoderun gamescope -W 2560 -H 1440 --force-grab-cursor --hdr-enabled --adaptive-sync -f -o 240 -r 240 -- mangohud %command% ```
DEMANDING GAMES — No RT: ### 3. Gezielte Modulauswahl
RADV_PERFTEST=gpl,ngg_streamout WINE_FULLSCREEN_FSR=1 DXVK_ASYNC=1 gamemoderun gamescope -W 2560 -H 1440 --force-grab-cursor --hdr-enabled --adaptive-sync -f -o 240 -r 240 -- mangohud %command% Installiere nur bestimmte Phasen (z. B. nur Paketlisten und Schriften):
```bash
sudo ./setup.sh --stages 04,05
```
RAY TRACING — DX12 titles: ### 4. Simulationslauf (Dry-Run)
Überprüfe geplante Aktionen, ohne Änderungen am System vorzunehmen:
```bash
./setup.sh --dry-run --stages 01,02,04
```
---
## 🛠️ CLI-Optionen
| Option | Argument | Beschreibung |
| :--- | :--- | :--- |
| `-a`, `--all` | | Führt alle Phasen (`00` bis `09`) sequenziell aus |
| `-s`, `--stages` | `<01,02,...>` | Kommagetrennte Liste der auszuführenden Phasen |
| `-u`, `--user` | `<username>` | Zielbenutzer für Userland/Dotfiles (Standard: `$SUDO_USER` mit Bestätigungsabfrage) |
| `-d`, `--dry-run` | | Simuliert die Ausführung ohne Systemänderungen |
| `-h`, `--help` | | Zeigt die Hilfe und alle verfügbaren Stages an |
---
## 📁 Projektstruktur
```
.
├── setup.sh # Zentraler Orchestrator (CLI Flags & whiptail TUI)
├── lib/ # Wiederverwendbare Hilfsbibliotheken
│ ├── utils.sh # Logging, Error-Traps (set -euo pipefail), Root/User-Erkennung & Abfrage
│ ├── apt.sh # APT-Keyring-Management (/etc/apt/keyrings/), Deb822, Pinning
│ └── tui.sh # Whiptail-Menüs und Dialoge
├── config/ # Konfigurationsdateien & Paketlisten
│ ├── setup.conf # Globale Variablen (Kernel, GRUB-Theme, Plymouth)
│ └── packages/ # Thematische Paketlisten
│ ├── 01-base.list # Grundlegende Systemwerkzeuge, Firmware, Microcode
│ ├── 02-desktop.list # Hyprland, Waybar, SDDM, Portale, Pipewire
│ ├── 03-gaming.list # Steam-Devices, Lutris, Gamescope, MangoHud, Wine
│ ├── 04-virtualization.list # QEMU, KVM, Libvirt, Bridge-Tools
│ ├── 05-multimedia.list # VLC, Amberol, GIMP, Loupe, LibreOffice
│ └── 06-flatpaks.list # Flatpak App-IDs & Flathub
├── stages/ # Sequenzielle, modular ausführbare Phasen
│ ├── 00-preflight.sh # Prüfung von Rechten, Ziel-User ($SUDO_USER) und Internet
│ ├── 01-apt-unstable.sh # Deb822-Quellen, Keyrings, Pinning, apt-listbugs, dist-upgrade
│ ├── 02-kernel-hardware.sh # XanMod-Kernel (main/edge), CPU P-State, Microcode, auto-cpufreq (Source)
│ ├── 03-bootloader.sh # GRUB Kernel-Parameter, Vimix-Theme, Plymouth Solar
│ ├── 04-packages.sh # Installation der ausgewählten thematischen Paketlisten
│ ├── 05-fonts.sh # Download & Installation von JetBrainsMono, Fantasque, VictorMono
│ ├── 06-services.sh # Aktivierung von AppArmor, Docker, Libvirt, zram
│ ├── 07-skel-and-user.sh # /etc/skel Vorlagen, ZSH-Shell-Setzen, Dotfiles-Sync
│ ├── 08-flatpaks-apps.sh # Flathub Setup, Flatpaks, Spotify, Waydroid, MIME-Types
│ └── 09-hyprland.sh # LinuxBeginnings Debian-Hyprland Auto-Installer & Dotfiles
└── data/ # Statische Konfigurationsdateien & Vorlagen
├── apt/
│ ├── sources.list.d/ # debian-unstable.sources, xanmod.sources
│ └── preferences.d/ # Pinning-Konfigurationen (unstable, xanmod)
├── etc/
│ ├── environment.d/ # 99-raytracing.conf, 99-upscaling.conf
│ └── profile.d/ # Bereinigte System-Profile-Skripte
├── skel/ # .zshrc, Templates für Dokumente & Skripte
└── usr/share/applications/ # Desktop-Dateien (z. B. Spotify)
```
---
## 🔒 Sicherheits- & Stabilitätsmerkmale
1. **Rechte- und Nutzertrennung**:
- Automatische Erkennung des regulären Desktop-Benutzers via `$SUDO_USER` / interactivem Fallback.
- Benutzerkonfigurationen und Gruppenrechte (`sudo`, `docker`, `libvirt`) werden sauber für den Zielbenutzer gesetzt.
2. **Keine gefährlichen Login-Hooks**:
- Vollständige Beseitigung unkontrollierter Live-Downloads (`curl | sh`) beim Login.
- Standardkonforme Bereitstellung über `/etc/skel` für neue und bestehende Benutzer.
3. **Idempotenz & Backups**:
- Alle Phasen können beliebig oft wiederholt werden.
- Vorhandene Dotfiles (`~/.zshrc`) und Konfigurationen (`/etc/default/grub`) werden vor Änderungen automatisch mit Zeitstempel (`.backup_YYYYMMDD_HHMMSS`) gesichert.
4. **Debian Unstable Absicherung**:
- Moderne Deb822-Quellen und dedizierte Keyrings in `/etc/apt/keyrings/`.
- Installation von `apt-listbugs` und `apt-listchanges` vor dem `dist-upgrade` schützt vor bekannten kritischen Paketproblemen.
5. **Sichere Shell-Verwaltung**:
- Standardkonforme Änderung der Login-Shell via `chsh -s` statt direkter `/etc/passwd`-Modifikation.
---
## 🎮 Gaming & Performance-Optimierungen
### 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`
- **Intel CPUs**: `intel_pstate=active`
- **Latenz-Optimierung**: `rcutree.rcu_idle_gp_delay=1 threadirqs`
### Game Launch-Parameter (Steam / Lutris)
```bash
# Standard Gaming Launch-Optionen mit MangoHud & Gamescope
gamemoderun gamescope -W 2560 -H 1440 --force-grab-cursor --hdr-enabled --adaptive-sync -f -o 240 -r 240 -- mangohud %command%
# 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%
MAXIMUM RT PERFORMANCE — with FSR:
RADV_PERFTEST=gpl,rt,ngg_streamout VKD3D_CONFIG=dxr,dxr11 DXVK_ASYNC=1 AMD_VULKAN_ICD=RADV WINE_FULLSCREEN_FSR=1 gamemoderun gamescope -W 2560 -H 1440 --force-grab-cursor --hdr-enabled --adaptive-sync -f -o 240 -r 240 -- mangohud %command%
``` ```
#### Parameter in /etc/environment.d/99-raytracing.conf ---
```bash
# AMD RDNA Ray Tracing Optimisations
RADV_PERFTEST=gpl,rt,ngg_streamout
VKD3D_CONFIG=dxr,dxr11
DXVK_ASYNC=1
AMD_VULKAN_ICD=RADV
mesa_glthread=true
MESA_VK_WSI_PRESENT_MODE=mailbox
```
#### Parameter in /etc/environment.d/99-upscaling.conf ## 📜 Lizenz & Autor
```bash
# AMD FSR 4 + FSR 3 Upscaling — March 2026
# FSR 4: use PROTON_FSR4_UPGRADE=1 launch option (RDNA4=native, RDNA3=fallback)
WINE_FULLSCREEN_FSR=1
WINE_FULLSCREEN_FSR_STRENGTH=2
MESA_VK_WSI_PRESENT_MODE=mailbox
```
## Lizenz - **Lizenz**: MIT License (siehe `LICENSE`)
- **Autor**: DragonSlayer_14
Dieses Projekt steht unter einer Open-Source-Lizenz. Weitere Informationen findest du in der Datei `LICENSE`.
## Autor
Erstellt und gepflegt von DragonSlayer_14.
+62
View File
@@ -0,0 +1,62 @@
# ==============================================================================
# config/packages/01-base.list - Base system utilities, firmware, shell & diagnostics
# ==============================================================================
7zip
adb
apparmor
apparmor-notify
apparmor-profiles
apparmor-profiles-extra
apparmor-utils
aptitude
baobab
bat
bleachbit
bluetooth
blueman
bluez
btop
ca-certificates
clamav
clamav-daemon
command-not-found
cryptomator
curl
dconf-editor
debian-goodies
fastfetch
file-roller
firmware-linux
firmware-linux-nonfree
firmware-misc-nonfree
flatpak
flatseal
fzf
glances
gnome-disk-utility
gnome-firmware
gnome-logs
gnome-system-monitor
gparted
htop
hunspell
hunspell-de-de-frami
irqbalance
keepassxc
lsd
man
network-manager-gnome
rfkill
ripgrep
rpi-imager
shellcheck
systemd-timesyncd
tar
tealdeer
timeshift
tree
unrar
unzip
zram-tools
zsh
+34
View File
@@ -0,0 +1,34 @@
# ==============================================================================
# config/packages/02-desktop.list - Wayland/Hyprland desktop, display manager & tools
# ==============================================================================
cava
dconf-editor
flameshot
gnome-calculator
gnome-decoder
gnome-font-viewer
gnome-keyring
gnome-snapshot
gnome-text-editor
grim
impression
input-remapper
localsend
nodejs
nwg-displays
nwg-look
obfuscate
pipewire
pipewire-pulse
sddm
slurp
speech-dispatcher
swappy
swaybg
thunar
wayland-utils
wireplumber
wl-clipboard
xdg-user-dirs
yazi
+19
View File
@@ -0,0 +1,19 @@
# ==============================================================================
# config/packages/03-gaming.list - Gaming tools, Vulkan drivers, Wine & Emulation
# ==============================================================================
gameconqueror
gamemode
gamescope
mangohud
mangoapp
mesa-utils
mesa-vulkan-drivers
openrgb
prismlauncher
protontricks
radeontop
steam-devices
vulkan-tools
wine
winetricks
+10
View File
@@ -0,0 +1,10 @@
# ==============================================================================
# config/packages/04-virtualization.list - QEMU, KVM & Libvirt packages
# ==============================================================================
bridge-utils
libvirt-clients
libvirt-daemon-system
qemu-system-x86
qemu-utils
virt-manager
+22
View File
@@ -0,0 +1,22 @@
# ==============================================================================
# config/packages/05-multimedia.list - Audio, Video, Graphics & Productivity
# ==============================================================================
amberol
easyeffects
ffmpeg
gimp
libreoffice
libreoffice-gtk4
libreoffice-l10n-de
loupe
simple-scan
vlc
vlc-data
vlc-l10n
vlc-plugin-access-extra
vlc-plugin-base
vlc-plugin-notify
vlc-plugin-pipewire
vlc-plugin-qt
vlc-plugin-video-output
+23
View File
@@ -0,0 +1,23 @@
# ==============================================================================
# config/packages/06-flatpaks.list - Flathub Flatpak Application IDs
# ==============================================================================
# Communication & Productivity
eu.betterbird.Betterbird
im.fluffychat.Fluffychat
org.pvermeer.WebAppHub
io.github.giantpinkrobots.flatsweep
# Creativity & AI
org.musescore.MuseScore
com.jeffser.Alpaca
# Gaming & Compatibility
com.valvesoftware.Steam
com.heroicgameslauncher.hgl
net.lutris.Lutris
org.freedesktop.Platform.VulkanLayer.gamescope
org.freedesktop.Platform.VulkanLayer.MangoHud
com.valvesoftware.Steam.CompatibilityTool.Proton-GE
net.davidotek.pupgui2
io.github.rfrench3.scopebuddy-gui
+20
View File
@@ -0,0 +1,20 @@
# ==============================================================================
# config/setup.conf - Configuration parameters for Debian Unstable Setup
# ==============================================================================
# Kernel & Hardware
# XanMod branches: "main" (stable & recommended), "edge" (bleeding-edge), "lts" (long-term support), "rt" (real-time)
XANMOD_BRANCH="main"
CPU_PSTATE_AUTO=1
# Bootloader & Appearance
GRUB_THEME="vimix"
PLYMOUTH_THEME="solar"
GRUB_TIMEOUT=0
GRUB_TIMEOUT_STYLE="hidden"
# Shell & Userland
DEFAULT_SHELL="zsh"
# Default Stages (if --all is passed or in default batch mode)
ALL_STAGES="00 01 02 03 04 05 06 07 08 09"
+7
View File
@@ -0,0 +1,7 @@
Package: *
Pin: release a=unstable
Pin-Priority: 900
Package: *
Pin: release a=experimental
Pin-Priority: 100
+3
View File
@@ -0,0 +1,3 @@
Package: *
Pin: origin deb.xanmod.org
Pin-Priority: 900
+5
View File
@@ -0,0 +1,5 @@
Types: deb
URIs: http://deb.xanmod.org
Suites: releases
Components: main
Signed-By: /etc/apt/keyrings/xanmod-archive-keyring.gpg
@@ -0,0 +1,3 @@
# Raytracing support environment flags for RADV / Mesa
VKD3D_CONFIG=dxr11,dxr
RADV_PERFTEST=rt
+3
View File
@@ -0,0 +1,3 @@
# Upscaling and gaming enhancement variables
WINE_FULLSCREEN_FSR=1
WINE_FULLSCREEN_FSR_STRENGTH=2
@@ -1,3 +1,5 @@
#!/bin/bash #!/bin/sh
# Update XDG User Dirs if tool is present
if command -v xdg-user-dirs-update >/dev/null 2>&1; then
xdg-user-dirs-update xdg-user-dirs-update
fi
-33
View File
@@ -1,33 +0,0 @@
#!/bin/bash
DEFAULT_USR_FOLDER="/usr/share/debian-gaming/home"
CONFIG_FOLDER="$HOME/.config/"
CHECK_FILE="$HOME/.config/.debian_gaming_configs_copied"
TEMPLATES_DIR=$(xdg-user-dir TEMPLATES 2>/dev/null || echo "$HOME/Templates")
if [ ! -e "$CHECK_FILE" ]; then
if [ -d "$DEFAULT_USR_FOLDER" ]; then
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
if [ -e "$HOME/.config" ]; then
mv $HOME/.config $HOME/.config.bak
fi
if [ -e "$HOME/.zshrc" ]; then
mv $HOME/.zshrc $HOME/.zshrc.bak
fi
mkdir -p $HOME/.config
cp -r $DEFAULT_USR_FOLDER/.config/* $HOME/.config
cp -r $DEFAULT_USR_FOLDER/templates/* $TEMPLATES_DIR
cp $DEFAULT_USR_FOLDER/zshrc $HOME/.zshrc
touch $CHECK_FILE
fi
fi
+9 -2
View File
@@ -1,3 +1,10 @@
for app in ~/.local/share/applications/waydroid.*.desktop; do #!/bin/sh
grep -q NoDisplay $app || sed '/^Icon=/a NoDisplay=true' -i $app # Hide Waydroid desktop applications from standard desktop menus
if [ -d "$HOME/.local/share/applications" ]; then
for app in "$HOME"/.local/share/applications/waydroid.*.desktop; do
[ -f "$app" ] || continue
if ! grep -q "NoDisplay" "$app"; then
sed -i '/^Icon=/a NoDisplay=true' "$app" 2>/dev/null || true
fi
done done
fi
+3 -1
View File
@@ -1,4 +1,6 @@
if groups | grep -q "\bsudo\b"; then #!/bin/sh
# Add sbin and /usr/sbin to PATH for sudoers if not already present
if groups 2>/dev/null | grep -q "\bsudo\b"; then
case ":$PATH:" in case ":$PATH:" in
*":/sbin:"*) ;; *":/sbin:"*) ;;
*) export PATH="$PATH:/sbin" ;; *) export PATH="$PATH:/sbin" ;;
+7 -8
View File
@@ -1,18 +1,18 @@
#!/bin/bash #!/bin/sh
# Display sudo reminder for administrative users once after initial setup
SUDO_FILE="$HOME/.sudo_as_admin_successful" SUDO_FILE="$HOME/.sudo_as_admin_successful"
HUSH_FILE="$HOME/.hushlogin" HUSH_FILE="$HOME/.hushlogin"
ONE_WEEK_AGO=$(date -d '7 days ago' +%s)
if [ -e "$SUDO_FILE" ]; then if [ -f "$SUDO_FILE" ]; then
FILE_MOD_TIME=$(stat -c %Y "$SUDO_FILE") FILE_MOD_TIME=$(stat -c %Y "$SUDO_FILE" 2>/dev/null || echo 0)
if [ "$FILE_MOD_TIME" -lt "$ONE_WEEK_AGO" ]; then ONE_WEEK_AGO=$(date -d '7 days ago' +%s 2>/dev/null || echo 0)
if [ "$FILE_MOD_TIME" -gt 0 ] && [ "$ONE_WEEK_AGO" -gt 0 ] && [ "$FILE_MOD_TIME" -lt "$ONE_WEEK_AGO" ]; then
rm -f "$SUDO_FILE" rm -f "$SUDO_FILE"
fi fi
fi fi
if [ ! -e "$SUDO_FILE" ] && [ ! -e "$HUSH_FILE" ]; then if [ ! -e "$SUDO_FILE" ] && [ ! -e "$HUSH_FILE" ]; then
case " $(groups) " in case " $(groups 2>/dev/null) " in
*\ admin\ *|*\ sudo\ *) *\ admin\ *|*\ sudo\ *)
if [ -x /usr/bin/sudo ]; then if [ -x /usr/bin/sudo ]; then
echo 'To run a command as administrator (user "root"), use "sudo <command>".' echo 'To run a command as administrator (user "root"), use "sudo <command>".'
@@ -21,4 +21,3 @@ if [ ! -e "$SUDO_FILE" ] && [ ! -e "$HUSH_FILE" ]; then
;; ;;
esac esac
fi fi
-49
View File
@@ -1,49 +0,0 @@
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
export ZSH="$HOME/.oh-my-zsh"
apt_pref='apt'
apt_upgr='upgrade'
ZSH_THEME="agnosterzak"
plugins=(
alias-finder
aliases
colored-man-pages
command-not-found
common-aliases
composer
cp
debian
docker
git
jsontools
kitty
python
ssh
symfony
themes
vscode
zsh-autosuggestions
zsh-syntax-highlighting
)
source $ZSH/oh-my-zsh.sh
# Display Pokemon-colorscripts
# Project page: https://gitlab.com/phoneybadger/pokemon-colorscripts#on-other-distros-and-macos
#pokemon-colorscripts --no-title -s -r #without fastfetch
#pokemon-colorscripts --no-title -s -r | fastfetch -c $HOME/.config/fastfetch/config-pokemon.jsonc --logo-type fi>
# fastfetch. Will be disabled if above colorscript was chosen to install
fastfetch -c $HOME/.config/fastfetch/config-compact.jsonc
# Set-up icons for files/directories in terminal using lsd
alias ls='lsd'
alias l='ls -l'
alias la='ls -a'
alias lla='ls -la'
alias lt='ls --tree'
+54
View File
@@ -0,0 +1,54 @@
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
export ZSH="$HOME/.oh-my-zsh"
apt_pref='apt'
apt_upgr='upgrade'
ZSH_THEME="agnosterzak"
plugins=(
alias-finder
aliases
colored-man-pages
command-not-found
common-aliases
composer
cp
debian
docker
git
jsontools
kitty
python
ssh
symfony
themes
vscode
zsh-autosuggestions
zsh-syntax-highlighting
)
# Oh-My-Zsh configuration
if [[ -d "$ZSH" && -f "$ZSH/oh-my-zsh.sh" ]]; then
source "$ZSH/oh-my-zsh.sh"
fi
# Fastfetch system info banner
if command -v fastfetch >/dev/null 2>&1; then
if [[ -f "$HOME/.config/fastfetch/config-compact.jsonc" ]]; then
fastfetch -c "$HOME/.config/fastfetch/config-compact.jsonc"
else
fastfetch
fi
fi
# Aliases using modern tools with fallback
if command -v lsd >/dev/null 2>&1; then
alias ls='lsd'
alias l='ls -l'
alias la='ls -a'
alias lla='ls -la'
alias lt='ls --tree'
fi
Executable
+140
View File
@@ -0,0 +1,140 @@
#!/usr/bin/env bash
# ==============================================================================
# lib/apt.sh - APT, Deb822, GPG Keyring and Package installation utilities
# ==============================================================================
set -euo pipefail
APT_KEYRINGS_DIR="/etc/apt/keyrings"
APT_SOURCES_DIR="/etc/apt/sources.list.d"
APT_PREFERENCES_DIR="/etc/apt/preferences.d"
# Ensure the standard keyring directory exists
apt_ensure_keyrings_dir() {
if [[ ! -d "$APT_KEYRINGS_DIR" ]]; then
log_info "Creating keyrings directory: $APT_KEYRINGS_DIR"
mkdir -p "$APT_KEYRINGS_DIR"
chmod 0755 "$APT_KEYRINGS_DIR"
fi
}
# Download and install a GPG key into /etc/apt/keyrings/
# Usage: apt_add_keyring_from_url "https://example.com/key.gpg" "example.gpg"
apt_add_keyring_from_url() {
local url="$1"
local keyring_filename="$2"
local dest_path="$APT_KEYRINGS_DIR/$keyring_filename"
apt_ensure_keyrings_dir
log_substep "Fetching GPG keyring from: $url -> $dest_path"
local tmp_key
tmp_key="$(mktemp /tmp/apt-key.XXXXXX)"
if curl -fsSL "$url" -o "$tmp_key"; then
# Check if the key is ASCII armored or binary
if gpg --dry-run --quiet --import "$tmp_key" >/dev/null 2>&1; then
if file "$tmp_key" | grep -q "PGP public key block"; then
gpg --dearmor -o "$dest_path" < "$tmp_key" 2>/dev/null || cp "$tmp_key" "$dest_path"
else
cp "$tmp_key" "$dest_path"
fi
chmod 0644 "$dest_path"
log_success "Keyring installed: $dest_path"
else
# If gpg check fails, fallback to direct copy if non-empty
if [[ -s "$tmp_key" ]]; then
cp "$tmp_key" "$dest_path"
chmod 0644 "$dest_path"
log_success "Keyring installed (raw): $dest_path"
else
log_error "Downloaded key from $url is empty or invalid."
rm -f "$tmp_key"
return 1
fi
fi
rm -f "$tmp_key"
else
rm -f "$tmp_key"
log_error "Failed to download GPG key from $url"
return 1
fi
}
# Install Deb822 sources file
# Usage: apt_install_sources_file "/path/to/source.sources" "debian-unstable.sources"
apt_install_sources_file() {
local src_path="$1"
local dest_name="$2"
local dest_path="$APT_SOURCES_DIR/$dest_name"
if [[ ! -f "$src_path" ]]; then
log_error "Source file does not exist: $src_path"
return 1
fi
mkdir -p "$APT_SOURCES_DIR"
cp "$src_path" "$dest_path"
chmod 0644 "$dest_path"
log_success "Installed APT Deb822 source: $dest_path"
}
# Install APT preferences file
# Usage: apt_install_preference_file "/path/to/pinning.pref" "99-custom.pref"
apt_install_preference_file() {
local src_path="$1"
local dest_name="$2"
local dest_path="$APT_PREFERENCES_DIR/$dest_name"
if [[ ! -f "$src_path" ]]; then
log_error "Preference file does not exist: $src_path"
return 1
fi
mkdir -p "$APT_PREFERENCES_DIR"
cp "$src_path" "$dest_path"
chmod 0644 "$dest_path"
log_success "Installed APT preference: $dest_path"
}
# Update APT package indexes
apt_update() {
log_step "Updating APT package indexes..."
DEBIAN_FRONTEND=noninteractive apt-get update -y
}
# Dist-upgrade system
apt_dist_upgrade() {
log_step "Upgrading system packages (dist-upgrade)..."
DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y
}
# Install packages from a .list file
# Usage: apt_install_package_list_file "/path/to/packages.list"
apt_install_package_list_file() {
local list_file="$1"
if [[ ! -f "$list_file" ]]; then
log_error "Package list file not found: $list_file"
return 1
fi
local -a pkgs=()
while IFS= read -r line || [[ -n "$line" ]]; do
# Trim leading/trailing whitespace
line="$(echo "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
# Skip empty lines and comment lines
[[ -z "$line" || "$line" =~ ^# ]] && continue
pkgs+=("$line")
done < "$list_file"
if [[ ${#pkgs[@]} -eq 0 ]]; then
log_info "No packages to install from $list_file"
return 0
fi
log_info "Installing ${#pkgs[@]} packages from $(basename "$list_file")..."
DEBIAN_FRONTEND=noninteractive apt-get install -y "${pkgs[@]}"
log_success "Installed packages from $(basename "$list_file")"
}
Executable
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# ==============================================================================
# lib/tui.sh - Interactive Whiptail TUI dialogs and checklists
# ==============================================================================
set -euo pipefail
# Check if whiptail is available
tui_check_whiptail() {
if ! command_exists whiptail; then
log_warn "whiptail is not installed. Attempting to install whiptail..."
DEBIAN_FRONTEND=noninteractive apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y whiptail
fi
}
# Display welcome message
tui_welcome() {
whiptail --title "Debian Unstable Setup & Hyprland Installer" \
--msgbox "Willkommen beim Debian Unstable & Desktop Setup!\n\nDieses Skript führt dich durch die modulare Einrichtung deines Debian Sid Systems mit XanMod-Kernel, Hyprland und Optimierungen.\n\nDrücke ENTER um zur Modulauswahl zu gelangen." \
14 70
}
# Present stage checklist to user
# Returns space-separated list of selected stage numbers (e.g., "01 02 03 04 05 06 07 08 09")
tui_select_stages() {
local choices
choices=$(whiptail --title "Modulauswahl / Stages" \
--checklist "Wähle die gewünschten Installations-Phasen mit der LEERTASTE aus:" \
22 78 9 \
"01" "Debian Unstable (Deb822, Pinning, Upgrade)" ON \
"02" "Kernel & Hardware (XanMod, P-State, Microcode)" ON \
"03" "Bootloader & Theme (GRUB, Vimix, Plymouth)" ON \
"04" "Pakete (Base, Desktop, Gaming, Virtualisierung)" ON \
"05" "Coding & Nerd Fonts (JetBrainsMono, VictorMono)" ON \
"06" "System-Dienste (AppArmor, Docker, Libvirt, zram)" ON \
"07" "Userland & Skel (Zsh, Skel-Templates, Dotfiles)" ON \
"08" "Flatpaks & Apps (Flathub, Flatpaks, MIME)" ON \
"09" "Hyprland Desktop (LinuxBeginnings Installer)" ON \
3>&1 1>&2 2>&3) || {
log_info "Setup durch Benutzer abgebrochen."
exit 0
}
# Clean quotes from whiptail output (e.g. '"01" "02"' -> '01 02')
local cleaned_choices
cleaned_choices=$(echo "$choices" | tr -d '"')
echo "$cleaned_choices"
}
# Prompt user for target user via Whiptail dialog
tui_prompt_target_user() {
local default_user="${1:-}"
local chosen=""
if [[ -n "$default_user" && "$default_user" != "root" ]]; then
if whiptail --title "Ziel-Benutzer bestätigen" \
--yes-button "Verwenden" \
--no-button "Anderer Benutzer" \
--yesno "Erkannter Ziel-Benutzer: $default_user\n\nMöchtest du diesen Benutzer für die Konfiguration (Dotfiles, Gruppen, Hyprland) verwenden?" \
10 65; then
chosen="$default_user"
fi
fi
while [[ -z "$chosen" ]]; do
local input_user
input_user=$(whiptail --title "Ziel-Benutzer eingeben" \
--inputbox "Bitte gib den Benutzernamen des Desktop-Benutzers ein:" \
10 60 "$default_user" \
3>&1 1>&2 2>&3) || {
log_info "Setup durch Benutzer abgebrochen."
exit 0
}
input_user="$(echo "$input_user" | tr -d '[:space:]')"
if [[ -z "$input_user" || "$input_user" == "root" ]]; then
whiptail --title "Ungültiger Benutzer" --msgbox "Ungültiger Benutzername (darf nicht leer oder root sein)." 8 50
continue
fi
if ! id "$input_user" >/dev/null 2>&1; then
whiptail --title "Benutzer nicht gefunden" --msgbox "Benutzer '$input_user' existiert nicht im System." 8 50
continue
fi
chosen="$input_user"
done
export TARGET_USER="$chosen"
echo "$chosen"
}
# Confirmation dialog before running
tui_confirm_execution() {
local selected_stages="$1"
local target_user="$2"
whiptail --title "Installation starten" \
--yesno "Folgende Konfiguration wird ausgeführt:\n\n- Ziel-Benutzer: $target_user\n- Ausgewählte Stages: $selected_stages\n\nMöchtest du die Installation jetzt starten?" \
14 70
}
Executable
+212
View File
@@ -0,0 +1,212 @@
#!/usr/bin/env bash
# ==============================================================================
# lib/utils.sh - Common utilities, logging, error handling & user detection
# ==============================================================================
set -euo pipefail
# ANSI Color Codes
export CLR_RESET='\033[0m'
export CLR_BOLD='\033[1m'
export CLR_DIM='\033[2m'
export CLR_RED='\033[0;31m'
export CLR_GREEN='\033[0;32m'
export CLR_YELLOW='\033[0;33m'
export CLR_BLUE='\033[0;34m'
export CLR_MAGENTA='\033[0;35m'
export CLR_CYAN='\033[0;36m'
export CLR_WHITE='\033[0;37m'
# Disable colors if not running in a terminal
if [[ ! -t 1 ]]; then
CLR_RESET=""
CLR_BOLD=""
CLR_DIM=""
CLR_RED=""
CLR_GREEN=""
CLR_YELLOW=""
CLR_BLUE=""
CLR_MAGENTA=""
CLR_CYAN=""
CLR_WHITE=""
fi
# Logging functions
log_info() {
printf "${CLR_BLUE}[INFO]${CLR_RESET} %s\n" "$*"
}
log_success() {
printf "${CLR_GREEN}[✓]${CLR_RESET} %s\n" "$*"
}
log_warn() {
printf "${CLR_YELLOW}[WARN]${CLR_RESET} %s\n" "$*" >&2
}
log_error() {
printf "${CLR_RED}[ERROR]${CLR_RESET} %s\n" "$*" >&2
}
log_step() {
printf "\n${CLR_BOLD}${CLR_CYAN}==>${CLR_RESET} ${CLR_BOLD}%s${CLR_RESET}\n" "$*"
}
log_substep() {
printf " ${CLR_CYAN}->${CLR_RESET} %s\n" "$*"
}
# Error trap handler
setup_err_trap() {
trap 'error_handler $? $LINENO "$BASH_COMMAND"' ERR
}
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'"
exit "$exit_code"
}
# Root permission check
require_root() {
if [[ "$(id -u)" -ne 0 ]]; then
log_error "This script must be run as root (or via sudo)!"
exit 1
fi
}
# Check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Determine and prompt for the non-root target user
prompt_target_user() {
if [[ -n "${TARGET_USER:-}" ]]; then
echo "$TARGET_USER"
return 0
fi
local candidate=""
if [[ -n "${SUDO_USER:-}" && "${SUDO_USER}" != "root" ]]; then
candidate="$SUDO_USER"
elif [[ -n "${PKEXEC_UID:-}" ]]; then
candidate="$(id -nu "$PKEXEC_UID" 2>/dev/null || true)"
elif [[ "$(id -u)" -ne 0 ]]; then
candidate="$(id -un)"
fi
# If candidate is still empty or root, try to detect the first normal user with UID >= 1000
if [[ -z "$candidate" || "$candidate" == "root" ]]; then
candidate="$(awk -F: '$3 >= 1000 && $3 < 60000 && $1 != "nobody" {print $1; exit}' /etc/passwd 2>/dev/null || true)"
fi
local chosen=""
local is_interactive=0
if [[ -t 0 || -c /dev/tty ]] && [[ "${DEBIAN_FRONTEND:-}" != "noninteractive" && "${CI:-}" != "1" && "${AUTO_CONFIRM:-}" != "1" ]]; then
is_interactive=1
fi
if [[ "$is_interactive" -eq 1 ]]; then
local tty_in="/dev/tty"
local tty_out="/dev/tty"
if [[ ! -c /dev/tty ]]; then
tty_in="/dev/stdin"
tty_out="/dev/stderr"
fi
if [[ -n "$candidate" && "$candidate" != "root" ]]; then
printf "\n${CLR_CYAN}Target User Detection:${CLR_RESET}\n" > "$tty_out"
printf "Detected target user: ${CLR_BOLD}%s${CLR_RESET}\n" "$candidate" > "$tty_out"
local answer=""
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"
fi
fi
while [[ -z "$chosen" ]]; do
local input_user=""
read -r -p "Please enter the target desktop username: " input_user < "$tty_in" > "$tty_out" 2>&1 || true
input_user="$(echo "$input_user" | tr -d '[:space:]')"
if [[ -z "$input_user" ]]; then
printf "${CLR_YELLOW}Username cannot be empty.${CLR_RESET}\n" > "$tty_out"
continue
fi
if [[ "$input_user" == "root" ]]; then
printf "${CLR_YELLOW}Root cannot be used as target desktop user.${CLR_RESET}\n" > "$tty_out"
continue
fi
if ! id "$input_user" >/dev/null 2>&1; then
printf "${CLR_YELLOW}User '%s' does not exist on this system.${CLR_RESET}\n" "$input_user" > "$tty_out"
continue
fi
chosen="$input_user"
done
else
chosen="$candidate"
fi
if [[ -z "$chosen" || "$chosen" == "root" ]]; then
log_error "Could not determine a valid non-root desktop target user."
return 1
fi
if ! id "$chosen" >/dev/null 2>&1; then
log_error "Target user '$chosen' does not exist."
return 1
fi
export TARGET_USER="$chosen"
echo "$chosen"
}
# Get the target user (memoized / exported in TARGET_USER)
get_target_user() {
prompt_target_user
}
# Get home directory of target user
get_target_home() {
local user
user="$(get_target_user)"
local user_home
user_home="$(getent passwd "$user" | cut -d: -f6)"
if [[ -z "$user_home" || ! -d "$user_home" ]]; then
user_home="/home/$user"
fi
echo "$user_home"
}
# Run a command as the target user
run_as_target_user() {
local user
user="$(get_target_user)"
if [[ "$(id -un)" == "$user" ]]; then
"$@"
else
su -l "$user" -s /bin/bash -c "$(printf "%q " "$@")"
fi
}
# Create a safe temporary directory with auto-cleanup
create_temp_dir() {
local prefix="${1:-setup-temp}"
local tmp_dir
tmp_dir="$(mktemp -d "/tmp/${prefix}.XXXXXX")"
echo "$tmp_dir"
}
# Safe backup function
backup_file_or_dir() {
local target="$1"
local timestamp
timestamp="$(date +%Y%m%d_%H%M%S)"
if [[ -e "$target" ]]; then
local backup_path="${target}.backup_${timestamp}"
cp -r "$target" "$backup_path"
log_info "Created backup: $backup_path"
fi
}
-60
View File
@@ -1,60 +0,0 @@
Debian Paketquellen installieren -> sources nach /etc/apt/sources.list.d
sudo apt install git sudo network-manager software-properties-common wget curl
XanMod Kernel - Repo + Keyring installieren -> https://xanmod.org
Apt-Pinning konfigurieren
sudo apt update
sudo apt install apt-listbugs apt-listchanges
apt policy hyprland wlroots wayland wayland-protocols mesa
=> wayland -> trixie
mesa -> trixie-backports
hyprland -> unstable
sudo apt install linux-xanmod-x64v3
sudo apt install -t trixie-backports mesa mesa-vulkan-drivers gamemode gamescope mangohud pipewire pipewire-pulse wireplumber
sudo apt install -t unstable hyprland wlroots wayland-protocols xdg-desktop-portal-wlr rofi-wayland waybar ags
sudo apt install grim slurp wl-clipboard swaybg irqbalance cpupower timeshift zsh 7zip unrar unzip codium fzf rg rsync clamav clamav-freshclam clamav-docs libclamunrar9 clamav-daemon flatpak rfkill xdg-user-dirs tree bluetooth bleachbit network-manager-gnome steam-installer libreoffice tealdeer gnome-disk-utility gnome-system-monitor keepassxc
sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
Lutris installieren
Spotify installieren
-> Spotify .desktop-Datei hinterlegen
Waydroid installieren
sudo apt update
sudo apt upgrade
Grub-Config anpassen
-> GRUB_TIMEOUT=0
-> GRUB_TIMEOUT_STYLE=hidden
-> GRUB_CMDLINE_LINUX_DEFAULT="quiet splash usbcore.autosuspend=-1 vt.global_cursor_default=0 loglevel=3 rd.luks.options=discard plymouth.ignore-serial-consoles"
-> GRUB_CMDLINE_LINUS="rcutree.rcu_idle_gp_delay=1"
Grub-Theme installieren
Plymouth installieren (Theme = Spinner)
update-grub
./etc/profile.d entsprechend kopieren
OhMyZsh installieren
-> sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
./home/.zshrc entsprechend kopieren
./home/.oh-my-zsh/themes entsprechend kopieren
source /etc/profile in /etc/zsh/zprofile einfügen
Shell des Users auf ZSH setzen
Portmaster installieren
Floorp installieren
Standardvorlagen hinterlegen
.config Ordner ziehen und hinterlegen
sudo timeshift --create --comments "initial install" --tags D
Executable
+209
View File
@@ -0,0 +1,209 @@
#!/usr/bin/env bash
# ==============================================================================
# setup.sh - Central Orchestrator for Debian Unstable Setup & Hyprland Installer
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Source Libraries & Config
source "$SCRIPT_DIR/lib/utils.sh"
source "$SCRIPT_DIR/lib/apt.sh"
source "$SCRIPT_DIR/lib/tui.sh"
if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then
# shellcheck source=/dev/null
source "$SCRIPT_DIR/config/setup.conf"
fi
setup_err_trap
# Show help text
show_help() {
cat <<EOF
Usage: sudo ./setup.sh [OPTIONS]
Debian Unstable Setup & Desktop Customization Framework
Options:
-a, --all Run all setup stages sequentially (00 through 09)
-s, --stages <list> Comma-separated list of stages to run (e.g. --stages 01,02,04)
-u, --user <username> Specify target desktop user (defaults to \$SUDO_USER)
-d, --dry-run Simulate stage execution without modifying the system
-h, --help Show this help message and exit
Available Stages:
00: Pre-flight Checks (System, Privileges, Internet)
01: Debian Unstable Migration (Deb822, Pinning, apt-listbugs, dist-upgrade)
02: Kernel & Hardware Tuning (XanMod, AMD/Intel P-State, auto-cpufreq)
03: Bootloader & Splash (GRUB configuration, Vimix Theme, Plymouth Solar)
04: Package Installation (Base, Desktop, Gaming, Virtualization, Multimedia)
05: Font Installation (JetBrainsMono, FantasqueSans, VictorMono)
06: System Services (AppArmor, Docker, Libvirt, zram)
07: Skel & User Environment (Zsh, Templates, Dotfiles Sync)
08: Flatpaks & Applications (Flathub, Steam, Lutris, MIME types)
09: Hyprland Desktop (LinuxBeginnings Auto-Installer)
Examples:
sudo ./setup.sh # Interactive TUI mode
sudo ./setup.sh --all # Full automated install
sudo ./setup.sh --stages 04,05 # Install only packages and fonts
sudo ./setup.sh --stages 01 --dry-run # Dry-run stage 01
EOF
}
# CLI Flags
FLAG_ALL=0
FLAG_STAGES=""
FLAG_DRY_RUN=0
CLI_USER=""
# Parse CLI arguments
while [[ $# -gt 0 ]]; do
case "$1" in
-a|--all)
FLAG_ALL=1
shift
;;
-s|--stages)
if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then
FLAG_STAGES="$2"
shift 2
else
log_error "Option '$1' requires a comma-separated list of stages."
exit 1
fi
;;
-u|--user)
if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then
CLI_USER="$2"
shift 2
else
log_error "Option '$1' requires a username."
exit 1
fi
;;
-d|--dry-run)
FLAG_DRY_RUN=1
shift
;;
-h|--help)
show_help
exit 0
;;
*)
log_error "Unknown option: $1"
show_help
exit 1
;;
esac
done
if [[ -n "$CLI_USER" ]]; then
export TARGET_USER="$CLI_USER"
fi
# Ensure root privileges unless dry-run
if [[ "$FLAG_DRY_RUN" -eq 0 ]]; then
require_root
fi
# Determine stages to run
SELECTED_STAGES=()
if [[ "$FLAG_ALL" -eq 1 ]]; then
SELECTED_STAGES=(01 02 03 04 05 06 07 08 09)
elif [[ -n "$FLAG_STAGES" ]]; then
IFS=',' read -r -a raw_stages <<< "$FLAG_STAGES"
for st in "${raw_stages[@]}"; do
# Format single digit numbers to two digits (e.g. 1 -> 01)
st="$(echo "$st" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
if [[ "$st" =~ ^[0-9]$ ]]; then
st="0$st"
fi
SELECTED_STAGES+=("$st")
done
else
# Interactive TUI Mode
if [[ -t 0 && -t 1 ]]; then
tui_check_whiptail
tui_welcome
TUI_SELECTION=$(tui_select_stages)
if [[ -z "$TUI_SELECTION" ]]; then
log_warn "No stages selected. Exiting."
exit 0
fi
read -r -a SELECTED_STAGES <<< "$TUI_SELECTION"
DETECTED_USER="${TARGET_USER:-$(get_target_user 2>/dev/null || true)}"
TARGET_USER_NAME="$(tui_prompt_target_user "$DETECTED_USER")"
export TARGET_USER="$TARGET_USER_NAME"
if ! tui_confirm_execution "${SELECTED_STAGES[*]}" "$TARGET_USER_NAME"; then
log_info "Installation aborted by user."
exit 0
fi
else
log_info "Non-interactive shell and no parameters provided. Defaulting to --all."
SELECTED_STAGES=(01 02 03 04 05 06 07 08 09)
fi
fi
# Ensure TARGET_USER is determined and confirmed for all stages
if [[ -z "${TARGET_USER:-}" ]]; then
TARGET_USER="$(get_target_user)"
export TARGET_USER
fi
# Map stage identifier to script file
get_stage_script() {
local stage_id="$1"
local match
match="$(find "$SCRIPT_DIR/stages" -maxdepth 1 -name "${stage_id}-*.sh" -type f | head -n1)"
echo "$match"
}
# Always run preflight check first unless dry-run
if [[ "$FLAG_DRY_RUN" -eq 0 ]]; then
PREFLIGHT_SCRIPT="$(get_stage_script "00")"
if [[ -n "$PREFLIGHT_SCRIPT" && -f "$PREFLIGHT_SCRIPT" ]]; then
bash "$PREFLIGHT_SCRIPT"
fi
fi
# Banner
log_step "Starting Debian Unstable Setup Execution"
log_info "Target User: $(get_target_user)"
log_info "Planned Stages: ${SELECTED_STAGES[*]}"
if [[ "$FLAG_DRY_RUN" -eq 1 ]]; then
log_warn "DRY-RUN MODE: No changes will be made to the system."
fi
# Execute Selected Stages
for stage in "${SELECTED_STAGES[@]}"; do
# Skip 00 if it was manually added since it already ran
if [[ "$stage" == "00" ]]; then
continue
fi
SCRIPT="$(get_stage_script "$stage")"
if [[ -z "$SCRIPT" || ! -f "$SCRIPT" ]]; then
log_warn "Stage script for '$stage' not found in $SCRIPT_DIR/stages! Skipping."
continue
fi
STAGE_NAME="$(basename "$SCRIPT" .sh)"
log_step "Executing Stage: $STAGE_NAME"
if [[ "$FLAG_DRY_RUN" -eq 1 ]]; then
log_info "[DRY-RUN] Would execute: bash $SCRIPT"
else
bash "$SCRIPT"
log_success "Completed Stage: $STAGE_NAME"
fi
done
log_step "All selected setup stages completed successfully!"
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/00-preflight.sh - System pre-flight checks, permissions & internet connectivity
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
setup_err_trap
log_step "Running Stage 00: Pre-flight System Checks..."
# 1. Check Root Privileges
log_substep "Checking root privileges..."
require_root
log_success "Running with root privileges."
# 2. Check Target Desktop User
log_substep "Detecting non-root target user..."
TARGET_USER="$(get_target_user)"
TARGET_HOME="$(get_target_home)"
if [[ -z "$TARGET_USER" || "$TARGET_USER" == "root" ]]; then
log_error "Could not determine target user. Run via 'sudo ./setup.sh' as the desktop user or set TARGET_USER=<user>."
exit 1
fi
log_success "Target user identified: $TARGET_USER (Home: $TARGET_HOME)"
# 3. Check Internet Connectivity
log_substep "Checking internet connectivity..."
INTERNET_OK=0
for host in "deb.debian.org" "1.1.1.1" "8.8.8.8"; do
if ping -c 1 -W 3 "$host" >/dev/null 2>&1 || curl -s --head --connect-timeout 3 "http://$host" >/dev/null 2>&1; then
INTERNET_OK=1
break
fi
done
if [[ "$INTERNET_OK" -ne 1 ]]; then
log_error "No active internet connection detected. Please connect to the internet and try again."
exit 1
fi
log_success "Internet connection verified."
# 4. Check Operating System
log_substep "Verifying operating system..."
if [[ -f /etc/os-release ]]; then
# shellcheck source=/dev/null
source /etc/os-release
log_info "Detected OS: ${NAME:-Debian} ${VERSION_ID:-} (${VERSION_CODENAME:-sid})"
if [[ "${ID:-}" != "debian" && "${ID_LIKE:-}" != *"debian"* ]]; then
log_warn "This setup script is optimized for Debian GNU/Linux. Current ID is '${ID:-unknown}'."
fi
else
log_warn "/etc/os-release not found. Proceeding with caution."
fi
# 5. Check Disk Space
log_substep "Checking available disk space..."
AVAILABLE_KB=$(df --output=avail / | tail -n1)
if [[ "$AVAILABLE_KB" -lt 5242880 ]]; then # Less than 5 GB
log_warn "Less than 5 GB of free space available on root partition ($(( AVAILABLE_KB / 1024 )) MB free)."
else
log_success "Sufficient disk space available ($(( AVAILABLE_KB / 1024 / 1024 )) GB free)."
fi
log_success "Stage 00: Pre-flight checks passed successfully."
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/01-apt-unstable.sh - Migration to Debian Unstable (Deb822), Pinning & Upgrade
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
source "$SCRIPT_DIR/lib/apt.sh"
setup_err_trap
log_step "Running Stage 01: Debian Unstable Migration & Package Sources Configuration"
require_root
# 1. Install prerequisites for APT HTTPS & Keyrings
log_substep "Installing APT prerequisites (curl, gnupg, ca-certificates)..."
DEBIAN_FRONTEND=noninteractive apt-get update -y
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
gnupg \
gpg \
ca-certificates \
apt-transport-https \
debian-archive-keyring
# 2. Ensure Keyrings directory exists
apt_ensure_keyrings_dir
# 3. Migrate /etc/apt/sources.list to Deb822 format
log_substep "Migrating APT sources to Deb822 format..."
if [[ -f /etc/apt/sources.list && ! -f /etc/apt/sources.list.bak_pre_unstable ]]; then
cp /etc/apt/sources.list /etc/apt/sources.list.bak_pre_unstable
# Comment out active lines in legacy sources.list to avoid duplicate source warnings
sed -i 's/^[[:space:]]*deb/# deb/' /etc/apt/sources.list
fi
# Deploy debian-unstable.sources
if [[ -f "$SCRIPT_DIR/data/apt/sources.list.d/debian-unstable.sources" ]]; then
apt_install_sources_file "$SCRIPT_DIR/data/apt/sources.list.d/debian-unstable.sources" "debian-unstable.sources"
fi
# 4. Deploy APT Preferences / Pinning
log_substep "Configuring APT Pinning preferences..."
mkdir -p /etc/apt/preferences.d
if compgen -G "$SCRIPT_DIR/data/apt/preferences.d/*.pref" > /dev/null; then
for pref_file in "$SCRIPT_DIR"/data/apt/preferences.d/*.pref; do
apt_install_preference_file "$pref_file" "$(basename "$pref_file")"
done
fi
# 5. Install apt-listbugs and apt-listchanges to safeguard Unstable upgrades
log_substep "Installing protection tools (apt-listbugs, apt-listchanges)..."
apt_update
DEBIAN_FRONTEND=noninteractive apt-get install -y apt-listbugs apt-listchanges
# 6. Perform Full Dist-Upgrade
log_substep "Performing full distribution upgrade to Debian Sid..."
apt_dist_upgrade
log_success "Stage 01: Debian Unstable migration and upgrade completed successfully!"
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/02-kernel-hardware.sh - XanMod Kernel, Microcode, auto-cpufreq & Hardware Tuning
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
source "$SCRIPT_DIR/lib/apt.sh"
if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then
# shellcheck source=/dev/null
source "$SCRIPT_DIR/config/setup.conf"
fi
setup_err_trap
log_step "Running Stage 02: Kernel & Hardware Tuning"
require_root
# 1. Setup XanMod Kernel Repository
log_substep "Configuring XanMod Kernel repository..."
apt_ensure_keyrings_dir
apt_add_keyring_from_url "https://dl.xanmod.org/archive.key" "xanmod-archive-keyring.gpg"
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
# 2. Determine XanMod Kernel Package
log_substep "Detecting CPU microarchitecture level and XanMod branch..."
BRANCH="${XANMOD_BRANCH:-main}"
log_info "Configured XanMod branch: $BRANCH"
BRANCH_SUFFIX=""
if [[ "$BRANCH" != "main" && -n "$BRANCH" ]]; then
BRANCH_SUFFIX="-$BRANCH"
fi
# Detect CPU x86-64 microarchitecture level
ARCH_SUFFIX="-x64v2"
if grep -q "avx2" /proc/cpuinfo 2>/dev/null; then
ARCH_SUFFIX="-x64v3"
log_info "CPU supports x86-64-v3 (AVX2 detected)."
else
log_info "CPU does not support AVX2. Using x86-64-v2."
fi
KERNEL_PKG="linux-xanmod${BRANCH_SUFFIX}${ARCH_SUFFIX}"
FALLBACK_PKG="linux-xanmod${BRANCH_SUFFIX}"
log_substep "Installing XanMod kernel package ($KERNEL_PKG)..."
if ! DEBIAN_FRONTEND=noninteractive apt-get install -y "$KERNEL_PKG"; then
log_warn "Failed to install $KERNEL_PKG, trying fallback package $FALLBACK_PKG..."
DEBIAN_FRONTEND=noninteractive apt-get install -y "$FALLBACK_PKG" || log_warn "XanMod installation failed, standard kernel will remain active."
fi
# 3. CPU Microcode Detection and Installation
log_substep "Detecting CPU vendor for microcode installation..."
CPU_VENDOR=$(lscpu 2>/dev/null | grep -oP 'Vendor ID:\s*\K.*' | tr -d ' ' || true)
case "$CPU_VENDOR" in
"AuthenticAMD")
log_info "AMD CPU detected ($CPU_VENDOR) -> Installing amd64-microcode"
DEBIAN_FRONTEND=noninteractive apt-get install -y amd64-microcode
;;
"GenuineIntel")
log_info "Intel CPU detected ($CPU_VENDOR) -> Installing intel-microcode"
DEBIAN_FRONTEND=noninteractive apt-get install -y intel-microcode
;;
*)
log_warn "Unknown CPU vendor '$CPU_VENDOR'. Skipping vendor-specific microcode."
;;
esac
# 4. Install & Enable auto-cpufreq from source repository
log_substep "Installing and configuring auto-cpufreq..."
if command_exists auto-cpufreq; then
log_info "auto-cpufreq is already installed."
else
log_info "Cloning and building auto-cpufreq from GitHub repository..."
# Ensure git and python3 build essentials are available
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git python3 python3-pip python3-setuptools 2>/dev/null || true
TEMP_DIR="$(create_temp_dir "auto-cpufreq")"
if git clone --depth=1 https://github.com/AdnanHodzic/auto-cpufreq.git "$TEMP_DIR" 2>/dev/null; then
(
cd "$TEMP_DIR"
./auto-cpufreq-installer --install || ./auto-cpufreq-installer --install --non-interactive || true
)
rm -rf "$TEMP_DIR"
else
log_warn "Failed to clone auto-cpufreq repository from GitHub."
fi
fi
if command_exists auto-cpufreq; then
auto-cpufreq --install 2>/dev/null || true
if command_exists systemctl; then
systemctl enable --now auto-cpufreq 2>/dev/null || log_warn "Could not enable auto-cpufreq systemd service."
fi
log_success "auto-cpufreq installed and service enabled."
else
log_warn "auto-cpufreq installation could not be completed."
fi
# 5. Environment configuration (Raytracing & Upscaling)
log_substep "Deploying graphics and performance environment configurations..."
mkdir -p /etc/environment.d
if compgen -G "$SCRIPT_DIR/data/etc/environment.d/*.conf" > /dev/null; then
for env_file in "$SCRIPT_DIR"/data/etc/environment.d/*.conf; do
cp "$env_file" /etc/environment.d/
log_info "Installed environment config: $(basename "$env_file")"
done
fi
log_success "Stage 02: Kernel and Hardware Tuning completed successfully!"
+112
View File
@@ -0,0 +1,112 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/03-bootloader.sh - GRUB configuration, CPU P-State, Vimix Theme & Plymouth
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then
# shellcheck source=/dev/null
source "$SCRIPT_DIR/config/setup.conf"
fi
setup_err_trap
log_step "Running Stage 03: Bootloader & Splash Screen Configuration"
require_root
GRUB_CFG="/etc/default/grub"
GRUB_TIMEOUT="${GRUB_TIMEOUT:-0}"
GRUB_TIMEOUT_STYLE="${GRUB_TIMEOUT_STYLE:-hidden}"
GRUB_CMDLINE_LINUX_DEFAULT_BASE="quiet splash apparmor=1 usbcore.autosuspend=-1 vt.global_cursor_default=0 loglevel=3 rd.luks.options=discard plymouth.ignore-serial-consoles threadirqs"
GRUB_CMDLINE_LINUX="rcutree.rcu_idle_gp_delay=1"
GRUB_THEME_DIR="/usr/share/debian-gaming/grub/grub2-themes"
# 1. CPU P-State Detection
log_substep "Detecting CPU vendor for P-State parameter..."
CPU_VENDOR=$(lscpu 2>/dev/null | grep -oP 'Vendor ID:\s*\K.*' | tr -d ' ' || true)
CPU_MODEL=$(lscpu 2>/dev/null | grep -oP 'Model name:\s*\K.*' | head -c 30 || true)
log_info "Detected CPU: $CPU_MODEL ($CPU_VENDOR)"
CPU_PARAM=""
case "$CPU_VENDOR" in
"AuthenticAMD")
CPU_PARAM="amd_pstate=active"
log_info "AMD CPU detected -> Adding amd_pstate=active"
;;
"GenuineIntel")
CPU_PARAM="intel_pstate=active"
log_info "Intel CPU detected -> Adding intel_pstate=active"
;;
*)
log_warn "Unknown CPU Vendor '$CPU_VENDOR' - no CPU pstate parameter added."
;;
esac
if [[ -n "$CPU_PARAM" ]]; then
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT_BASE $CPU_PARAM"
else
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT_BASE"
fi
# 2. Configure /etc/default/grub
if [[ -f "$GRUB_CFG" ]]; then
log_substep "Updating $GRUB_CFG..."
backup_file_or_dir "$GRUB_CFG"
# Set parameters with sed
sed -i "s|^GRUB_TIMEOUT=.*|GRUB_TIMEOUT=$GRUB_TIMEOUT|" "$GRUB_CFG"
sed -i "s|^GRUB_TIMEOUT_STYLE=.*|GRUB_TIMEOUT_STYLE=$GRUB_TIMEOUT_STYLE|" "$GRUB_CFG"
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT=\"$GRUB_CMDLINE_LINUX_DEFAULT\"|" "$GRUB_CFG"
sed -i "s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\"$GRUB_CMDLINE_LINUX\"|" "$GRUB_CFG"
# Ensure entries exist if sed didn't find them
grep -q '^GRUB_TIMEOUT=' "$GRUB_CFG" || echo "GRUB_TIMEOUT=$GRUB_TIMEOUT" >> "$GRUB_CFG"
grep -q '^GRUB_TIMEOUT_STYLE=' "$GRUB_CFG" || echo "GRUB_TIMEOUT_STYLE=$GRUB_TIMEOUT_STYLE" >> "$GRUB_CFG"
grep -q '^GRUB_CMDLINE_LINUX_DEFAULT=' "$GRUB_CFG" || echo "GRUB_CMDLINE_LINUX_DEFAULT=\"$GRUB_CMDLINE_LINUX_DEFAULT\"" >> "$GRUB_CFG"
grep -q '^GRUB_CMDLINE_LINUX=' "$GRUB_CFG" || echo "GRUB_CMDLINE_LINUX=\"$GRUB_CMDLINE_LINUX\"" >> "$GRUB_CFG"
else
log_warn "$GRUB_CFG not found. Is GRUB installed?"
fi
# 3. Install & Configure Plymouth
log_substep "Installing and configuring Plymouth splash theme..."
if DEBIAN_FRONTEND=noninteractive apt-get install -y plymouth plymouth-themes 2>/dev/null; then
PLYMOUTH_THEME="${PLYMOUTH_THEME:-solar}"
if command_exists plymouth-set-default-theme; then
plymouth-set-default-theme -R "$PLYMOUTH_THEME" 2>/dev/null || log_warn "Could not set Plymouth theme to $PLYMOUTH_THEME"
log_success "Plymouth configured with theme: $PLYMOUTH_THEME"
fi
fi
# 4. Install Vimix GRUB Theme
log_substep "Installing Vimix GRUB theme..."
DEBIAN_FRONTEND=noninteractive apt-get install -y git 2>/dev/null || true
mkdir -p "$GRUB_THEME_DIR"
if [[ ! -d "$GRUB_THEME_DIR/.git" ]]; then
if git clone --depth 1 https://github.com/vinceliuice/grub2-themes.git "$GRUB_THEME_DIR" 2>/dev/null; then
"$GRUB_THEME_DIR/install.sh" -b -t "${GRUB_THEME:-vimix}" 2>/dev/null || log_warn "Vimix theme installer encountered an issue."
log_success "Vimix GRUB theme installed."
else
log_warn "Failed to clone grub2-themes repository. Skipping theme."
fi
else
log_info "GRUB Theme repository already cloned; updating..."
(cd "$GRUB_THEME_DIR" && git pull 2>/dev/null && ./install.sh -b -t "${GRUB_THEME:-vimix}" 2>/dev/null) || log_warn "Vimix theme update skipped."
fi
# 5. Update GRUB & Initramfs
log_substep "Running update-grub and update-initramfs..."
if command_exists update-grub; then
update-grub
fi
if command_exists update-initramfs; then
update-initramfs -u 2>/dev/null || true
fi
log_success "Stage 03: Bootloader and Splash configuration completed successfully!"
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/04-packages.sh - Installation of categorised system and desktop packages
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
source "$SCRIPT_DIR/lib/apt.sh"
setup_err_trap
log_step "Running Stage 04: Thematic Package Installation"
require_root
PACKAGES_DIR="$SCRIPT_DIR/config/packages"
if [[ ! -d "$PACKAGES_DIR" ]]; then
log_error "Package configuration directory $PACKAGES_DIR not found!"
exit 1
fi
# List of APT package lists to process (excluding flatpaks which are handled in stage 08)
APT_LISTS=(
"01-base.list"
"02-desktop.list"
"03-gaming.list"
"04-virtualization.list"
"05-multimedia.list"
)
log_substep "Updating package lists before installation..."
apt_update
for list_name in "${APT_LISTS[@]}"; do
list_path="$PACKAGES_DIR/$list_name"
if [[ -f "$list_path" ]]; then
log_step "Installing package category: $list_name"
apt_install_package_list_file "$list_path" || log_warn "Some packages from $list_name could not be installed."
else
log_warn "Package list file $list_name not found in $PACKAGES_DIR."
fi
done
log_success "Stage 04: Thematic package installation completed successfully!"
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/05-fonts.sh - Download and clean installation of Coding & Nerd Fonts
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
setup_err_trap
log_step "Running Stage 05: Coding & Nerd Fonts Installation"
require_root
FONT_DIR="/usr/share/fonts"
TEMP_DIR="$(create_temp_dir "fonts-setup")"
# Ensure cleanup of temp directory on exit
cleanup() {
if [[ -d "$TEMP_DIR" ]]; then
log_info "Cleaning up temporary font download directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
fi
}
trap cleanup EXIT ERR
mkdir -p "$FONT_DIR"
# 1. JetBrains Mono Nerd Font
log_substep "Downloading and installing JetBrainsMono Nerd Font..."
JB_ARCHIVE="$TEMP_DIR/JetBrainsMono.tar.xz"
JB_DEST="$FONT_DIR/JetBrainsMonoNerd"
if curl -fsSL "https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.tar.xz" -o "$JB_ARCHIVE"; then
mkdir -p "$JB_DEST"
tar -xJkf "$JB_ARCHIVE" -C "$JB_DEST" 2>/dev/null || tar -xJf "$JB_ARCHIVE" -C "$JB_DEST"
log_success "JetBrainsMono Nerd Font installed to $JB_DEST"
else
log_warn "Failed to download JetBrainsMono Nerd Font."
fi
# 2. Fantasque Sans Mono Nerd Font
log_substep "Downloading and installing Fantasque Sans Mono Nerd Font..."
FANTASQUE_ARCHIVE="$TEMP_DIR/FantasqueSansMono.zip"
FANTASQUE_DEST="$FONT_DIR/FantasqueSansMonoNerd"
if curl -fsSL "https://github.com/ryanoasis/nerd-fonts/releases/download/v3.3.0/FantasqueSansMono.zip" -o "$FANTASQUE_ARCHIVE"; then
mkdir -p "$FANTASQUE_DEST"
unzip -o -q "$FANTASQUE_ARCHIVE" -d "$FANTASQUE_DEST"
log_success "FantasqueSansMono Nerd Font installed to $FANTASQUE_DEST"
else
log_warn "Failed to download FantasqueSansMono Nerd Font."
fi
# 3. Victor Mono Font
log_substep "Downloading and installing Victor Mono Font..."
VICTOR_ARCHIVE="$TEMP_DIR/VictorMonoAll.zip"
VICTOR_DEST="$FONT_DIR/VictorMono"
if curl -fsSL "https://rubjo.github.io/victor-mono/VictorMonoAll.zip" -o "$VICTOR_ARCHIVE"; then
mkdir -p "$VICTOR_DEST"
unzip -o -q "$VICTOR_ARCHIVE" -d "$VICTOR_DEST"
log_success "Victor Mono Font installed to $VICTOR_DEST"
else
log_warn "Failed to download Victor Mono Font."
fi
# 4. Refresh Font Cache
log_substep "Updating font cache..."
if command_exists fc-cache; then
fc-cache -f
log_success "Font cache refreshed."
fi
log_success "Stage 05: Fonts installation completed successfully!"
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/06-services.sh - System services activation (AppArmor, Docker, Libvirt, zram)
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
source "$SCRIPT_DIR/lib/apt.sh"
setup_err_trap
log_step "Running Stage 06: System Services Configuration & User Privileges"
require_root
TARGET_USER="$(get_target_user)"
# 1. AppArmor Service
log_substep "Enabling and starting AppArmor service..."
if command_exists systemctl; then
systemctl enable apparmor 2>/dev/null || true
systemctl start apparmor 2>/dev/null || true
log_success "AppArmor service enabled."
fi
# 2. zram-tools Configuration
log_substep "Configuring zram swap service..."
if command_exists systemctl; then
systemctl enable --now zramswap.service 2>/dev/null || true
log_success "zram service enabled."
fi
# 3. Docker Service & Repository
log_substep "Setting up Docker service & repository..."
apt_ensure_keyrings_dir
apt_add_keyring_from_url "https://download.docker.com/linux/debian/gpg" "docker.asc"
DEBIAN_CODENAME="sid"
if [[ -f /etc/os-release ]]; then
# shellcheck source=/dev/null
source /etc/os-release
DEBIAN_CODENAME="${VERSION_CODENAME:-sid}"
# Docker uses 'bookworm' or 'trixie' upstream repo suite for Debian testing/unstable if sid is not explicitly provided
if [[ "$DEBIAN_CODENAME" == "sid" ]]; then
DEBIAN_CODENAME="trixie"
fi
fi
ARCH="$(dpkg --print-architecture)"
cat <<EOF > /etc/apt/sources.list.d/docker.sources
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $DEBIAN_CODENAME
Components: stable
Architectures: $ARCH
Signed-By: /etc/apt/keyrings/docker.asc
EOF
chmod 0644 /etc/apt/sources.list.d/docker.sources
apt_update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin 2>/dev/null || log_warn "Could not install all Docker packages."
if command_exists systemctl; then
systemctl enable --now docker.service 2>/dev/null || true
fi
# 4. Libvirt / KVM Virtualization
log_substep "Configuring Virtualization (Libvirt / KVM)..."
HAS_VIRT=$(grep -Eoc '(vmx|svm)' /proc/cpuinfo 2>/dev/null || echo 0)
if [[ "$HAS_VIRT" -gt 0 ]]; then
log_info "Hardware virtualization support detected."
if command_exists systemctl; then
systemctl enable --now libvirtd.service 2>/dev/null || true
fi
if command_exists virsh; then
virsh net-start default 2>/dev/null || true
virsh net-autostart default 2>/dev/null || true
fi
# Add target user to libvirt and kvm groups
groupadd -f libvirt
groupadd -f kvm
usermod -aG libvirt,kvm "$TARGET_USER"
log_success "Target user $TARGET_USER added to libvirt & kvm groups."
else
log_info "No hardware virtualization extensions (VT-x/AMD-V) detected in /proc/cpuinfo."
fi
# 5. User Group Memberships
log_substep "Updating user group memberships for $TARGET_USER..."
groupadd -f sudo
groupadd -f docker
usermod -aG sudo,docker "$TARGET_USER"
log_success "Target user $TARGET_USER added to sudo and docker groups."
log_success "Stage 06: System services configuration completed successfully!"
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/07-skel-and-user.sh - /etc/skel templates, Zsh setup, user environment sync & chsh
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
setup_err_trap
log_step "Running Stage 07: User Environment, Skel Templates & Shell Configuration"
require_root
TARGET_USER="$(get_target_user)"
TARGET_HOME="$(get_target_home)"
log_info "Configuring userland environment for target user: $TARGET_USER ($TARGET_HOME)"
# 1. Deploy System Profile Scripts (/etc/profile.d)
log_substep "Deploying system profile scripts to /etc/profile.d/..."
mkdir -p /etc/profile.d
if [[ -d "$SCRIPT_DIR/data/etc/profile.d" ]]; then
for profile_script in "$SCRIPT_DIR"/data/etc/profile.d/*.sh; do
[[ -f "$profile_script" ]] || continue
cp "$profile_script" /etc/profile.d/
chmod 0755 "/etc/profile.d/$(basename "$profile_script")"
log_info "Installed profile script: $(basename "$profile_script")"
done
fi
# Ensure Zsh profiles source /etc/profile
mkdir -p /etc/zsh
grep -q '^source /etc/profile' /etc/zsh/zprofile 2>/dev/null || echo 'source /etc/profile' >> /etc/zsh/zprofile
# 2. Provision /etc/skel for Future New Users
log_substep "Provisioning /etc/skel with default templates and configs..."
mkdir -p /etc/skel/Templates
if [[ -d "$SCRIPT_DIR/data/skel/Templates" ]]; then
cp -r "$SCRIPT_DIR"/data/skel/Templates/* /etc/skel/Templates/ 2>/dev/null || true
fi
if [[ -f "$SCRIPT_DIR/data/skel/.zshrc" ]]; then
cp "$SCRIPT_DIR/data/skel/.zshrc" /etc/skel/.zshrc
fi
chown -R root:root /etc/skel
# 3. Synchronize User Environment for Target User
log_substep "Synchronizing Dotfiles & Templates into $TARGET_HOME..."
mkdir -p "$TARGET_HOME/Templates"
# Backup existing .zshrc if present
if [[ -f "$TARGET_HOME/.zshrc" ]]; then
backup_file_or_dir "$TARGET_HOME/.zshrc"
fi
if [[ -f "$SCRIPT_DIR/data/skel/.zshrc" ]]; then
cp "$SCRIPT_DIR/data/skel/.zshrc" "$TARGET_HOME/.zshrc"
fi
if [[ -d "$SCRIPT_DIR/data/skel/Templates" ]]; then
cp -r "$SCRIPT_DIR"/data/skel/Templates/* "$TARGET_HOME/Templates/" 2>/dev/null || true
fi
# 4. Install Oh-My-Zsh for Target User (if not already installed)
if [[ ! -d "$TARGET_HOME/.oh-my-zsh" ]]; then
log_substep "Installing Oh-My-Zsh repository for $TARGET_USER..."
if command_exists git; then
run_as_target_user git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git "$TARGET_HOME/.oh-my-zsh" 2>/dev/null || log_warn "Could not clone Oh-My-Zsh repository."
fi
fi
# Fix ownership
chown -R "$TARGET_USER:$TARGET_USER" "$TARGET_HOME/.zshrc" "$TARGET_HOME/Templates"
if [[ -d "$TARGET_HOME/.oh-my-zsh" ]]; then
chown -R "$TARGET_USER:$TARGET_USER" "$TARGET_HOME/.oh-my-zsh"
fi
# 5. Set Default Shell to Zsh using standard chsh
log_substep "Setting default shell to Zsh for $TARGET_USER..."
ZSH_BIN="$(command -v zsh || echo "/usr/bin/zsh")"
if [[ -x "$ZSH_BIN" ]]; then
# Ensure zsh is listed in /etc/shells
grep -q "^$ZSH_BIN$" /etc/shells 2>/dev/null || echo "$ZSH_BIN" >> /etc/shells
CURRENT_SHELL="$(getent passwd "$TARGET_USER" | cut -d: -f7)"
if [[ "$CURRENT_SHELL" != "$ZSH_BIN" ]]; then
chsh -s "$ZSH_BIN" "$TARGET_USER"
log_success "Default shell for $TARGET_USER set to $ZSH_BIN"
else
log_info "Default shell for $TARGET_USER is already $ZSH_BIN"
fi
else
log_warn "Zsh binary not found at $ZSH_BIN. Skipping chsh."
fi
log_success "Stage 07: Skel & userland configuration completed successfully!"
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/08-flatpaks-apps.sh - Flathub setup, Flatpaks, Spotify, Waydroid & MIME associations
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
source "$SCRIPT_DIR/lib/apt.sh"
setup_err_trap
log_step "Running Stage 08: Flatpaks, Additional Apps & MIME Associations"
require_root
TARGET_USER="$(get_target_user)"
TARGET_HOME="$(get_target_home)"
# 1. Flathub Repository Setup
log_substep "Configuring Flathub remote repository..."
if command_exists flatpak; then
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || log_warn "Could not add Flathub remote."
log_success "Flathub repository enabled."
else
log_warn "flatpak command not found. Skipping Flatpak installation."
fi
# 2. Install Flatpaks from config/packages/06-flatpaks.list
FLATPAK_LIST="$SCRIPT_DIR/config/packages/06-flatpaks.list"
if command_exists flatpak && [[ -f "$FLATPAK_LIST" ]]; then
log_substep "Installing Flatpak applications from $FLATPAK_LIST..."
while IFS= read -r app_id || [[ -n "$app_id" ]]; do
app_id="$(echo "$app_id" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
[[ -z "$app_id" || "$app_id" =~ ^# ]] && continue
log_info "Installing Flatpak: $app_id"
flatpak install -y flathub "$app_id" 2>/dev/null || log_warn "Failed to install Flatpak: $app_id"
done < "$FLATPAK_LIST"
fi
# 3. Spotify Client Installation (Debian APT repo)
log_substep "Configuring Spotify repository and client..."
apt_ensure_keyrings_dir
if curl -fsSL https://download.spotify.com/debian/pubkey_5384CE82BA52C83A.asc | gpg --dearmor -o /etc/apt/keyrings/spotify.gpg 2>/dev/null; then
chmod 0644 /etc/apt/keyrings/spotify.gpg
cat <<EOF > /etc/apt/sources.list.d/spotify.sources
Types: deb
URIs: http://repository.spotify.com
Suites: stable
Components: non-free
Signed-By: /etc/apt/keyrings/spotify.gpg
EOF
chmod 0644 /etc/apt/sources.list.d/spotify.sources
apt_update
DEBIAN_FRONTEND=noninteractive apt-get install -y spotify-client 2>/dev/null || log_warn "Could not install spotify-client via APT."
fi
# 4. Deploy Custom Desktop Applications
if [[ -d "$SCRIPT_DIR/data/usr/share/applications" ]]; then
log_substep "Deploying custom desktop entries..."
mkdir -p /usr/share/applications
cp -r "$SCRIPT_DIR"/data/usr/share/applications/* /usr/share/applications/ 2>/dev/null || true
fi
# 5. Waydroid Container Setup
log_substep "Checking Waydroid installation..."
if ! command_exists waydroid; then
log_info "Installing Waydroid repository and package..."
if curl -fsSL https://repo.waydro.id | bash 2>/dev/null; then
DEBIAN_FRONTEND=noninteractive apt-get install -y waydroid 2>/dev/null || log_warn "Failed to install waydroid package."
fi
fi
if command_exists systemctl && command_exists waydroid; then
systemctl enable --now waydroid-container 2>/dev/null || true
log_success "Waydroid container service enabled."
fi
# 6. Set Default Desktop MIME Types for Target User
log_substep "Setting default XDG MIME handlers for $TARGET_USER..."
run_as_target_user xdg-mime default org.gnome.Loupe.desktop image/jpeg 2>/dev/null || true
run_as_target_user xdg-mime default org.gnome.Loupe.desktop image/png 2>/dev/null || true
run_as_target_user xdg-mime default io.bassi.Amberol.desktop audio/mpeg 2>/dev/null || true
run_as_target_user xdg-mime default io.bassi.Amberol.desktop audio/x-wav 2>/dev/null || true
run_as_target_user xdg-mime default io.bassi.Amberol.desktop audio/flac 2>/dev/null || true
run_as_target_user xdg-mime default io.bassi.Amberol.desktop audio/ogg 2>/dev/null || true
run_as_target_user xdg-mime default org.gnome.TextEditor.desktop text/plain 2>/dev/null || true
run_as_target_user xdg-mime default org.gnome.TextEditor.desktop text/x-log 2>/dev/null || true
run_as_target_user xdg-mime default org.gnome.TextEditor.desktop text/markdown 2>/dev/null || true
run_as_target_user xdg-mime default eu.betterbird.Betterbird.desktop x-scheme-handler/mailto 2>/dev/null || true
log_success "Stage 08: Flatpaks, Applications and MIME associations completed successfully!"
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# ==============================================================================
# stages/09-hyprland.sh - LinuxBeginnings Debian-Hyprland auto-installer & desktop setup
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$SCRIPT_DIR/lib/utils.sh"
setup_err_trap
log_step "Running Stage 09: Hyprland Desktop (LinuxBeginnings Installer)"
require_root
TARGET_USER="$(get_target_user)"
TARGET_HOME="$(get_target_home)"
log_info "Configuring Hyprland Desktop for target user: $TARGET_USER ($TARGET_HOME)"
log_substep "Downloading and executing LinuxBeginnings Debian-Hyprland installer..."
INSTALLER_URL="https://raw.githubusercontent.com/LinuxBeginnings/Debian-Hyprland/main/auto-install.sh"
TEMP_INSTALLER="$(mktemp "/tmp/hyprland-install.XXXXXX.sh")"
if curl -fsSL "$INSTALLER_URL" -o "$TEMP_INSTALLER"; then
chmod +x "$TEMP_INSTALLER"
chown "$TARGET_USER:$TARGET_USER" "$TEMP_INSTALLER"
log_info "Running LinuxBeginnings auto-installer under user '$TARGET_USER'..."
if run_as_target_user bash "$TEMP_INSTALLER"; then
log_success "LinuxBeginnings Debian-Hyprland installation completed successfully."
else
log_warn "LinuxBeginnings installer exited with non-zero status. Check logs if needed."
fi
rm -f "$TEMP_INSTALLER"
else
log_error "Failed to download LinuxBeginnings Debian-Hyprland installer from $INSTALLER_URL"
exit 1
fi
log_success "Stage 09: Hyprland Desktop installation completed successfully!"