mirror of
https://github.com/stornic56/debianito-post-install.git
synced 2026-07-16 13:59:50 +00:00
Compare commits
11 Commits
bfd3144c7e
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d8878b67e1 | |||
| ba72fd9f87 | |||
| f043c130a8 | |||
| 2ebb33460c | |||
| a91b0caa25 | |||
| 4ef48eac3b | |||
| 110d89baf8 | |||
| 8d1a05e3e0 | |||
| ad0b39e159 | |||
| 3972cc4811 | |||
| 2272306313 |
@@ -1,10 +1,11 @@
|
|||||||
# Debianito - Post-Installation Automation for Debian
|
<h1 align="center">Debianito - Post-Installation Automation for Debian</h1>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
Debianito is a user-friendly post-installation automation script for Debian 11 (Bullseye), Debian 12 (Bookworm) and Debian 13 (Trixie). It streamlines system configuration, driver installation (including NVIDIA drivers with legacy support via rescue environment), repository setup with backports support, gaming tools integration, and more with an interactive menu-driven interface.
|
Debianito is a user-friendly post-installation automation script for Debian 11 (Bullseye), Debian 12 (Bookworm) and Debian 13 (Trixie). It streamlines system configuration, driver installation (including NVIDIA drivers), repository setup with backports support, gaming tools integration, and more with an interactive menu-driven interface.
|
||||||
|
|
||||||
[](https://github.com/stornic56/debianito-post-install/blob/main/LICENSE)
|
[](https://github.com/stornic56/debianito-post-install/blob/main/LICENSE)
|
||||||
|

|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -50,15 +51,18 @@ After running the script:
|
|||||||
| **1** | [System Info](/docs/system_info.md) | Show detected OS, CPU, RAM, GPU and hardware details |
|
| **1** | [System Info](/docs/system_info.md) | Show detected OS, CPU, RAM, GPU and hardware details |
|
||||||
| **2** | [User Privileges & Feedback](/docs/user_priv_feed.md) | Configure sudo group membership, enable passwordless sudo for frequent tasks, repair home directory ownership issues, and toggle visual password feedback (asterisks) in terminal |
|
| **2** | [User Privileges & Feedback](/docs/user_priv_feed.md) | Configure sudo group membership, enable passwordless sudo for frequent tasks, repair home directory ownership issues, and toggle visual password feedback (asterisks) in terminal |
|
||||||
| **3** | [Configure Repositories](/docs/repos_config.md) | Setup official repos with non-free/contrib options, optional Backports support and Deb822/classic format injection.|
|
| **3** | [Configure Repositories](/docs/repos_config.md) | Setup official repos with non-free/contrib options, optional Backports support and Deb822/classic format injection.|
|
||||||
| **4** | [Firmware & Wireless Drivers](/docs/firmware.md) | Install essential firmware for GPUs and wireless|
|
| **4** | [Firmware, Wireless & Bluetooth](/docs/firmware.md) | Install essential firmware for GPUs and wireless|
|
||||||
| **5** | [Graphics Drivers & Mesa Stack](/docs/gpu.md) | Configure AMD/Intel/NVIDIA drivers and Mesa graphics stack + monitoring tools |
|
| **5** | [Graphics Drivers & Mesa Stack](/docs/gpu.md) | Configure AMD/Intel/NVIDIA drivers and Mesa graphics stack + monitoring tools |
|
||||||
| **6** | [Backports Kernel](/docs/kernel.md) | Install latest kernel from Debian backports|
|
| **6** | [Backports Kernel](/docs/kernel.md) | Install latest kernel from Debian backports|
|
||||||
| **7** | [Gaming Setup and Performance](/docs/gaming.md)| Steam, Heroic Games Launcher, [RetroArch](/docs/retroarch.md) GameMode, MangoHud, OpenRGB, Java JRE (Temurin 8/17/21) |
|
| **7** | [Gaming Setup ](/docs/gaming.md)| Steam, Heroic Games Launcher, [RetroArch](/docs/retroarch.md) GameMode, MangoHud, OpenRGB, Java JRE (Temurin 8/17/21) |
|
||||||
| **8** | [Install ZRAM](/docs/zram.md)| Configure compressed RAM for memory optimization|
|
| **8** | [ZRAM](/docs/zram.md)| Configure compressed RAM for memory optimization|
|
||||||
| **9** | Install Programs and Software | Selection from several categories (Development, Themes, System, etc.) |
|
| **9** | [Swap Management](/docs/swap.md)| Manage swap file or partition size and enable/disable swap space for system stability|
|
||||||
| **10** | Exit | Return to terminal |
|
| **10** | Install Programs and Software | Browse and install packages by category (Development, Themes, System Tools, etc.) using APT |
|
||||||
|
| **11** | [Boot Rescue + GRUB](/docs/boot.md))| Config and fix GRUB bootloader issues, chroot repair, or restore system boot configuration|
|
||||||
|
| **12** | [Desktop & Display](/docs/desktops_display.md)| Install and configure desktops and display managers|
|
||||||
|
| **13** | Exit | Return to terminal |
|
||||||
|
|
||||||
### Install Programs and Software (Option 9)
|
### Install Programs and Software (Option 10)
|
||||||
|
|
||||||
The submenu offers the next categories:
|
The submenu offers the next categories:
|
||||||
|
|
||||||
@@ -67,16 +71,17 @@ The submenu offers the next categories:
|
|||||||
| **0** | Essential Pack | Quick install of common tools (compression, system info, VLC, MS fonts)|
|
| **0** | Essential Pack | Quick install of common tools (compression, system info, VLC, MS fonts)|
|
||||||
| **1** | Customization System | Desktop themes, icon themes, cursor themes, and fonts |
|
| **1** | Customization System | Desktop themes, icon themes, cursor themes, and fonts |
|
||||||
| **2** | Download & Network | Downloaders (aria2, ytdlp, FileZilla) + Torrent clients (qBittorrent, Deluge, Transmission) |
|
| **2** | Download & Network | Downloaders (aria2, ytdlp, FileZilla) + Torrent clients (qBittorrent, Deluge, Transmission) |
|
||||||
| **3** | Internet (Browsers, Email Clients, VPN Tools) | Web browsers (Firefox/Mozilla, LibreWolf, Floorp, Chromium, Brave, Tor), email clients (Thunderbird), and VPN tools including Riseup |
|
| **3** | Internet (Browsers, Email Clients, VPN) | Web browsers (Firefox/Mozilla, LibreWolf, Floorp, Chromium, Brave, Tor), email client (Thunderbird), and VPN tools (RiseUp, Proton, Mullvad)|
|
||||||
| **4** | Media Players | Multimedia playback with VLC media player and MPV for advanced video/audio support |
|
| **4** | Media Players | Multimedia playback with VLC media player and MPV for advanced video/audio support |
|
||||||
| **5** | Multimedia & Design | image editing (GIMP), video editing (Kdenlive, HandBrake), 3D modeling (Blender), audio recording (Audacity), and graphics design (Inkscape) |
|
| **5** | Multimedia & Design | image editing (GIMP), video editing (Kdenlive, HandBrake), 3D modeling (Blender), audio recording (Audacity), and graphics design (Inkscape) |
|
||||||
| **6** | Code Editors & IDEs | vim, vim-gtk3, Neovim, Helix, nano, Emacs, Kate, Mousepad, Gedit, Geany, GNOME Text Editor, and VSCodium (VS Code open-source) |
|
| **6** | Code Editors & IDEs | vim, vim-gtk3, Neovim, Helix, nano, Emacs, Kate, Mousepad, Gedit, Geany, GNOME Text Editor, and VSCodium (VS Code open-source) |
|
||||||
| **7** | Servers & Dev Tools | Web servers (Nginx/Apache), databases (PostgreSQL/MariaDB), Java Development Kit (Temurin 17/21/25 JDK), Docker, Python, SSH tools, fail2ban, Jellyfin Server and essential utilities |
|
| **7** | Servers & Dev Tools | Web servers (Nginx/Apache), databases (PostgreSQL/MariaDB), Java Development Kit (Temurin 17/21/25 JDK), Docker, Python, SSH tools, Jellyfin Server and essential utilities |
|
||||||
| **8** | Security & Networking | Wireshark, tcpdump, Zenmap, ClamAV, UFW, Fail2ban |
|
| **8** | Security & Networking | Wireshark, tcpdump, Zenmap, ClamAV, UFW, fail2ban |
|
||||||
| **9** | Software Centers | Choose a software store to install. |
|
| **9** | Software Centers | Choose a software store to install. |
|
||||||
| **10** | System Tools | htop/btop, ncdu, Timeshift, tmux/screen, nvme-cli, Flatpak support, extension repository manager and qemu/virtmanager |
|
| **10** | Office & Productivity | Choose a software store to install. |
|
||||||
| **11** | Fetch / System Info | fastfetch/neofetch, hyfetch, Linux logo and screenfetch |
|
| **12** | System Tools | htop/btop, ncdu, Timeshift, tmux/screen, nvme-cli, Flatpak support, extension repository manager and qemu/virtmanager |
|
||||||
| **12** | Back to Main Menu | Return directly to the main Debianito menu (exit submenu) |
|
| **12** | Fetch / System Info | fastfetch/neofetch, hyfetch, Linux logo and screenfetch |
|
||||||
|
| **13** | Back to Main Menu | Return directly to the main Debianito menu (exit submenu) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -84,9 +89,14 @@ The submenu offers the next categories:
|
|||||||
|
|
||||||
| Directory/File | Description |
|
| Directory/File | Description |
|
||||||
|----------------|-------------|
|
|----------------|-------------|
|
||||||
| `./debianito.sh` | Main entry point; handles menu navigation and system detection. |
|
| `debianito.sh` | Main entry point; handles menu navigation and system detection. |
|
||||||
| `/modules/` | Modular scripts for specific tasks: sudo config, repos, firmware, gpu, kernel, gaming, zram. |
|
| `docs/` | Documentation directory containing Markdown files for each module. |
|
||||||
| `/modules/extras/` | Split-by-category sub-modules for the "Install Programs and Software" menu (Option 9). |
|
| `modules/` | Core modular scripts organized by category: repos, gpu, gaming, kernel, firmware, zram, etc. |
|
||||||
|
| `modules/bullseye/` | Legacy Debian 11 (Bullseye) specific modules: `extras.sh`, `legacy.sh`, `repos.sh`. |
|
||||||
|
| `modules/extras/` | Software installer sub-modules split by category (themes, downloaders, internet, dev tools, etc.). |
|
||||||
|
| `modules/gaming/` | Gaming launcher and optimization scripts: Steam, Heroic, Lutris, performance tools. |
|
||||||
|
| `modules/gpu/` | GPU driver installation scripts for AMD and NVIDIA with architecture detection. |
|
||||||
|
| `modules/repos/` | Repository management scripts: migration tool (`migrate.sh`) and format detection (`repo_detect.sh`). |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
├── debianito.sh
|
├── debianito.sh
|
||||||
@@ -100,12 +110,16 @@ The submenu offers the next categories:
|
|||||||
│ ├── system_info.md
|
│ ├── system_info.md
|
||||||
│ ├── user_priv_feed.md
|
│ ├── user_priv_feed.md
|
||||||
│ └── zram.md
|
│ └── zram.md
|
||||||
|
├── media
|
||||||
|
│ └── gift
|
||||||
|
│ └── script.gif
|
||||||
├── modules
|
├── modules
|
||||||
│ ├── bluetooth.sh
|
│ ├── bluetooth.sh
|
||||||
│ ├── bullseye
|
│ ├── bullseye
|
||||||
│ │ ├── extras.sh
|
│ │ ├── extras.sh
|
||||||
│ │ ├── legacy.sh
|
│ │ ├── legacy.sh
|
||||||
│ │ └── repos.sh
|
│ │ └── repos.sh
|
||||||
|
│ ├── desktop_display.sh
|
||||||
│ ├── extras
|
│ ├── extras
|
||||||
│ │ ├── design
|
│ │ ├── design
|
||||||
│ │ │ └── design.sh
|
│ │ │ └── design.sh
|
||||||
@@ -158,15 +172,17 @@ The submenu offers the next categories:
|
|||||||
│ ├── gpu.sh
|
│ ├── gpu.sh
|
||||||
│ ├── kernel.sh
|
│ ├── kernel.sh
|
||||||
│ ├── repos
|
│ ├── repos
|
||||||
|
│ │ ├── migrate.sh
|
||||||
│ │ └── repo_detect.sh
|
│ │ └── repo_detect.sh
|
||||||
│ ├── repos.sh
|
│ ├── repos.sh
|
||||||
|
│ ├── rescue.sh
|
||||||
│ ├── sudo_config.sh
|
│ ├── sudo_config.sh
|
||||||
|
│ ├── swap.sh
|
||||||
│ ├── sysinfo.sh
|
│ ├── sysinfo.sh
|
||||||
│ ├── utils.sh
|
│ ├── utils.sh
|
||||||
│ └── zram.sh
|
│ └── zram.sh
|
||||||
└── README.md
|
└── README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
> 🤖 **AI-Assisted Development Note**
|
> 🤖 **AI-Assisted Development Note**
|
||||||
|
|||||||
+36
-12
@@ -28,6 +28,9 @@ source "${MODULES_DIR}/repos.sh"
|
|||||||
[ -f "${MODULES_DIR}/extras.sh" ] && source "${MODULES_DIR}/extras.sh"
|
[ -f "${MODULES_DIR}/extras.sh" ] && source "${MODULES_DIR}/extras.sh"
|
||||||
[ -f "${MODULES_DIR}/zram.sh" ] && source "${MODULES_DIR}/zram.sh"
|
[ -f "${MODULES_DIR}/zram.sh" ] && source "${MODULES_DIR}/zram.sh"
|
||||||
[ -f "${MODULES_DIR}/extras/java.sh" ] && source "${MODULES_DIR}/extras/java.sh"
|
[ -f "${MODULES_DIR}/extras/java.sh" ] && source "${MODULES_DIR}/extras/java.sh"
|
||||||
|
[ -f "${MODULES_DIR}/rescue.sh" ] && source "${MODULES_DIR}/rescue.sh"
|
||||||
|
[ -f "${MODULES_DIR}/swap.sh" ] && source "${MODULES_DIR}/swap.sh"
|
||||||
|
[ -f "${MODULES_DIR}/desktop_display.sh" ] && source "${MODULES_DIR}/desktop_display.sh"
|
||||||
|
|
||||||
# ── Bullseye-specific modules (loaded only on Debian 11) ──
|
# ── Bullseye-specific modules (loaded only on Debian 11) ──
|
||||||
if [ -d "${MODULES_DIR}/bullseye" ]; then
|
if [ -d "${MODULES_DIR}/bullseye" ]; then
|
||||||
@@ -42,27 +45,31 @@ DEBIAN_CODENAME=""
|
|||||||
|
|
||||||
main_menu() {
|
main_menu() {
|
||||||
# Auto-adjust TUI dimensions for small terminals
|
# Auto-adjust TUI dimensions for small terminals
|
||||||
if [ "$LINES" -lt $((TUI_ALTO + 6)) ] || [ "$COLUMNS" -lt $((TUI_ANCHO + 6)) ]; then
|
if [ "${LINES:-24}" -lt $((TUI_ALTO + 6)) ] || [ "${COLUMNS:-80}" -lt $((TUI_ANCHO + 6)) ]; then
|
||||||
TUI_ALTO=$((LINES - 4 > 8 ? LINES - 4 : 8))
|
TUI_ALTO=$((LINES - 4 > 8 ? LINES - 4 : 8))
|
||||||
TUI_ANCHO=$((COLUMNS - 4 > 50 ? COLUMNS - 4 : 50))
|
TUI_ANCHO=$((COLUMNS - 4 > 50 ? COLUMNS - 4 : 50))
|
||||||
TUI_ALTO_LISTA=$((TUI_ALTO - 10 > 4 ? TUI_ALTO - 10 : 4))
|
TUI_ALTO_LISTA=$((TUI_ALTO - 10 > 4 ? TUI_ALTO - 10 : 4))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
|
sudo -v >/dev/null 2>&1 || true
|
||||||
|
local STATE_REFRESHED=false
|
||||||
local choice
|
local choice
|
||||||
choice=$(whiptail --title "DEBIANITO — simple configurator script" --menu "" \
|
choice=$(_menu "DEBIANITO — Simple Configurator Script" "" \
|
||||||
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"1" "System Info" \
|
"1" "System Information" \
|
||||||
"2" "User Privileges & Feedback" \
|
"2" "User Privileges & Feedback" \
|
||||||
"3" "Configure repositories" \
|
"3" "Configure Repositories" \
|
||||||
"4" "Firmware, Wireless & Bluetooth" \
|
"4" "Firmware, Wireless & Bluetooth" \
|
||||||
"5" "Graphics Drivers & Mesa Stack" \
|
"5" "Graphics Drivers & Mesa Stack" \
|
||||||
"6" "Backports Kernel" \
|
"6" "Backports Kernel" \
|
||||||
"7" "Gaming Setup" \
|
"7" "Gaming Setup" \
|
||||||
"8" "ZRAM (Swap)" \
|
"8" "ZRAM" \
|
||||||
"9" "Install Programs and Software" \
|
"9" "Swap Management" \
|
||||||
"10" "Exit" \
|
"10" "Install Programs and Software" \
|
||||||
3>&1 1>&2 2>&3)
|
"11" "Boot Rescue + GRUB" \
|
||||||
|
"12" "Desktop & Display" \
|
||||||
|
"13" "Exit")
|
||||||
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
@@ -75,6 +82,7 @@ main_menu() {
|
|||||||
else
|
else
|
||||||
configure_repos || true
|
configure_repos || true
|
||||||
fi
|
fi
|
||||||
|
STATE_REFRESHED=true
|
||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
if [ "$DEBIAN_VERSION" = "11" ] && type install_firmware_bullseye &>/dev/null; then
|
if [ "$DEBIAN_VERSION" = "11" ] && type install_firmware_bullseye &>/dev/null; then
|
||||||
@@ -83,7 +91,7 @@ main_menu() {
|
|||||||
install_firmware || true
|
install_firmware || true
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
5) install_gpu_drivers || true ;;
|
5) install_gpu_drivers || true; STATE_REFRESHED=true ;;
|
||||||
6)
|
6)
|
||||||
if [ "$DEBIAN_VERSION" = "11" ]; then
|
if [ "$DEBIAN_VERSION" = "11" ]; then
|
||||||
_msg "Not Available" \
|
_msg "Not Available" \
|
||||||
@@ -93,6 +101,7 @@ kernels. Use the stable kernel provided by Bullseye." 10 60
|
|||||||
else
|
else
|
||||||
install_kernel_backports || true
|
install_kernel_backports || true
|
||||||
fi
|
fi
|
||||||
|
STATE_REFRESHED=true
|
||||||
;;
|
;;
|
||||||
7)
|
7)
|
||||||
if [ "$DEBIAN_VERSION" = "11" ] && type install_gaming_bullseye &>/dev/null; then
|
if [ "$DEBIAN_VERSION" = "11" ] && type install_gaming_bullseye &>/dev/null; then
|
||||||
@@ -100,24 +109,38 @@ kernels. Use the stable kernel provided by Bullseye." 10 60
|
|||||||
else
|
else
|
||||||
install_gaming || true
|
install_gaming || true
|
||||||
fi
|
fi
|
||||||
|
STATE_REFRESHED=true
|
||||||
;;
|
;;
|
||||||
8) install_zram || true ;;
|
8) install_zram || true ;;
|
||||||
9)
|
9) manage_swap || true; STATE_REFRESHED=true ;;
|
||||||
|
10)
|
||||||
if [ "$DEBIAN_VERSION" = "11" ] && type install_extras_bullseye &>/dev/null; then
|
if [ "$DEBIAN_VERSION" = "11" ] && type install_extras_bullseye &>/dev/null; then
|
||||||
install_extras_bullseye || true
|
install_extras_bullseye || true
|
||||||
else
|
else
|
||||||
install_extras || true
|
install_extras || true
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
10) echo "Exiting."; exit 0 ;;
|
11) rescue_boot || true ;;
|
||||||
|
12) manage_desktop_display || true ;;
|
||||||
|
13) echo "Exiting."; exit 0 ;;
|
||||||
esac
|
esac
|
||||||
|
if $STATE_REFRESHED; then
|
||||||
|
refresh_system_state
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
check_root
|
check_root
|
||||||
check_sudo
|
check_sudo
|
||||||
|
if ! _check_network; then
|
||||||
|
echo -e "${YELLOW}──────────────────────────────────────────${NC}"
|
||||||
|
echo -e "${YELLOW} No internet connectivity detected.${NC}"
|
||||||
|
echo -e "${YELLOW} Package installation will fail without network.${NC}"
|
||||||
|
echo -e "${YELLOW} You can use: System Info, User Privileges, and${NC}"
|
||||||
|
echo -e "${YELLOW} other offline features.${NC}"
|
||||||
|
echo -e "${YELLOW}──────────────────────────────────────────${NC}"
|
||||||
|
fi
|
||||||
check_system_time
|
check_system_time
|
||||||
sync_system_time
|
|
||||||
|
|
||||||
detect_debian_version
|
detect_debian_version
|
||||||
detect_cpu_ram
|
detect_cpu_ram
|
||||||
@@ -127,6 +150,7 @@ detect_network
|
|||||||
detect_displayserver
|
detect_displayserver
|
||||||
detect_storage
|
detect_storage
|
||||||
detect_desktop_environment
|
detect_desktop_environment
|
||||||
|
_configure_lightdm
|
||||||
detect_audio_server
|
detect_audio_server
|
||||||
|
|
||||||
# ── Bullseye-specific init (archive phase) ──
|
# ── Bullseye-specific init (archive phase) ──
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
## Option 11: Boot Rescue & Repair
|
||||||
|
|
||||||
|
### 1. What does this component do?
|
||||||
|
This component serves as a comprehensive rescue toolkit designed to diagnose and fix boot-related issues on Debian systems, specifically targeting GRUB configuration, UEFI Secure Boot integrity, and initrd image validity. It provides three primary operations: configuring the GRUB boot menu behavior (including timeout adjustments and visibility settings), repairing UEFI Secure Boot by reinstalling signed bootloader packages after kernel or driver changes, and regenerating initramfs images to resolve missing driver errors. All modifications are protected by automatic backup creation before system files are altered, with built-in rollback mechanisms that restore the original state if any operation fails during execution.
|
||||||
|
|
||||||
|
### 2. Logical Execution Flow
|
||||||
|
|
||||||
|
**Block 1 — GRUB Boot Menu Settings**
|
||||||
|
- **Menu Options:** Users select from four presets or a custom option to control boot behavior:
|
||||||
|
1. Hide GRUB menu entirely (Fastest boot, requires holding ESC during power-on).
|
||||||
|
2. Show 3-second countdown (Faster boot).
|
||||||
|
3. Show menu for 5 seconds (Default behavior).
|
||||||
|
4. Custom timeout (User inputs specific seconds; -1 allows indefinite wait).
|
||||||
|
- **Variable Application:** Each selection updates three core variables: `GRUB_TIMEOUT`, `GRUB_TIMEOUT_STYLE`, and `GRUB_RECORDFAIL_TIMEOUT`. The custom option also allows setting `GRUB_DISABLE_OS_PROBER` to prevent extra entries.
|
||||||
|
- **Backup & Safety:** Before applying changes, the script creates a timestamped backup of `/etc/default/grub`. It writes an override configuration file at `/etc/default/grub.d/99_script_override.cfg` to ensure settings persist across updates.
|
||||||
|
- **Execution & Rollback:** The system runs `update-grub` to apply changes. If this command fails, the script automatically restores the timestamped backup and removes the override file to prevent boot issues.
|
||||||
|
|
||||||
|
**Block 2 — UEFI Secure Boot Repair**
|
||||||
|
- **Pre-checks:** Before proceeding, the script verifies two conditions:
|
||||||
|
1. The system is running in UEFI mode (checks for existence of `/sys/firmware/efi`).
|
||||||
|
2. Secure Boot is currently enabled (uses `mokutil --sb-state` to confirm status).
|
||||||
|
- **Skip Logic:** If either check fails, the process stops immediately with a message indicating no repair is needed or applicable.
|
||||||
|
- **Repair Steps:** Upon user confirmation:
|
||||||
|
1. Reinstalls signed boot packages (`shim-signed`, `grub-efi-amd64-signed`, `linux-image-amd64`).
|
||||||
|
2. Reinstalls GRUB to the EFI partition using `grub-install` with the appropriate target and directory detection (preferring `/boot/efi` over `/boot`).
|
||||||
|
3. Regenerates the GRUB configuration via `update-grub`.
|
||||||
|
|
||||||
|
**Block 3 — Initramfs Regeneration**
|
||||||
|
- **Confirmation:** The script prompts for user confirmation before proceeding to avoid unintended rebuilds.
|
||||||
|
- **Execution:** Upon approval, it runs `update-initramfs -u -k all` to regenerate initrd images for all installed kernels.
|
||||||
|
- **Purpose:** This fixes boot issues caused by missing drivers or corrupted initrd images that prevent the system from loading properly.
|
||||||
|
|
||||||
|
### 3. Intelligent Automation
|
||||||
|
|
||||||
|
- **EFI Directory Detection:** The script intelligently detects the EFI partition, checking `/boot/efi` first and falling back to `/boot` if necessary.
|
||||||
|
- **Secure Boot State Verification:** Instead of assuming Secure Boot is active, it uses `mokutil --sb-state` to verify the actual state before attempting repairs on non-UEFI or disabled systems.
|
||||||
|
- **GRUB Backup Strategy:** A timestamped backup file (e.g., `/etc/default/grub.backup.YYYYMMDD_HHMMSS`) is created prior to any modification, ensuring a safe point for rollback.
|
||||||
|
- **Rollback Mechanism:** If `update-grub` fails during the GRUB settings or Secure Boot repair process, the script automatically restores the backup and cleans up temporary override files.
|
||||||
|
- **Override Persistence:** Configuration values are written to `/etc/default/grub.d/99_script_override.cfg`, ensuring that changes survive package updates which might otherwise reset `/etc/default/grub`.
|
||||||
|
- **Input Validation:** Custom timeout inputs are validated using regex matching for integers (e.g., `^-?[0-9]+$`), allowing negative numbers like -1 while rejecting invalid text.
|
||||||
|
- **Variable Handling Logic:** The `_set_grub_var()` function handles three distinct cases: updating an existing variable, uncommenting a commented variable, or appending a new variable if it does not exist in the configuration file.
|
||||||
|
|
||||||
|
### 4. Paquetes y Recursos Gestionados
|
||||||
|
|
||||||
|
**Boot Packages Reinstalled (Secure Boot Repair):**
|
||||||
|
| Package | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| shim-signed | UEFI Secure Boot shim (first-stage bootloader) |
|
||||||
|
| grub-efi-amd64-signed | Signed GRUB for UEFI |
|
||||||
|
| linux-image-amd64 | Kernel image (re-signed) |
|
||||||
|
|
||||||
|
**GRUB Settings Modified:**
|
||||||
|
| Variable | Option 1 | Option 2 | Option 3 | Custom |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| GRUB_TIMEOUT | 0 | 3 | 5 | User value |
|
||||||
|
| GRUB_TIMEOUT_STYLE | hidden | menu | menu | menu |
|
||||||
|
| GRUB_RECORDFAIL_TIMEOUT | 0 | 3 | 5 | User value |
|
||||||
|
| GRUB_DISABLE_OS_PROBER | true | — | — | — |
|
||||||
|
|
||||||
|
**System Files Modified:**
|
||||||
|
| Package | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| /etc/default/grub | Main GRUB configuration |
|
||||||
|
| /etc/default/grub.d/99_script_override.cfg | Persistent override (survives grub updates) |
|
||||||
|
| /etc/default/grub.backup.* | Timestamped backup (auto-created) |
|
||||||
|
|
||||||
|
>**Note UEFI:** The Secure Boot repair ONLY works on UEFI systems. The script checks for `/sys/firmware/efi` and `mokutil --sb-state` before attempting anything. Legacy BIOS systems are automatically skipped.
|
||||||
|
|
||||||
|
>**Note GRUB:** After hiding the GRUB menu (Option 1), you must hold ESC immediately after powering on to access the menu. There is no other way to reach it during boot.
|
||||||
|
|
||||||
|
> **Technical data:** The override file at `/etc/default/grub.d/99_script_override.cfg` persists across kernel updates because GRUB reads drop-in configs from that directory. This is more reliable than editing `/etc/default/grub` directly for values that should survive updates.
|
||||||
|
|
||||||
|
> **Technical data:** `GRUB_DISABLE_OS_PROBER=true` is set when hiding the menu to prevent OS prober from adding extra entries that would require the menu to appear. For multi-boot systems, use Option 3 or Custom instead.
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
## Option 12: Desktop & Display
|
||||||
|
|
||||||
|
### 1. What does this component do?
|
||||||
|
This component manages display managers (the login screen you see before entering your desktop). It allows users to install and configure LightDM, GDM3, SDDM, or greetd. It handles autologin setup, user list visibility toggles, and a specific Wayland override for NVIDIA GPUs. Currently, Desktop Environment management is marked as "Coming Soon".
|
||||||
|
|
||||||
|
### 2. Logical Flow of Execution
|
||||||
|
The execution logic is divided into five functional blocks:
|
||||||
|
|
||||||
|
**Block 1 — Display Manager Selection**
|
||||||
|
- The main menu offers two primary options within Option 12: "Desktop Environment" (currently unavailable) and "Display Manager".
|
||||||
|
- Selecting "Display Manager" opens a submenu listing available display managers based on the Debian version.
|
||||||
|
- **Available Managers:**
|
||||||
|
- LightDM (available on all Debian versions).
|
||||||
|
- GDM3 (available on all Debian versions).
|
||||||
|
- SDDM (available on all Debian versions).
|
||||||
|
- greetd (available only on Debian 12 and 13).
|
||||||
|
- Each selected manager opens its own dedicated configuration submenu.
|
||||||
|
|
||||||
|
**Block 2 — LightDM Configuration**
|
||||||
|
- A checklist menu presents three options:
|
||||||
|
1. Install LightDM + GTK Greeter (auto-selects the display manager via debconf-set-selections).
|
||||||
|
2. Enable user list at login screen (writes `greeter-hide-users=false` to a configuration file in `.conf.d`).
|
||||||
|
3. Enable autologin for current user (uncomments `autologin-user` and sets timeout to 0 in the main config).
|
||||||
|
- **Idempotency:** The script checks if `lightdm` and `lightdm-gtk-greeter-settings` are already installed before attempting installation, skipping redundant steps.
|
||||||
|
|
||||||
|
**Block 3 — GDM3 Configuration**
|
||||||
|
- A checklist menu presents up to four options:
|
||||||
|
1. Install/Reinstall gdm3 (auto-selects via debconf).
|
||||||
|
2. Toggle user list visibility (toggles `disable-user-list` in greeter.dconf-defaults).
|
||||||
|
3. Configure autologin (prompts for a username via whiptail inputbox to set in daemon.conf).
|
||||||
|
4. Force Enable Wayland on NVIDIA (Bookworm/Trixie + NVIDIA only).
|
||||||
|
- **Mechanism:** Creates or removes a symlink: `/etc/udev/rules.d/61-gdm.rules` → `/dev/null`.
|
||||||
|
- **Purpose:** This disables the udev rule that blocks GDM from using Wayland on NVIDIA GPUs.
|
||||||
|
- **Risk Warning:** Displays a warning that this may break graphics or cause instability.
|
||||||
|
- **Toggle Behavior:** If the symlink exists, removing it reverts to default behavior; if not present, creating it enables the override.
|
||||||
|
|
||||||
|
**Block 4 — SDDM Configuration**
|
||||||
|
- A submenu offers two options:
|
||||||
|
1. Install SDDM (auto-selects via debconf).
|
||||||
|
2. Enable Autologin:
|
||||||
|
- **Session Detection:** Auto-detects the installed session by checking `.desktop` files in priority order: `plasmawayland` → `lxqt-wayland` → `plasma` → `lxqt`.
|
||||||
|
- **Configuration:** Writes autologin settings to `/etc/sddm.conf.d/autologin.conf`.
|
||||||
|
- **Fallback:** If no session is found, it enables autologin but warns that SDDM will use the default session.
|
||||||
|
|
||||||
|
**Block 5 — greetd Configuration**
|
||||||
|
- greetd is a minimal, modern display manager designed for Wayland environments.
|
||||||
|
- Submenu options vary by Debian version:
|
||||||
|
- **All Versions:** Install base `greetd`, Install `greetd` + `tuigreet` (recommended TUI greeter).
|
||||||
|
- **Debian 13 only:** Additional options to install `gtk-greet`, `nwg-hello`, or `wlgreet`.
|
||||||
|
- **Backports Handling:** On Bookworm, `tuigreet` is installed from backports if not enabled.
|
||||||
|
- **Important Warning:** greetd is installed but NOT configured by the script. The user must manually create `/etc/greetd/config.toml` to be able to log in. The script displays a warning with references to man pages for configuration details.
|
||||||
|
|
||||||
|
### 3. Smart Automations
|
||||||
|
The component utilizes several intelligent automation features:
|
||||||
|
- **debconf-set-selections:** Pre-selects the display manager as default before `apt install`, preventing the interactive "Configuring shared/default-x-display-manager" dialog that would otherwise pause the script execution.
|
||||||
|
- **Session Auto-Detection (SDDM):** Checks `.desktop` files in priority order (Wayland first, then X11) to set the correct session type for autologin configuration.
|
||||||
|
- **Wayland Toggle:** Creates or removes a udev rule symlink to `/dev/null`. This is a known workaround that disables the GDM rule blocking NVIDIA Wayland support.
|
||||||
|
- **greetd Backports:** On Bookworm, `tuigreet` is installed from backports (newer version) if not already enabled in the system.
|
||||||
|
- **Manual Config Warning:** The script explicitly informs users that greetd requires manual configuration and points to man pages for further details.
|
||||||
|
- **User Detection:** Uses `SUDO_USER` (the real user who ran sudo) instead of `$USER` (which is root during script execution). This ensures the correct user is set for automatic login across all display managers.
|
||||||
|
|
||||||
|
### 4. Packages and Resources Managed
|
||||||
|
|
||||||
|
**Display Manager Packages:**
|
||||||
|
| DM | Packages | Debian Versions |
|
||||||
|
|---|---|---|
|
||||||
|
| LightDM | lightdm, lightdm-gtk-greeter, lightdm-gtk-greeter-settings | All |
|
||||||
|
| GDM3 | gdm3 | All |
|
||||||
|
| SDDM | sddm | All |
|
||||||
|
| greetd (base) | greetd | 12, 13 |
|
||||||
|
| greetd + tuigreet | greetd, tuigreet | 12 (backports), 13 |
|
||||||
|
| greetd + gtk-greet | greetd, gtk-greet | 13 only |
|
||||||
|
| greetd + nwg-hello | greetd, nwg-hello | 13 only |
|
||||||
|
| greetd + wlgreet | greetd, wlgreet | 13 only |
|
||||||
|
|
||||||
|
**Configuration Files Modified:**
|
||||||
|
| DM | File Path | Configuration Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| LightDM | /etc/lightdm/lightdm.conf.d/50-debianito-userlist.conf | User list visibility toggle |
|
||||||
|
| LightDM | /etc/lightdm/lightdm.conf | Autologin user + timeout settings |
|
||||||
|
| GDM3 | /etc/gdm3/greeter.dconf-defaults | User list toggle (disable-user-list) |
|
||||||
|
| GDM3 | /etc/gdm3/daemon.conf | Autologin user and enable flag |
|
||||||
|
| GDM3 | /etc/udev/rules.d/61-gdm.rules | Wayland override (symlink to /dev/null) |
|
||||||
|
| SDDM | /etc/sddm.conf.d/autologin.conf | Autologin user + session type |
|
||||||
|
|
||||||
|
**Session Detection Priority (SDDM Autologin):**
|
||||||
|
| Priority | Session File | Session Type |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | /usr/share/wayland-sessions/plasmawayland.desktop | KDE Wayland |
|
||||||
|
| 2 | /usr/share/wayland-sessions/lxqt-wayland.desktop | LXQt Wayland |
|
||||||
|
| 3 | /usr/share/xsessions/plasma.desktop | KDE X11 |
|
||||||
|
| 4 | /usr/share/xsessions/lxqt.desktop | LXQt X11 |
|
||||||
|
|
||||||
|
> ⚠️ **Warning: Wayland on NVIDIA:** The "Force Enable Wayland on NVIDIA" option creates a symlink that disables the GDM udev rule. This is a known workaround but MAY cause graphics instability or breakage. To revert, remove `/etc/udev/rules.d/61-gdm.rules`.
|
||||||
|
|
||||||
|
> ⚠️ **Warning: greetd:** Unlike other display managers, greetd is installed but NOT configured by this script. You MUST manually create `/etc/greetd/config.toml` before you can log in. See `man greetd` and `man 5 greetd-sessions` for configuration details.
|
||||||
|
|
||||||
|
> ⚠️ **Warning: Autologin:** All autologin configurations use `SUDO_USER` (the user who ran sudo) instead of `$USER` (which is root during script execution). This ensures the correct user is set for automatic login.
|
||||||
|
|
||||||
|
> 💡 **Technical Note:** `debconf-set-selections` pre-selects the display manager before apt install, preventing the interactive "Configuring shared/default-x-display-manager" dialog that would otherwise pause the script.
|
||||||
+26
-7
@@ -116,16 +116,35 @@ This approach eliminates the security risk of running OpenRGB as root while main
|
|||||||
| **Temurin 17** | Modern Minecraft servers, newer game clients | Balances performance and compatibility for post-1.16+ game versions |
|
| **Temurin 17** | Modern Minecraft servers, newer game clients | Balances performance and compatibility for post-1.16+ game versions |
|
||||||
| **Temurin 21** | Latest game engines, cutting-edge mods | Provides best performance for modern Java applications |
|
| **Temurin 21** | Latest game engines, cutting-edge mods | Provides best performance for modern Java applications |
|
||||||
|
|
||||||
The script injects the official Adoptium repository to pull community-maintained builds rather than Oracle's proprietary JRE:
|
**Repository Management via extrepo:** The script leverages the `extrepo` utility to manage external repositories cleanly rather than manually injecting repository URLs into system files. This approach offers several advantages:
|
||||||
```bash
|
|
||||||
# Repository injection logic (simplified)
|
|
||||||
echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | sudo tee /etc/apt/sources.list.d/adoptium.list
|
|
||||||
```
|
|
||||||
|
|
||||||
**Version Selection Logic:** Users can choose which Temurin version to install based on their specific game requirements. The module justifies offering all three versions because:
|
1. **Automated Keyring Handling:** `extrepo` manages GPG keys and source file configurations automatically, eliminating manual intervention with `/etc/apt/sources.list.d/`.
|
||||||
|
2. **Dependency Resolution:** The utility checks for its own installation and handles the enabling of the Adoptium Temurin repository before proceeding with package installation.
|
||||||
|
3. **Maintenance Safety:** Updates to the upstream repository are reflected through `extrepo` without requiring direct edits to system configuration files, reducing the risk of breakage during OS updates.
|
||||||
|
|
||||||
|
**Version Selection Logic:** Users can choose which Temurin version to install based on their specific game requirements via a TUI menu (`install_minecraft_java()`). The module justifies offering all three versions because:
|
||||||
|
|
||||||
1. **Backward Compatibility:** Java 8 remains in use by many Minecraft mods and older game clients that haven't been updated for newer JVMs
|
1. **Backward Compatibility:** Java 8 remains in use by many Minecraft mods and older game clients that haven't been updated for newer JVMs
|
||||||
2. **Performance Optimization:** Java 21 provides the best performance characteristics for modern games with heavy multithreading requirements
|
2. **Performance Optimization:** Java 21 provides the best performance characteristics for modern games with heavy multithreading requirements
|
||||||
3. **Security Updates:** All Temurin versions receive regular security patches from the Eclipse Foundation community
|
3. **Security Updates:** All Temurin versions receive regular security patches from the Eclipse Foundation community
|
||||||
|
|
||||||
The installation process ensures clean repository management without polluting the system with multiple conflicting JRE installations, maintaining Debian's package integrity while providing flexibility for different gaming scenarios.
|
The installation process ensures clean repository management without polluting the system with multiple conflicting JRE installations, maintaining Debian's package integrity while providing flexibility for different gaming scenarios. It automatically installs `extrepo` if not present and enables the Adoptium source before proceeding with version-specific packages (e.g., `temurin-8-jre`, `temurin-17-jre`).
|
||||||
|
|
||||||
|
|
||||||
|
### References:
|
||||||
|
|
||||||
|
- [https://wiki.debian.org/Steam](https://wiki.debian.org/Steam)
|
||||||
|
- [wiki.archlinux.org/title/Steam](wiki.archlinux.org/title/Steam)
|
||||||
|
- [https://repo.steampowered.com/steam/](https://repo.steampowered.com/steam/)
|
||||||
|
- [https://www.protondb.com/](https://www.protondb.com/)
|
||||||
|
- [https://github.com/lutris/lutris](https://github.com/lutris/lutris)
|
||||||
|
- [https://github.com/lutris/docs/blob/master/InstallingDrivers.md](https://github.com/lutris/docs/blob/master/InstallingDrivers.md)
|
||||||
|
- [https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher](https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher)
|
||||||
|
- [https://github.com/flightlessmango/Mangohud](https://github.com/flightlessmango/Mangohud)
|
||||||
|
- [https://github.com/feralinteractive/gamemode](https://github.com/feralinteractive/gamemode)
|
||||||
|
- [https://gitlab.com/CalcProgrammer1/OpenRGB](https://gitlab.com/CalcProgrammer1/OpenRGB)
|
||||||
|
- [https://adoptium.net/es/installation/linux](https://adoptium.net/es/installation/linux)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+9
-7
@@ -48,9 +48,10 @@ This "detect-then-deploy" model prevents users from installing unnecessary drive
|
|||||||
| **Gen4** (Broadwater) | 65nm | GMA X4500, GMA X4500HD | `i915` | `i915` | Not supported | Predecessor to HD Graphics. Very limited support. The i915 DRI driver is the original, now obsolete. |
|
| **Gen4** (Broadwater) | 65nm | GMA X4500, GMA X4500HD | `i915` | `i915` | Not supported | Predecessor to HD Graphics. Very limited support. The i915 DRI driver is the original, now obsolete. |
|
||||||
| **Gen5** (Ironlake) | 32nm | HD Graphics (Westmere/Arrandale) | `i915` | `crocus` | Not supported | First generation "HD Graphics". OpenGL up to 3.3 only. Legacy driver `i965` was **removed** in Mesa 24.1, so `crocus` is now the only option. |
|
| **Gen5** (Ironlake) | 32nm | HD Graphics (Westmere/Arrandale) | `i915` | `crocus` | Not supported | First generation "HD Graphics". OpenGL up to 3.3 only. Legacy driver `i965` was **removed** in Mesa 24.1, so `crocus` is now the only option. |
|
||||||
| **Gen6** (Sandy Bridge) | 32nm | HD Graphics 2000/3000 | `i915` | `crocus` | Not supported | Significant performance improvement. Maximum OpenGL 3.3. |
|
| **Gen6** (Sandy Bridge) | 32nm | HD Graphics 2000/3000 | `i915` | `crocus` | Not supported | Significant performance improvement. Maximum OpenGL 3.3. |
|
||||||
| **Gen7** (Ivy Bridge) | 22nm | HD Graphics 2500/4000 | `i915` | `crocus` | Not supported | First generation at 22nm. `crocus` is the recommended driver. |
|
| **Gen7** (Ivy Bridge) | 22nm | HD Graphics 2500/4000 | `i915` | `crocus` | `ANV/HASVK` [(incomplete/broken)](https://www.reddit.com/r/vulkan/s/Hnf5zU8WZY) | First Gen at 22nm. `crocus` is the recommended OpenGL driver. Vulkan is exposed but completely non-conformant (0.0.0.0 ), lacks basic features (e.g., texture swizzle), and is [unusable for real-world tasks](https://www.phoronix.com/news/Intel-HasVK-Drop-Dead-Code).|
|
||||||
|
| **Gen7** (Bay Trail) | 22nm | HD Graphics (Bay Trail) | `i915` | `crocus` | `ANV`[(incomplete)](https://lists.debian.org/debian-user/2023/07/msg00550.html) | `conformanceVersion = 0.0.0.0` Support is experimental up to Vulkan 1.2, lacks basic extensions, and may cause instability. The separate HASVK driver exists but is not used on this system. |
|
||||||
| **Gen7.5** (Haswell) | 22nm | HD Graphics 4600, Iris Pro 5200 | `i915` | `crocus` | `hasvk` | Vulkan support via community driver `hasvk` (Vulkan 1.3). |
|
| **Gen7.5** (Haswell) | 22nm | HD Graphics 4600, Iris Pro 5200 | `i915` | `crocus` | `hasvk` | Vulkan support via community driver `hasvk` (Vulkan 1.3). |
|
||||||
| **Gen8** (Broadwell) | 14nm | HD Graphics 5300, Iris Pro 6200, Iris 6100 | `i915` | `iris/crocus` | `hasvk` | First generation at 14nm, `iris` becomes the main OpenGL driver. |
|
| **Gen8** (Broadwell) | 14nm | HD Graphics 5300, Iris Pro 6200, Iris 6100 | `i915` | `iris` | `hasvk` | First generation at 14nm, `iris` becomes the main OpenGL driver. |
|
||||||
| **Gen9** (Skylake) | 14nm | HD Graphics 530, Iris 540/550 | `i915` | `iris` | `anv` | Mature architecture with strong Linux support. Major performance boost for iGPU. |
|
| **Gen9** (Skylake) | 14nm | HD Graphics 530, Iris 540/550 | `i915` | `iris` | `anv` | Mature architecture with strong Linux support. Major performance boost for iGPU. |
|
||||||
| **Gen9.5** (Kaby Lake, Coffee Lake, Comet Lake) | 14nm+ / 14nm++ | UHD Graphics 620/630, UHD 610/630 | `i915` | `iris` | `anv` | Process node optimization for 14nm. "UHD" replaces "HD" in naming convention. |
|
| **Gen9.5** (Kaby Lake, Coffee Lake, Comet Lake) | 14nm+ / 14nm++ | UHD Graphics 620/630, UHD 610/630 | `i915` | `iris` | `anv` | Process node optimization for 14nm. "UHD" replaces "HD" in naming convention. |
|
||||||
| **Gen11** (Ice Lake) | 10nm | UHD Graphics G1, Iris Plus G4/G7 | `i915` | `iris` | `anv` | First architecture at 10nm. Vulkan 1.3+ support. |
|
| **Gen11** (Ice Lake) | 10nm | UHD Graphics G1, Iris Plus G4/G7 | `i915` | `iris` | `anv` | First architecture at 10nm. Vulkan 1.3+ support. |
|
||||||
@@ -59,7 +60,7 @@ This "detect-then-deploy" model prevents users from installing unnecessary drive
|
|||||||
| **Xe2-LPG** (Lunar Lake) | TSMC N3B | Arc Graphics (Xe2-LPG - 8 Xe-Cores) | `i915?/xe` | `iris` | `anv` | First iGPU with Xe2 architecture (Battlemage). |
|
| **Xe2-LPG** (Lunar Lake) | TSMC N3B | Arc Graphics (Xe2-LPG - 8 Xe-Cores) | `i915?/xe` | `iris` | `anv` | First iGPU with Xe2 architecture (Battlemage). |
|
||||||
| **Xe3-LPG** (Panther Lake) | Intel 18A | Arc Graphics (Xe3 iGPU) | `i915?/xe` | `iris` | `anv` | High-power iGPU. Requires Kernel 6.19 and Mesa 26 as base. |
|
| **Xe3-LPG** (Panther Lake) | Intel 18A | Arc Graphics (Xe3 iGPU) | `i915?/xe` | `iris` | `anv` | High-power iGPU. Requires Kernel 6.19 and Mesa 26 as base. |
|
||||||
| **Xe-HPG** (Alchemist) | TSMC N6 | **Arc A380, A580, A750, A770** (dGPU) | `i915/xe` | `iris` | `anv` | First modern dGPU (Arc). Support since Kernel 6 and Mesa 22. |
|
| **Xe-HPG** (Alchemist) | TSMC N6 | **Arc A380, A580, A750, A770** (dGPU) | `i915/xe` | `iris` | `anv` | First modern dGPU (Arc). Support since Kernel 6 and Mesa 22. |
|
||||||
| **Xe2-HPG** (Battlemage) | TSMC N5 | **Arc B580, B570** (dGPU) | `i915/xe` | `iris` | `anv` | Second generation dGPU. Very solid day-one Linux support since Kernel 6.12 and Mesa 24.2 |
|
| **Xe2-HPG** (Battlemage) | TSMC N5 | **Arc B570, B580** (dGPU) | [`i915/xe`](https://www.phoronix.com/review/intel-xe-i915-linux-619) | `iris` | `anv` | Second generation dGPU. Very solid day-one Linux support since Kernel 6.12 and Mesa 24.2 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -71,6 +72,7 @@ This "detect-then-deploy" model prevents users from installing unnecessary drive
|
|||||||
* **Legacy Hardware (Gen5-Gen8)**: The classic `i965` driver was **officially removed from Mesa in version 24.1**. **[`crocus`](https://www.phoronix.com/news/Intel-Crocus-Default-Gallium3D)** (Gallium3D) is the only active driver for this legacy hardware.
|
* **Legacy Hardware (Gen5-Gen8)**: The classic `i965` driver was **officially removed from Mesa in version 24.1**. **[`crocus`](https://www.phoronix.com/news/Intel-Crocus-Default-Gallium3D)** (Gallium3D) is the only active driver for this legacy hardware.
|
||||||
* **Modern Hardware (Gen9 and Xe)**: **`iris`** is the standard driver. It works excellently on both iGPUs and Arc dGPUs (Alchemist/Battlemage).
|
* **Modern Hardware (Gen9 and Xe)**: **`iris`** is the standard driver. It works excellently on both iGPUs and Arc dGPUs (Alchemist/Battlemage).
|
||||||
* **Vulkan**:
|
* **Vulkan**:
|
||||||
|
* **Old Hardware about Ivy Bridge and Bay Trail (Gen7)**: Although the ANV/HASVK drivers expose these GPUs as Vulkan devices (reporting API versions as high as 1.2 or 1.3), their state is completely non-compliant (conformanceVersion = 0.0.0.0). The support is purely theoretical, it lacks basic hardware features (e.g., texture swizzle on Ivy Bridge) and is unstable or unusable for real-world applications. Because of this, in Mesa 22.3, the Gen7/Gen8 Vulkan code was separated from the main driver (ANV) and moved to the legacy HASVK driver to avoid hindering the development of modern hardware. You can read the technical details of this decision [here](https://www.phoronix.com/news/Intel-HASVK-Old-Vulkan-Gen7-8).
|
||||||
* **Legacy Hardware (Gen7.5 - Gen8)**: Uses **[`hasvk`](https://www.phoronix.com/news/Intel-ANV-HASVK-Split-Merged)**, a community-maintained driver (not directly by Intel engineers), offering Vulkan 1.2? on 2013-era hardware.
|
* **Legacy Hardware (Gen7.5 - Gen8)**: Uses **[`hasvk`](https://www.phoronix.com/news/Intel-ANV-HASVK-Split-Merged)**, a community-maintained driver (not directly by Intel engineers), offering Vulkan 1.2? on 2013-era hardware.
|
||||||
*Additionally, in early 2024, the compiler code shared between `iris` and `anv` for [Gen8](https://www.phoronix.com/news/Intel-Mesa-Splitting-Gen8) was also isolated, following the same principle: to enable faster development for modern hardware without breaking Broadwell support*.
|
*Additionally, in early 2024, the compiler code shared between `iris` and `anv` for [Gen8](https://www.phoronix.com/news/Intel-Mesa-Splitting-Gen8) was also isolated, following the same principle: to enable faster development for modern hardware without breaking Broadwell support*.
|
||||||
* **Modern Hardware (Gen9+)**: **[`anv`](https://docs.mesa3d.org/drivers/anv.html)** is Intel's official driver. On recent hardware (Gen12+, Arc) it reaches the **Vulkan 1.4 standard**.
|
* **Modern Hardware (Gen9+)**: **[`anv`](https://docs.mesa3d.org/drivers/anv.html)** is Intel's official driver. On recent hardware (Gen12+, Arc) it reaches the **Vulkan 1.4 standard**.
|
||||||
@@ -118,7 +120,7 @@ These generations depend **exclusively** on the proprietary driver and closed st
|
|||||||
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
||||||
| **Fermi**<br>*(GF100/110)* | **390.xx** (Legacy) | `nvidia` (Closed) | **Vulkan 1.0** | No | **CUDA 8.0** | Last driver to support this architecture. Has not received security fixes for years. Only viable for completely offline systems. |
|
| **Fermi**<br>*(GF100/110)* | **390.xx** (Legacy) | `nvidia` (Closed) | **Vulkan 1.0** | No | **CUDA 8.0** | Last driver to support this architecture. Has not received security fixes for years. Only viable for completely offline systems. |
|
||||||
| **Kepler**<br>*(GK100/110)* | **470.xx** (Legacy) | `nvidia` (Closed) | **Vulkan 1.2** | No | **CUDA 11.8** | Last generation to receive "Legacy" status. Good compatibility with OpenGL 4.6, but Vulkan support stalled at 1.2. |
|
| **Kepler**<br>*(GK100/110)* | **470.xx** (Legacy) | `nvidia` (Closed) | **Vulkan 1.2** | No | **CUDA 11.8** | Last generation to receive "Legacy" status. Good compatibility with OpenGL 4.6, but Vulkan support stalled at 1.2. |
|
||||||
| **Maxwell**<br>*(GM100/200)* | **580.xx** (Old Standard) | `nvidia` (Closed) | **Vulkan 1.3** | No | **CUDA 12.0** | Removed from official support in driver 555 (CUDA 12.1). Requires pinning system to branch 550. |
|
| **Maxwell**<br>*(GM100/200)* | **580.xx** (Old Standard) | `nvidia` (Closed) | **Vulkan 1.3** | No | **CUDA 12.0** | Removed from official support in driver 580 (CUDA 12.1). |
|
||||||
| **Pascal**<br>*(GP100/102/104)* | **580.xx** (Old Standard) | `nvidia` (Closed) | **Vulkan 1.3** | No | **CUDA 12.0** | Shares same fate as Maxwell. Still very popular (GTX 1060/1080), but requires blocking packages (e.g., in Debian) to prevent updates that break graphics support. |
|
| **Pascal**<br>*(GP100/102/104)* | **580.xx** (Old Standard) | `nvidia` (Closed) | **Vulkan 1.3** | No | **CUDA 12.0** | Shares same fate as Maxwell. Still very popular (GTX 1060/1080), but requires blocking packages (e.g., in Debian) to prevent updates that break graphics support. |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -131,7 +133,7 @@ Starting with Turing, NVIDIA introduced the **open kernel module**. From driver
|
|||||||
| **Turing**<br>*(TU100/102/116)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | First generation to use Open Kernel Module (introduced in 515, default in 525). *Note:* Security processor firmware (GSP) remains a closed blob. Excellent NVK support. |
|
| **Turing**<br>*(TU100/102/116)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | First generation to use Open Kernel Module (introduced in 515, default in 525). *Note:* Security processor firmware (GSP) remains a closed blob. Excellent NVK support. |
|
||||||
| **Ampere**<br>*(GA100/102/104/107)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | Mature support in both proprietary driver and NVK. For RTX 3060/3080/3090, NVK offers extremely competitive performance versus proprietary in many scenarios. |
|
| **Ampere**<br>*(GA100/102/104/107)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | Mature support in both proprietary driver and NVK. For RTX 3060/3080/3090, NVK offers extremely competitive performance versus proprietary in many scenarios. |
|
||||||
| **Ada Lovelace**<br>*(AD100/102/103/104)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | NVK added full Ada support recently. Proprietary driver still required if hardware Ray Tracing or DLSS 3 (Frame Generation) is needed, as NVK does not yet implement these proprietary extensions. |
|
| **Ada Lovelace**<br>*(AD100/102/103/104)* | 525.xx to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (Vulkan 1.3) | **CUDA 12.8+** | NVK added full Ada support recently. Proprietary driver still required if hardware Ray Tracing or DLSS 3 (Frame Generation) is needed, as NVK does not yet implement these proprietary extensions. |
|
||||||
| **Blackwell**<br>*(GB100/102/202)* | [570](https://docs.nvidia.com/datacenter/tesla/tesla-release-notes-570-211-01/index.html) to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (In development) | **CUDA 12.8+** | Latest generation architecture (RTX 5090/5080). NVK support is landing in the most recent kernel versions (6.12+) and Mesa (24.3+). Requires very updated `linux-firmware`. |
|
| **Blackwell**<br>*(GB100/102/202)* | [570.xx](https://docs.nvidia.com/datacenter/tesla/tesla-release-notes-570-211-01/index.html) to 610+ | `nvidia` (**Open Module**) | **Vulkan 1.3** | **Yes** (In development) | **CUDA 12.8+** | Latest generation architecture (RTX 5090/5080). NVK support is landing in the most recent kernel versions (6.12+) and Mesa (24.3+). Requires very updated `linux-firmware`. |
|
||||||
|
|
||||||
#### 💡 Quick context glossary for documentation:
|
#### 💡 Quick context glossary for documentation:
|
||||||
* **Open Module:** Starting with driver 515, [NVIDIA releases code that interacts directly with the Linux kernel under MIT/GPL license](https://developer.nvidia.com/blog/nvidia-releases-open-source-gpu-kernel-modules/). However, the GPU still requires loading a proprietary closed microcode called **GSP (GPU System Processor)** to boot.
|
* **Open Module:** Starting with driver 515, [NVIDIA releases code that interacts directly with the Linux kernel under MIT/GPL license](https://developer.nvidia.com/blog/nvidia-releases-open-source-gpu-kernel-modules/). However, the GPU still requires loading a proprietary closed microcode called **GSP (GPU System Processor)** to boot.
|
||||||
@@ -153,8 +155,8 @@ When the script detects Intel or AMD hardware, it triggers a specific installati
|
|||||||
|
|
||||||
| Vendor | Kernel Driver (KMD) | Mesa User-Space Driver | VAAPI Backend Strategy |
|
| Vendor | Kernel Driver (KMD) | Mesa User-Space Driver | VAAPI Backend Strategy |
|
||||||
| :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- |
|
||||||
| **Intel Gen < 8** | `i915` | `crocus` / `iris` | Installs `i965-va-driver-shaders`. Legacy path for older CPUs. |
|
| **Intel Gen < 8** | `i915` | `crocus` / `iris` | Installs [`i965-va-driver-shaders`](https://github.com/intel/intel-vaapi-driver/). Legacy path for older CPUs. |
|
||||||
| **Intel Gen 8+** | `i915` | `iris` / `anv` | Installs `intel-media-va-driver-non-free`. Modern, preferred backend for Broadwell+. |
|
| **Intel Gen 8+** | `i915` | `iris` / `anv` | Installs [`intel-media-va-driver-non-free](https://github.com/intel/media-driver). Modern, preferred backend for Broadwell+. |
|
||||||
| **AMD GCN/RDNA** | `amdgpu` | `radeonsi` (GL) + `RADV` (VK) | Uses standard `va-driver-all`. Requires kernel param tuning for older GCN. |
|
| **AMD GCN/RDNA** | `amdgpu` | `radeonsi` (GL) + `RADV` (VK) | Uses standard `va-driver-all`. Requires kernel param tuning for older GCN. |
|
||||||
|
|
||||||
**Critical Consistency Check:**
|
**Critical Consistency Check:**
|
||||||
|
|||||||
+27
-16
@@ -36,7 +36,7 @@ deb https://deb.debian.org/debian bookworm main contrib non-free non-free-firmwa
|
|||||||
```yaml
|
```yaml
|
||||||
Types: deb
|
Types: deb
|
||||||
URIs: https://deb.debian.org/debian
|
URIs: https://deb.debian.org/debian
|
||||||
Suites: bookworm bookworm-updates
|
Suites: trixie trixie-updates
|
||||||
Components: main contrib non-free non-free-firmware
|
Components: main contrib non-free non-free-firmware
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -52,6 +52,7 @@ The script automatically detects your current format and offers migration option
|
|||||||
|
|
||||||
The `configure_repos()` function in `repos.sh` executes the following sequence:
|
The `configure_repos()` function in `repos.sh` executes the following sequence:
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
│ INITIAL DETECTION PHASE │
|
│ INITIAL DETECTION PHASE │
|
||||||
@@ -71,51 +72,61 @@ The `configure_repos()` function in `repos.sh` executes the following sequence:
|
|||||||
┌─────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
│ USER INTERACTION PHASE │
|
│ USER INTERACTION PHASE │
|
||||||
├─────────────────────────────────────────────────────────────┤
|
├─────────────────────────────────────────────────────────────┤
|
||||||
│ 4. Repository Format Selection (Trixie only) │
|
│ 4. Repository Menu Loop (while true) │
|
||||||
│ └── whiptail yesno: Migrate to DEB822? (default NO) │
|
│ └── _menu: Select action from multiple options │
|
||||||
│ │
|
│ │
|
||||||
│ 5. Backports Enablement │
|
│ Options Available: │
|
||||||
│ └── whiptail confirm: Enable Backports? │
|
│ ├── Debian 13+ (Trixie): │
|
||||||
|
│ │ ├── 1. Enable Contrib & Non-Free Components │
|
||||||
|
│ │ ├── 2. Migrate traditional sources.list to DEB822 │
|
||||||
|
│ │ ├── 3. Setup/Update Backports repositories │
|
||||||
|
│ │ ├── 4. [ADVANCED] Upgrade system branch (Testing/SID)│
|
||||||
|
│ │ └── 5. Back to main menu │
|
||||||
|
│ │
|
||||||
|
│ └── Other Versions: │
|
||||||
|
│ ├── 1-3 same as above │
|
||||||
|
│ └── No option 4 (branch upgrade not available) │
|
||||||
└─────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────┘
|
||||||
↓
|
↓
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
│ DECISION MATRIX PHASE │
|
│ DECISION MATRIX PHASE │
|
||||||
├─────────────────────────────────────────────────────────────┤
|
├─────────────────────────────────────────────────────────────┤
|
||||||
│ 6. Determine Action Type │
|
│ 5. Determine Action Type (per menu selection) │
|
||||||
│ ├── If format changed → "migrate" │
|
│ ├── If format changed → "migrate" │
|
||||||
│ ├── If nothing changed → "update" (skip) │
|
│ ├── If nothing changed → "skip" (idempotent) │
|
||||||
│ └── Otherwise → "write" │
|
│ └── Otherwise → "write" │
|
||||||
│ │
|
│ │
|
||||||
│ 7. Idempotency Check │
|
│ 6. Idempotency Check │
|
||||||
│ └── content_differs() compares generated vs existing │
|
│ └── content_differs() compares generated vs existing │
|
||||||
└─────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────┘
|
||||||
↓
|
↓
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
│ EXECUTION PHASE │
|
│ EXECUTION PHASE │
|
||||||
├─────────────────────────────────────────────────────────────┤
|
├─────────────────────────────────────────────────────────────┤
|
||||||
│ 8. Backup Current Repositories │
|
│ 7. Backup Current Repositories │
|
||||||
│ └── backup_current_repos() → temp directory │
|
│ └── backup_current_repos() → temp directory │
|
||||||
│ │
|
│ │
|
||||||
│ 9. Write Configuration │
|
│ 8. Write Configuration │
|
||||||
│ ├── _write_deb822() OR _write_classic() │
|
│ ├── _write_deb822() OR _write_classic() │
|
||||||
│ ├── Creates appropriate file(s) │
|
│ ├── Creates appropriate file(s) │
|
||||||
│ └── Includes main + backports if enabled │
|
│ └── Includes main + backports if enabled │
|
||||||
│ │
|
│ │
|
||||||
│ 10. Update Package Lists │
|
│ 9. Update Package Lists │
|
||||||
│ └── sudo apt update │
|
│ └── sudo apt update │
|
||||||
└─────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────┘
|
||||||
↓
|
↓
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
│ POST-EXECUTION PHASE │
|
│ POST-EXECUTION PHASE │
|
||||||
├─────────────────────────────────────────────────────────────┤
|
├─────────────────────────────────────────────────────────────┤
|
||||||
│ 11. Success Path │
|
│ 10. Success Path │
|
||||||
│ ├── REPOS_CONFIGURED=true │
|
│ ├── REPOS_CONFIGURED=true │
|
||||||
│ ├── Cleanup disabled files │
|
│ ├── Cleanup disabled files │
|
||||||
│ └── Optional: Upgrade system if packages available │
|
│ └── Optional: Upgrade system if packages available │
|
||||||
│ │
|
│ │
|
||||||
│ 12. Failure Path (apt update failed) │
|
│ 11. Failure Path (apt update failed) │
|
||||||
│ └── restore_previous_repos() → rollback to backup │
|
│ └── restore_previous_repos() → rollback to backup │
|
||||||
└─────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Key Safety Mechanisms:**
|
**Key Safety Mechanisms:**
|
||||||
@@ -134,7 +145,7 @@ The script enables specific APT component branches that are essential for hardwa
|
|||||||
|-----------|---------|--------------|---------------------|
|
|-----------|---------|--------------|---------------------|
|
||||||
| **main** | Free, open-source software (Debian official) | All packages | Always enabled |
|
| **main** | Free, open-source software (Debian official) | All packages | Always enabled |
|
||||||
| **contrib** | Free software that uses non-free components | Proprietary codecs, drivers | Enabled in all versions |
|
| **contrib** | Free software that uses non-free components | Proprietary codecs, drivers | Enabled in all versions |
|
||||||
| **non-free** | Non-free firmware and proprietary software | NVIDIA/AMD GPU drivers, Wi-Fi firmware | Required for hardware support |
|
| **non-free** | Non-free firmware and proprietary software | NVIDIA GPU drivers, Wi-Fi firmware | Required for hardware support |
|
||||||
| **non-free-firmware** | Firmware blobs (Wi-Fi, Bluetooth, etc.) | Wireless adapters, embedded chips | **Critical from Debian 12+** |
|
| **non-free-firmware** | Firmware blobs (Wi-Fi, Bluetooth, etc.) | Wireless adapters, embedded chips | **Critical from Debian 12+** |
|
||||||
|
|
||||||
#### Why `non-free-firmware` is Vital (Debian 12+)
|
#### Why `non-free-firmware` is Vital (Debian 12+)
|
||||||
@@ -143,7 +154,7 @@ Starting with Debian Bookworm (12.0), the `non-free-firmware` component was sepa
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Before Debian 12 (Bookworm)
|
# Before Debian 12 (Bookworm)
|
||||||
deb https://deb.debian.org/debian bookworm main contrib non-free
|
deb https://deb.debian.org/debian bullseye main contrib non-free
|
||||||
|
|
||||||
# After Debian 12 (Bookworm+) - SEPARATE COMPONENTS
|
# After Debian 12 (Bookworm+) - SEPARATE COMPONENTS
|
||||||
deb https://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
|
deb https://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
|
||||||
@@ -221,7 +232,7 @@ The script includes a detailed explanation because backports enable critical fea
|
|||||||
|
|
||||||
| Feature | Without Backports | With Backports |
|
| Feature | Without Backports | With Backports |
|
||||||
|---------|-------------------|----------------|
|
|---------|-------------------|----------------|
|
||||||
| **Linux Kernel** | Stable kernel only (e.g., 5.10) | Newer kernels (e.g., 6.x series) |
|
| **Linux Kernel** | Stable kernel only (e.g., 6.1-6.12) | Newer kernels (e.g., 6.x/7.x series) |
|
||||||
| **GPU "Drivers"** | Latest Mesa from stable | Latest Mesa from testing |
|
| **GPU "Drivers"** | Latest Mesa from stable | Latest Mesa from testing |
|
||||||
| **Wi-Fi Firmware** | Older firmware versions | Newest firmware for modern cards |
|
| **Wi-Fi Firmware** | Older firmware versions | Newest firmware for modern cards |
|
||||||
| **System Stability** | Maximum stability | Tested-but-newer packages |
|
| **System Stability** | Maximum stability | Tested-but-newer packages |
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
## Option 9: Swap
|
||||||
|
|
||||||
|
### 1. What does this component do?
|
||||||
|
This module is responsible for the secure management of disk-based swap space within the `debianito` environment. Unlike standard Linux tools that might overwrite existing configurations or conflict with memory compression features (like ZRAM), this script operates as a **priority-aware, persistent swap manager**.
|
||||||
|
|
||||||
|
Its primary functions include:
|
||||||
|
* **Dynamic Allocation:** Creating and resizing swapfiles based on detected RAM capacity without requiring physical partition changes.
|
||||||
|
* **Priority Integration:** Explicitly setting the swap priority (`pri=10`) to ensure it sits below ZRAM (which uses `priority=100`). This prevents the system from using disk I/O for memory swapping until compressed RAM is exhausted, optimizing performance.
|
||||||
|
* **Persistence Management:** Safely editing `/etc/fstab` with a unique tag (`# debianito-managed-swap`) to ensure swap survives reboots without corrupting manual entries.
|
||||||
|
* **Safety Locking:** Prevents concurrent operations using file locking mechanisms to avoid race conditions during active system usage.
|
||||||
|
|
||||||
|
### 2. How does it work?
|
||||||
|
The script leverages several advanced Linux subsystems and safety protocols:
|
||||||
|
|
||||||
|
1. **File System Detection:** It identifies the filesystem type of the target partition (e.g., `ext4`, `btrfs`). For Btrfs, it applies specific flags (`chattr +C` for copy-on-write optimization) to prevent performance degradation during swap operations.
|
||||||
|
2. **Allocation Strategy:** It prefers `fallocate` for instant space reservation on supported filesystems, falling back to `dd if=/dev/zero` for compatibility or zeroing requirements (like Btrfs).
|
||||||
|
3. **Fstab Validation:** Before writing changes to `/etc/fstab`, it creates a temporary file and validates the syntax using `findmnt --verify`. If validation fails, the script aborts and restores the original state.
|
||||||
|
4. **Concurrency Control:** It utilizes `flock` on `/run/lock/debianito-swap.lock`. This ensures that if another process is modifying swap settings (e.g., a system update), this script will wait or exit gracefully to prevent filesystem corruption.
|
||||||
|
5. **Swappiness Tuning:** It configures `vm.swappiness` via both runtime (`sysctl -w`) and persistent (`/etc/sysctl.d/99-swappiness-debianito.conf`) mechanisms, defaulting to values that favor RAM usage over disk swapping (e.g., 10-20).
|
||||||
|
|
||||||
|
### 3. The Logical Decision Tree (Step by Step)
|
||||||
|
The execution flow follows a strict logical tree designed for safety and idempotency:
|
||||||
|
|
||||||
|
1. **Initialization & Locking:**
|
||||||
|
* The `manage_swap()` function attempts to acquire an exclusive lock (`flock -n`). If the lock is held by another process, it immediately exits with a "Busy" message to prevent conflicts.
|
||||||
|
|
||||||
|
2. **Menu Selection Loop:**
|
||||||
|
* Enters a continuous loop presenting options (Status, Create, Remove, Swappiness).
|
||||||
|
* Breaks only when the user selects "Back to main menu".
|
||||||
|
|
||||||
|
3. **Action Execution Paths:**
|
||||||
|
* **Path A: Status Check (`_swap_current_status`)**
|
||||||
|
* Reads active swap entries via `swapon --show`.
|
||||||
|
* Reads current swappiness from `/proc/sys/vm/swappiness`.
|
||||||
|
* Parses `/etc/fstab` for managed tags.
|
||||||
|
* **Path B: Create/Resize (`_swap_create_file`)**
|
||||||
|
* **Recommendation:** Calculates optimal size based on RAM (e.g., 2GB for >16GB RAM, 4GB for 8-16GB).
|
||||||
|
* **Btrfs Check:** If the filesystem is Btrfs, it warns about `nodatacow` requirements and hibernation limitations.
|
||||||
|
* **Existence Check:** If `/swapfile` exists, it prompts to confirm recreation (deleting old data first via `swapoff`).
|
||||||
|
* **Allocation:** Uses `fallocate` or `dd` to zero the file. Sets permissions (`chmod 600`) and initializes swap (`mkswap`).
|
||||||
|
* **Persistence:** Attempts to write the new entry to `/etc/fstab`. If validation fails, it cleans up (removes file) before exiting.
|
||||||
|
* **Path C: Remove (`_swap_remove_file`)**
|
||||||
|
* Checks for the unique `SWAP_FSTAB_TAG` in fstab.
|
||||||
|
* Confirms user intent to delete.
|
||||||
|
* Executes `swapoff`, removes the fstab line, and deletes the physical file.
|
||||||
|
* **Path D: Swappiness (`_swap_set_swappiness`)**
|
||||||
|
* Validates input (0-100 integer).
|
||||||
|
* Writes a temporary sysctl config file.
|
||||||
|
* Applies changes immediately via `sysctl -w`.
|
||||||
|
|
||||||
|
### 4. What does each menu item do and what does it mean?
|
||||||
|
Each option in the swap management submenu serves a specific technical purpose:
|
||||||
|
|
||||||
|
* **Option 1: Show current swap & swappiness**
|
||||||
|
* **Technical Action:** Aggregates data from `/proc/swaps`, `/proc/sys/vm/swappiness`, and `/etc/fstab`.
|
||||||
|
* **Significance:** Provides an audit trail of the current memory management state. It verifies if ZRAM is active (implied by priority check) and how much disk swap is currently in use.
|
||||||
|
|
||||||
|
* **Option 2: Create / resize swapfile**
|
||||||
|
* **Technical Action:** Allocates a new block device file (`/swapfile`) or expands an existing one. Sets the `pri=10` flag to ensure it acts as a secondary memory layer after ZRAM fills up.
|
||||||
|
* **Significance:** Essential for systems with low RAM that need overflow protection without installing physical partitions. The "Resize" capability allows adapting to new hardware configurations dynamically.
|
||||||
|
|
||||||
|
* **Option 3: Remove swapfile**
|
||||||
|
* **Technical Action:** Disables the swapfile (`swapoff`), removes it from `/etc/fstab`, and deletes the file from disk.
|
||||||
|
* **Significance:** Useful for troubleshooting, freeing up disk space (e.g., on SSDs where write cycles are a concern), or migrating to ZRAM-only configurations if RAM is sufficient.
|
||||||
|
|
||||||
|
* **Option 4: Change swappiness**
|
||||||
|
* **Technical Action:** Modifies the kernel parameter `vm.swappiness`.
|
||||||
|
* **Significance:** Controls the "aggressiveness" of swapping. A lower value (e.g., 10) tells the kernel to keep data in RAM longer, only using swap as a last resort. This is critical for desktop performance and battery life on laptops.
|
||||||
|
|
||||||
|
* **Option 5: Back to main menu**
|
||||||
|
* **Technical Action:** Releases the file lock (`exec 9>&-`) and terminates the submenu loop.
|
||||||
|
* **Significance:** Returns control to the user, ensuring no swap operations are running in the background before they navigate to other system configurations.
|
||||||
@@ -241,3 +241,11 @@ To ensure ZRAM persists across reboots, the script writes configuration to `/etc
|
|||||||
```bash
|
```bash
|
||||||
echo "zram" | sudo tee /etc/modules-load.d/zram.conf
|
echo "zram" | sudo tee /etc/modules-load.d/zram.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### References:
|
||||||
|
|
||||||
|
- [https://docs.kernel.org/admin-guide/blockdev/zram.html](https://docs.kernel.org/admin-guide/blockdev/zram.html)
|
||||||
|
- [https://wiki.debian.org/ZRam](https://wiki.debian.org/ZRam)
|
||||||
|
- [https://wiki.archlinux.org/title/Zram](https://wiki.archlinux.org/title/Zram)
|
||||||
|
- [https://wiki.gentoo.org/wiki/Zram](https://wiki.gentoo.org/wiki/Zram)
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 852 KiB |
@@ -19,7 +19,7 @@ _install_bluetooth_stack() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if is_installed bluez && is_installed bluez-utils; then
|
if is_installed bluez; then
|
||||||
echo " → Bluetooth stack already installed."
|
echo " → Bluetooth stack already installed."
|
||||||
service_enable_only=true
|
service_enable_only=true
|
||||||
fi
|
fi
|
||||||
@@ -27,7 +27,7 @@ _install_bluetooth_stack() {
|
|||||||
if [ ! ${service_enable_only:-false} = true ]; then
|
if [ ! ${service_enable_only:-false} = true ]; then
|
||||||
local bt_pkgs=()
|
local bt_pkgs=()
|
||||||
! is_installed bluez && bt_pkgs+=(bluez)
|
! is_installed bluez && bt_pkgs+=(bluez)
|
||||||
! is_installed bluez-utils && bt_pkgs+=(bluez-utils)
|
! is_installed bluez-tools && bt_pkgs+=(bluez-tools)
|
||||||
! is_installed bluez-obexd && bt_pkgs+=(bluez-obexd)
|
! is_installed bluez-obexd && bt_pkgs+=(bluez-obexd)
|
||||||
if [ ${#bt_pkgs[@]} -gt 0 ]; then
|
if [ ${#bt_pkgs[@]} -gt 0 ]; then
|
||||||
_run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y ${bt_pkgs[*]}" "Installing Bluetooth stack..."
|
_run_cmd "Bluetooth" "sudo DEBIAN_FRONTEND=noninteractive apt install -y ${bt_pkgs[*]}" "Installing Bluetooth stack..."
|
||||||
|
|||||||
+185
-172
@@ -58,15 +58,13 @@ Instalar?"; then
|
|||||||
# ======================================================================
|
# ======================================================================
|
||||||
|
|
||||||
_cat_customization_bullseye() {
|
_cat_customization_bullseye() {
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
|
||||||
local sub
|
local sub
|
||||||
sub=$(whiptail --title "Customization (Bullseye)" --menu \
|
sub=$(_menu "Customization (Bullseye)" "Select type:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
|
||||||
"1" "Desktop Themes (GTK/KDE)" \
|
"1" "Desktop Themes (GTK/KDE)" \
|
||||||
"2" "Icon Themes" \
|
"2" "Icon Themes" \
|
||||||
"3" "Cursor Themes" \
|
"3" "Cursor Themes" \
|
||||||
"4" "Fonts" \
|
"4" "Fonts" \
|
||||||
3>&1 1>&2 2>&3)
|
)
|
||||||
[ -z "$sub" ] && return
|
[ -z "$sub" ] && return
|
||||||
case $sub in
|
case $sub in
|
||||||
1) _cat_themes_bullseye ;;
|
1) _cat_themes_bullseye ;;
|
||||||
@@ -77,16 +75,17 @@ _cat_customization_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_themes_bullseye() {
|
_cat_themes_bullseye() {
|
||||||
|
local item_count=6
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Desktop Themes (Bullseye)" --checklist \
|
choices=$(_checklist "Desktop Themes (Bullseye)" "Select desktop themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select desktop themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"arc-theme" "Arc GTK theme" "$(_state arc-theme)" \
|
||||||
"arc-theme" "Arc GTK theme$(_inst arc-theme)" "$(_state arc-theme)" \
|
"blackbird-gtk-theme" "Blackbird GTK theme" "$(_state blackbird-gtk-theme)" \
|
||||||
"blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$(_state blackbird-gtk-theme)" \
|
"bluebird-gtk-theme" "Bluebird GTK theme" "$(_state bluebird-gtk-theme)" \
|
||||||
"bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$(_state bluebird-gtk-theme)" \
|
"breeze-gtk-theme" "Breeze GTK theme (KDE port)" "$(_state breeze-gtk-theme)" \
|
||||||
"breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$(_state breeze-gtk-theme)" \
|
"greybird-gtk-theme" "Greybird GTK theme" "$(_state greybird-gtk-theme)" \
|
||||||
"greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$(_state greybird-gtk-theme)" \
|
"numix-gtk-theme" "Numix GTK theme" "$(_state numix-gtk-theme)" \
|
||||||
"numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$(_state numix-gtk-theme)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -98,20 +97,21 @@ _cat_themes_bullseye() {
|
|||||||
|
|
||||||
_cat_icons_bullseye() {
|
_cat_icons_bullseye() {
|
||||||
local items=(
|
local items=(
|
||||||
"breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$(_state breeze-icon-theme)"
|
"breeze-icon-theme" "Breeze icon theme" "$(_state breeze-icon-theme)"
|
||||||
"deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$(_state deepin-icon-theme)"
|
"deepin-icon-theme" "Deepin icon theme" "$(_state deepin-icon-theme)"
|
||||||
"moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$(_state moka-icon-theme)"
|
"moka-icon-theme" "Moka icon theme" "$(_state moka-icon-theme)"
|
||||||
"numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$(_state numix-icon-theme)"
|
"numix-icon-theme" "Numix icon theme" "$(_state numix-icon-theme)"
|
||||||
"numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$(_state numix-icon-theme-circle)"
|
"numix-icon-theme-circle" "Numix Circle icon theme" "$(_state numix-icon-theme-circle)"
|
||||||
"obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$(_state obsidian-icon-theme)"
|
"obsidian-icon-theme" "Obsidian icon theme" "$(_state obsidian-icon-theme)"
|
||||||
"papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$(_state papirus-icon-theme)"
|
"papirus-icon-theme" "Papirus icon theme" "$(_state papirus-icon-theme)"
|
||||||
"paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$(_state paper-icon-theme)"
|
"paper-icon-theme" "Paper icon theme" "$(_state paper-icon-theme)"
|
||||||
"suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$(_state suru-icon-theme)"
|
"suru-icon-theme" "Suru icon theme" "$(_state suru-icon-theme)"
|
||||||
)
|
)
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Icon Themes (Bullseye)" --checklist \
|
choices=$(_checklist "Icon Themes (Bullseye)" "Select icon themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select icon themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"${items[@]}" )
|
||||||
"${items[@]}" 3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -122,15 +122,16 @@ _cat_icons_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_cursors_bullseye() {
|
_cat_cursors_bullseye() {
|
||||||
|
local item_count=5
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Cursor Themes (Bullseye)" --checklist \
|
choices=$(_checklist "Cursor Themes (Bullseye)" "Select cursor themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select cursor themes${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"breeze-cursor-theme" "Breeze cursors (KDE)" "$(_state breeze-cursor-theme)" \
|
||||||
"breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$(_state breeze-cursor-theme)" \
|
"chameleon-cursor-theme" "Chameleon cursors" "$(_state chameleon-cursor-theme)" \
|
||||||
"chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$(_state chameleon-cursor-theme)" \
|
"dmz-cursor-theme" "DMZ cursors" "$(_state dmz-cursor-theme)" \
|
||||||
"dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$(_state dmz-cursor-theme)" \
|
"oxygencursors" "Oxygen cursors (KDE legacy)" "$(_state oxygencursors)" \
|
||||||
"oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$(_state oxygencursors)" \
|
"xcursor-themes" "X11 base cursors" "$(_state xcursor-themes)" \
|
||||||
"xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$(_state xcursor-themes)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -141,14 +142,15 @@ _cat_cursors_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_fonts_bullseye() {
|
_cat_fonts_bullseye() {
|
||||||
|
local item_count=4
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Fonts (Bullseye)" --checklist \
|
choices=$(_checklist "Fonts (Bullseye)" "Available fonts${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Available fonts${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"fonts-firacode" "Fira Code monospace font" "$(_state fonts-firacode)" \
|
||||||
"fonts-firacode" "Fira Code monospace font$(_inst fonts-firacode)" "$(_state fonts-firacode)" \
|
"fonts-noto" "Noto fonts (Google)" "$(_state fonts-noto)" \
|
||||||
"fonts-noto" "Noto fonts (Google)$(_inst fonts-noto)" "$(_state fonts-noto)" \
|
"fonts-dejavu-core" "DejaVu core fonts" "$(_state fonts-dejavu-core)" \
|
||||||
"fonts-dejavu-core" "DejaVu core fonts$(_inst fonts-dejavu-core)" "$(_state fonts-dejavu-core)" \
|
"ttf-mscorefonts-installer" "Microsoft Core Fonts" "$(_state ttf-mscorefonts-installer)" \
|
||||||
"ttf-mscorefonts-installer" "Microsoft Core Fonts$(_inst ttf-mscorefonts-installer)" "$(_state ttf-mscorefonts-installer)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -161,24 +163,26 @@ _cat_fonts_bullseye() {
|
|||||||
_cat_download_bullseye() {
|
_cat_download_bullseye() {
|
||||||
local choices1 choices2=""
|
local choices1 choices2=""
|
||||||
|
|
||||||
choices1=$(whiptail --title "Downloaders" --checklist \
|
local item_count1=2
|
||||||
"Select download tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
local lista_alto1=$((item_count1 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count1))
|
||||||
"aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$(_state aria2)" \
|
choices1=$(_checklist "Downloaders" "Select download tools:" $TUI_ALTO $TUI_ANCHO $lista_alto1 \
|
||||||
"filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$(_state filezilla)" \
|
"aria2" "Multiprotocol downloader (CLI)" "$(_state aria2)" \
|
||||||
3>&1 1>&2 2>&3)
|
"filezilla" "FTP/SFTP client (GUI)" "$(_state filezilla)" \
|
||||||
|
)
|
||||||
clear
|
clear
|
||||||
|
|
||||||
choices2=$(whiptail --title "Torrent Clients" --checklist \
|
local item_count2=8
|
||||||
"Select torrent clients${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
local lista_alto2=$((item_count2 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count2))
|
||||||
"deluge" "BitTorrent client (GTK)$(_inst deluge)" "$(_state deluge)" \
|
choices2=$(_checklist "Torrent Clients" "Select torrent clients${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto2 \
|
||||||
"deluged" "BitTorrent daemon/server$(_inst deluged)" "$(_state deluged)" \
|
"deluge" "BitTorrent client (GTK)" "$(_state deluge)" \
|
||||||
"mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$(_state mktorrent)" \
|
"deluged" "BitTorrent daemon/server" "$(_state deluged)" \
|
||||||
"qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$(_state qbittorrent)" \
|
"mktorrent" "Torrent metainfo creator (CLI)" "$(_state mktorrent)" \
|
||||||
"qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$(_state qbittorrent-nox)" \
|
"qbittorrent" "BitTorrent client (Qt)" "$(_state qbittorrent)" \
|
||||||
"transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$(_state transmission-cli)" \
|
"qbittorrent-nox" "BitTorrent WebUI/CLI" "$(_state qbittorrent-nox)" \
|
||||||
"transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$(_state transmission-gtk)" \
|
"transmission-cli" "BitTorrent client (CLI)" "$(_state transmission-cli)" \
|
||||||
"transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$(_state transmission-qt)" \
|
"transmission-gtk" "BitTorrent client (GTK)" "$(_state transmission-gtk)" \
|
||||||
3>&1 1>&2 2>&3)
|
"transmission-qt" "BitTorrent client (Qt)" "$(_state transmission-qt)" \
|
||||||
|
)
|
||||||
clear
|
clear
|
||||||
|
|
||||||
local cleaned
|
local cleaned
|
||||||
@@ -196,21 +200,22 @@ _cat_download_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_internet_bullseye() {
|
_cat_internet_bullseye() {
|
||||||
|
local item_count=11
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Internet (Bullseye)" --checklist \
|
choices=$(_checklist "Internet (Bullseye)" "Select browsers, email${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select browsers, email${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"chromium" "Chromium web browser" "$(_state chromium)" \
|
||||||
"chromium" "Chromium web browser$(_inst chromium)" "$(_state chromium)" \
|
"dillo" "Lightweight graphical browser" "$(_state dillo)" \
|
||||||
"dillo" "Lightweight graphical browser$(_inst dillo)" "$(_state dillo)" \
|
"elinks" "Text-mode web browser" "$(_state elinks)" \
|
||||||
"elinks" "Text-mode web browser$(_inst elinks)" "$(_state elinks)" \
|
"epiphany-browser" "GNOME web browser" "$(_state epiphany-browser)" \
|
||||||
"epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$(_state epiphany-browser)" \
|
"falkon" "KDE web browser (QtWebEngine)" "$(_state falkon)" \
|
||||||
"falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$(_state falkon)" \
|
"firefox-esr" "Firefox ESR (official Debian)" "$(_state firefox-esr)" \
|
||||||
"firefox-esr" "Firefox ESR (official Debian)$(_inst firefox-esr)" "$(_state firefox-esr)" \
|
"konqueror" "KDE file manager / web browser" "$(_state konqueror)" \
|
||||||
"konqueror" "KDE file manager / web browser$(_inst konqueror)" "$(_state konqueror)" \
|
"qutebrowser" "Keyboard-driven browser (Qt)" "$(_state qutebrowser)" \
|
||||||
"qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$(_state qutebrowser)" \
|
"thunderbird" "Email client" "$(_state thunderbird)" \
|
||||||
"thunderbird" "Email client$(_inst thunderbird)" "$(_state thunderbird)" \
|
"torbrowser-launcher" "Tor Browser launcher" "$(_state torbrowser-launcher)" \
|
||||||
"torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$(_state torbrowser-launcher)" \
|
"w3m" "Text-mode browser + deps" "$(_state w3m)" \
|
||||||
"w3m" "Text-mode browser + deps$(_inst w3m)" "$(_state w3m)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -237,12 +242,13 @@ _cat_internet_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_players_bullseye() {
|
_cat_players_bullseye() {
|
||||||
|
local item_count=2
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Media Players (Bullseye)" --checklist \
|
choices=$(_checklist "Media Players (Bullseye)" "Select media players${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select media players${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"mpv" "Lightweight media player" "$(_state mpv)" \
|
||||||
"mpv" "Lightweight media player$(_inst mpv)" "$(_state mpv)" \
|
"vlc" "VLC media player" "$(_state vlc)" \
|
||||||
"vlc" "VLC media player$(_inst vlc)" "$(_state vlc)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -257,23 +263,24 @@ _cat_players_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_design_bullseye() {
|
_cat_design_bullseye() {
|
||||||
|
local item_count=13
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Multimedia & Design (Bullseye)" --checklist \
|
choices=$(_checklist "Multimedia & Design (Bullseye)" "Select multimedia and design tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select multimedia and design tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"ardour" "Digital audio workstation" "$(_state ardour)" \
|
||||||
"ardour" "Digital audio workstation$(_inst ardour)" "$(_state ardour)" \
|
"audacity" "Audio editor/recorder" "$(_state audacity)" \
|
||||||
"audacity" "Audio editor/recorder$(_inst audacity)" "$(_state audacity)" \
|
"blender" "3D modeling/animation suite" "$(_state blender)" \
|
||||||
"blender" "3D modeling/animation suite$(_inst blender)" "$(_state blender)" \
|
"ffmpeg" "Multimedia framework (CLI)" "$(_state ffmpeg)" \
|
||||||
"ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$(_state ffmpeg)" \
|
"gimp" "Image editor" "$(_state gimp)" \
|
||||||
"gimp" "Image editor$(_inst gimp)" "$(_state gimp)" \
|
"handbrake" "Video transcoder (DVD ripper)" "$(_state handbrake)" \
|
||||||
"handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$(_state handbrake)" \
|
"inkscape" "Vector graphics editor" "$(_state inkscape)" \
|
||||||
"inkscape" "Vector graphics editor$(_inst inkscape)" "$(_state inkscape)" \
|
"kdenlive" "Video editor (KDE)" "$(_state kdenlive)" \
|
||||||
"kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$(_state kdenlive)" \
|
"krita" "Digital painting/illustration" "$(_state krita)" \
|
||||||
"krita" "Digital painting/illustration$(_inst krita)" "$(_state krita)" \
|
"obs-studio" "Screen recording/streaming" "$(_state obs-studio)" \
|
||||||
"obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$(_state obs-studio)" \
|
"openshot-qt" "Video editor (simple)" "$(_state openshot-qt)" \
|
||||||
"openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$(_state openshot-qt)" \
|
"scribus" "Desktop publishing (DTP)" "$(_state scribus)" \
|
||||||
"scribus" "Desktop publishing (DTP)$(_inst scribus)" "$(_state scribus)" \
|
"shotcut" "Video editor (cross-platform)" "$(_state shotcut)" \
|
||||||
"shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$(_state shotcut)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -288,19 +295,20 @@ _cat_design_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_programming_bullseye() {
|
_cat_programming_bullseye() {
|
||||||
|
local item_count=9
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Code Editors & IDEs (Bullseye)" --checklist \
|
choices=$(_checklist "Code Editors & IDEs (Bullseye)" "Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"vim" "Classic terminal editor" "$(_state vim)" \
|
||||||
"vim" "Classic terminal editor$(_inst vim)" "$(_state vim)" \
|
"vim-gtk3" "Vim with GTK3 GUI" "$(_state vim-gtk3)" \
|
||||||
"vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$(_state vim-gtk3)" \
|
"neovim" "Modern vim fork" "$(_state neovim)" \
|
||||||
"neovim" "Modern vim fork$(_inst neovim)" "$(_state neovim)" \
|
"nano" "Simple terminal editor" "$(_state nano)" \
|
||||||
"nano" "Simple terminal editor$(_inst nano)" "$(_state nano)" \
|
"emacs" "Extensible editor / IDE" "$(_state emacs)" \
|
||||||
"emacs" "Extensible editor / IDE$(_inst emacs)" "$(_state emacs)" \
|
"kate" "KDE advanced text editor" "$(_state kate)" \
|
||||||
"kate" "KDE advanced text editor$(_inst kate)" "$(_state kate)" \
|
"mousepad" "Xfce text editor" "$(_state mousepad)" \
|
||||||
"mousepad" "Xfce text editor$(_inst mousepad)" "$(_state mousepad)" \
|
"gedit" "GNOME text editor" "$(_state gedit)" \
|
||||||
"gedit" "GNOME text editor$(_inst gedit)" "$(_state gedit)" \
|
"geany" "Lightweight IDE" "$(_state geany)" \
|
||||||
"geany" "Lightweight IDE$(_inst geany)" "$(_state geany)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -315,24 +323,25 @@ _cat_programming_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_dev_bullseye() {
|
_cat_dev_bullseye() {
|
||||||
|
local item_count=14
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Servers & Dev Tools (Bullseye)" --checklist \
|
choices=$(_checklist "Servers & Dev Tools (Bullseye)" "Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"apache2" "Apache web server" "$(_state apache2)" \
|
||||||
"apache2" "Apache web server$(_inst apache2)" "$(_state apache2)" \
|
"build-essential" "C/C++ build tools (gcc, make)" "$(_state build-essential)" \
|
||||||
"build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$(_state build-essential)" \
|
"docker" "Docker container runtime" "$(_state docker.io)" \
|
||||||
"docker" "Docker container runtime$(_inst docker.io)" "$(_state docker.io)" \
|
"mariadb-server" "MariaDB database server" "$(_state mariadb-server)" \
|
||||||
"mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$(_state mariadb-server)" \
|
"netcat-openbsd" "TCP/IP networking utility" "$(_state netcat-openbsd)" \
|
||||||
"netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$(_state netcat-openbsd)" \
|
"nginx" "Nginx web server" "$(_state nginx)" \
|
||||||
"nginx" "Nginx web server$(_inst nginx)" "$(_state nginx)" \
|
"openssh-server" "SSH server" "$(_state openssh-server)" \
|
||||||
"openssh-server" "SSH server$(_inst openssh-server)" "$(_state openssh-server)" \
|
"openssl" "OpenSSL cryptography toolkit" "$(_state openssl)" \
|
||||||
"openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$(_state openssl)" \
|
"postgresql" "PostgreSQL database server" "$(_state postgresql)" \
|
||||||
"postgresql" "PostgreSQL database server$(_inst postgresql)" "$(_state postgresql)" \
|
"python3-pip" "Python 3 pip + venv + dev" "$(_state python3-pip)" \
|
||||||
"python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$(_state python3-pip)" \
|
"redis-server" "Redis key-value store" "$(_state redis-server)" \
|
||||||
"redis-server" "Redis key-value store$(_inst redis-server)" "$(_state redis-server)" \
|
"sqlite3" "SQLite database engine" "$(_state sqlite3)" \
|
||||||
"sqlite3" "SQLite database engine$(_inst sqlite3)" "$(_state sqlite3)" \
|
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)" OFF \
|
||||||
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)$(_inst jellyfin)" OFF \
|
|
||||||
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)$(_any_jdk_installed_desc)" "$(_any_jdk_state)" \
|
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)$(_any_jdk_installed_desc)" "$(_any_jdk_state)" \
|
||||||
3>&1 1>&2 2>&3)
|
)
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -378,15 +387,16 @@ _cat_dev_bullseye() {
|
|||||||
echo -e "${GREEN}Servers & dev tools installed.${NC}"
|
echo -e "${GREEN}Servers & dev tools installed.${NC}"
|
||||||
}
|
}
|
||||||
_cat_security_bullseye() {
|
_cat_security_bullseye() {
|
||||||
|
local item_count=5
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Security & Networking (Bullseye)" --checklist \
|
choices=$(_checklist "Security & Networking (Bullseye)" "Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"wireshark" "Network protocol analyzer (GUI)" "$(_state wireshark)" \
|
||||||
"wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$(_state wireshark)" \
|
"tcpdump" "Command-line packet analyzer" "$(_state tcpdump)" \
|
||||||
"tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$(_state tcpdump)" \
|
"fail2ban" "Brute-force protection daemon" "$(_state fail2ban)" \
|
||||||
"fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$(_state fail2ban)" \
|
"ufw" "Uncomplicated firewall" "$(_state ufw)" \
|
||||||
"ufw" "Uncomplicated firewall$(_inst ufw)" "$(_state ufw)" \
|
"clamav" "Antivirus engine (ClamAV)" "$(_state clamav)" \
|
||||||
"clamav" "Antivirus engine (ClamAV)$(_inst clamav)" "$(_state clamav)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -408,29 +418,30 @@ _cat_security_bullseye() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_general_bullseye() {
|
_cat_general_bullseye() {
|
||||||
|
local item_count=18
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "System Tools (Bullseye)" --checklist \
|
choices=$(_checklist "System Tools (Bullseye)" "Select system utilities${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select system utilities${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"compress" "Compression tools (zip, unrar, p7zip)" "$(_state zip)" \
|
||||||
"compress" "Compression tools (zip, unrar, p7zip)$(_inst zip)" "$(_state zip)" \
|
"conky" "System monitor for desktop" "$(_state conky)" \
|
||||||
"conky" "System monitor for desktop$(_inst conky)" "$(_state conky)" \
|
"cpu-x" "CPU-X (alternative to CPU-Z)" "$(_state cpu-x)" \
|
||||||
"cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$(_state cpu-x)" \
|
"curl-wget" "HTTP transfer tools (curl, wget)" "$(_state curl)" \
|
||||||
"curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$(_state curl)" \
|
"flatpak" "Flatpak sandbox (Bullseye native)" "$(_state flatpak)" \
|
||||||
"flatpak" "Flatpak sandbox (Bullseye native)$(_inst flatpak)" "$(_state flatpak)" \
|
"fwupd" "Firmware update daemon" "$(_state fwupd)" \
|
||||||
"fwupd" "Firmware update daemon$(_inst fwupd)" "$(_state fwupd)" \
|
"gnome-disk-utility" "Disk management GUI" "$(_state gnome-disk-utility)" \
|
||||||
"gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$(_state gnome-disk-utility)" \
|
"gparted" "Partition editor" "$(_state gparted)" \
|
||||||
"gparted" "Partition editor$(_inst gparted)" "$(_state gparted)" \
|
"htop" "Interactive process viewer" "$(_state htop)" \
|
||||||
"htop" "Interactive process viewer$(_inst htop)" "$(_state htop)" \
|
"inxi" "System information tool" "$(_state inxi)" \
|
||||||
"inxi" "System information tool$(_inst inxi)" "$(_state inxi)" \
|
"kvm" "QEMU/KVM virtualization" "$(_state virt-manager)" \
|
||||||
"kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$(_state virt-manager)" \
|
"lshw" "List hardware details" "$(_state lshw)" \
|
||||||
"lshw" "List hardware details$(_inst lshw)" "$(_state lshw)" \
|
"mc" "Midnight Commander" "$(_state mc)" \
|
||||||
"mc" "Midnight Commander$(_inst mc)" "$(_state mc)" \
|
"nvme-cli" "NVMe SSD health monitoring" "$(_state nvme-cli)" \
|
||||||
"nvme-cli" "NVMe SSD health monitoring$(_inst nvme-cli)" "$(_state nvme-cli)" \
|
"ncdu" "Disk usage analyzer" "$(_state ncdu)" \
|
||||||
"ncdu" "Disk usage analyzer$(_inst ncdu)" "$(_state ncdu)" \
|
"psensor" "Temperature monitor" "$(_state psensor)" \
|
||||||
"psensor" "Temperature monitor$(_inst psensor)" "$(_state psensor)" \
|
"timeshift" "System restore snapshots" "$(_state timeshift)" \
|
||||||
"timeshift" "System restore snapshots$(_inst timeshift)" "$(_state timeshift)" \
|
"tmux" "Terminal multiplexer" "$(_state tmux)" \
|
||||||
"tmux" "Terminal multiplexer$(_inst tmux)" "$(_state tmux)" \
|
"wine" "Windows compatibility layer" "$(_state wine)" \
|
||||||
"wine" "Windows compatibility layer$(_inst wine)" "$(_state wine)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -472,15 +483,17 @@ _cat_general_bullseye() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
wine)
|
wine)
|
||||||
if ! is_installed "wine"; then
|
if ! is_installed "wine64"; then
|
||||||
if ! dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
|
_run_cmd "Wine" "sudo apt install -y --no-install-recommends wine64 fonts-wine" "Installing Wine (64-bit only)..."
|
||||||
sudo dpkg --add-architecture i386
|
local wine_ver
|
||||||
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
|
wine_ver=$(wine --version 2>/dev/null)
|
||||||
fi
|
if [ -n "$wine_ver" ]; then
|
||||||
_run_cmd "Wine" "sudo apt install -y wine wine32 wine64 libwine libwine:i386 fonts-wine" "Installing Wine..."
|
echo -e "${GREEN}Wine (64-bit) installed: ${wine_ver}${NC}"
|
||||||
echo -e "${GREEN}Wine installed.${NC}"
|
|
||||||
else
|
else
|
||||||
echo "Wine already installed."
|
echo -e "${YELLOW}Wine installed but version check failed.${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Wine64 already installed."
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
fwupd)
|
fwupd)
|
||||||
@@ -490,6 +503,7 @@ _cat_general_bullseye() {
|
|||||||
if _confirm "Firmware Scan" "Scan for firmware updates now?"; then
|
if _confirm "Firmware Scan" "Scan for firmware updates now?"; then
|
||||||
sudo fwupdmgr refresh --force 2>/dev/null || true
|
sudo fwupdmgr refresh --force 2>/dev/null || true
|
||||||
sudo fwupdmgr get-updates 2>&1 || true
|
sudo fwupdmgr get-updates 2>&1 || true
|
||||||
|
_pause
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
nvme-cli)
|
nvme-cli)
|
||||||
@@ -505,19 +519,20 @@ _cat_general_bullseye() {
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
echo -e "${GREEN}System tools installed.${NC}"
|
echo -e "${GREEN}System tools installed.${NC}"
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|
||||||
_cat_fetch_bullseye() {
|
_cat_fetch_bullseye() {
|
||||||
local items=(
|
local items=(
|
||||||
"neofetch" "System info fetcher$(_inst neofetch)" "$(_state neofetch)"
|
"neofetch" "System info fetcher" "$(_state neofetch)"
|
||||||
"screenfetch" "System info (BSD/Linux)$(_inst screenfetch)" "$(_state screenfetch)"
|
"screenfetch" "System info (BSD/Linux)" "$(_state screenfetch)"
|
||||||
"linuxlogo" "Linux logo + system info$(_inst linuxlogo)" "$(_state linuxlogo)"
|
"linuxlogo" "Linux logo + system info" "$(_state linuxlogo)"
|
||||||
)
|
)
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Fetch Tools (Bullseye)" --checklist \
|
choices=$(_checklist "Fetch Tools (Bullseye)" "Select system info tools:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select system info tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
"${items[@]}" )
|
||||||
"${items[@]}" 3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
@@ -540,8 +555,7 @@ install_extras_bullseye() {
|
|||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
local cat_choice
|
local cat_choice
|
||||||
cat_choice=$(whiptail --title "Extra Software — Bullseye" --menu \
|
cat_choice=$(_menu "Extra Software — Bullseye" "Select a category${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"Select a category${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
|
||||||
"0" "Essential Pack" \
|
"0" "Essential Pack" \
|
||||||
"1" "Customization System" \
|
"1" "Customization System" \
|
||||||
"2" "Download & Network" \
|
"2" "Download & Network" \
|
||||||
@@ -555,7 +569,7 @@ install_extras_bullseye() {
|
|||||||
"10" "System Tools" \
|
"10" "System Tools" \
|
||||||
"11" "Fetch / System Info" \
|
"11" "Fetch / System Info" \
|
||||||
"12" "Back to main menu" \
|
"12" "Back to main menu" \
|
||||||
3>&1 1>&2 2>&3)
|
)
|
||||||
|
|
||||||
[ -z "$cat_choice" ] && return
|
[ -z "$cat_choice" ] && return
|
||||||
clear
|
clear
|
||||||
@@ -581,11 +595,10 @@ install_extras_bullseye() {
|
|||||||
|
|
||||||
_cat_software_centers_bullseye() {
|
_cat_software_centers_bullseye() {
|
||||||
local sc_choice
|
local sc_choice
|
||||||
sc_choice=$(whiptail --title "Software Centers" --menu \
|
sc_choice=$(_menu "Software Centers" "Choose a software store to install:" 12 65 2 \
|
||||||
"Choose a software store to install:" 12 65 2 \
|
"gnome-software" "Software Center for GNOME" \
|
||||||
"gnome-software" "Software Center for GNOME$(_inst gnome-software)" \
|
"plasma-discover" "Software manager for Plasma" \
|
||||||
"plasma-discover" "Software manager for Plasma$(_inst plasma-discover)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
[ -z "$sc_choice" ] && return
|
[ -z "$sc_choice" ] && return
|
||||||
|
|
||||||
_run_cmd "Install" "sudo apt install -y $sc_choice" "Installing ${sc_choice}..."
|
_run_cmd "Install" "sudo apt install -y $sc_choice" "Installing ${sc_choice}..."
|
||||||
|
|||||||
+14
-29
@@ -27,28 +27,6 @@ No security updates will be available." 12 60
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Fermi PCI ID detection — 6 condiciones inclusivas
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
is_nvidia_fermi() {
|
|
||||||
local dev_id
|
|
||||||
dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | \
|
|
||||||
grep -oP '10de:\K[0-9a-fA-F]+' | head -n1)
|
|
||||||
[ -z "$dev_id" ] && { echo false; return; }
|
|
||||||
|
|
||||||
local dev_int
|
|
||||||
dev_int=$((16#${dev_id,,}))
|
|
||||||
|
|
||||||
if [ "$dev_int" -ge $((16#06C0)) ] && [ "$dev_int" -le $((16#06DF)) ]; then echo true; return; fi
|
|
||||||
if [ "$dev_int" -ge $((16#0DC0)) ] && [ "$dev_int" -le $((16#0DFF)) ]; then echo true; return; fi
|
|
||||||
if [ "$dev_int" -ge $((16#0DE0)) ] && [ "$dev_int" -le $((16#0DFF)) ]; then echo true; return; fi
|
|
||||||
if [ "$dev_int" -ge $((16#0E00)) ] && [ "$dev_int" -le $((16#0E1F)) ]; then echo true; return; fi
|
|
||||||
if [ "$dev_int" -ge $((16#1080)) ] && [ "$dev_int" -le $((16#10DF)) ]; then echo true; return; fi
|
|
||||||
if [ "$dev_int" -eq $((16#1201)) ]; then echo true; return; fi
|
|
||||||
|
|
||||||
echo false
|
|
||||||
}
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# NVIDIA driver installer for Bullseye (Kepler → 470, Fermi → 390)
|
# NVIDIA driver installer for Bullseye (Kepler → 470, Fermi → 390)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -186,17 +164,17 @@ Installs matching 32-bit graphics drivers."; then
|
|||||||
|
|
||||||
# Gaming tools checklist (no Steam, no Heroic)
|
# Gaming tools checklist (no Steam, no Heroic)
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Gaming Tools — Bullseye" --checklist \
|
choices=$(_checklist "Gaming Tools — Bullseye" \
|
||||||
"Select gaming optimization tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"Select gaming optimization tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"gamemode" "Game performance optimization" ON \
|
"gamemode" "Game performance optimization" ON \
|
||||||
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
|
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
|
||||||
"goverlay" "MangoHud config GUI" ON \
|
"goverlay" "MangoHud config GUI" ON \
|
||||||
"lutris" "Game launcher/manager" OFF \
|
"lutris" "Game launcher/manager" OFF \
|
||||||
"java" "Java Runtimes (8, 17, 21)" OFF \
|
"java" "Java Runtimes (8, 17, 21)" OFF)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
|
|
||||||
if [ -z "$choices" ]; then
|
if [ -z "$choices" ]; then
|
||||||
echo "No gaming tools selected."
|
echo "No gaming tools selected."
|
||||||
|
_pause
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -206,24 +184,31 @@ Installs matching 32-bit graphics drivers."; then
|
|||||||
for pkg in $cleaned; do
|
for pkg in $cleaned; do
|
||||||
case $pkg in
|
case $pkg in
|
||||||
mangohud)
|
mangohud)
|
||||||
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Installing MangoHud..."
|
local mh_pkgs="mangohud"
|
||||||
if $enable_32bit; then
|
if $enable_32bit; then
|
||||||
local mh32_ver
|
local mh32_ver
|
||||||
mh32_ver=$(apt-cache policy mangohud:i386 2>/dev/null | \
|
mh32_ver=$(apt-cache policy mangohud:i386 2>/dev/null | \
|
||||||
awk 'NR==3 {print $2; exit}')
|
awk 'NR==3 {print $2; exit}')
|
||||||
if [ -n "$mh32_ver" ] && [ "$mh32_ver" != "(none)" ]; then
|
if [ -n "$mh32_ver" ] && [ "$mh32_ver" != "(none)" ]; then
|
||||||
_run_cmd "MangoHud" "sudo apt install -y mangohud:i386" \
|
mh_pkgs+=" mangohud:i386"
|
||||||
"Installing MangoHud 32-bit..."
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
_run_cmd "MangoHud" "sudo apt install -y $mh_pkgs" "Installing MangoHud (64 + 32-bit)..."
|
||||||
;;
|
;;
|
||||||
gamemode) _run_cmd "GameMode" "sudo apt install -y gamemode" "Installing GameMode..." ;;
|
gamemode) _run_cmd "GameMode" "sudo apt install -y gamemode" "Installing GameMode..." ;;
|
||||||
goverlay) _run_cmd "GOverlay" "sudo apt install -y goverlay" "Installing GOverlay..." ;;
|
goverlay) _run_cmd "GOverlay" "sudo apt install -y goverlay" "Installing GOverlay..." ;;
|
||||||
lutris) _run_cmd "Lutris" "sudo apt install -y lutris" "Installing Lutris..." ;;
|
lutris)
|
||||||
|
local pkgs="lutris wine64"
|
||||||
|
if dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
|
||||||
|
pkgs+=" wine32"
|
||||||
|
fi
|
||||||
|
_run_cmd "Lutris" "sudo apt install -y $pkgs" "Installing Lutris + Wine..."
|
||||||
|
;;
|
||||||
java) _install_gaming_java ;;
|
java) _install_gaming_java ;;
|
||||||
*) _run_install "$pkg" ;;
|
*) _run_install "$pkg" ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
echo -e "${GREEN}Lightweight gaming setup complete.${NC}"
|
echo -e "${GREEN}Lightweight gaming setup complete.${NC}"
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,281 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
manage_desktop_display() {
|
||||||
|
while true; do
|
||||||
|
local choice
|
||||||
|
choice=$(_menu "Desktop & Display" \
|
||||||
|
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
||||||
|
"1" "Desktop Environment" \
|
||||||
|
"2" "Display Manager" \
|
||||||
|
"3" "Back to main menu")
|
||||||
|
[ -z "$choice" ] && break
|
||||||
|
clear
|
||||||
|
case "$choice" in
|
||||||
|
1) _msg "Coming Soon" "Desktop Environment management will be available in a future update." 10 60 ;;
|
||||||
|
2) display_manager_menu ;;
|
||||||
|
3) break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
display_manager_menu() {
|
||||||
|
while true; do
|
||||||
|
local -a dm_items=()
|
||||||
|
dm_items+=("1" "LightDM")
|
||||||
|
dm_items+=("2" "GDM3")
|
||||||
|
dm_items+=("3" "SDDM")
|
||||||
|
if [ "$DEBIAN_VERSION" = "12" ] || [ "$DEBIAN_VERSION" = "13" ]; then
|
||||||
|
dm_items+=("4" "greetd")
|
||||||
|
dm_items+=("5" "Back")
|
||||||
|
else
|
||||||
|
dm_items+=("4" "Back")
|
||||||
|
fi
|
||||||
|
local choice
|
||||||
|
choice=$(_menu "Display Manager" \
|
||||||
|
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
||||||
|
"${dm_items[@]}")
|
||||||
|
[ -z "$choice" ] && break
|
||||||
|
clear
|
||||||
|
case "$choice" in
|
||||||
|
1) lightdm_config_menu ;;
|
||||||
|
2) configure_gdm3 ;;
|
||||||
|
3) configure_sddm ;;
|
||||||
|
4) configure_greetd ;;
|
||||||
|
5) break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
lightdm_config_menu() {
|
||||||
|
local -a items=()
|
||||||
|
items+=("install_lightdm" "Install LightDM & GTK Greeter" "$(_state lightdm)")
|
||||||
|
items+=("enable_userlist" "Enable user list at login screen" "OFF")
|
||||||
|
items+=("enable_autologin" "Enable autologin for current user" "OFF")
|
||||||
|
local choices
|
||||||
|
choices=$(_checklist "LightDM Configuration" \
|
||||||
|
"Select options to apply:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
|
"${items[@]}")
|
||||||
|
if [ -z "$choices" ]; then
|
||||||
|
echo "No changes."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local cleaned
|
||||||
|
cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
for item in $cleaned; do
|
||||||
|
case $item in
|
||||||
|
install_lightdm)
|
||||||
|
if ! is_installed lightdm || ! is_installed lightdm-gtk-greeter-settings; then
|
||||||
|
echo "lightdm shared/default-x-display-manager select lightdm" | sudo debconf-set-selections
|
||||||
|
_run_cmd "LightDM" "sudo apt install -y lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings" "Installing LightDM & GTK Greeter..."
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[LightDM] LightDM and GTK Greeter settings are already installed, skipping...${NC}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
enable_userlist)
|
||||||
|
local conf="/etc/lightdm/lightdm.conf.d/50-debianito-userlist.conf"
|
||||||
|
sudo mkdir -p "$(dirname "$conf")"
|
||||||
|
if echo "[Seat:*]
|
||||||
|
greeter-hide-users=false" | sudo tee "$conf" > /dev/null; then
|
||||||
|
echo -e "${GREEN}User list enabled in LightDM.${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}Failed to write configuration.${NC}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
enable_autologin)
|
||||||
|
local dm_conf="/etc/lightdm/lightdm.conf"
|
||||||
|
local lightdm_user="${SUDO_USER:-$USER}"
|
||||||
|
sudo sed -i 's/^#[[:space:]]*autologin-user[[:space:]=].*/autologin-user='"$lightdm_user"'/' "$dm_conf"
|
||||||
|
sudo sed -i 's/^#[[:space:]]*autologin-user-timeout[[:space:]=].*/autologin-user-timeout=0/' "$dm_conf"
|
||||||
|
echo -e "${GREEN}Autologin enabled for user: ${lightdm_user}${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_pause
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_greetd() {
|
||||||
|
while true; do
|
||||||
|
local -a gd_items=()
|
||||||
|
gd_items+=("1" "Install base greetd")
|
||||||
|
gd_items+=("2" "Install greetd + tuigreet (Recommended TUI greeter)")
|
||||||
|
if [ "$DEBIAN_VERSION" = "13" ]; then
|
||||||
|
gd_items+=("3" "Install gtkgreet (Requires manual setup)")
|
||||||
|
gd_items+=("4" "Install nwg-hello (Requires manual setup)")
|
||||||
|
gd_items+=("5" "Install wlgreet (Requires manual setup)")
|
||||||
|
gd_items+=("6" "Back")
|
||||||
|
else
|
||||||
|
gd_items+=("3" "Back")
|
||||||
|
fi
|
||||||
|
local choice
|
||||||
|
choice=$(_menu "greetd Configuration" \
|
||||||
|
"Select an option${SCROLL_HINT}:" \
|
||||||
|
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
|
"${gd_items[@]}")
|
||||||
|
[ -z "$choice" ] && return
|
||||||
|
clear
|
||||||
|
case "$choice" in
|
||||||
|
1)
|
||||||
|
echo "greetd shared/default-x-display-manager select greetd" | sudo debconf-set-selections
|
||||||
|
_run_cmd "greetd" "sudo apt install -y greetd" "Installing greetd..."
|
||||||
|
_msg "greetd" "Warning: greetd was installed but NOT configured.\n\nYou must manually create /etc/greetd/config.toml\nto be able to log in.\n\nSee 'man greetd' and 'man 5 greetd-sessions'."
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
if [ "$DEBIAN_VERSION" = "12" ]; then
|
||||||
|
if [ "$(is_backports_enabled)" != true ]; then
|
||||||
|
_write_deb822_backports "bookworm"
|
||||||
|
sudo apt update -qq
|
||||||
|
fi
|
||||||
|
_run_cmd "greetd" "sudo apt install -y -t bookworm-backports tuigreet greetd" "Installing greetd + tuigreet..."
|
||||||
|
else
|
||||||
|
_run_cmd "greetd" "sudo apt install -y greetd tuigreet" "Installing greetd + tuigreet..."
|
||||||
|
fi
|
||||||
|
_msg "greetd" "Warning: greetd was installed but NOT configured.\n\nYou must manually create /etc/greetd/config.toml\nto be able to log in.\n\nSee 'man greetd' and 'man 5 greetd-sessions'."
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
if [ "$DEBIAN_VERSION" = "13" ]; then
|
||||||
|
echo "greetd shared/default-x-display-manager select greetd" | sudo debconf-set-selections
|
||||||
|
_run_cmd "greetd" "sudo apt install -y greetd gtkgreet" "Installing greetd + gtkgreet..."
|
||||||
|
_msg "greetd" "Warning: greetd was installed but NOT configured.\n\nYou must manually create /etc/greetd/config.toml\nto be able to log in.\n\nSee 'man greetd' and 'man 5 greetd-sessions'."
|
||||||
|
else
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
if [ "$DEBIAN_VERSION" = "13" ]; then
|
||||||
|
echo "greetd shared/default-x-display-manager select greetd" | sudo debconf-set-selections
|
||||||
|
_run_cmd "greetd" "sudo apt install -y greetd nwg-hello" "Installing greetd + nwg-hello..."
|
||||||
|
_msg "greetd" "Warning: greetd was installed but NOT configured.\n\nYou must manually create /etc/greetd/config.toml\nto be able to log in.\n\nSee 'man greetd' and 'man 5 greetd-sessions'."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
if [ "$DEBIAN_VERSION" = "13" ]; then
|
||||||
|
echo "greetd shared/default-x-display-manager select greetd" | sudo debconf-set-selections
|
||||||
|
_run_cmd "greetd" "sudo apt install -y greetd wlgreet" "Installing greetd + wlgreet..."
|
||||||
|
_msg "greetd" "Warning: greetd was installed but NOT configured.\n\nYou must manually create /etc/greetd/config.toml\nto be able to log in.\n\nSee 'man greetd' and 'man 5 greetd-sessions'."
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
6) return ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_gdm3() {
|
||||||
|
while true; do
|
||||||
|
local items_enabled=()
|
||||||
|
items_enabled+=("install" "Install/Reinstall gdm3 (Set as default)" "$(_state gdm3)")
|
||||||
|
items_enabled+=("userlist" "Hide user list (disable-user-list)" "OFF")
|
||||||
|
items_enabled+=("autologin" "Configure Autologin" "OFF")
|
||||||
|
if [ "$DEBIAN_VERSION" = "12" ] || [ "$DEBIAN_VERSION" = "13" ]; then
|
||||||
|
if [ "$HAS_NVIDIA" = true ]; then
|
||||||
|
items_enabled+=("wayland" "Force Enable Wayland on NVIDIA (Risk!)" "OFF")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
local choice
|
||||||
|
choice=$(_checklist "GDM3 Configuration" \
|
||||||
|
"Select options to apply${SCROLL_HINT}:" \
|
||||||
|
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
|
"${items_enabled[@]}")
|
||||||
|
[ -z "$choice" ] && return
|
||||||
|
clear
|
||||||
|
|
||||||
|
local cleaned
|
||||||
|
cleaned=$(echo "$choice" | tr -d '"')
|
||||||
|
for item in $cleaned; do
|
||||||
|
case $item in
|
||||||
|
install)
|
||||||
|
echo "gdm3 shared/default-x-display-manager select gdm3" | sudo debconf-set-selections
|
||||||
|
_run_cmd "GDM3" "sudo apt install -y gdm3" "Installing gdm3..."
|
||||||
|
;;
|
||||||
|
userlist)
|
||||||
|
local greeter_conf="/etc/gdm3/greeter.dconf-defaults"
|
||||||
|
if sudo grep -q '^disable-user-list=true' "$greeter_conf" 2>/dev/null; then
|
||||||
|
sudo sed -i 's/^disable-user-list=true/# disable-user-list=true/' "$greeter_conf"
|
||||||
|
echo -e "${GREEN}User list is now VISIBLE.${NC}"
|
||||||
|
else
|
||||||
|
sudo sed -i 's/^#[[:space:]]*disable-user-list=true/disable-user-list=true/' "$greeter_conf"
|
||||||
|
echo -e "${GREEN}User list is now HIDDEN.${NC}"
|
||||||
|
fi
|
||||||
|
sudo dpkg-reconfigure gdm3 >/dev/null 2>&1
|
||||||
|
;;
|
||||||
|
autologin)
|
||||||
|
local daemon_conf="/etc/gdm3/daemon.conf"
|
||||||
|
local username
|
||||||
|
username=$(whiptail --title "GDM3 Autologin" \
|
||||||
|
--inputbox "Enter username to autologin (leave empty to DISABLE autologin):" \
|
||||||
|
10 60 "" 3>&1 1>&2 2>&3 || true)
|
||||||
|
if [ -n "$username" ]; then
|
||||||
|
sudo sed -i 's/^# *AutomaticLoginEnable[[:space:]=].*/AutomaticLoginEnable=true/' "$daemon_conf"
|
||||||
|
sudo sed -i 's/^# *AutomaticLogin[[:space:]=].*/AutomaticLogin='"$username"'/' "$daemon_conf"
|
||||||
|
echo -e "${GREEN}Autologin enabled for user: ${username}${NC}"
|
||||||
|
else
|
||||||
|
sudo sed -i 's/^AutomaticLoginEnable[[:space:]=].*/# AutomaticLoginEnable=false/' "$daemon_conf"
|
||||||
|
sudo sed -i 's/^AutomaticLogin[[:space:]=].*/# AutomaticLogin=/' "$daemon_conf"
|
||||||
|
echo -e "${GREEN}Autologin disabled.${NC}"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
wayland)
|
||||||
|
local rules_link="/etc/udev/rules.d/61-gdm.rules"
|
||||||
|
if [ -L "$rules_link" ] || [ -f "$rules_link" ]; then
|
||||||
|
sudo rm -f "$rules_link"
|
||||||
|
echo -e "${GREEN}Reverted. Wayland will be disabled by default on next reboot.${NC}"
|
||||||
|
elif [ -f "/lib/udev/rules.d/61-gdm.rules" ]; then
|
||||||
|
if _confirm "Wayland on NVIDIA" \
|
||||||
|
"Force-enable Wayland on NVIDIA?\n\nRisk: This may break graphics or cause instability.\nProceed?"; then
|
||||||
|
sudo ln -s /dev/null "$rules_link"
|
||||||
|
echo -e "${GREEN}Wayland override created. Reboot required.${NC}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
_pause
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_sddm() {
|
||||||
|
while true; do
|
||||||
|
local choice
|
||||||
|
choice=$(_menu "SDDM Configuration" \
|
||||||
|
"Select an option${SCROLL_HINT}:" \
|
||||||
|
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
|
"1" "Install SDDM (Set as default)" \
|
||||||
|
"2" "Enable Autologin" \
|
||||||
|
"3" "Back")
|
||||||
|
[ -z "$choice" ] && return
|
||||||
|
clear
|
||||||
|
case "$choice" in
|
||||||
|
1)
|
||||||
|
echo "sddm shared/default-x-display-manager select sddm" | sudo debconf-set-selections
|
||||||
|
_run_cmd "SDDM" "sudo apt install -y sddm" "Installing SDDM..."
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
local sddm_session=""
|
||||||
|
local sddm_user="${SUDO_USER:-$USER}"
|
||||||
|
if [ -f /usr/share/wayland-sessions/plasmawayland.desktop ]; then
|
||||||
|
sddm_session="plasmawayland"
|
||||||
|
elif [ -f /usr/share/wayland-sessions/lxqt-wayland.desktop ]; then
|
||||||
|
sddm_session="lxqt-wayland"
|
||||||
|
elif [ -f /usr/share/xsessions/plasma.desktop ]; then
|
||||||
|
sddm_session="plasma"
|
||||||
|
elif [ -f /usr/share/xsessions/lxqt.desktop ]; then
|
||||||
|
sddm_session="lxqt"
|
||||||
|
fi
|
||||||
|
sudo mkdir -p /etc/sddm.conf.d
|
||||||
|
cat << EOF | sudo tee /etc/sddm.conf.d/autologin.conf > /dev/null
|
||||||
|
[Autologin]
|
||||||
|
User=${sddm_user}
|
||||||
|
Session=${sddm_session}
|
||||||
|
Relogin=false
|
||||||
|
EOF
|
||||||
|
if [ -n "$sddm_session" ]; then
|
||||||
|
echo -e "${GREEN}Autologin enabled for user ${sddm_user}, session: ${sddm_session}.${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}Autologin enabled for user ${sddm_user}. No session set (SDDM will use default).${NC}"
|
||||||
|
fi
|
||||||
|
_pause
|
||||||
|
;;
|
||||||
|
3) return ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
+2
-3
@@ -27,7 +27,7 @@ install_extras() {
|
|||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
local cat_choice
|
local cat_choice
|
||||||
cat_choice=$(whiptail --title "Extra Software" --menu \
|
cat_choice=$(_menu "Install Programs and Software" \
|
||||||
"Select a category${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"Select a category${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"0" "Essential Pack" \
|
"0" "Essential Pack" \
|
||||||
"1" "Customization System" \
|
"1" "Customization System" \
|
||||||
@@ -42,8 +42,7 @@ install_extras() {
|
|||||||
"10" "Office & Productivity" \
|
"10" "Office & Productivity" \
|
||||||
"11" "System Tools" \
|
"11" "System Tools" \
|
||||||
"12" "Fetch / System Info" \
|
"12" "Fetch / System Info" \
|
||||||
"13" "Back to main menu" \
|
"13" "Back to main menu")
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
|
|
||||||
[ -z "$cat_choice" ] && return
|
[ -z "$cat_choice" ] && return
|
||||||
clear
|
clear
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Shared helpers for extras categories
|
# Shared helpers for extras categories
|
||||||
|
|
||||||
_inst() {
|
|
||||||
if is_installed "$1"; then echo " (installed)"; else echo ""; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_state() {
|
|
||||||
is_installed "$1" && echo "ON" || echo "OFF"
|
|
||||||
}
|
|
||||||
|
|
||||||
_install_clamav() {
|
_install_clamav() {
|
||||||
if is_installed "clamav"; then
|
if is_installed "clamav"; then
|
||||||
echo "ClamAV already installed."
|
echo "ClamAV already installed."
|
||||||
@@ -21,6 +13,7 @@ _install_clamav() {
|
|||||||
sudo systemctl stop clamav-freshclam 2>/dev/null || true
|
sudo systemctl stop clamav-freshclam 2>/dev/null || true
|
||||||
sudo freshclam || true
|
sudo freshclam || true
|
||||||
sudo systemctl start clamav-freshclam 2>/dev/null || true
|
sudo systemctl start clamav-freshclam 2>/dev/null || true
|
||||||
|
_pause
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _confirm "ClamAV" "Run quick scan on /bin to verify engine works?"; then
|
if _confirm "ClamAV" "Run quick scan on /bin to verify engine works?"; then
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
_cat_design() {
|
_cat_design() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local audacity_state; audacity_state=$(_state "audacity")
|
local audacity_state; audacity_state=$(_state "audacity")
|
||||||
local ardour_state; ardour_state=$(_state "ardour")
|
local ardour_state; ardour_state=$(_state "ardour")
|
||||||
local blender_state; blender_state=$(_state "blender")
|
local blender_state; blender_state=$(_state "blender")
|
||||||
local ffmpeg_state; ffmpeg_state=$(_state "ffmpeg")
|
|
||||||
local gimp_state; gimp_state=$(_state "gimp")
|
local gimp_state; gimp_state=$(_state "gimp")
|
||||||
local handbrake_state; handbrake_state=$(_state "handbrake")
|
local handbrake_state; handbrake_state=$(_state "handbrake")
|
||||||
local inkscape_state; inkscape_state=$(_state "inkscape")
|
local inkscape_state; inkscape_state=$(_state "inkscape")
|
||||||
@@ -17,35 +18,34 @@ _cat_design() {
|
|||||||
local openshot_state; openshot_state=$(_state "openshot-qt")
|
local openshot_state; openshot_state=$(_state "openshot-qt")
|
||||||
local scribus_state; scribus_state=$(_state "scribus")
|
local scribus_state; scribus_state=$(_state "scribus")
|
||||||
local shotcut_state; shotcut_state=$(_state "shotcut")
|
local shotcut_state; shotcut_state=$(_state "shotcut")
|
||||||
|
items+=(
|
||||||
|
"audacity" "Audio editor/recorder" "$audacity_state"
|
||||||
|
"ardour" "Digital audio workstation" "$ardour_state"
|
||||||
|
"blender" "3D modeling/animation" "$blender_state"
|
||||||
|
"gimp" "Image editor" "$gimp_state"
|
||||||
|
"handbrake" "Video transcoder" "$handbrake_state"
|
||||||
|
"inkscape" "Vector graphics editor" "$inkscape_state"
|
||||||
|
"kdenlive" "Video editor (KDE)" "$kdenlive_state"
|
||||||
|
"krita" "Digital painting" "$krita_state"
|
||||||
|
"obs-studio" "Screen recording" "$obs_state"
|
||||||
|
"openshot-qt" "Simple video editor" "$openshot_state"
|
||||||
|
"scribus" "Desktop publishing" "$scribus_state"
|
||||||
|
"shotcut" "Cross-platform video editor" "$shotcut_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
local ffmpeg_state; ffmpeg_state=$(_state "ffmpeg")
|
||||||
|
items+=("ffmpeg" "Multimedia framework (CLI)" "$ffmpeg_state")
|
||||||
|
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Multimedia & Design" --checklist \
|
choices=$(_checklist "Multimedia & Design" "Select multimedia and design tools${SCROLL_HINT}:" \
|
||||||
"Select multimedia and design tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
$TUI_ALTO $TUI_ANCHO $lista_alto "${items[@]}")
|
||||||
"audacity" "Audio editor/recorder$(_inst audacity)" "$audacity_state" \
|
|
||||||
"ardour" "Digital audio workstation$(_inst ardour)" "$ardour_state" \
|
|
||||||
"blender" "3D modeling/animation suite$(_inst blender)" "$blender_state" \
|
|
||||||
"ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$ffmpeg_state" \
|
|
||||||
"gimp" "Image editor (Photoshop alternative)$(_inst gimp)" "$gimp_state" \
|
|
||||||
"handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$handbrake_state" \
|
|
||||||
"inkscape" "Vector graphics editor$(_inst inkscape)" "$inkscape_state" \
|
|
||||||
"kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$kdenlive_state" \
|
|
||||||
"krita" "Digital painting/illustration$(_inst krita)" "$krita_state" \
|
|
||||||
"obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$obs_state" \
|
|
||||||
"openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$openshot_state" \
|
|
||||||
"scribus" "Desktop publishing (DTP)$(_inst scribus)" "$scribus_state" \
|
|
||||||
"shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$shotcut_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
|
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
|
||||||
for pkg in $cleaned; do
|
for pkg in $cleaned; do
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
|
|||||||
+23
-19
@@ -4,6 +4,7 @@
|
|||||||
_cat_dev() {
|
_cat_dev() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
local apache_state; apache_state=$(_state "apache2")
|
local apache_state; apache_state=$(_state "apache2")
|
||||||
local build_state; build_state=$(_state "build-essential")
|
local build_state; build_state=$(_state "build-essential")
|
||||||
local certbot_state; certbot_state=$(_state "certbot")
|
local certbot_state; certbot_state=$(_state "certbot")
|
||||||
@@ -19,27 +20,30 @@ _cat_dev() {
|
|||||||
local sqlite_state; sqlite_state=$(_state "sqlite3")
|
local sqlite_state; sqlite_state=$(_state "sqlite3")
|
||||||
local jdk_desc; jdk_desc=$(_any_jdk_installed_desc)
|
local jdk_desc; jdk_desc=$(_any_jdk_installed_desc)
|
||||||
local jdk_state; jdk_state=$(_any_jdk_state)
|
local jdk_state; jdk_state=$(_any_jdk_state)
|
||||||
|
items+=(
|
||||||
|
"apache2" "Apache web server" "$apache_state"
|
||||||
|
"build-essential" "C/C++ build tools (gcc, make)" "$build_state"
|
||||||
|
"certbot" "Let's Encrypt TLS certificates" "$certbot_state"
|
||||||
|
"docker" "Docker + docker-compose" "$docker_state"
|
||||||
|
"mariadb-server" "MariaDB database server" "$mariadb_state"
|
||||||
|
"netcat-openbsd" "TCP/IP networking utility" "$netcat_state"
|
||||||
|
"nginx" "Nginx web server" "$nginx_state"
|
||||||
|
"openssh-server" "SSH server" "$ssh_state"
|
||||||
|
"openssl" "OpenSSL cryptography toolkit" "$openssl_state"
|
||||||
|
"postgresql" "PostgreSQL database server" "$pg_state"
|
||||||
|
"python3-pip" "Python 3 pip + venv + dev" "$pip_state"
|
||||||
|
"redis-server" "Redis key-value store" "$redis_state"
|
||||||
|
"sqlite3" "SQLite database engine" "$sqlite_state"
|
||||||
|
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)" OFF
|
||||||
|
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}"
|
||||||
|
)
|
||||||
|
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Development & Servers" --checklist \
|
choices=$(_checklist "Development & Servers" "Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select development tools and servers${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"apache2" "Apache web server$(_inst apache2)" "$apache_state" \
|
)
|
||||||
"build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$build_state" \
|
|
||||||
"certbot" "Let's Encrypt TLS certificates$(_inst certbot)" "$certbot_state" \
|
|
||||||
"docker" "Docker + docker-compose$(_inst docker.io)" "$docker_state" \
|
|
||||||
"mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$mariadb_state" \
|
|
||||||
"netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$netcat_state" \
|
|
||||||
"nginx" "Nginx web server$(_inst nginx)" "$nginx_state" \
|
|
||||||
"openssh-server" "SSH server$(_inst openssh-server)" "$ssh_state" \
|
|
||||||
"openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$openssl_state" \
|
|
||||||
"postgresql" "PostgreSQL database server$(_inst postgresql)" "$pg_state" \
|
|
||||||
"python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$pip_state" \
|
|
||||||
"redis-server" "Redis key-value store$(_inst redis-server)" "$redis_state" \
|
|
||||||
"sqlite3" "SQLite database engine$(_inst sqlite3)" "$sqlite_state" \
|
|
||||||
"jellyfin" "Jellyfin Media Server (Web GUI on port 8096)$(_inst jellyfin)" OFF \
|
|
||||||
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
|
|||||||
@@ -4,43 +4,57 @@
|
|||||||
_cat_download() {
|
_cat_download() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items1=()
|
||||||
|
local -a items2=()
|
||||||
local aria2_state; aria2_state=$(_state "aria2")
|
local aria2_state; aria2_state=$(_state "aria2")
|
||||||
local filezilla_state; filezilla_state=$(_state "filezilla")
|
|
||||||
local ytdlp_state; ytdlp_state=$(_state "yt-dlp")
|
local ytdlp_state; ytdlp_state=$(_state "yt-dlp")
|
||||||
local ytdlp_gui_state; ytdlp_gui_state=$(_state "youtubedl-gui")
|
|
||||||
|
|
||||||
local deluge_state; deluge_state=$(_state "deluge")
|
|
||||||
local deluged_state; deluged_state=$(_state "deluged")
|
local deluged_state; deluged_state=$(_state "deluged")
|
||||||
local mktorrent_state; mktorrent_state=$(_state "mktorrent")
|
local mktorrent_state; mktorrent_state=$(_state "mktorrent")
|
||||||
local qbit_state; qbit_state=$(_state "qbittorrent")
|
|
||||||
local qbitnox_state; qbitnox_state=$(_state "qbittorrent-nox")
|
local qbitnox_state; qbitnox_state=$(_state "qbittorrent-nox")
|
||||||
local tr_cli_state; tr_cli_state=$(_state "transmission-cli")
|
local tr_cli_state; tr_cli_state=$(_state "transmission-cli")
|
||||||
|
items1+=(
|
||||||
|
"aria2" "Multiprotocol downloader (CLI)" "$aria2_state"
|
||||||
|
"yt-dlp" "Video downloader CLI" "$ytdlp_state"
|
||||||
|
)
|
||||||
|
items2+=(
|
||||||
|
"deluged" "BitTorrent daemon/server" "$deluged_state"
|
||||||
|
"mktorrent" "Torrent metainfo creator (CLI)" "$mktorrent_state"
|
||||||
|
"qbittorrent-nox" "BitTorrent WebUI/CLI" "$qbitnox_state"
|
||||||
|
"transmission-cli" "BitTorrent client (CLI)" "$tr_cli_state"
|
||||||
|
)
|
||||||
|
if ! $headless; then
|
||||||
|
local filezilla_state; filezilla_state=$(_state "filezilla")
|
||||||
|
local ytdlp_gui_state; ytdlp_gui_state=$(_state "youtubedl-gui")
|
||||||
|
local deluge_state; deluge_state=$(_state "deluge")
|
||||||
|
local qbit_state; qbit_state=$(_state "qbittorrent")
|
||||||
local tr_gtk_state; tr_gtk_state=$(_state "transmission-gtk")
|
local tr_gtk_state; tr_gtk_state=$(_state "transmission-gtk")
|
||||||
local tr_qt_state; tr_qt_state=$(_state "transmission-qt")
|
local tr_qt_state; tr_qt_state=$(_state "transmission-qt")
|
||||||
|
items1+=(
|
||||||
|
"filezilla" "FTP/SFTP client (GUI)" "$filezilla_state"
|
||||||
|
"youtubedl-gui" "GUI for yt-dlp" "$ytdlp_gui_state"
|
||||||
|
)
|
||||||
|
items2+=(
|
||||||
|
"deluge" "BitTorrent client (GTK)" "$deluge_state"
|
||||||
|
"qbittorrent" "BitTorrent client (Qt)" "$qbit_state"
|
||||||
|
"transmission-gtk" "BitTorrent client (GTK)" "$tr_gtk_state"
|
||||||
|
"transmission-qt" "BitTorrent client (Qt)" "$tr_qt_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count1=${#items1[@]}
|
||||||
|
local lista_alto1=$((item_count1 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count1))
|
||||||
local choices1 choices2=""
|
local choices1 choices2=""
|
||||||
|
|
||||||
choices1=$(whiptail --title "Downloaders" --checklist \
|
choices1=$(_checklist "Downloaders" "Select download tools:" $TUI_ALTO $TUI_ANCHO $lista_alto1 \
|
||||||
"Select download tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
"${items1[@]}" \
|
||||||
"aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$aria2_state" \
|
)
|
||||||
"filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$filezilla_state" \
|
|
||||||
"yt-dlp" "Video downloader CLI$(_inst yt-dlp)" "$ytdlp_state" \
|
|
||||||
"youtubedl-gui" "GUI for yt-dlp$(_inst youtubedl-gui)" "$ytdlp_gui_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
choices2=$(whiptail --title "Torrent Clients" --checklist \
|
local item_count2=${#items2[@]}
|
||||||
"Select torrent clients:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
local lista_alto2=$((item_count2 > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count2))
|
||||||
"deluge" "BitTorrent client (GTK)$(_inst deluge)" "$deluge_state" \
|
choices2=$(_checklist "Torrent Clients" "Select torrent clients:" $TUI_ALTO $TUI_ANCHO $lista_alto2 \
|
||||||
"deluged" "BitTorrent daemon/server$(_inst deluged)" "$deluged_state" \
|
"${items2[@]}" \
|
||||||
"mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$mktorrent_state" \
|
)
|
||||||
"qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$qbit_state" \
|
|
||||||
"qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$qbitnox_state" \
|
|
||||||
"transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$tr_cli_state" \
|
|
||||||
"transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$tr_gtk_state" \
|
|
||||||
"transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$tr_qt_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
local cleaned
|
local cleaned
|
||||||
@@ -60,10 +74,6 @@ _cat_download() {
|
|||||||
install_backports_or_stable qbittorrent-nox
|
install_backports_or_stable qbittorrent-nox
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ _quick_install() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
_msg "Essential Pack" \
|
_msg "Essential Pack" \
|
||||||
"Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, ${fetch_pkg})\n - VLC media player\n - Microsoft fonts" 13 60
|
"Install basic programs:\n\n - Compression (zip, unrar, 7z)\n - System tools (htop, inxi, ${fetch_pkg}, $(_is_headless || echo "VLC"))\n - Microsoft fonts" 13 60
|
||||||
|
|
||||||
local quick_pkgs=(
|
local quick_pkgs=(
|
||||||
zip unzip rar unrar p7zip-full p7zip-rar
|
zip unzip rar unrar p7zip-full p7zip-rar
|
||||||
"$fetch_pkg" htop vlc inxi ttf-mscorefonts-installer
|
"$fetch_pkg" htop inxi ttf-mscorefonts-installer
|
||||||
)
|
)
|
||||||
|
_is_headless || quick_pkgs+=(vlc)
|
||||||
_run_install_batch "${quick_pkgs[@]}"
|
_run_install_batch "${quick_pkgs[@]}"
|
||||||
echo -e "${GREEN}Essential Pack installed.${NC}"
|
echo -e "${GREEN}Essential Pack installed.${NC}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,29 +18,29 @@ _cat_fetch() {
|
|||||||
hyfetch_state=$(_state "hyfetch")
|
hyfetch_state=$(_state "hyfetch")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local items=()
|
local -a items=()
|
||||||
|
|
||||||
if [ "$fetch_pkg" = "fastfetch" ]; then
|
if [ "$fetch_pkg" = "fastfetch" ]; then
|
||||||
items+=("fastfetch" "System info fetcher$(_inst fastfetch)" "$fetch_state")
|
items+=("fastfetch" "System info fetcher" "$fetch_state")
|
||||||
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
||||||
items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state")
|
items+=("hyfetch" "Neofetch with pride flags" "$hyfetch_state")
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
items+=("linuxlogo" "Linux logo + system info$(_inst linuxlogo)" "$linuxlogo_state")
|
items+=("linuxlogo" "Linux logo + system info" "$linuxlogo_state")
|
||||||
if [ "$fetch_pkg" = "neofetch" ]; then
|
if [ "$fetch_pkg" = "neofetch" ]; then
|
||||||
items+=("neofetch" "System info fetcher$(_inst neofetch)" "$fetch_state")
|
items+=("neofetch" "System info fetcher" "$fetch_state")
|
||||||
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
||||||
items+=("hyfetch" "Neofetch with pride flags$(_inst hyfetch)" "$hyfetch_state")
|
items+=("hyfetch" "Neofetch with pride flags" "$hyfetch_state")
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
items+=("screenfetch" "System info (BSD/Linux)$(_inst screenfetch)" "$screenfetch_state")
|
items+=("screenfetch" "System info (BSD/Linux)" "$screenfetch_state")
|
||||||
|
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Fetch Tools" --checklist \
|
choices=$(_checklist "Fetch Tools" "Select system info tools:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select system info tools:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
|
||||||
"${items[@]}" \
|
"${items[@]}" \
|
||||||
3>&1 1>&2 2>&3)
|
)
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# internet.sh — Browsers, email, VPN
|
# internet.sh — Browsers, email, VPN
|
||||||
# extrepo-powered: mozilla, floorp, palemoon, librewolf, tailscale, mullvad, protonvpn
|
# extrepo-powered: mozilla, floorp, palemoon, librewolf, tailscale, mullvad, protonvpn
|
||||||
|
# firefox-esr from Debian repos (with locale auto-detect)
|
||||||
|
|
||||||
# ── Helpers extrepo ──
|
# ── Helpers extrepo ──
|
||||||
_ensure_extrepo() {
|
_ensure_extrepo() {
|
||||||
@@ -116,65 +117,85 @@ install_protonvpn() {
|
|||||||
_cat_internet() {
|
_cat_internet() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local chromium_state; chromium_state=$(_state "chromium")
|
local chromium_state; chromium_state=$(_state "chromium")
|
||||||
local dillo_state; dillo_state=$(_state "dillo")
|
local dillo_state; dillo_state=$(_state "dillo")
|
||||||
local elinks_state; elinks_state=$(_state "elinks")
|
|
||||||
local epiphany_state; epiphany_state=$(_state "epiphany-browser")
|
local epiphany_state; epiphany_state=$(_state "epiphany-browser")
|
||||||
local falkon_state; falkon_state=$(_state "falkon")
|
local falkon_state; falkon_state=$(_state "falkon")
|
||||||
local firefox_state="OFF"
|
local firefox_state="OFF"
|
||||||
if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then
|
if command -v firefox &>/dev/null && ! is_installed "firefox-esr"; then
|
||||||
firefox_state="ON"
|
firefox_state="ON"
|
||||||
fi
|
fi
|
||||||
|
local firefox_esr_state
|
||||||
|
firefox_esr_state=$(_state "firefox-esr")
|
||||||
local floorp_state; floorp_state=$(_state "floorp")
|
local floorp_state; floorp_state=$(_state "floorp")
|
||||||
local konqueror_state; konqueror_state=$(_state "konqueror")
|
local konqueror_state; konqueror_state=$(_state "konqueror")
|
||||||
local librewolf_state; librewolf_state=$(_state "librewolf")
|
local librewolf_state; librewolf_state=$(_state "librewolf")
|
||||||
local palemoon_state; palemoon_state=$(_state "palemoon")
|
local palemoon_state; palemoon_state=$(_state "palemoon")
|
||||||
local privacybrowser_state; privacybrowser_state=$(_state "privacybrowser")
|
local privacybrowser_state; privacybrowser_state=$(_state "privacybrowser")
|
||||||
local qutebrowser_state; qutebrowser_state=$(_state "qutebrowser")
|
local qutebrowser_state; qutebrowser_state=$(_state "qutebrowser")
|
||||||
local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn")
|
|
||||||
local thunderbird_state; thunderbird_state=$(_state "thunderbird")
|
local thunderbird_state; thunderbird_state=$(_state "thunderbird")
|
||||||
local torbrowser_state; torbrowser_state=$(_state "torbrowser-launcher")
|
local torbrowser_state; torbrowser_state=$(_state "torbrowser-launcher")
|
||||||
|
local mullvadbrowser_state; mullvadbrowser_state=$(_state "mullvad-browser")
|
||||||
|
local protonvpn_state; protonvpn_state=$(_state "protonvpn")
|
||||||
|
items+=(
|
||||||
|
"chromium" "Chromium web browser" "$chromium_state"
|
||||||
|
"dillo" "Lightweight graphical browser" "$dillo_state"
|
||||||
|
"epiphany-browser" "GNOME web browser" "$epiphany_state"
|
||||||
|
"falkon" "KDE web browser (QtWebEngine)" "$falkon_state"
|
||||||
|
"firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state"
|
||||||
|
"firefox-esr" "Firefox ESR (official Debian + locale auto)" "$firefox_esr_state"
|
||||||
|
"floorp" "Firefox-based browser (extrepo)" "$floorp_state"
|
||||||
|
"konqueror" "KDE file manager / web browser" "$konqueror_state"
|
||||||
|
"librewolf" "Privacy-focused Firefox fork (extrepo)" "$librewolf_state"
|
||||||
|
"palemoon" "Classic Firefox-derived browser (extrepo)" "$palemoon_state"
|
||||||
|
"privacybrowser" "Privacy-focused web browser" "$privacybrowser_state"
|
||||||
|
"qutebrowser" "Keyboard-driven browser (Qt)" "$qutebrowser_state"
|
||||||
|
"thunderbird" "Email client" "$thunderbird_state"
|
||||||
|
"torbrowser-launcher" "Tor Browser launcher" "$torbrowser_state"
|
||||||
|
"mullvad-browser" "Mullvad privacy browser" "$mullvadbrowser_state"
|
||||||
|
"protonvpn" "ProtonVPN client" "$protonvpn_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
local elinks_state; elinks_state=$(_state "elinks")
|
||||||
|
local riseupvpn_state; riseupvpn_state=$(_state "riseup-vpn")
|
||||||
local w3m_state; w3m_state=$(_state "w3m")
|
local w3m_state; w3m_state=$(_state "w3m")
|
||||||
local tailscale_state; tailscale_state=$(_state "tailscale")
|
local tailscale_state; tailscale_state=$(_state "tailscale")
|
||||||
local mullvad_state; mullvad_state=$(_state "mullvad-vpn")
|
local mullvad_state; mullvad_state=$(_state "mullvad-vpn")
|
||||||
local mullvadbrowser_state; mullvadbrowser_state=$(_state "mullvad-browser")
|
items+=(
|
||||||
local protonvpn_state; protonvpn_state=$(_state "protonvpn")
|
"elinks" "Text-mode web browser" "$elinks_state"
|
||||||
|
"riseup-vpn" "Riseup VPN client" "$riseupvpn_state"
|
||||||
|
"w3m" "Text-mode browser + deps (w3m-img)" "$w3m_state"
|
||||||
|
"tailscale" "Zero-config VPN & mesh networking" "$tailscale_state"
|
||||||
|
"mullvad-vpn" "Mullvad VPN client (WireGuard)" "$mullvad_state"
|
||||||
|
)
|
||||||
|
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Internet" --checklist \
|
choices=$(_checklist "Internet" "Select browsers, email, and VPN tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select browsers, email, and VPN tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"chromium" "Chromium web browser$(_inst chromium)" "$chromium_state" \
|
)
|
||||||
"dillo" "Lightweight graphical browser$(_inst dillo)" "$dillo_state" \
|
|
||||||
"elinks" "Text-mode web browser$(_inst elinks)" "$elinks_state" \
|
|
||||||
"epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$epiphany_state" \
|
|
||||||
"falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$falkon_state" \
|
|
||||||
"firefox" "Firefox from Mozilla (replaces ESR)" "$firefox_state" \
|
|
||||||
"floorp" "Firefox-based browser (extrepo)$(_inst floorp)" "$floorp_state" \
|
|
||||||
"konqueror" "KDE file manager / web browser$(_inst konqueror)" "$konqueror_state" \
|
|
||||||
"librewolf" "Privacy-focused Firefox fork (extrepo)$(_inst librewolf)" "$librewolf_state" \
|
|
||||||
"palemoon" "Classic Firefox-derived browser (extrepo)" "$palemoon_state" \
|
|
||||||
"privacybrowser" "Privacy-focused web browser$(_inst privacybrowser)" "$privacybrowser_state" \
|
|
||||||
"qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$qutebrowser_state" \
|
|
||||||
"riseup-vpn" "Riseup VPN client$(_inst riseup-vpn)" "$riseupvpn_state" \
|
|
||||||
"thunderbird" "Email client$(_inst thunderbird)" "$thunderbird_state" \
|
|
||||||
"torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$torbrowser_state" \
|
|
||||||
"w3m" "Text-mode browser + deps (w3m-img)$(_inst w3m)" "$w3m_state" \
|
|
||||||
"tailscale" "Zero-config VPN & mesh networking$(_inst tailscale)" "$tailscale_state" \
|
|
||||||
"mullvad-vpn" "Mullvad VPN client (WireGuard)$(_inst mullvad-vpn)" "$mullvad_state" \
|
|
||||||
"mullvad-browser" "Mullvad privacy browser$(_inst mullvad-browser)" "$mullvadbrowser_state" \
|
|
||||||
"protonvpn" "ProtonVPN client$(_inst protonvpn)" "$protonvpn_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
|
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
|
||||||
|
if echo "$cleaned" | grep -q "firefox" && echo "$cleaned" | grep -q "firefox-esr"; then
|
||||||
|
_msg "Firefox" "You selected both Firefox (Mozilla) and Firefox ESR.\nPlease choose only one Firefox variant." 10 60
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
for pkg in $cleaned; do
|
for pkg in $cleaned; do
|
||||||
case $pkg in
|
case $pkg in
|
||||||
firefox)
|
firefox)
|
||||||
install_firefox_mozilla
|
install_firefox_mozilla
|
||||||
;;
|
;;
|
||||||
|
firefox-esr)
|
||||||
|
install_firefox_esr
|
||||||
|
;;
|
||||||
floorp)
|
floorp)
|
||||||
_enable_floorp_repo
|
_enable_floorp_repo
|
||||||
_run_install floorp
|
_run_install floorp
|
||||||
@@ -222,10 +243,6 @@ _cat_internet() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
@@ -239,7 +256,12 @@ _cat_internet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_firefox_mozilla() {
|
install_firefox_mozilla() {
|
||||||
if command -v firefox &>/dev/null && ! command -v firefox-esr &>/dev/null; then
|
if [ "$DEBIAN_VERSION" -lt 12 ] 2>/dev/null; then
|
||||||
|
_msg "Firefox" "Mozilla Firefox is only available on\nDebian 12 (Bookworm) and 13 (Trixie).\n\nSkipping installation." 10 60
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v firefox &>/dev/null && ! is_installed "firefox-esr"; then
|
||||||
echo "Firefox (Mozilla) is already installed."
|
echo "Firefox (Mozilla) is already installed."
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
@@ -255,6 +277,36 @@ install_firefox_mozilla() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
_enable_mozilla_repo
|
_enable_mozilla_repo
|
||||||
_run_install firefox
|
_run_cmd "Firefox" "sudo apt install -y firefox" "Installing Firefox (Mozilla)..."
|
||||||
echo -e "${GREEN}Firefox (Mozilla) installed.${NC}"
|
echo -e "${GREEN}Firefox (Mozilla) installed.${NC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_firefox_esr() {
|
||||||
|
if is_installed "firefox-esr"; then
|
||||||
|
echo "Firefox ESR is already installed."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v firefox &>/dev/null; then
|
||||||
|
if _confirm "Firefox" "Mozilla Firefox is installed.\nRemove it before installing Firefox ESR?"; then
|
||||||
|
echo "Removing Mozilla Firefox..."
|
||||||
|
sudo apt remove -y firefox
|
||||||
|
else
|
||||||
|
echo "Keeping Mozilla Firefox."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
_run_cmd "Firefox ESR" "sudo apt install -y firefox-esr" "Installing Firefox ESR..."
|
||||||
|
|
||||||
|
local lang_pkg
|
||||||
|
lang_pkg=$(_detect_lang_pkg "firefox-esr-l10n")
|
||||||
|
if [ -n "$lang_pkg" ]; then
|
||||||
|
_run_cmd "Firefox ESR Locale" "sudo apt install -y ${lang_pkg}" \
|
||||||
|
"Installing locale: ${lang_pkg}..."
|
||||||
|
else
|
||||||
|
echo "No matching locale package found for your language."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}Firefox ESR installed.${NC}"
|
||||||
|
}
|
||||||
|
|||||||
+13
-11
@@ -14,27 +14,29 @@ _enable_temurin_repo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_minecraft_java() {
|
install_minecraft_java() {
|
||||||
local ver
|
local choices
|
||||||
ver=$(whiptail --title "Java Runtimes for Minecraft" --menu \
|
choices=$(_checklist "Java Runtimes for Minecraft" \
|
||||||
"Select Java version:" 12 65 3 \
|
"Select Java version(s) to install:" 14 65 3 \
|
||||||
"8" "Java 8 — Classic mods & Minecraft <= 1.16.5" \
|
"8" "Java 8 — Classic mods & Minecraft <= 1.16.5" OFF \
|
||||||
"17" "Java 17 — Minecraft 1.17 to 1.20.4" \
|
"17" "Java 17 — Minecraft 1.17 to 1.20.4" ON \
|
||||||
"21" "Java 21 — Modern Minecraft >= 1.20.5 & 1.21+" \
|
"21" "Java 21 — Modern Minecraft >= 1.20.5 & 1.21+" OFF)
|
||||||
3>&1 1>&2 2>&3)
|
[ -z "$choices" ] && { echo "No Java version selected."; return; }
|
||||||
[ -z "$ver" ] && { echo "No Java version selected."; return; }
|
|
||||||
_enable_temurin_repo
|
_enable_temurin_repo
|
||||||
|
local cleaned
|
||||||
|
cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
for ver in $cleaned; do
|
||||||
_run_cmd "Java" "sudo apt install -y temurin-${ver}-jre" \
|
_run_cmd "Java" "sudo apt install -y temurin-${ver}-jre" \
|
||||||
"Installing Temurin JRE ${ver}..."
|
"Installing Temurin JRE ${ver}..."
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
_install_dev_java() {
|
_install_dev_java() {
|
||||||
local ver
|
local ver
|
||||||
ver=$(whiptail --title "Java Development Kits (JDK)" --menu \
|
ver=$(_menu "Java Development Kits (JDK)" \
|
||||||
"Select JDK version:" 12 60 3 \
|
"Select JDK version:" 12 60 3 \
|
||||||
"17" "Java 17 LTS Development Kit" \
|
"17" "Java 17 LTS Development Kit" \
|
||||||
"21" "Java 21 LTS Development Kit" \
|
"21" "Java 21 LTS Development Kit" \
|
||||||
"25" "Java 25 LTS Development Kit" \
|
"25" "Java 25 LTS Development Kit")
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
[ -z "$ver" ] && { echo "No JDK version selected."; return; }
|
[ -z "$ver" ] && { echo "No JDK version selected."; return; }
|
||||||
_enable_temurin_repo
|
_enable_temurin_repo
|
||||||
_run_install "temurin-${ver}-jdk"
|
_run_install "temurin-${ver}-jdk"
|
||||||
|
|||||||
@@ -33,16 +33,8 @@ install_libreoffice_bpo() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local sys_lang
|
local lang_pkg
|
||||||
sys_lang=$(echo "${LANG:-en}" | cut -c1-2 | tr '[:upper:]' '[:lower:]')
|
lang_pkg=$(_detect_lang_pkg "libreoffice-l10n")
|
||||||
|
|
||||||
local lang_pkg=""
|
|
||||||
if [ "$sys_lang" != "en" ]; then
|
|
||||||
local candidate="libreoffice-l10n-${sys_lang}"
|
|
||||||
if apt-cache show "$candidate" &>/dev/null 2>&1; then
|
|
||||||
lang_pkg="$candidate"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local ver
|
local ver
|
||||||
ver=$(apt-cache policy libreoffice 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
ver=$(apt-cache policy libreoffice 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
||||||
@@ -68,12 +60,22 @@ install_libreoffice_bpo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_cat_office() {
|
_cat_office() {
|
||||||
|
local headless=false
|
||||||
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
|
items+=(
|
||||||
|
"onlyoffice" "OnlyOffice Desktop Editors (extrepo)" OFF
|
||||||
|
"libreoffice" "LibreOffice (backports on Bookworm/Trixie)" OFF
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Office & Productivity" --checklist \
|
choices=$(_checklist "Office & Productivity" "Select office applications${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select office applications${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"onlyoffice" "OnlyOffice Desktop Editors (extrepo)" OFF \
|
)
|
||||||
"libreoffice" "LibreOffice (backports on Bookworm/Trixie)" OFF \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
|||||||
@@ -4,16 +4,22 @@
|
|||||||
_cat_players() {
|
_cat_players() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local mpv_state; mpv_state=$(_state "mpv")
|
local mpv_state; mpv_state=$(_state "mpv")
|
||||||
local vlc_state; vlc_state=$(_state "vlc")
|
local vlc_state; vlc_state=$(_state "vlc")
|
||||||
|
items+=(
|
||||||
|
"mpv" "Lightweight media player" "$mpv_state"
|
||||||
|
"vlc" "VLC media player" "$vlc_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Media Players" --checklist \
|
choices=$(_checklist "Media Players" "Select media players:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select media players:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"mpv" "Lightweight media player$(_inst mpv)" "$mpv_state" \
|
)
|
||||||
"vlc" "VLC media player$(_inst vlc)" "$vlc_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
@@ -21,10 +27,6 @@ _cat_players() {
|
|||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
|
||||||
for pkg in $cleaned; do
|
for pkg in $cleaned; do
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4,12 +4,21 @@
|
|||||||
_cat_programming() {
|
_cat_programming() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
local vim_state; vim_state=$(_state "vim")
|
local vim_state; vim_state=$(_state "vim")
|
||||||
local vimgtk_state; vimgtk_state=$(_state "vim-gtk3")
|
|
||||||
local neovim_state; neovim_state=$(_state "neovim")
|
local neovim_state; neovim_state=$(_state "neovim")
|
||||||
local hx_state; hx_state=$(_state "hx")
|
local hx_state; hx_state=$(_state "hx")
|
||||||
local nano_state; nano_state=$(_state "nano")
|
local nano_state; nano_state=$(_state "nano")
|
||||||
local emacs_state; emacs_state=$(_state "emacs")
|
local emacs_state; emacs_state=$(_state "emacs")
|
||||||
|
items+=(
|
||||||
|
"vim" "Classic terminal editor" "$vim_state"
|
||||||
|
"neovim" "Modern vim fork" "$neovim_state"
|
||||||
|
"hx" "Helix modal editor (Rust)" "$hx_state"
|
||||||
|
"nano" "Simple terminal editor" "$nano_state"
|
||||||
|
"emacs" "Extensible editor / IDE" "$emacs_state"
|
||||||
|
)
|
||||||
|
if ! $headless; then
|
||||||
|
local vimgtk_state; vimgtk_state=$(_state "vim-gtk3")
|
||||||
local kate_state; kate_state=$(_state "kate")
|
local kate_state; kate_state=$(_state "kate")
|
||||||
local mousepad_state; mousepad_state=$(_state "mousepad")
|
local mousepad_state; mousepad_state=$(_state "mousepad")
|
||||||
local gedit_state; gedit_state=$(_state "gedit")
|
local gedit_state; gedit_state=$(_state "gedit")
|
||||||
@@ -19,24 +28,23 @@ _cat_programming() {
|
|||||||
if command -v codium &>/dev/null; then
|
if command -v codium &>/dev/null; then
|
||||||
codium_state="ON"
|
codium_state="ON"
|
||||||
fi
|
fi
|
||||||
|
items+=(
|
||||||
|
"vim-gtk3" "Vim with GTK3 GUI" "$vimgtk_state"
|
||||||
|
"kate" "KDE advanced text editor" "$kate_state"
|
||||||
|
"mousepad" "Xfce text editor" "$mousepad_state"
|
||||||
|
"gedit" "GNOME text editor" "$gedit_state"
|
||||||
|
"geany" "Lightweight IDE" "$geany_state"
|
||||||
|
"gnome-text-editor" "GNOME modern text editor" "$gte_state"
|
||||||
|
"vscodium" "VS Code open-source (extrepo)" "$codium_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Programming Applications" --checklist \
|
choices=$(_checklist "Programming Applications" "Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select editors and IDEs${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"vim" "Classic terminal editor$(_inst vim)" "$vim_state" \
|
)
|
||||||
"vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$vimgtk_state" \
|
|
||||||
"neovim" "Modern vim fork$(_inst neovim)" "$neovim_state" \
|
|
||||||
"hx" "Helix modal editor (Rust)$(_inst hx)" "$hx_state" \
|
|
||||||
"nano" "Simple terminal editor$(_inst nano)" "$nano_state" \
|
|
||||||
"emacs" "Extensible editor / IDE$(_inst emacs)" "$emacs_state" \
|
|
||||||
"kate" "KDE advanced text editor$(_inst kate)" "$kate_state" \
|
|
||||||
"mousepad" "Xfce text editor$(_inst mousepad)" "$mousepad_state" \
|
|
||||||
"gedit" "GNOME text editor$(_inst gedit)" "$gedit_state" \
|
|
||||||
"geany" "Lightweight IDE$(_inst geany)" "$geany_state" \
|
|
||||||
"gnome-text-editor" "GNOME modern text editor$(_inst gnome-text-editor)" "$gte_state" \
|
|
||||||
"vscodium" "VS Code open-source (extrepo)$(_inst codium)" "$codium_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
@@ -49,10 +57,6 @@ _cat_programming() {
|
|||||||
install_vscodium
|
install_vscodium
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4,24 +4,32 @@
|
|||||||
_cat_security() {
|
_cat_security() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local wireshark_state; wireshark_state=$(_state "wireshark")
|
local wireshark_state; wireshark_state=$(_state "wireshark")
|
||||||
local tcpdump_state; tcpdump_state=$(_state "tcpdump")
|
|
||||||
local zenmap_state; zenmap_state=$(_state "zenmap")
|
local zenmap_state; zenmap_state=$(_state "zenmap")
|
||||||
|
items+=(
|
||||||
|
"wireshark" "Network protocol analyzer (GUI)" "$wireshark_state"
|
||||||
|
"zenmap" "Network scanner GUI (Nmap frontend)" "$zenmap_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
local tcpdump_state; tcpdump_state=$(_state "tcpdump")
|
||||||
local fail2ban_state; fail2ban_state=$(_state "fail2ban")
|
local fail2ban_state; fail2ban_state=$(_state "fail2ban")
|
||||||
local ufw_state; ufw_state=$(_state "ufw")
|
local ufw_state; ufw_state=$(_state "ufw")
|
||||||
local clamav_state; clamav_state=$(_state "clamav")
|
local clamav_state; clamav_state=$(_state "clamav")
|
||||||
|
items+=(
|
||||||
|
"tcpdump" "Command-line packet analyzer" "$tcpdump_state"
|
||||||
|
"fail2ban" "Brute-force protection daemon" "$fail2ban_state"
|
||||||
|
"ufw" "Uncomplicated firewall" "$ufw_state"
|
||||||
|
"clamav" "Antivirus engine (ClamAV)" "$clamav_state"
|
||||||
|
)
|
||||||
|
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Security & Networking" --checklist \
|
choices=$(_checklist "Security & Networking" "Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select security and networking tools${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$wireshark_state" \
|
)
|
||||||
"tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$tcpdump_state" \
|
|
||||||
"zenmap" "Network scanner GUI (Nmap frontend)$(_inst zenmap)" "$zenmap_state" \
|
|
||||||
"fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$fail2ban_state" \
|
|
||||||
"ufw" "Uncomplicated firewall$(_inst ufw)" "$ufw_state" \
|
|
||||||
"clamav" "Antivirus engine (ClamAV)$(_inst clamav)" "$clamav_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
# software_centers.sh — Standalone Software Center installer
|
# software_centers.sh — Standalone Software Center installer
|
||||||
|
|
||||||
_cat_software_centers() {
|
_cat_software_centers() {
|
||||||
|
local headless=false
|
||||||
|
_is_headless && headless=true
|
||||||
|
if $headless; then
|
||||||
|
echo "Software centers require a GUI — skipping."
|
||||||
|
return
|
||||||
|
fi
|
||||||
local de_type
|
local de_type
|
||||||
de_type=$(_detect_desktop_type)
|
de_type=$(_detect_desktop_type)
|
||||||
local sc_choice
|
local sc_choice
|
||||||
sc_choice=$(whiptail --title "Software Centers" --menu \
|
sc_choice=$(_menu "Software Centers" "Choose a software store to install:" 12 65 2 \
|
||||||
"Choose a software store to install:" 12 65 2 \
|
"gnome-software" "Software Center for GNOME" \
|
||||||
"gnome-software" "Software Center for GNOME$(_inst gnome-software)" \
|
"plasma-discover" "Software manager for Plasma" \
|
||||||
"plasma-discover" "Software manager for Plasma$(_inst plasma-discover)" \
|
)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
[ -z "$sc_choice" ] && return
|
[ -z "$sc_choice" ] && return
|
||||||
|
|
||||||
if { [ "$de_type" = "qt" ] && [ "$sc_choice" = "gnome-software" ]; } || \
|
if { [ "$de_type" = "qt" ] && [ "$sc_choice" = "gnome-software" ]; } || \
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ _detect_desktop_type() {
|
|||||||
_cat_general() {
|
_cat_general() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
local alacritty_state; alacritty_state=$(_state "alacritty")
|
local -a items=()
|
||||||
local btop_state; btop_state=$(_state "btop")
|
local btop_state; btop_state=$(_state "btop")
|
||||||
local compress_state
|
local compress_state
|
||||||
if is_installed "zip" && is_installed "unzip" && is_installed "p7zip-full"; then
|
if is_installed "zip" && is_installed "unzip" && is_installed "p7zip-full"; then
|
||||||
@@ -27,8 +27,6 @@ _cat_general() {
|
|||||||
else
|
else
|
||||||
compress_state="OFF"
|
compress_state="OFF"
|
||||||
fi
|
fi
|
||||||
local conky_state; conky_state=$(_state "conky")
|
|
||||||
local corectrl_state; corectrl_state=$(_state "corectrl")
|
|
||||||
local cpufetch_state; cpufetch_state=$(_state "cpufetch")
|
local cpufetch_state; cpufetch_state=$(_state "cpufetch")
|
||||||
local cpu_x_state; cpu_x_state=$(_state "cpu-x")
|
local cpu_x_state; cpu_x_state=$(_state "cpu-x")
|
||||||
local curl_wget_state
|
local curl_wget_state
|
||||||
@@ -37,62 +35,72 @@ _cat_general() {
|
|||||||
else
|
else
|
||||||
curl_wget_state="OFF"
|
curl_wget_state="OFF"
|
||||||
fi
|
fi
|
||||||
local dcgtk_state; dcgtk_state=$(_state "doublecmd-gtk")
|
|
||||||
local dcqt_state; dcqt_state=$(_state "doublecmd-qt")
|
|
||||||
local extrepo_state; extrepo_state=$(_state "extrepo")
|
local extrepo_state; extrepo_state=$(_state "extrepo")
|
||||||
local flatpak_state; flatpak_state=$(_state "flatpak")
|
local flatpak_state; flatpak_state=$(_state "flatpak")
|
||||||
local fwupd_state; fwupd_state=$(_state "fwupd")
|
local fwupd_state; fwupd_state=$(_state "fwupd")
|
||||||
local disks_state; disks_state=$(_state "gnome-disk-utility")
|
|
||||||
local gparted_state; gparted_state=$(_state "gparted")
|
|
||||||
local hardinfo_state; hardinfo_state=$(_state "hardinfo")
|
|
||||||
local htop_state; htop_state=$(_state "htop")
|
local htop_state; htop_state=$(_state "htop")
|
||||||
local inxi_state; inxi_state=$(_state "inxi")
|
local inxi_state; inxi_state=$(_state "inxi")
|
||||||
local kitty_state; kitty_state=$(_state "kitty")
|
|
||||||
local kvm_state; kvm_state=$(_state "virt-manager")
|
local kvm_state; kvm_state=$(_state "virt-manager")
|
||||||
local lshw_state; lshw_state=$(_state "lshw")
|
local lshw_state; lshw_state=$(_state "lshw")
|
||||||
local mc_state; mc_state=$(_state "mc")
|
local mc_state; mc_state=$(_state "mc")
|
||||||
local nala_state; nala_state=$(_state "nala")
|
local nala_state; nala_state=$(_state "nala")
|
||||||
local ncdu_state; ncdu_state=$(_state "ncdu")
|
local ncdu_state; ncdu_state=$(_state "ncdu")
|
||||||
local psensor_state; psensor_state=$(_state "psensor")
|
|
||||||
local timeshift_state; timeshift_state=$(_state "timeshift")
|
|
||||||
local tmux_state; tmux_state=$(_state "tmux")
|
local tmux_state; tmux_state=$(_state "tmux")
|
||||||
local wine_state; wine_state=$(_state "wine")
|
local wine_state; wine_state=$(_state "wine")
|
||||||
local nvme_state; nvme_state=$(_state "nvme-cli")
|
local nvme_state; nvme_state=$(_state "nvme-cli")
|
||||||
|
items+=(
|
||||||
|
"btop" "Resource monitor (fancy top)" "$btop_state"
|
||||||
|
"compress" "Compression tools (zip, unrar, 7z)" "$compress_state"
|
||||||
|
"cpufetch" "CPU info fetcher" "$cpufetch_state"
|
||||||
|
"cpu-x" "CPU-X (alternative to CPU-Z)" "$cpu_x_state"
|
||||||
|
"curl-wget" "HTTP transfer tools (curl, wget)" "$curl_wget_state"
|
||||||
|
"extrepo" "External repository manager" "$extrepo_state"
|
||||||
|
"flatpak" "Flatpak sandbox + Flathub" "$flatpak_state"
|
||||||
|
"fwupd" "Firmware update daemon" "$fwupd_state"
|
||||||
|
"htop" "Interactive process viewer" "$htop_state"
|
||||||
|
"inxi" "System information tool" "$inxi_state"
|
||||||
|
"kvm" "QEMU/KVM virtualization" "$kvm_state"
|
||||||
|
"lshw" "List hardware details" "$lshw_state"
|
||||||
|
"mc" "Midnight Commander (file manager)" "$mc_state"
|
||||||
|
"nala" "APT frontend (parallel downloads)" "$nala_state"
|
||||||
|
"ncdu" "Disk usage analyzer (ncurses)" "$ncdu_state"
|
||||||
|
"nvme-cli" "NVMe SSD health monitoring" "$nvme_state"
|
||||||
|
"tmux" "Terminal multiplexer" "$tmux_state"
|
||||||
|
"wine" "Windows compatibility layer" "$wine_state"
|
||||||
|
)
|
||||||
|
if ! $headless; then
|
||||||
|
local alacritty_state; alacritty_state=$(_state "alacritty")
|
||||||
|
local conky_state; conky_state=$(_state "conky")
|
||||||
|
local corectrl_state; corectrl_state=$(_state "corectrl")
|
||||||
|
local dcgtk_state; dcgtk_state=$(_state "doublecmd-gtk")
|
||||||
|
local dcqt_state; dcqt_state=$(_state "doublecmd-qt")
|
||||||
|
local disks_state; disks_state=$(_state "gnome-disk-utility")
|
||||||
|
local gparted_state; gparted_state=$(_state "gparted")
|
||||||
|
local hardinfo_state; hardinfo_state=$(_state "hardinfo")
|
||||||
|
local kitty_state; kitty_state=$(_state "kitty")
|
||||||
|
local psensor_state; psensor_state=$(_state "psensor")
|
||||||
|
local timeshift_state; timeshift_state=$(_state "timeshift")
|
||||||
|
items+=(
|
||||||
|
"alacritty" "GPU-accelerated terminal" "$alacritty_state"
|
||||||
|
"conky" "System monitor for desktop" "$conky_state"
|
||||||
|
"corectrl" "AMD GPU control (CoreCtrl)" "$corectrl_state"
|
||||||
|
"doublecmd-gtk" "Dual-panel file manager (GTK)" "$dcgtk_state"
|
||||||
|
"doublecmd-qt" "Dual-panel file manager (Qt)" "$dcqt_state"
|
||||||
|
"gnome-disk-utility" "Disk management GUI" "$disks_state"
|
||||||
|
"gparted" "GNOME partition editor" "$gparted_state"
|
||||||
|
"hardinfo" "Graphical system profiler" "$hardinfo_state"
|
||||||
|
"kitty" "GPU-based terminal emulator" "$kitty_state"
|
||||||
|
"psensor" "Hardware temperature monitor" "$psensor_state"
|
||||||
|
"timeshift" "System restore snapshots" "$timeshift_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "System Tools" --checklist \
|
choices=$(_checklist "System Tools" "Select system utilities to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select system utilities to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"alacritty" "GPU-accelerated terminal$(_inst alacritty)" "$alacritty_state" \
|
)
|
||||||
"btop" "Resource monitor (fancy top)$(_inst btop)" "$btop_state" \
|
|
||||||
"compress" "Compression tools (zip, unrar, 7z)$(_inst zip)" "$compress_state" \
|
|
||||||
"conky" "System monitor for desktop$(_inst conky)" "$conky_state" \
|
|
||||||
"corectrl" "AMD GPU control (CoreCtrl)$(_inst corectrl)" "$corectrl_state" \
|
|
||||||
"cpufetch" "CPU info fetcher$(_inst cpufetch)" "$cpufetch_state" \
|
|
||||||
"cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$cpu_x_state" \
|
|
||||||
"curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$curl_wget_state" \
|
|
||||||
"doublecmd-gtk" "Dual-panel file manager (GTK)$(_inst doublecmd-gtk)" "$dcgtk_state" \
|
|
||||||
"doublecmd-qt" "Dual-panel file manager (Qt)$(_inst doublecmd-qt)" "$dcqt_state" \
|
|
||||||
"extrepo" "External repository manager$(_inst extrepo)" "$extrepo_state" \
|
|
||||||
"flatpak" "Flatpak sandbox + Flathub$(_inst flatpak)" "$flatpak_state" \
|
|
||||||
"fwupd" "Firmware update daemon$(_inst fwupd)" "$fwupd_state" \
|
|
||||||
"gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$disks_state" \
|
|
||||||
"gparted" "GNOME partition editor$(_inst gparted)" "$gparted_state" \
|
|
||||||
"hardinfo" "Graphical system profiler$(_inst hardinfo)" "$hardinfo_state" \
|
|
||||||
"htop" "Interactive process viewer$(_inst htop)" "$htop_state" \
|
|
||||||
"inxi" "System information tool$(_inst inxi)" "$inxi_state" \
|
|
||||||
"kitty" "GPU-based terminal emulator$(_inst kitty)" "$kitty_state" \
|
|
||||||
"kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$kvm_state" \
|
|
||||||
"lshw" "List hardware details$(_inst lshw)" "$lshw_state" \
|
|
||||||
"mc" "Midnight Commander (file manager)$(_inst mc)" "$mc_state" \
|
|
||||||
"nvme-cli" "NVMe SSD health monitoring$(_inst nvme-cli)" "$nvme_state" \
|
|
||||||
"nala" "APT frontend (parallel downloads)$(_inst nala)" "$nala_state" \
|
|
||||||
"ncdu" "Disk usage analyzer (ncurses)$(_inst ncdu)" "$ncdu_state" \
|
|
||||||
"psensor" "Hardware temperature monitor$(_inst psensor)" "$psensor_state" \
|
|
||||||
"timeshift" "System restore snapshots$(_inst timeshift)" "$timeshift_state" \
|
|
||||||
"tmux" "Terminal multiplexer$(_inst tmux)" "$tmux_state" \
|
|
||||||
"wine" "Windows compatibility layer$(_inst wine)" "$wine_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
@@ -180,12 +188,15 @@ _cat_general() {
|
|||||||
_run_cmd "fwupd" "sudo fwupdmgr update -y" "Installing firmware updates..."
|
_run_cmd "fwupd" "sudo fwupdmgr update -y" "Installing firmware updates..."
|
||||||
else
|
else
|
||||||
echo "Skipping firmware update."
|
echo "Skipping firmware update."
|
||||||
|
_pause
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "No firmware updates available."
|
echo "No firmware updates available."
|
||||||
|
_pause
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo -e "${GREEN}fwupd setup complete.${NC}"
|
echo -e "${GREEN}fwupd setup complete.${NC}"
|
||||||
|
_pause
|
||||||
;;
|
;;
|
||||||
kvm)
|
kvm)
|
||||||
if ! is_installed "virt-manager"; then
|
if ! is_installed "virt-manager"; then
|
||||||
@@ -198,17 +209,17 @@ _cat_general() {
|
|||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
wine)
|
wine)
|
||||||
if ! is_installed "wine"; then
|
if ! is_installed "wine64"; then
|
||||||
echo "Checking for i386 architecture..."
|
_run_cmd "Wine" "sudo apt install -y --no-install-recommends wine64 fonts-wine" "Installing Wine (64-bit only)..."
|
||||||
if ! dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
|
local wine_ver
|
||||||
echo "Enabling i386 architecture for Wine..."
|
wine_ver=$(wine --version 2>/dev/null)
|
||||||
sudo dpkg --add-architecture i386
|
if [ -n "$wine_ver" ]; then
|
||||||
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
|
echo -e "${GREEN}Wine (64-bit) installed: ${wine_ver}${NC}"
|
||||||
fi
|
|
||||||
_run_cmd "Wine" "sudo apt install -y wine wine32 wine64 libwine libwine:i386 fonts-wine" "Installing Wine..."
|
|
||||||
echo -e "${GREEN}Wine installed. Run 'winecfg' to configure.${NC}"
|
|
||||||
else
|
else
|
||||||
echo "Wine already installed."
|
echo -e "${YELLOW}Wine installed but version check failed.${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Wine64 already installed."
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
nvme-cli)
|
nvme-cli)
|
||||||
@@ -250,15 +261,10 @@ _cat_general() {
|
|||||||
echo -e " ${GREEN}Percentage Used:${NC} ${pu:-N/A}"
|
echo -e " ${GREEN}Percentage Used:${NC} ${pu:-N/A}"
|
||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
echo "Press [ENTER] to continue..."
|
_pause
|
||||||
read -r
|
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
@@ -269,5 +275,6 @@ _cat_general() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo -e "${GREEN}System tools installed.${NC}"
|
echo -e "${GREEN}System tools installed.${NC}"
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,23 +2,32 @@
|
|||||||
# cursors.sh — Cursor themes
|
# cursors.sh — Cursor themes
|
||||||
|
|
||||||
_cat_cursors() {
|
_cat_cursors() {
|
||||||
|
local headless=false
|
||||||
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local bibata_state; bibata_state=$(_state "bibata-cursor-theme")
|
local bibata_state; bibata_state=$(_state "bibata-cursor-theme")
|
||||||
local breeze_state; breeze_state=$(_state "breeze-cursor-theme")
|
local breeze_state; breeze_state=$(_state "breeze-cursor-theme")
|
||||||
local chameleon_state; chameleon_state=$(_state "chameleon-cursor-theme")
|
local chameleon_state; chameleon_state=$(_state "chameleon-cursor-theme")
|
||||||
local dmz_state; dmz_state=$(_state "dmz-cursor-theme")
|
local dmz_state; dmz_state=$(_state "dmz-cursor-theme")
|
||||||
local xcursor_state; xcursor_state=$(_state "xcursor-themes")
|
local xcursor_state; xcursor_state=$(_state "xcursor-themes")
|
||||||
local oxygen_state; oxygen_state=$(_state "oxygencursors")
|
local oxygen_state; oxygen_state=$(_state "oxygencursors")
|
||||||
|
items+=(
|
||||||
|
"bibata-cursor-theme" "Bibata cursors" "$bibata_state"
|
||||||
|
"breeze-cursor-theme" "Breeze cursors (KDE)" "$breeze_state"
|
||||||
|
"chameleon-cursor-theme" "Chameleon cursors" "$chameleon_state"
|
||||||
|
"dmz-cursor-theme" "DMZ cursors" "$dmz_state"
|
||||||
|
"xcursor-themes" "X11 base cursors" "$xcursor_state"
|
||||||
|
"oxygencursors" "Oxygen cursors (KDE legacy)" "$oxygen_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Cursor Themes" --checklist \
|
choices=$(_checklist "Cursor Themes" "Select cursor themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select cursor themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"bibata-cursor-theme" "Bibata cursors$(_inst bibata-cursor-theme)" "$bibata_state" \
|
)
|
||||||
"breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$breeze_state" \
|
|
||||||
"chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$chameleon_state" \
|
|
||||||
"dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$dmz_state" \
|
|
||||||
"xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$xcursor_state" \
|
|
||||||
"oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$oxygen_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
_cat_themes() {
|
_cat_themes() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local arc_state; arc_state=$(_state "arc-theme")
|
local arc_state; arc_state=$(_state "arc-theme")
|
||||||
local blackbird_state; blackbird_state=$(_state "blackbird-gtk-theme")
|
local blackbird_state; blackbird_state=$(_state "blackbird-gtk-theme")
|
||||||
local bluebird_state; bluebird_state=$(_state "bluebird-gtk-theme")
|
local bluebird_state; bluebird_state=$(_state "bluebird-gtk-theme")
|
||||||
@@ -11,18 +13,23 @@ _cat_themes() {
|
|||||||
local greybird_state; greybird_state=$(_state "greybird-gtk-theme")
|
local greybird_state; greybird_state=$(_state "greybird-gtk-theme")
|
||||||
local numix_gtk_state; numix_gtk_state=$(_state "numix-gtk-theme")
|
local numix_gtk_state; numix_gtk_state=$(_state "numix-gtk-theme")
|
||||||
local orchis_state; orchis_state=$(_state "orchis-gtk-theme")
|
local orchis_state; orchis_state=$(_state "orchis-gtk-theme")
|
||||||
|
items+=(
|
||||||
|
"arc-theme" "Arc GTK theme" "$arc_state"
|
||||||
|
"blackbird-gtk-theme" "Blackbird GTK theme" "$blackbird_state"
|
||||||
|
"bluebird-gtk-theme" "Bluebird GTK theme" "$bluebird_state"
|
||||||
|
"breeze-gtk-theme" "Breeze GTK theme (KDE port)" "$breeze_gtk_state"
|
||||||
|
"greybird-gtk-theme" "Greybird GTK theme" "$greybird_state"
|
||||||
|
"numix-gtk-theme" "Numix GTK theme" "$numix_gtk_state"
|
||||||
|
"orchis-gtk-theme" "Orchis GTK theme" "$orchis_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Desktop Themes (GTK/KDE)" --checklist \
|
choices=$(_checklist "Desktop Themes (GTK/KDE)" "Select desktop themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select desktop themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"arc-theme" "Arc GTK theme$(_inst arc-theme)" "$arc_state" \
|
)
|
||||||
"blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$blackbird_state" \
|
|
||||||
"bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$bluebird_state" \
|
|
||||||
"breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$breeze_gtk_state" \
|
|
||||||
"greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$greybird_state" \
|
|
||||||
"numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_gtk_state" \
|
|
||||||
"orchis-gtk-theme" "Orchis GTK theme$(_inst orchis-gtk-theme)" "$orchis_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
@@ -30,10 +37,6 @@ _cat_themes() {
|
|||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
|
||||||
for pkg in $cleaned; do
|
for pkg in $cleaned; do
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
# fonts.sh — Fonts
|
# fonts.sh — Fonts
|
||||||
|
|
||||||
_cat_fonts() {
|
_cat_fonts() {
|
||||||
|
local headless=false
|
||||||
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local bebas_state; bebas_state=$(_state "fonts-bebas-neue")
|
local bebas_state; bebas_state=$(_state "fonts-bebas-neue")
|
||||||
local anon_state; anon_state=$(_state "fonts-anonymous-pro")
|
local anon_state; anon_state=$(_state "fonts-anonymous-pro")
|
||||||
local verana_state; verana_state=$(_state "fonts-adf-verana")
|
local verana_state; verana_state=$(_state "fonts-adf-verana")
|
||||||
@@ -10,19 +14,24 @@ _cat_fonts() {
|
|||||||
local mscore_state; mscore_state=$(_state "ttf-mscorefonts-installer")
|
local mscore_state; mscore_state=$(_state "ttf-mscorefonts-installer")
|
||||||
local ubuntu_state; ubuntu_state=$(_state "fonts-ubuntu")
|
local ubuntu_state; ubuntu_state=$(_state "fonts-ubuntu")
|
||||||
local recommended_state; recommended_state=$(_state "fonts-recommended")
|
local recommended_state; recommended_state=$(_state "fonts-recommended")
|
||||||
|
items+=(
|
||||||
|
"fonts-bebas-neue" "Bebas Neue (display)" "$bebas_state"
|
||||||
|
"fonts-anonymous-pro" "Anonymous Pro (monospace)" "$anon_state"
|
||||||
|
"fonts-adf-verana" "ADF Verana (sans-serif)" "$verana_state"
|
||||||
|
"fonts-3270" "IBM 3270 terminal font" "$f3270_state"
|
||||||
|
"fonts-liberation" "Liberation (MS-compatible)" "$liberation_state"
|
||||||
|
"ttf-mscorefonts-installer" "Microsoft fonts (EULA required)" "$mscore_state"
|
||||||
|
"fonts-ubuntu" "Ubuntu font family" "$ubuntu_state"
|
||||||
|
"fonts-recommended" "Debian recommended fonts" "$recommended_state"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Fonts" --checklist \
|
choices=$(_checklist "Fonts" "Select fonts to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select fonts to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"${items[@]}" \
|
||||||
"fonts-bebas-neue" "Bebas Neue (display)$(_inst fonts-bebas-neue)" "$bebas_state" \
|
)
|
||||||
"fonts-anonymous-pro" "Anonymous Pro (monospace)$(_inst fonts-anonymous-pro)" "$anon_state" \
|
|
||||||
"fonts-adf-verana" "ADF Verana (sans-serif)$(_inst fonts-adf-verana)" "$verana_state" \
|
|
||||||
"fonts-3270" "IBM 3270 terminal font$(_inst fonts-3270)" "$f3270_state" \
|
|
||||||
"fonts-liberation" "Liberation (MS-compatible)$(_inst fonts-liberation)" "$liberation_state" \
|
|
||||||
"ttf-mscorefonts-installer" "Microsoft fonts (EULA required)$(_inst ttf-mscorefonts-installer)" "$mscore_state" \
|
|
||||||
"fonts-ubuntu" "Ubuntu font family$(_inst fonts-ubuntu)" "$ubuntu_state" \
|
|
||||||
"fonts-recommended" "Debian recommended fonts$(_inst fonts-recommended)" "$recommended_state" \
|
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
_cat_icons() {
|
_cat_icons() {
|
||||||
local headless=false
|
local headless=false
|
||||||
_is_headless && headless=true
|
_is_headless && headless=true
|
||||||
|
local -a items=()
|
||||||
|
if ! $headless; then
|
||||||
local breeze_state; breeze_state=$(_state "breeze-icon-theme")
|
local breeze_state; breeze_state=$(_state "breeze-icon-theme")
|
||||||
local deepin_state; deepin_state=$(_state "deepin-icon-theme")
|
local deepin_state; deepin_state=$(_state "deepin-icon-theme")
|
||||||
local ele_state; ele_state=$(_state "elementary-icon-theme")
|
local ele_state; ele_state=$(_state "elementary-icon-theme")
|
||||||
@@ -17,34 +19,34 @@ _cat_icons() {
|
|||||||
local suru_state; suru_state=$(_state "suru-icon-theme")
|
local suru_state; suru_state=$(_state "suru-icon-theme")
|
||||||
|
|
||||||
local kf6_state="OFF"
|
local kf6_state="OFF"
|
||||||
local has_kf6=false
|
|
||||||
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
||||||
kf6_state=$(_state "kf6-breeze-icon-theme")
|
kf6_state=$(_state "kf6-breeze-icon-theme")
|
||||||
has_kf6=true
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local items=(
|
items=(
|
||||||
"breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$breeze_state"
|
"breeze-icon-theme" "Breeze icon theme" "$breeze_state"
|
||||||
"deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$deepin_state"
|
"deepin-icon-theme" "Deepin icon theme" "$deepin_state"
|
||||||
"elementary-icon-theme" "Elementary icon theme$(_inst elementary-icon-theme)" "$ele_state"
|
"elementary-icon-theme" "Elementary icon theme" "$ele_state"
|
||||||
"elementary-xfce-icon-theme" "Elementary Xfce icons$(_inst elementary-xfce-icon-theme)" "$ele_xfce_state"
|
"elementary-xfce-icon-theme" "Elementary Xfce icons" "$ele_xfce_state"
|
||||||
"moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$moka_state"
|
"moka-icon-theme" "Moka icon theme" "$moka_state"
|
||||||
"numix-icon-theme" "Numix icon theme$(_inst numix-icon-theme)" "$numix_state"
|
"numix-icon-theme" "Numix icon theme" "$numix_state"
|
||||||
"numix-icon-theme-circle" "Numix Circle icon theme$(_inst numix-icon-theme-circle)" "$numix_c_state"
|
"numix-icon-theme-circle" "Numix Circle icon theme" "$numix_c_state"
|
||||||
"obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$obsidian_state"
|
"obsidian-icon-theme" "Obsidian icon theme" "$obsidian_state"
|
||||||
"papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$papirus_state"
|
"papirus-icon-theme" "Papirus icon theme" "$papirus_state"
|
||||||
"paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$paper_state"
|
"paper-icon-theme" "Paper icon theme" "$paper_state"
|
||||||
"suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$suru_state"
|
"suru-icon-theme" "Suru icon theme" "$suru_state"
|
||||||
)
|
)
|
||||||
if $has_kf6; then
|
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
||||||
items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme$(_inst kf6-breeze-icon-theme)" "$kf6_state")
|
items+=("kf6-breeze-icon-theme" "KF6 Breeze icon theme" "$kf6_state")
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
local item_count=${#items[@]}
|
||||||
|
local lista_alto=$((item_count > TUI_ALTO_LISTA ? TUI_ALTO_LISTA : item_count))
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Icon Themes" --checklist \
|
choices=$(_checklist "Icon Themes" "Select icon themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $lista_alto \
|
||||||
"Select icon themes to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
|
||||||
"${items[@]}" \
|
"${items[@]}" \
|
||||||
3>&1 1>&2 2>&3)
|
)
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && return
|
[ -z "$choices" ] && return
|
||||||
@@ -52,10 +54,6 @@ _cat_icons() {
|
|||||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
|
||||||
for pkg in $cleaned; do
|
for pkg in $cleaned; do
|
||||||
if $headless; then
|
|
||||||
echo "Skipping $pkg (headless mode)"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! is_installed "$pkg"; then
|
if ! is_installed "$pkg"; then
|
||||||
_run_install "$pkg"
|
_run_install "$pkg"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,15 +2,13 @@
|
|||||||
# themes.sh — Customization submenu dispatcher
|
# themes.sh — Customization submenu dispatcher
|
||||||
|
|
||||||
_cat_customization() {
|
_cat_customization() {
|
||||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
|
||||||
local sub
|
local sub
|
||||||
sub=$(whiptail --title "Customization System" --menu \
|
sub=$(_menu "Customization System" "Select type:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
|
||||||
"1" "Desktop Themes (GTK/KDE)" \
|
"1" "Desktop Themes (GTK/KDE)" \
|
||||||
"2" "Icon Themes" \
|
"2" "Icon Themes" \
|
||||||
"3" "Cursor Themes" \
|
"3" "Cursor Themes" \
|
||||||
"4" "Fonts" \
|
"4" "Fonts" \
|
||||||
3>&1 1>&2 2>&3)
|
)
|
||||||
[ -z "$sub" ] && return
|
[ -z "$sub" ] && return
|
||||||
case $sub in
|
case $sub in
|
||||||
1) _cat_themes ;;
|
1) _cat_themes ;;
|
||||||
|
|||||||
+79
-7
@@ -130,7 +130,7 @@ _is_broadcom_b43() {
|
|||||||
local dec=$((16#$id))
|
local dec=$((16#$id))
|
||||||
if [ "$dec" -ge $((16#4301)) ] && [ "$dec" -le $((16#4331)) ]; then return 0; fi
|
if [ "$dec" -ge $((16#4301)) ] && [ "$dec" -le $((16#4331)) ]; then return 0; fi
|
||||||
if [ "$dec" -ge $((16#4336)) ] && [ "$dec" -le $((16#4338)) ]; then return 0; fi
|
if [ "$dec" -ge $((16#4336)) ] && [ "$dec" -le $((16#4338)) ]; then return 0; fi
|
||||||
case "$id" in 4352|4357|4358|4360|4727) return 0 ;; esac
|
case "$id" in 4352) return 0 ;; esac
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ _build_firmware_plan() {
|
|||||||
if is_installed bluez; then
|
if is_installed bluez; then
|
||||||
plan+=" [+] bluez (already installed)\n"
|
plan+=" [+] bluez (already installed)\n"
|
||||||
else
|
else
|
||||||
plan+=" [+] bluez + bluez-utils + bluez-obexd (base stack)\n"
|
plan+=" [+] bluez + bluez-tools + bluez-obexd (base stack)\n"
|
||||||
fi
|
fi
|
||||||
case "${DESKTOP_ENV:-other}" in
|
case "${DESKTOP_ENV:-other}" in
|
||||||
kde) plan+=" [+] bluedevil (KDE applet)\n"
|
kde) plan+=" [+] bluedevil (KDE applet)\n"
|
||||||
@@ -255,8 +255,22 @@ _handle_wireless() {
|
|||||||
fi
|
fi
|
||||||
installed_any=true
|
installed_any=true
|
||||||
elif _is_broadcom_b43 "$dev_id"; then
|
elif _is_broadcom_b43 "$dev_id"; then
|
||||||
|
if ! dpkg -l firmware-b43-installer >/dev/null 2>&1; then
|
||||||
_run_install_pkg firmware-b43-installer
|
_run_install_pkg firmware-b43-installer
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d /lib/firmware/b43 ] || [ -z "$(ls -A /lib/firmware/b43 2>/dev/null)" ]; then
|
||||||
|
_msg "b43 Firmware Warning" \
|
||||||
|
"The firmware-b43-installer package was installed, but the\n\
|
||||||
|
proprietary firmware download appears to have failed\n\
|
||||||
|
(no files found in /lib/firmware/b43).\n\n\
|
||||||
|
To fix this, connect a wired network and run:\n\
|
||||||
|
sudo dpkg-reconfigure firmware-b43-installer\n\n\
|
||||||
|
After the firmware is downloaded, reboot the system." 14 75
|
||||||
|
_pause
|
||||||
|
else
|
||||||
installed_any=true
|
installed_any=true
|
||||||
|
fi
|
||||||
elif _is_broadcom_b43legacy "$dev_id"; then
|
elif _is_broadcom_b43legacy "$dev_id"; then
|
||||||
_run_install_pkg firmware-b43legacy-installer
|
_run_install_pkg firmware-b43legacy-installer
|
||||||
installed_any=true
|
installed_any=true
|
||||||
@@ -264,10 +278,36 @@ _handle_wireless() {
|
|||||||
local bcm_ver header_ver
|
local bcm_ver header_ver
|
||||||
bcm_ver=$(apt-cache policy broadcom-sta-dkms 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
bcm_ver=$(apt-cache policy broadcom-sta-dkms 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
||||||
header_ver=$(apt-cache policy linux-headers-$(uname -r) 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
header_ver=$(apt-cache policy linux-headers-$(uname -r) 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
||||||
|
|
||||||
|
if ! apt-cache policy "linux-headers-$(uname -r)" 2>/dev/null | grep -q "Candidate: [^ (none)]"; then
|
||||||
|
_msg "Broadcom Error" \
|
||||||
|
"linux-headers-$(uname -r) not available.\n\nCannot compile broadcom-sta-dkms without kernel headers." 10 60
|
||||||
|
_pause
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
if _confirm "Broadcom WiFi" "Install Broadcom driver?\n\nRequired for this chipset. Compiles a kernel module.\n\n broadcom-sta-dkms ${bcm_ver:-unknown}\n linux-headers-$(uname -r) ${header_ver:-unknown}\n\nProceed?"; then
|
if _confirm "Broadcom WiFi" "Install Broadcom driver?\n\nRequired for this chipset. Compiles a kernel module.\n\n broadcom-sta-dkms ${bcm_ver:-unknown}\n linux-headers-$(uname -r) ${header_ver:-unknown}\n\nProceed?"; then
|
||||||
_run_cmd "Broadcom" "sudo DEBIAN_FRONTEND=noninteractive apt install -y linux-headers-$(uname -r) broadcom-sta-dkms" \
|
_run_cmd "Broadcom" "sudo DEBIAN_FRONTEND=noninteractive apt install -y linux-headers-$(uname -r) broadcom-sta-dkms" \
|
||||||
"Installing Broadcom driver..."
|
"Installing Broadcom driver..."
|
||||||
|
|
||||||
|
local has_broadcom_bt=false
|
||||||
|
for btdev in "${PCI_BT_DEVS[@]}"; do
|
||||||
|
if echo "$btdev" | grep -qi 'broadcom'; then
|
||||||
|
has_broadcom_bt=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if $has_broadcom_bt; then
|
||||||
|
echo -e "${YELLOW}Broadcom combo card (WiFi + Bluetooth) detected.${NC}"
|
||||||
|
cat > /etc/modprobe.d/broadcom-combo.conf <<'EOF'
|
||||||
|
# Broadcom combo: ensure btusb loads after wl
|
||||||
|
softdep wl post: btusb
|
||||||
|
EOF
|
||||||
|
echo -e "${YELLOW}A reboot may be required for Bluetooth to work correctly.${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Broadcom proprietary driver installed. A reboot may be required."
|
echo "Broadcom proprietary driver installed. A reboot may be required."
|
||||||
|
_pause
|
||||||
installed_any=true
|
installed_any=true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -281,17 +321,48 @@ _handle_wireless() {
|
|||||||
|
|
||||||
if ! $installed_any; then
|
if ! $installed_any; then
|
||||||
echo "No special WiFi firmware needed -- base firmware-linux-nonfree covers this system."
|
echo "No special WiFi firmware needed -- base firmware-linux-nonfree covers this system."
|
||||||
|
_pause
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ── Ensure non-free repository is enabled ──
|
||||||
|
_ensure_nonfree_repo() {
|
||||||
|
local nonfree_found=false
|
||||||
|
if [ -f /etc/apt/sources.list ] && grep -Eq '^[^#]*\bnon-free\b' /etc/apt/sources.list 2>/dev/null; then
|
||||||
|
nonfree_found=true
|
||||||
|
fi
|
||||||
|
if ! $nonfree_found && [ -d /etc/apt/sources.list.d ]; then
|
||||||
|
if grep -qr 'Components:.*\bnon-free\b' /etc/apt/sources.list.d/*.sources 2>/dev/null; then
|
||||||
|
nonfree_found=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if $nonfree_found; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _confirm "non-free Repository" "Component 'non-free' (and 'non-free-firmware') is required for WiFi/Bluetooth/GPU firmware.\n\nAdd them to your APT repositories?"; then
|
||||||
|
if [ -f /etc/apt/sources.list ]; then
|
||||||
|
sudo sed -i '/^deb / { /non-free/! s/\(main[^ ]*\)/\1 non-free non-free-firmware/ }' /etc/apt/sources.list
|
||||||
|
fi
|
||||||
|
if [ -d /etc/apt/sources.list.d ]; then
|
||||||
|
for f in /etc/apt/sources.list.d/*.sources; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
sudo sed -i '/^Components:/ { /non-free/! s/$/ non-free non-free-firmware/ }' "$f"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
sudo apt update
|
||||||
|
echo -e "${GREEN}non-free repository enabled.${NC}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# ── Main entry point ──
|
# ── Main entry point ──
|
||||||
install_firmware() {
|
install_firmware() {
|
||||||
echo -e "${YELLOW}Base firmware check...${NC}"
|
echo -e "${YELLOW}Base firmware check...${NC}"
|
||||||
|
|
||||||
if ! grep -qr "non-free" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null; then
|
if ! _ensure_nonfree_repo; then
|
||||||
_msg "Error" "Error: No 'non-free' repositories were detected.\n\
|
_msg "Error" "No 'non-free' repositories were enabled and the user declined to add them.\nPlease enable non-free manually or accept the prompt in the Firmware option." 10 65
|
||||||
Please first run the 'Configure repositories' option in the\n\
|
|
||||||
main menu to install proprietary firmwares." 10 65
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -302,7 +373,7 @@ main menu to install proprietary firmwares." 10 65
|
|||||||
# 2. Plan
|
# 2. Plan
|
||||||
local plan
|
local plan
|
||||||
plan=$(_build_firmware_plan)
|
plan=$(_build_firmware_plan)
|
||||||
_msg "Firmware & Wireless Setup" "$plan" 22 72
|
_msg "Firmware, Wireless & Bluetooth Setup" "$plan" 22 72
|
||||||
|
|
||||||
# 3. Confirm
|
# 3. Confirm
|
||||||
if ! _confirm "Firmware" "Apply the network & firmware plan?"; then
|
if ! _confirm "Firmware" "Apply the network & firmware plan?"; then
|
||||||
@@ -366,4 +437,5 @@ main menu to install proprietary firmwares." 10 65
|
|||||||
|
|
||||||
# 8. Summary
|
# 8. Summary
|
||||||
echo -e "${GREEN}Network & firmware setup complete.${NC}"
|
echo -e "${GREEN}Network & firmware setup complete.${NC}"
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-99
@@ -49,122 +49,61 @@ ensure_contrib_repo() {
|
|||||||
install_gaming() {
|
install_gaming() {
|
||||||
echo -e "${YELLOW}Gaming setup...${NC}"
|
echo -e "${YELLOW}Gaming setup...${NC}"
|
||||||
|
|
||||||
# 1. 32-bit support prompt FIRST
|
# 1. Single checklist with ALL options (including i386 toggle)
|
||||||
local enable_32bit=false
|
|
||||||
if _confirm "32-bit Support" "Enable i386 architecture for 32-bit games?\n\nRequired by Steam/Proton for 32-bit games.\nInstalls matching 32-bit graphics drivers."; then
|
|
||||||
enable_32bit=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $enable_32bit; then
|
|
||||||
echo "Enabling 32-bit architecture (i386)..."
|
|
||||||
if ! dpkg --print-foreign-architectures | grep -q i386; then
|
|
||||||
sudo dpkg --add-architecture i386
|
|
||||||
fi
|
|
||||||
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
|
|
||||||
|
|
||||||
echo "Installing 32-bit graphics drivers..."
|
|
||||||
if [ "$GPU_TYPE" = "nvidia" ]; then
|
|
||||||
case "${NVIDIA_DRIVER_MODE:-stable}" in
|
|
||||||
cuda-repo)
|
|
||||||
local nv32_pkg="nvidia-driver-libs:i386"
|
|
||||||
local nv32_ver
|
|
||||||
nv32_ver=$(dpkg -l "$nv32_pkg" 2>/dev/null | awk '/^ii/ {print $3}')
|
|
||||||
if [ -z "$nv32_ver" ] || ! echo "$nv32_ver" | grep -q "^590"; then
|
|
||||||
local msg="Source: NVIDIA CUDA Repository (Pinned v590)\n"
|
|
||||||
msg+="NVIDIA 32-bit Libraries (v590 branch)\n\n"
|
|
||||||
msg+="[+] nvidia-driver-libs:i386"
|
|
||||||
if _confirm "NVIDIA 32-bit" "$msg" 12 70; then
|
|
||||||
_run_cmd "32-bit NVIDIA" \
|
|
||||||
"sudo apt install -y ${nv32_pkg}" \
|
|
||||||
"Installing 32-bit NVIDIA libraries from CUDA repo..."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
_msg "NVIDIA 32-bit" \
|
|
||||||
"32-bit NVIDIA CUDA libraries already deployed.\n\nv590 ${nv32_ver}" 10 70
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
backports)
|
|
||||||
local nv32_pkg="nvidia-driver-libs:i386"
|
|
||||||
local nv32_ver
|
|
||||||
nv32_ver=$(apt-cache policy "$nv32_pkg" 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
|
||||||
local msg="Source: Debian ${DEBIAN_CODENAME^}-Backports\n"
|
|
||||||
msg+="NVIDIA 32-bit Libraries ${nv32_ver:-unknown}\n\n"
|
|
||||||
msg+="[+] nvidia-driver-libs:i386"
|
|
||||||
if _confirm "NVIDIA 32-bit" "$msg" 12 70; then
|
|
||||||
_run_cmd "32-bit NVIDIA" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports ${nv32_pkg}" \
|
|
||||||
"Installing 32-bit NVIDIA drivers from backports..."
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
stable)
|
|
||||||
local nv32_pkg="nvidia-driver-libs:i386"
|
|
||||||
local nv32_ver
|
|
||||||
nv32_ver=$(apt-cache policy "$nv32_pkg" 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
|
||||||
local use_bpo32=false
|
|
||||||
if [ "$(is_backports_enabled)" == "true" ]; then
|
|
||||||
local bpo_nv32_ver
|
|
||||||
bpo_nv32_ver=$(apt-cache madison "$nv32_pkg" 2>/dev/null | \
|
|
||||||
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1)
|
|
||||||
if [ -n "$bpo_nv32_ver" ]; then
|
|
||||||
local msg="Source: Debian ${DEBIAN_CODENAME^} (Backports available)\n"
|
|
||||||
msg+="NVIDIA 32-bit Libraries: ${nv32_pkg}\n\n"
|
|
||||||
msg+=" Backports: ${bpo_nv32_ver}\n"
|
|
||||||
msg+=" Stable: ${nv32_ver:-unknown}\n\n"
|
|
||||||
msg+="Choose version:"
|
|
||||||
if _confirm_custom "NVIDIA 32-bit" "$msg" "Backports" "Stable" 14 70; then
|
|
||||||
use_bpo32=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if $use_bpo32; then
|
|
||||||
_run_cmd "32-bit NVIDIA" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports ${nv32_pkg}" \
|
|
||||||
"Installing 32-bit NVIDIA drivers from backports..."
|
|
||||||
else
|
|
||||||
local msg="Source: Debian ${DEBIAN_CODENAME^} Stable\n"
|
|
||||||
msg+="NVIDIA 32-bit Libraries ${nv32_ver:-unknown}\n\n"
|
|
||||||
msg+="[+] nvidia-driver-libs:i386"
|
|
||||||
if _confirm "NVIDIA 32-bit" "$msg" 12 70; then
|
|
||||||
_run_cmd "32-bit NVIDIA" "sudo apt install -y ${nv32_pkg}" \
|
|
||||||
"Installing 32-bit NVIDIA drivers..."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
_install_mesa_32bit
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Gaming packages checklist
|
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "Gaming Setup" --checklist \
|
choices=$(_checklist "Gaming Setup" \
|
||||||
"Select gaming packages to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
"Select gaming packages to install${SCROLL_HINT}:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"steam" "Steam (requires 32-bit support)" ON \
|
"steam" "Steam (requires 32-bit support)" ON \
|
||||||
"gamemode" "Game performance optimization" ON \
|
"gamemode" "Game performance optimization" ON \
|
||||||
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
|
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
|
||||||
"heroic" "Heroic Launcher (Epic/GOG)" OFF \
|
|
||||||
"java" "Java Runtimes (8, 17, 21)" OFF \
|
|
||||||
"goverlay" "MangoHud config GUI" ON \
|
"goverlay" "MangoHud config GUI" ON \
|
||||||
"openrgb" "OpenRGB (RGB lighting control)$(_inst openrgb)" OFF \
|
"heroic" "Heroic Launcher (Epic/GOG)" OFF \
|
||||||
"lutris" "Game launcher/manager" OFF \
|
"java" "Minecraft Java Runtime" OFF \
|
||||||
"retroarch" "RetroArch Emulator Frontend$(_inst retroarch)" OFF \
|
"openrgb" "OpenRGB (RGB lighting control)" OFF \
|
||||||
3>&1 1>&2 2>&3)
|
"lutris" "Lutris + Wine (requires 32-bit support)" OFF \
|
||||||
|
"retroarch" "RetroArch Emulator Frontend" OFF \
|
||||||
|
"i386" "Enable 32-bit (i386) architecture" ON)
|
||||||
|
|
||||||
if [ -z "$choices" ]; then
|
if [ -z "$choices" ]; then
|
||||||
echo "No gaming packages selected."
|
echo "No gaming packages selected."
|
||||||
|
_pause
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local cleaned
|
local cleaned
|
||||||
cleaned=$(echo "$choices" | tr -d '"')
|
cleaned=$(echo "$choices" | tr -d '"')
|
||||||
|
|
||||||
# 3. Warn if Steam selected without 32-bit
|
# 2. Determine if 32-bit is needed (steam, lutris, or explicit i386 toggle)
|
||||||
if echo "$cleaned" | grep -qw "steam" && ! $enable_32bit; then
|
local need_32bit=false
|
||||||
echo -e "${YELLOW}Warning: Steam requires 32-bit support.${NC}"
|
for p in $cleaned; do
|
||||||
echo "Installation may fail. Re-run this option and enable 32-bit support."
|
case $p in steam|lutris) need_32bit=true ;; esac
|
||||||
|
done
|
||||||
|
echo "$cleaned" | grep -qw i386 && need_32bit=true
|
||||||
|
|
||||||
|
# Strip pseudo-entry "i386" from the install list
|
||||||
|
local install_list
|
||||||
|
install_list=$(echo "$cleaned" | tr ' ' '\n' | grep -v '^i386$' | tr '\n' ' ')
|
||||||
|
install_list=${install_list% }
|
||||||
|
|
||||||
|
# 3. Enable i386 architecture if needed
|
||||||
|
if $need_32bit && ! dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
|
||||||
|
echo -e "${YELLOW}Enabling i386 architecture (required by selection)...${NC}"
|
||||||
|
sudo dpkg --add-architecture i386
|
||||||
|
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 4. Install selected packages
|
# 4. Install 32-bit graphics drivers only if 32-bit is needed
|
||||||
for pkg in $cleaned; do
|
if $need_32bit; then
|
||||||
|
echo "Installing 32-bit graphics drivers..."
|
||||||
|
if [ "$GPU_TYPE" = "nvidia" ]; then
|
||||||
|
_install_nvidia_32bit
|
||||||
|
else
|
||||||
|
_install_mesa_32bit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Install selected packages
|
||||||
|
for pkg in $install_list; do
|
||||||
case $pkg in
|
case $pkg in
|
||||||
steam)
|
steam)
|
||||||
if ensure_contrib_repo; then
|
if ensure_contrib_repo; then
|
||||||
@@ -192,4 +131,5 @@ install_gaming() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo -e "${GREEN}Gaming setup complete.${NC}"
|
echo -e "${GREEN}Gaming setup complete.${NC}"
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|||||||
+64
-50
@@ -2,66 +2,80 @@
|
|||||||
# Shared helpers for gaming submodules
|
# Shared helpers for gaming submodules
|
||||||
|
|
||||||
_install_mesa_32bit() {
|
_install_mesa_32bit() {
|
||||||
local mesa_pkgs=(
|
local base_pkgs=(
|
||||||
"mesa-vulkan-drivers" "mesa-vulkan-drivers:i386"
|
"mesa-vulkan-drivers"
|
||||||
"libgl1-mesa-dri" "libgl1-mesa-dri:i386"
|
"libgl1-mesa-dri"
|
||||||
"libglx-mesa0" "libglx-mesa0:i386"
|
"libglx-mesa0"
|
||||||
"libegl-mesa0" "libegl-mesa0:i386"
|
"libegl-mesa0"
|
||||||
"mesa-va-drivers" "mesa-va-drivers:i386"
|
"mesa-va-drivers"
|
||||||
|
"mesa-libgallium"
|
||||||
)
|
)
|
||||||
|
|
||||||
local ref_ver
|
local i386_active=false
|
||||||
ref_ver=$(apt-cache policy mesa-vulkan-drivers:i386 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
dpkg --print-foreign-architectures 2>/dev/null | grep -q i386 && i386_active=true
|
||||||
local ref_bpo_ver
|
|
||||||
ref_bpo_ver=$(apt-cache madison mesa-vulkan-drivers:i386 2>/dev/null | \
|
|
||||||
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1)
|
|
||||||
local comp_line="Components: Vulkan:i386, OpenGL:i386, GLX:i386, EGL:i386, VA-API:i386"
|
|
||||||
|
|
||||||
if [ "$(is_backports_enabled)" == "true" ] && [ -n "$ref_bpo_ver" ]; then
|
local install_list=()
|
||||||
local bpo_pkgs=()
|
|
||||||
local stable_pkgs=()
|
|
||||||
|
|
||||||
for mpkg in "${mesa_pkgs[@]}"; do
|
for p in "${base_pkgs[@]}"; do
|
||||||
local bpo_ver
|
if apt-cache show "$p" >/dev/null 2>&1; then
|
||||||
bpo_ver=$(apt-cache madison "$mpkg" 2>/dev/null | \
|
install_list+=("$p")
|
||||||
grep "${DEBIAN_CODENAME}-backports" | awk '{print $3}' | head -1)
|
fi
|
||||||
if [ -n "$bpo_ver" ]; then
|
if $i386_active && apt-cache show "${p}:i386" >/dev/null 2>&1; then
|
||||||
bpo_pkgs+=("$mpkg")
|
install_list+=("${p}:i386")
|
||||||
else
|
|
||||||
stable_pkgs+=("$mpkg")
|
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
local src_label="Debian ${DEBIAN_CODENAME^}-Backports"
|
if [ ${#install_list[@]} -eq 0 ]; then
|
||||||
[ ${#stable_pkgs[@]} -gt 0 ] && src_label+=" + Stable"
|
echo "No Mesa 32-bit packages available for installation."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
local msg="Mesa 32-bit drivers required for gaming.\n\n"
|
_run_cmd "Mesa 32-bit" "sudo apt install -y ${install_list[*]}" \
|
||||||
msg+="Source: ${src_label}\n"
|
"Installing Mesa drivers (${#install_list[@]} packages)..."
|
||||||
msg+="Mesa ${ref_bpo_ver:-$ref_ver}\n"
|
echo -e "${GREEN}Mesa 32-bit libraries installed.${NC}"
|
||||||
msg+="${comp_line}\n\n"
|
}
|
||||||
[ ${#stable_pkgs[@]} -gt 0 ] && msg+="Some packages only available in stable.\n"
|
|
||||||
msg+="Choose version:"
|
|
||||||
|
|
||||||
if _confirm_custom "Mesa 32-bit" "$msg" "Backports" "Stable" 14 70; then
|
apt_cache_exists() {
|
||||||
_run_cmd "Mesa 32-bit" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports ${bpo_pkgs[*]}" \
|
apt-cache show "$1" >/dev/null 2>&1
|
||||||
"Installing 32-bit Mesa from backports..."
|
}
|
||||||
if [ ${#stable_pkgs[@]} -gt 0 ]; then
|
|
||||||
_run_cmd "Mesa 32-bit" "sudo apt install -y ${stable_pkgs[*]}" \
|
_detect_installed_nvidia_driver() {
|
||||||
"Installing remaining 32-bit Mesa from stable..."
|
dpkg -l 2>/dev/null | awk '
|
||||||
|
/^ii/ && ($2=="nvidia-driver" || $2=="nvidia-open" ||
|
||||||
|
$2 ~ /^nvidia-legacy-[0-9]+xx-driver$/ ||
|
||||||
|
$2 ~ /^nvidia-tesla-[0-9]+-driver$/) {print $2; exit}'
|
||||||
|
}
|
||||||
|
|
||||||
|
_nvidia_libs_pkg() {
|
||||||
|
case "$1" in
|
||||||
|
nvidia-driver|nvidia-open) echo "nvidia-driver-libs" ;;
|
||||||
|
*) echo "${1}-libs" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_install_nvidia_32bit() {
|
||||||
|
local drv_pkg
|
||||||
|
drv_pkg=$(_detect_installed_nvidia_driver)
|
||||||
|
if [ -z "$drv_pkg" ]; then
|
||||||
|
_msg "NVIDIA 32-bit" \
|
||||||
|
"No NVIDIA driver detected.\n\nRun Graphics Drivers (option 5) first,\nthen return to add 32-bit libraries." 10 60
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
else
|
|
||||||
_run_cmd "Mesa 32-bit" "sudo apt install -y ${mesa_pkgs[*]}" \
|
local drv_ver
|
||||||
"Installing 32-bit Mesa from stable..."
|
drv_ver=$(dpkg -s "$drv_pkg" 2>/dev/null | sed -n 's/^Version: //p')
|
||||||
fi
|
local libs_pkg
|
||||||
else
|
libs_pkg=$(_nvidia_libs_pkg "$drv_pkg")
|
||||||
local msg="Mesa 32-bit drivers required for gaming.\n\n"
|
|
||||||
msg+="Source: Debian Stable\n"
|
if ! apt_cache_exists "${libs_pkg}:i386"; then
|
||||||
msg+="Mesa ${ref_ver}\n"
|
_msg "NVIDIA 32-bit" \
|
||||||
msg+="${comp_line}\n\n"
|
"No ${libs_pkg}:i386 available for your driver (${drv_pkg}).\nSkipping 32-bit NVIDIA libraries." 10 60
|
||||||
msg+="Install Mesa 32-bit drivers?"
|
return 0
|
||||||
if _confirm "Mesa 32-bit" "$msg" 14 70; then
|
|
||||||
_run_cmd "Mesa 32-bit" "sudo apt install -y ${mesa_pkgs[*]}" \
|
|
||||||
"Installing 32-bit Mesa..."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if _confirm "NVIDIA 32-bit" \
|
||||||
|
"Driver: ${drv_pkg} ${drv_ver}\n\nInstall ${libs_pkg}:i386 (same version to prevent ABI mismatch)." 12 70; then
|
||||||
|
_run_cmd "NVIDIA 32-bit" "sudo apt install -y ${libs_pkg}:i386=${drv_ver}" \
|
||||||
|
"Installing 32-bit NVIDIA libraries (${drv_ver})..."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-11
@@ -3,17 +3,37 @@
|
|||||||
|
|
||||||
install_heroic() {
|
install_heroic() {
|
||||||
local heroic_deb="/tmp/heroic.deb"
|
local heroic_deb="/tmp/heroic.deb"
|
||||||
_run_cmd "Heroic" "sudo apt install -y curl wget" "Installing dependencies..."
|
local ua="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||||
local gh_url
|
|
||||||
gh_url=$(curl -s --connect-timeout 10 https://api.github.com/repos/Heroic-Games-Launcher/\
|
_run_cmd "Heroic" "sudo apt install -y curl jq" "Installing dependencies..."
|
||||||
HeroicGamesLauncher/releases/latest | \
|
|
||||||
grep -oP 'https://[^"]+amd64\.deb' | head -1)
|
local json
|
||||||
if [ -z "$gh_url" ]; then
|
json=$(curl -s --connect-timeout 10 -H "User-Agent: $ua" \
|
||||||
echo -e "${RED}Could not determine latest Heroic release.${NC}"
|
"https://api.github.com/repos/Heroic-Games-Launcher/HeroicGamesLauncher/releases/latest") || {
|
||||||
else
|
_msg "Heroic Error" "Could not fetch release data from GitHub API." 8 60
|
||||||
_run_cmd "Heroic" "wget -O $heroic_deb $gh_url" "Downloading Heroic..."
|
return 1
|
||||||
_run_cmd "Heroic" "sudo apt install -y $heroic_deb" "Installing Heroic..."
|
}
|
||||||
|
|
||||||
|
local deb_url
|
||||||
|
deb_url=$(echo "$json" | jq -r '
|
||||||
|
.assets[] | select(.name | endswith("amd64.deb")) | .browser_download_url
|
||||||
|
' 2>/dev/null || true)
|
||||||
|
|
||||||
|
if [ -z "$deb_url" ]; then
|
||||||
|
_msg "Heroic Error" "Could not find amd64.deb asset in latest release." 10 60
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_run_cmd "Heroic" "curl -sL -H 'User-Agent: $ua' -o '$heroic_deb' '$deb_url'" "Downloading Heroic..."
|
||||||
|
|
||||||
|
if ! dpkg-deb --info "$heroic_deb" >/dev/null 2>&1; then
|
||||||
|
_msg "Heroic Error" "Downloaded .deb is corrupted or truncated.\n\nRemoving file." 10 60
|
||||||
|
rm -f "$heroic_deb"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}Package integrity verified.${NC}"
|
||||||
|
_run_cmd "Heroic" "sudo apt install -y '$heroic_deb'" "Installing Heroic..."
|
||||||
rm -f "$heroic_deb"
|
rm -f "$heroic_deb"
|
||||||
echo -e "${GREEN}Heroic Games Launcher installed.${NC}"
|
echo -e "${GREEN}Heroic Games Launcher installed.${NC}"
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-22
@@ -2,11 +2,11 @@
|
|||||||
# Gaming performance tools installation
|
# Gaming performance tools installation
|
||||||
|
|
||||||
install_mangohud() {
|
install_mangohud() {
|
||||||
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Installing MangoHud..."
|
local pkgs="mangohud"
|
||||||
if dpkg --print-foreign-architectures | grep -q i386; then
|
if dpkg --print-foreign-architectures | grep -q i386; then
|
||||||
echo "Installing 32-bit MangoHud..."
|
pkgs+=" mangohud:i386"
|
||||||
_run_cmd "MangoHud" "sudo apt install -y mangohud:i386" "Installing 32-bit MangoHud..."
|
|
||||||
fi
|
fi
|
||||||
|
_run_cmd "MangoHud" "sudo apt install -y $pkgs" "Installing MangoHud (64 + 32-bit)..."
|
||||||
}
|
}
|
||||||
|
|
||||||
install_gamemode() {
|
install_gamemode() {
|
||||||
@@ -18,37 +18,70 @@ install_goverlay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_lutris() {
|
install_lutris() {
|
||||||
_run_install lutris
|
local pkgs="lutris wine64"
|
||||||
|
if dpkg --print-foreign-architectures 2>/dev/null | grep -q i386; then
|
||||||
|
pkgs+=" wine32"
|
||||||
|
fi
|
||||||
|
_run_cmd "Lutris" "sudo apt install -y $pkgs" "Installing Lutris + Wine..."
|
||||||
}
|
}
|
||||||
|
|
||||||
install_openrgb() {
|
install_openrgb() {
|
||||||
local url
|
local deb_suffix
|
||||||
if [ "$DEBIAN_VERSION" = "12" ]; then
|
case "$DEBIAN_CODENAME" in
|
||||||
url="https://codeberg.org/OpenRGB/OpenRGB/releases/download/release_candidate_1.0rc2/openrgb_1.0rc2_amd64_bookworm_0fca93e.deb"
|
bookworm) deb_suffix="bookworm" ;;
|
||||||
elif [ "$DEBIAN_VERSION" = "13" ]; then
|
trixie) deb_suffix="trixie" ;;
|
||||||
url="https://codeberg.org/OpenRGB/OpenRGB/releases/download/release_candidate_1.0rc2/openrgb_1.0rc2_amd64_trixie_0fca93e.deb"
|
*)
|
||||||
else
|
|
||||||
echo "OpenRGB requires Debian 12 (Bookworm) or 13 (Trixie)."
|
echo "OpenRGB requires Debian 12 (Bookworm) or 13 (Trixie)."
|
||||||
return 1
|
return 1
|
||||||
fi
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
local deb_path="/tmp/openrgb.deb"
|
local deb_path="/tmp/openrgb.deb"
|
||||||
local ua="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
local ua="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||||
|
|
||||||
_run_cmd "OpenRGB" "curl -L -o ${deb_path} -A '${ua}' '${url}'" "Downloading OpenRGB..."
|
_run_cmd "OpenRGB" "sudo apt install -y curl jq" "Installing dependencies..."
|
||||||
|
|
||||||
if [ ! -s "${deb_path}" ]; then
|
local json
|
||||||
echo -e "${RED}[-]${NC} Download failed: empty or missing file."
|
json=$(curl -s --connect-timeout 10 \
|
||||||
rm -f "${deb_path}"
|
"https://codeberg.org/api/v1/repos/OpenRGB/OpenRGB/releases?limit=1") || {
|
||||||
|
echo -e "${RED}Could not fetch OpenRGB releases from Codeberg API.${NC}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
local deb_url sha256
|
||||||
|
while IFS=' ' read -r url hash; do
|
||||||
|
deb_url="$url"
|
||||||
|
sha256="$hash"
|
||||||
|
done < <(echo "$json" | jq -r '
|
||||||
|
.[0].assets[] | select(.name | contains("amd64_'"${deb_suffix}"'.deb")) |
|
||||||
|
"\(.browser_download_url) \(.sha256 // "")"
|
||||||
|
' 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -z "$deb_url" ]; then
|
||||||
|
echo -e "${RED}Could not find OpenRGB .deb for ${DEBIAN_CODENAME^}.${NC}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${GREEN}[+]${NC} Installing OpenRGB package..."
|
_run_cmd "OpenRGB" "curl -L -o '${deb_path}' -A '${ua}' '${deb_url}'" "Downloading OpenRGB..."
|
||||||
if ! sudo apt install -y "${deb_path}"; then
|
|
||||||
rm -f "${deb_path}"
|
if [ -n "$sha256" ]; then
|
||||||
echo -e "${RED}[-]${NC} Package installation failed."
|
if ! echo "$sha256 $deb_path" | sha256sum -c --strict; then
|
||||||
|
echo -e "${RED}SHA256 mismatch! Downloaded file may be corrupted. Removing.${NC}"
|
||||||
|
rm -f "$deb_path"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
echo -e "${GREEN}SHA256 verified.${NC}"
|
||||||
|
else
|
||||||
|
if ! dpkg-deb --info "$deb_path" >/dev/null 2>&1; then
|
||||||
|
echo -e "${RED}Downloaded .deb is corrupted. Removing.${NC}"
|
||||||
|
rm -f "$deb_path"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo -e "${YELLOW}No SHA256 in API, validated via dpkg-deb.${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo apt install -y "$deb_path"
|
||||||
|
rm -f "$deb_path"
|
||||||
|
|
||||||
sudo modprobe i2c-dev
|
sudo modprobe i2c-dev
|
||||||
if ! grep -q "^i2c-dev" /etc/modules 2>/dev/null; then
|
if ! grep -q "^i2c-dev" /etc/modules 2>/dev/null; then
|
||||||
@@ -58,8 +91,8 @@ install_openrgb() {
|
|||||||
sudo udevadm control --reload-rules && sudo udevadm trigger
|
sudo udevadm control --reload-rules && sudo udevadm trigger
|
||||||
sudo setcap cap_sys_rawio=ep /usr/bin/openrgb 2>/dev/null || true
|
sudo setcap cap_sys_rawio=ep /usr/bin/openrgb 2>/dev/null || true
|
||||||
|
|
||||||
rm -f "${deb_path}"
|
echo -e "${GREEN}OpenRGB installed. Reboot or log out/in for i2c group to take effect.${NC}"
|
||||||
echo -e "${GREEN}OpenRGB installed. NOTE: You must reboot or log out/in for the 'i2c' group to take effect.${NC}"
|
_pause
|
||||||
}
|
}
|
||||||
|
|
||||||
install_retroarch() {
|
install_retroarch() {
|
||||||
@@ -86,5 +119,5 @@ install_retroarch() {
|
|||||||
echo " Please check our repository's documentation or visit:"
|
echo " Please check our repository's documentation or visit:"
|
||||||
echo " https://wiki.debian.org/RetroArch"
|
echo " https://wiki.debian.org/RetroArch"
|
||||||
echo "================================================================="
|
echo "================================================================="
|
||||||
read -p "Press ENTER to continue..."
|
_pause
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -105,13 +105,17 @@ install_gpu_drivers() {
|
|||||||
else
|
else
|
||||||
install_nvidia_driver
|
install_nvidia_driver
|
||||||
fi
|
fi
|
||||||
|
elif [ "$(is_nvidia_fermi)" = "true" ]; then
|
||||||
|
_msg "NVIDIA Fermi — Bookworm" \
|
||||||
|
"Fermi GPUs (GF1xx) are not supported\nin Debian 12 (Bookworm).\nThe nvidia-legacy-390xx driver is\nnot available in this version.\n\nNo NVIDIA driver will be installed."
|
||||||
|
NVIDIA_DRIVER_MODE=""
|
||||||
else
|
else
|
||||||
install_nvidia_driver
|
install_nvidia_driver
|
||||||
fi
|
fi
|
||||||
elif [ "$DEBIAN_VERSION" = "13" ]; then
|
elif [ "$DEBIAN_VERSION" = "13" ]; then
|
||||||
if [ "$(is_nvidia_kepler)" = "true" ]; then
|
if [ "$(is_nvidia_kepler)" = "true" ] || [ "$(is_nvidia_fermi)" = "true" ]; then
|
||||||
_msg "NVIDIA Kepler — Trixie" \
|
_msg "NVIDIA — Trixie" \
|
||||||
"Your GPU is NVIDIA Kepler architecture.\nThe nvidia-tesla-470 driver is not available\nin Debian 13 (Trixie).\n\nNo NVIDIA driver will be installed for this GPU.\nOther GPUs (Intel/AMD) will still be configured."
|
"Kepler and Fermi GPUs are not supported\nin Debian 13 (Trixie).\n\nThe nvidia-legacy drivers are not available\nin this version of Debian.\n\nNo NVIDIA driver will be installed."
|
||||||
NVIDIA_DRIVER_MODE=""
|
NVIDIA_DRIVER_MODE=""
|
||||||
else
|
else
|
||||||
install_nvidia_driver
|
install_nvidia_driver
|
||||||
|
|||||||
+54
-24
@@ -15,12 +15,45 @@ is_nvidia_kepler() {
|
|||||||
if [ "$dev_int" -ge $((16#1000)) ] && [ "$dev_int" -le $((16#103F)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1000)) ] && [ "$dev_int" -le $((16#103F)) ]; then echo true; return; fi
|
||||||
# Bloque 3: GK104/GK106 (completo) — 0x1180..0x11FF
|
# Bloque 3: GK104/GK106 (completo) — 0x1180..0x11FF
|
||||||
if [ "$dev_int" -ge $((16#1180)) ] && [ "$dev_int" -le $((16#11FF)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1180)) ] && [ "$dev_int" -le $((16#11FF)) ]; then echo true; return; fi
|
||||||
# Bloque 4: GK208/GK208B acotado — 0x1280..0x12BF
|
# Bloque 4: GK208/GK208B (completo) — 0x1280..0x12BF
|
||||||
if [ "$dev_int" -ge $((16#1280)) ] && [ "$dev_int" -le $((16#12BF)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1280)) ] && [ "$dev_int" -le $((16#12BF)) ]; then echo true; return; fi
|
||||||
|
|
||||||
echo false
|
echo false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_nvidia_fermi() {
|
||||||
|
local dev_id
|
||||||
|
dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | grep -oP '10de:\K[0-9a-fA-F]+' | head -n1)
|
||||||
|
[ -z "$dev_id" ] && { echo false; return; }
|
||||||
|
|
||||||
|
local dev_int
|
||||||
|
dev_int=$((16#${dev_id,,}))
|
||||||
|
|
||||||
|
# GF100 / GF110 — GTX 480, GTX 580, Quadro 6000, Tesla C2050
|
||||||
|
if [ "$dev_int" -ge $((16#06C0)) ] && [ "$dev_int" -le $((16#06DF)) ]; then echo true; return; fi
|
||||||
|
# GF104 / GF114 — GTS 450, GTX 460M, GT 555M
|
||||||
|
if [ "$dev_int" -ge $((16#0DC0)) ] && [ "$dev_int" -le $((16#0DCF)) ]; then echo true; return; fi
|
||||||
|
# GF104 / GF108 — GT 445M, GT 435M, GT 550M
|
||||||
|
if [ "$dev_int" -ge $((16#0DD0)) ] && [ "$dev_int" -le $((16#0DDF)) ]; then echo true; return; fi
|
||||||
|
# GF108 — GT 440, GT 430, GT 520, GT 610, GT 620M, NVS 5400M
|
||||||
|
if [ "$dev_int" -ge $((16#0DE0)) ] && [ "$dev_int" -le $((16#0DEF)) ]; then echo true; return; fi
|
||||||
|
# GF108 — GT 525M, GT 540M, GT 550M, Quadro 600, Quadro 500M
|
||||||
|
if [ "$dev_int" -ge $((16#0DF0)) ] && [ "$dev_int" -le $((16#0DFF)) ]; then echo true; return; fi
|
||||||
|
# GF104 / GF114 — GTX 460, GTX 470M, GTX 485M
|
||||||
|
if [ "$dev_int" -ge $((16#0E22)) ] && [ "$dev_int" -le $((16#0E31)) ]; then echo true; return; fi
|
||||||
|
# GF119 — GT 520M, GT 610M, NVS 4200M
|
||||||
|
if [ "$dev_int" -ge $((16#1050)) ] && [ "$dev_int" -le $((16#105F)) ]; then echo true; return; fi
|
||||||
|
# GF110 — GTX 580, GTX 570, GTX 560 Ti, GTX 590
|
||||||
|
if [ "$dev_int" -ge $((16#1080)) ] && [ "$dev_int" -le $((16#108F)) ]; then echo true; return; fi
|
||||||
|
# GF110 — Tesla M2090, Quadro 5010M, Quadro 7000
|
||||||
|
if [ "$dev_int" -ge $((16#1090)) ] && [ "$dev_int" -le $((16#109F)) ]; then echo true; return; fi
|
||||||
|
# GF116 / GF119 — GTX 560, GTX 460 v2, GTX 555, GT 645
|
||||||
|
if [ "$dev_int" -ge $((16#1200)) ] && [ "$dev_int" -le $((16#120F)) ]; then echo true; return; fi
|
||||||
|
# GF116 / GF108 — GTX 550 Ti, GTS 450 rev, GT 545, GT 640 (Fermi)
|
||||||
|
if [ "$dev_int" -ge $((16#1240)) ] && [ "$dev_int" -le $((16#124F)) ]; then echo true; return; fi
|
||||||
|
echo false
|
||||||
|
}
|
||||||
|
|
||||||
is_nvidia_maxwell() {
|
is_nvidia_maxwell() {
|
||||||
local dev_id
|
local dev_id
|
||||||
dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | grep -oP '10de:\K[0-9a-fA-F]+' | head -n1)
|
dev_id=$(lspci -nn | grep -iE "VGA|3D" | grep -i nvidia | grep -oP '10de:\K[0-9a-fA-F]+' | head -n1)
|
||||||
@@ -29,16 +62,14 @@ is_nvidia_maxwell() {
|
|||||||
local dev_int
|
local dev_int
|
||||||
dev_int=$((16#${dev_id,,}))
|
dev_int=$((16#${dev_id,,}))
|
||||||
|
|
||||||
# GM108 (GT 830M, GT 840M, GT 940M)
|
# GM108/GM107/GM204 — gama media/baja + Quadros M (incluye 980M/970M)
|
||||||
if [ "$dev_int" -ge $((16#1340)) ] && [ "$dev_int" -le $((16#134F)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1340)) ] && [ "$dev_int" -le $((16#13FF)) ]; then echo true; return; fi
|
||||||
# GM107 (GTX 750 Ti, GTX 860M)
|
# GM206 — GTX 960, GTX 950, Quadro M2000
|
||||||
if [ "$dev_int" -ge $((16#1380)) ] && [ "$dev_int" -le $((16#138F)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1400)) ] && [ "$dev_int" -le $((16#14FF)) ]; then echo true; return; fi
|
||||||
# GM200 (TITAN X, GTX 980 Ti)
|
# GM200 — TITAN X, GTX 980 Ti
|
||||||
if [ "$dev_int" -ge $((16#13C0)) ] && [ "$dev_int" -le $((16#13CF)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#17C0)) ] && [ "$dev_int" -le $((16#17CF)) ]; then echo true; return; fi
|
||||||
# GM204 (GTX 980, GTX 970)
|
# GM200 profesional — Quadro M6000, Tesla M40
|
||||||
if [ "$dev_int" -ge $((16#13D0)) ] && [ "$dev_int" -le $((16#13DF)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#17F0)) ] && [ "$dev_int" -le $((16#17FF)) ]; then echo true; return; fi
|
||||||
# GM206 (GTX 960, GTX 950)
|
|
||||||
if [ "$dev_int" -ge $((16#1480)) ] && [ "$dev_int" -le $((16#148F)) ]; then echo true; return; fi
|
|
||||||
|
|
||||||
echo false
|
echo false
|
||||||
}
|
}
|
||||||
@@ -51,18 +82,16 @@ is_nvidia_pascal() {
|
|||||||
local dev_int
|
local dev_int
|
||||||
dev_int=$((16#${dev_id,,}))
|
dev_int=$((16#${dev_id,,}))
|
||||||
|
|
||||||
# GP100 (Tesla P100, Quadro GP100)
|
# GP100 — Tesla P100, Quadro GP100
|
||||||
if [ "$dev_int" -ge $((16#15F0)) ] && [ "$dev_int" -le $((16#15FF)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#15F0)) ] && [ "$dev_int" -le $((16#15FF)) ]; then echo true; return; fi
|
||||||
# GP104 (GTX 1080, GTX 1070)
|
# GP102 — TITAN Xp, GTX 1080 Ti, Tesla P40, Quadro P6000
|
||||||
if [ "$dev_int" -ge $((16#1B00)) ] && [ "$dev_int" -le $((16#1B1F)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1B00)) ] && [ "$dev_int" -le $((16#1B3F)) ]; then echo true; return; fi
|
||||||
# GP102 (TITAN Xp, GTX 1080 Ti)
|
# GP104 — GTX 1080, GTX 1070, Quadro P5000/P4000/P5200/P4200
|
||||||
if [ "$dev_int" -ge $((16#1B80)) ] && [ "$dev_int" -le $((16#1B8F)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1B80)) ] && [ "$dev_int" -le $((16#1BBF)) ]; then echo true; return; fi
|
||||||
# GP106 (GTX 1060)
|
# GP106 + GP107 — GTX 1060, GTX 1050 Ti, GTX 1050, Quadro P2000/P1000/P620/P600
|
||||||
if [ "$dev_int" -ge $((16#1C00)) ] && [ "$dev_int" -le $((16#1C2F)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1C00)) ] && [ "$dev_int" -le $((16#1CFF)) ]; then echo true; return; fi
|
||||||
# GP107 (GTX 1050 Ti, GTX 1050)
|
# GP108 — GT 1030, GT 1010, MX150/250/350/330, Quadro P520
|
||||||
if [ "$dev_int" -ge $((16#1C80)) ] && [ "$dev_int" -le $((16#1C8F)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#1D00)) ] && [ "$dev_int" -le $((16#1D7F)) ]; then echo true; return; fi
|
||||||
# GP108 (GT 1030, GT 1010)
|
|
||||||
if [ "$dev_int" -ge $((16#1D00)) ] && [ "$dev_int" -le $((16#1DFF)) ]; then echo true; return; fi
|
|
||||||
|
|
||||||
echo false
|
echo false
|
||||||
}
|
}
|
||||||
@@ -77,8 +106,8 @@ is_nvidia_blackwell() {
|
|||||||
|
|
||||||
# Blackwell (GB20x) rango bajo: 0x2900 – 0x29BF
|
# Blackwell (GB20x) rango bajo: 0x2900 – 0x29BF
|
||||||
if [ "$dev_int" -ge $((16#2900)) ] && [ "$dev_int" -le $((16#29BF)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#2900)) ] && [ "$dev_int" -le $((16#29BF)) ]; then echo true; return; fi
|
||||||
# Blackwell (GB20x) rango alto: 0x2B80 – 0x31FF
|
# Blackwell (GB20x) rango alto: 0x2B80 – 0x31DF
|
||||||
if [ "$dev_int" -ge $((16#2B80)) ] && [ "$dev_int" -le $((16#31FF)) ]; then echo true; return; fi
|
if [ "$dev_int" -ge $((16#2B80)) ] && [ "$dev_int" -le $((16#31DF)) ]; then echo true; return; fi
|
||||||
|
|
||||||
echo false
|
echo false
|
||||||
}
|
}
|
||||||
@@ -161,6 +190,7 @@ offer_generic_tools() {
|
|||||||
if _confirm "GPU Tools" "Install monitoring and info tools?\n\n${tool_pkgs}"; then
|
if _confirm "GPU Tools" "Install monitoring and info tools?\n\n${tool_pkgs}"; then
|
||||||
_run_cmd "GPU Tools" "sudo apt install -y nvtop vainfo" "Installing GPU tools..."
|
_run_cmd "GPU Tools" "sudo apt install -y nvtop vainfo" "Installing GPU tools..."
|
||||||
vainfo
|
vainfo
|
||||||
|
_pause "vainfo output shown above."
|
||||||
else
|
else
|
||||||
echo "Skipping GPU monitoring tools."
|
echo "Skipping GPU monitoring tools."
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ offer_amd_tools() {
|
|||||||
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} nvtop vainfo" "Installing AMD tools..."
|
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} nvtop vainfo" "Installing AMD tools..."
|
||||||
fi
|
fi
|
||||||
vainfo
|
vainfo
|
||||||
|
_pause "vainfo output shown above."
|
||||||
|
|
||||||
if $corectrl_available; then
|
if $corectrl_available; then
|
||||||
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
||||||
@@ -108,6 +109,7 @@ offer_intel_tools() {
|
|||||||
if _confirm "Intel Tools" "Intel GPU monitoring tools\n\n${driver_info}\n\nPackages:\n${pkg_info}"; then
|
if _confirm "Intel Tools" "Intel GPU monitoring tools\n\n${driver_info}\n\nPackages:\n${pkg_info}"; then
|
||||||
_run_cmd "Intel Tools" "sudo apt install -y ${pkg_list[*]} vainfo" "Installing Intel monitoring tools..."
|
_run_cmd "Intel Tools" "sudo apt install -y ${pkg_list[*]} vainfo" "Installing Intel monitoring tools..."
|
||||||
vainfo
|
vainfo
|
||||||
|
_pause "vainfo output shown above."
|
||||||
else
|
else
|
||||||
echo "Skipping Intel monitoring tools."
|
echo "Skipping Intel monitoring tools."
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -27,4 +27,5 @@ install_kernel_backports() {
|
|||||||
|
|
||||||
_run_cmd "Kernel" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports linux-image-amd64" "Installing kernel from backports..."
|
_run_cmd "Kernel" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports linux-image-amd64" "Installing kernel from backports..."
|
||||||
echo -e "${GREEN}Kernel installed. Reboot to use it.${NC}"
|
echo -e "${GREEN}Kernel installed. Reboot to use it.${NC}"
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|||||||
+204
-117
@@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
source "${MODULES_DIR}/repos/migrate.sh" 2>/dev/null || true
|
||||||
|
|
||||||
# State for backup/restore
|
# State for backup/restore
|
||||||
REPO_BACKUP_DIR=""
|
REPO_BACKUP_DIR=""
|
||||||
|
|
||||||
@@ -84,18 +86,19 @@ _clean_embedded_backports_deb822() {
|
|||||||
|
|
||||||
_write_deb822() {
|
_write_deb822() {
|
||||||
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
|
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
|
||||||
|
local components="${5:-main contrib non-free non-free-firmware}"
|
||||||
|
|
||||||
local main_file="/etc/apt/sources.list.d/debian.sources"
|
local main_file="/etc/apt/sources.list.d/debian.sources"
|
||||||
local main_content=""
|
local main_content=""
|
||||||
main_content+="Types: deb\n"
|
main_content+="Types: deb\n"
|
||||||
main_content+="URIs: https://deb.debian.org/debian\n"
|
main_content+="URIs: https://deb.debian.org/debian\n"
|
||||||
main_content+="Suites: ${codename} ${codename}-updates\n"
|
main_content+="Suites: ${codename} ${codename}-updates\n"
|
||||||
main_content+="Components: main contrib non-free non-free-firmware\n"
|
main_content+="Components: ${components}\n"
|
||||||
main_content+="\n"
|
main_content+="\n"
|
||||||
main_content+="Types: deb\n"
|
main_content+="Types: deb\n"
|
||||||
main_content+="URIs: https://security.debian.org/debian-security\n"
|
main_content+="URIs: https://security.debian.org/debian-security\n"
|
||||||
main_content+="Suites: ${codename}-security\n"
|
main_content+="Suites: ${codename}-security\n"
|
||||||
main_content+="Components: main contrib non-free non-free-firmware\n"
|
main_content+="Components: ${components}\n"
|
||||||
|
|
||||||
if content_differs "$main_file" "$main_content"; then
|
if content_differs "$main_file" "$main_content"; then
|
||||||
if _confirm "Deb822 Sources" "Write main deb822 configuration to ${main_file}?"; then
|
if _confirm "Deb822 Sources" "Write main deb822 configuration to ${main_file}?"; then
|
||||||
@@ -174,20 +177,21 @@ _remove_deb822_backports() {
|
|||||||
|
|
||||||
_write_classic() {
|
_write_classic() {
|
||||||
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
|
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
|
||||||
|
local components="${5:-main contrib non-free non-free-firmware}"
|
||||||
|
|
||||||
local main_file="/etc/apt/sources.list"
|
local main_file="/etc/apt/sources.list"
|
||||||
local main_content=""
|
local main_content=""
|
||||||
main_content+="# Official repository\n"
|
main_content+="# Official repository\n"
|
||||||
main_content+="deb https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n"
|
main_content+="deb https://deb.debian.org/debian ${codename} ${components}\n"
|
||||||
main_content+="# deb-src https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n"
|
main_content+="# deb-src https://deb.debian.org/debian ${codename} ${components}\n"
|
||||||
main_content+="\n"
|
main_content+="\n"
|
||||||
main_content+="# Updates\n"
|
main_content+="# Updates\n"
|
||||||
main_content+="deb https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n"
|
main_content+="deb https://deb.debian.org/debian ${codename}-updates ${components}\n"
|
||||||
main_content+="# deb-src https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n"
|
main_content+="# deb-src https://deb.debian.org/debian ${codename}-updates ${components}\n"
|
||||||
main_content+="\n"
|
main_content+="\n"
|
||||||
main_content+="# Security\n"
|
main_content+="# Security\n"
|
||||||
main_content+="deb https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n"
|
main_content+="deb https://security.debian.org/debian-security ${codename}-security ${components}\n"
|
||||||
main_content+="# deb-src https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n"
|
main_content+="# deb-src https://security.debian.org/debian-security ${codename}-security ${components}\n"
|
||||||
|
|
||||||
if content_differs "$main_file" "$main_content"; then
|
if content_differs "$main_file" "$main_content"; then
|
||||||
if _confirm "Classic Sources" "Write main classic configuration to ${main_file}?"; then
|
if _confirm "Classic Sources" "Write main classic configuration to ${main_file}?"; then
|
||||||
@@ -273,125 +277,66 @@ configure_repos() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Informational banner ──
|
# ── Repositories submenu ──
|
||||||
_msg "Repositories" \
|
while true; do
|
||||||
"This section will automatically enable the 'contrib' and \n\
|
local repo_choice
|
||||||
'non-free' branches in your official Debian repositories. \n\
|
|
||||||
(The 'non-free-firmware' branch is already enabled by default in Debian 12 and 13.)\n\n\
|
|
||||||
This is CRUCIAL for obtaining proprietary software packages and\n\
|
|
||||||
essential hardware drivers, including graphics drivers,\n\
|
|
||||||
Wi-Fi firmware, and CPU microcode." 14 70
|
|
||||||
|
|
||||||
# Detect current state
|
if [ "$DEBIAN_CODENAME" = "sid" ]; then
|
||||||
local current_format
|
repo_choice=$(_menu "Configure Repositories" \
|
||||||
current_format=$(detect_repo_format)
|
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
||||||
local bp_status
|
"1" "Enable Contrib & Non-Free Components" \
|
||||||
if detect_backports_status "$DEBIAN_CODENAME"; then
|
"2" "Migrate traditional sources.list to DEB822 format" \
|
||||||
bp_status="enabled"
|
"3" "Back to main menu")
|
||||||
else
|
else
|
||||||
bp_status="disabled"
|
repo_choice=$(_menu "Configure Repositories" \
|
||||||
fi
|
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
||||||
local bp_location
|
"1" "Enable Contrib & Non-Free Components" \
|
||||||
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
|
"2" "Migrate traditional sources.list to DEB822 format" \
|
||||||
|
"3" "Setup/Update Backports repositories" \
|
||||||
echo "Current format: ${current_format:-none}"
|
"4" "[ADVANCED] Upgrade system branch (Testing / SID)" \
|
||||||
echo "Backports: $bp_status (location: $bp_location)"
|
"5" "Back to main menu")
|
||||||
|
|
||||||
# ── Format selection dialog (only Trixie gets the choice) ──
|
|
||||||
local use_deb822=false
|
|
||||||
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
|
||||||
if whiptail --title "Repository Format" --defaultno --yesno \
|
|
||||||
"Do you want to migrate your repositories to the new
|
|
||||||
DEB822 (.sources) format?
|
|
||||||
|
|
||||||
DEB822 is the modern, structured Debian standard. It won't
|
|
||||||
harm your system, and the script will handle the transition
|
|
||||||
safely if you accept.
|
|
||||||
|
|
||||||
NOTE: 'NO' (default) is recommended to maintain the classic
|
|
||||||
linear format as it comes pre-configured in Debian 13 (Trixie)." 16 70; then
|
|
||||||
use_deb822=true
|
|
||||||
fi
|
|
||||||
elif [ "$current_format" = "deb822" ]; then
|
|
||||||
use_deb822=true
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Choose backports
|
[ -z "$repo_choice" ] && break
|
||||||
local enable_backports=false
|
clear
|
||||||
if _confirm "Backports" "Do you want to enable the official Debian Backports repository?\n\n\
|
|
||||||
Backports provides newer, selectively updated packages from the\n\
|
|
||||||
next Debian testing branch, recompiled to run stably on your\n\
|
|
||||||
current system.\n\n\
|
|
||||||
This is HIGHLY RECOMMENDED if you have modern hardware, as it\n\
|
|
||||||
delivers newer Linux Kernels, updated display drivers, and modern\n\
|
|
||||||
Mesa versions without compromising overall system stability." 16 70; then
|
|
||||||
enable_backports=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Determine what to do
|
case "$repo_choice" in
|
||||||
local target_format
|
1) _repos_enable_components ;;
|
||||||
$use_deb822 && target_format="deb822" || target_format="classic"
|
2) _repos_migrate_format ;;
|
||||||
|
3)
|
||||||
if [ "$current_format" = "none" ]; then
|
if [ "$DEBIAN_CODENAME" = "sid" ]; then
|
||||||
local action="write"
|
break
|
||||||
elif [ "$target_format" != "$current_format" ]; then
|
|
||||||
local action="migrate"
|
|
||||||
else
|
else
|
||||||
local action="update"
|
_repos_setup_backports
|
||||||
fi
|
fi
|
||||||
|
;;
|
||||||
|
4) _branch_migration || true ;;
|
||||||
|
5) break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# If nothing changed (same format + same backports state), skip
|
# ---------------------------------------------------------------------------
|
||||||
if [ "$action" = "update" ] && [ "$enable_backports" = "$bp_status" ]; then
|
# Submenu helpers
|
||||||
# Check if backports location is correct (standalone)
|
# ---------------------------------------------------------------------------
|
||||||
if $enable_backports; then
|
|
||||||
local correct_location="standalone-deb822"
|
|
||||||
$use_deb822 || correct_location="standalone-classic"
|
|
||||||
if [ "$bp_location" = "$correct_location" ]; then
|
|
||||||
# Also verify no embedded backports linger
|
|
||||||
if [ "$target_format" = "deb822" ]; then
|
|
||||||
! grep -qE "^Suites:.*${DEBIAN_CODENAME}-backports\b" /etc/apt/sources.list.d/debian.sources 2>/dev/null || { action="update"; true; }
|
|
||||||
else
|
|
||||||
! grep -qE "^[^#]*${DEBIAN_CODENAME}-backports\b" /etc/apt/sources.list 2>/dev/null || { action="update"; true; }
|
|
||||||
fi
|
|
||||||
if [ "$action" = "update" ]; then
|
|
||||||
echo "Repository configuration is already up-to-date. Skipping."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Backports disabled: verify no backports files exist
|
|
||||||
if [ ! -f /etc/apt/sources.list.d/debian-backports.sources ] && \
|
|
||||||
[ ! -f /etc/apt/sources.list.d/debian-backports.list ]; then
|
|
||||||
echo "Repository configuration is already up-to-date. Skipping."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
backup_current_repos
|
_components_enabled() {
|
||||||
|
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
|
||||||
if $use_deb822; then
|
for c in $(grep "^Components:" /etc/apt/sources.list.d/debian.sources 2>/dev/null | cut -d: -f2-); do
|
||||||
_write_deb822 "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
|
[ "$c" = "contrib" ] || [ "$c" = "non-free" ] && return 0
|
||||||
else
|
done
|
||||||
_write_classic "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
|
|
||||||
fi
|
fi
|
||||||
|
if [ -f /etc/apt/sources.list ]; then
|
||||||
echo "Updating package lists..."
|
local components
|
||||||
sudo apt update
|
components=$(grep "^[^#]*deb .* main" /etc/apt/sources.list 2>/dev/null | head -1 | sed 's/.*main\s*//')
|
||||||
local apt_rc=$?
|
for c in $components; do
|
||||||
if [ $apt_rc -eq 0 ]; then
|
[ "$c" = "contrib" ] || [ "$c" = "non-free" ] && return 0
|
||||||
REPOS_CONFIGURED=true
|
done
|
||||||
echo -e "${GREEN}Repositories configured and updated successfully.${NC}"
|
|
||||||
|
|
||||||
if $use_deb822; then
|
|
||||||
# Remove any leftover disabled files from old classic format
|
|
||||||
[ -f /etc/apt/sources.list.disabled ] && sudo rm -f /etc/apt/sources.list.disabled
|
|
||||||
else
|
|
||||||
[ -f /etc/apt/sources.list.d/debian.sources.disabled ] && sudo rm -f /etc/apt/sources.list.d/debian.sources.disabled
|
|
||||||
fi
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
cleanup_repo_backup
|
_repos_offer_upgrade() {
|
||||||
|
|
||||||
local upgradable
|
local upgradable
|
||||||
upgradable=$(apt list --upgradable 2>/dev/null | grep -c /)
|
upgradable=$(apt list --upgradable 2>/dev/null | grep -c /)
|
||||||
if [ "$upgradable" -gt 0 ]; then
|
if [ "$upgradable" -gt 0 ]; then
|
||||||
@@ -406,9 +351,151 @@ Mesa versions without compromising overall system stability." 16 70; then
|
|||||||
echo "Skipping upgrade."
|
echo "Skipping upgrade."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_repos_enable_components() {
|
||||||
|
local current_format bp_enabled bp_location components
|
||||||
|
current_format=$(detect_repo_format)
|
||||||
|
|
||||||
|
if _components_enabled; then
|
||||||
|
if ! _confirm "Disable Components" \
|
||||||
|
"Contrib and non-free are already enabled. Disable them?"; then
|
||||||
|
echo "No changes made."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
components="main"
|
||||||
|
else
|
||||||
|
if ! _confirm "Enable Components" \
|
||||||
|
"Enable contrib and non-free components?\n\n\
|
||||||
|
Needed for proprietary drivers, firmware, and other
|
||||||
|
popular software (like gaming platforms and proprietary tools)." 12 60; then
|
||||||
|
echo "No changes made."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
components="main contrib non-free non-free-firmware"
|
||||||
|
fi
|
||||||
|
|
||||||
|
bp_enabled=false
|
||||||
|
bp_location="none"
|
||||||
|
if detect_backports_status "$DEBIAN_CODENAME"; then
|
||||||
|
bp_enabled=true
|
||||||
|
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
|
||||||
|
fi
|
||||||
|
|
||||||
|
backup_current_repos
|
||||||
|
|
||||||
|
if [ "$current_format" = "deb822" ] || [ "$current_format" = "none" ]; then
|
||||||
|
_write_deb822 "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components"
|
||||||
|
else
|
||||||
|
_write_classic "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Updating package lists..."
|
||||||
|
if sudo apt update; then
|
||||||
|
REPOS_CONFIGURED=true
|
||||||
|
cleanup_repo_backup
|
||||||
|
echo -e "${GREEN}Repository components configured.${NC}"
|
||||||
|
_repos_offer_upgrade
|
||||||
else
|
else
|
||||||
restore_previous_repos
|
restore_previous_repos
|
||||||
echo -e "${RED}apt update failed. Previous repository configuration restored.${NC}"
|
echo -e "${RED}apt update failed. Previous configuration restored.${NC}"
|
||||||
return 1
|
|
||||||
fi
|
fi
|
||||||
|
_pause
|
||||||
|
}
|
||||||
|
|
||||||
|
_repos_migrate_format() {
|
||||||
|
local current_format bp_enabled bp_location
|
||||||
|
current_format=$(detect_repo_format)
|
||||||
|
|
||||||
|
if [ "$current_format" != "classic" ]; then
|
||||||
|
echo "Repositories are already in DEB822 format."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DEBIAN_CODENAME" != "trixie" ]; then
|
||||||
|
echo "Format migration is only relevant for Debian 13 (Trixie)."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Preserve existing backports state across format migration
|
||||||
|
bp_enabled=false
|
||||||
|
bp_location="none"
|
||||||
|
if detect_backports_status "$DEBIAN_CODENAME"; then
|
||||||
|
bp_enabled=true
|
||||||
|
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
|
||||||
|
fi
|
||||||
|
|
||||||
|
backup_current_repos
|
||||||
|
_write_deb822 "$DEBIAN_CODENAME" "migrate" "$bp_enabled" "$bp_location"
|
||||||
|
|
||||||
|
echo "Updating package lists..."
|
||||||
|
if sudo apt update; then
|
||||||
|
REPOS_CONFIGURED=true
|
||||||
|
cleanup_repo_backup
|
||||||
|
echo -e "${GREEN}Repository format migrated to DEB822.${NC}"
|
||||||
|
else
|
||||||
|
restore_previous_repos
|
||||||
|
echo -e "${RED}apt update failed. Backup restored.${NC}"
|
||||||
|
fi
|
||||||
|
_pause
|
||||||
|
}
|
||||||
|
|
||||||
|
_repos_setup_backports() {
|
||||||
|
local current_format bp_status bp_location
|
||||||
|
current_format=$(detect_repo_format)
|
||||||
|
|
||||||
|
if detect_backports_status "$DEBIAN_CODENAME"; then
|
||||||
|
bp_status="enabled"
|
||||||
|
else
|
||||||
|
bp_status="disabled"
|
||||||
|
fi
|
||||||
|
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
|
||||||
|
|
||||||
|
echo "Backports are currently $bp_status."
|
||||||
|
|
||||||
|
local enable_backports=false
|
||||||
|
if _confirm "Backports" "Do you want to enable the official Debian Backports repository?\n\n\
|
||||||
|
Backports provides newer, selectively updated packages from the next\n\
|
||||||
|
Debian testing branch, recompiled to run stably on your current system.\n\n\
|
||||||
|
Answer NO to disable or remove backports if they are currently enabled." 16 70; then
|
||||||
|
enable_backports=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nothing to do — already in desired state
|
||||||
|
if { $enable_backports && [ "$bp_status" = "enabled" ]; } || \
|
||||||
|
{ ! $enable_backports && [ "$bp_status" = "disabled" ]; }; then
|
||||||
|
echo "Backports are already configured as requested."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
backup_current_repos
|
||||||
|
|
||||||
|
if $enable_backports; then
|
||||||
|
if [ "$current_format" = "deb822" ]; then
|
||||||
|
_write_deb822_backports "$DEBIAN_CODENAME"
|
||||||
|
else
|
||||||
|
_write_classic_backports "$DEBIAN_CODENAME"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$current_format" = "deb822" ]; then
|
||||||
|
_remove_deb822_backports "$DEBIAN_CODENAME"
|
||||||
|
else
|
||||||
|
_remove_classic_backports "$DEBIAN_CODENAME"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Updating package lists..."
|
||||||
|
if sudo apt update; then
|
||||||
|
cleanup_repo_backup
|
||||||
|
echo -e "${GREEN}Backports configured.${NC}"
|
||||||
|
else
|
||||||
|
restore_previous_repos
|
||||||
|
echo -e "${RED}apt update failed. Backup restored.${NC}"
|
||||||
|
fi
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# migrate.sh — Stable → Testing / SID branch migration
|
||||||
|
# License GPL v3
|
||||||
|
|
||||||
|
_MIGRATE_BACKUP=""
|
||||||
|
|
||||||
|
_persistent_backup_repos() {
|
||||||
|
local stamp
|
||||||
|
stamp=$(date +%Y%m%d-%H%M%S)
|
||||||
|
_MIGRATE_BACKUP="/var/backups/debianito-repos-${stamp}.tar.gz"
|
||||||
|
sudo mkdir -p /var/backups
|
||||||
|
local files=()
|
||||||
|
[ -f /etc/apt/sources.list ] && files+=("/etc/apt/sources.list")
|
||||||
|
[ -d /etc/apt/sources.list.d ] && files+=("/etc/apt/sources.list.d")
|
||||||
|
[ ${#files[@]} -eq 0 ] && return 1
|
||||||
|
sudo tar czf "$_MIGRATE_BACKUP" "${files[@]}" 2>/dev/null
|
||||||
|
echo "Backup: $_MIGRATE_BACKUP"
|
||||||
|
}
|
||||||
|
|
||||||
|
_restore_backup() {
|
||||||
|
if [ -z "$_MIGRATE_BACKUP" ] || [ ! -f "$_MIGRATE_BACKUP" ]; then
|
||||||
|
_msg "Restore Error" "No backup found at $_MIGRATE_BACKUP.\nCannot restore. Your system may be in an inconsistent state." 10 70
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo -e "${YELLOW}Restoring repository backup...${NC}"
|
||||||
|
sudo tar xzf "$_MIGRATE_BACKUP" -C / 2>/dev/null
|
||||||
|
echo -e "${GREEN}Backup restored from $_MIGRATE_BACKUP${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_write_deb822_branch() {
|
||||||
|
local target="$1"
|
||||||
|
local main_file="/etc/apt/sources.list.d/debian.sources"
|
||||||
|
|
||||||
|
local main_content=""
|
||||||
|
if [ "$target" = "sid" ]; then
|
||||||
|
main_content+="Types: deb\n"
|
||||||
|
main_content+="URIs: https://deb.debian.org/debian\n"
|
||||||
|
main_content+="Suites: sid\n"
|
||||||
|
main_content+="Components: main contrib non-free non-free-firmware\n"
|
||||||
|
main_content+="\n"
|
||||||
|
main_content+="Types: deb\n"
|
||||||
|
main_content+="URIs: https://security.debian.org/debian-security\n"
|
||||||
|
main_content+="Suites: sid\n"
|
||||||
|
main_content+="Components: main contrib non-free non-free-firmware\n"
|
||||||
|
else
|
||||||
|
# testing
|
||||||
|
main_content+="Types: deb\n"
|
||||||
|
main_content+="URIs: https://deb.debian.org/debian\n"
|
||||||
|
main_content+="Suites: testing testing-updates\n"
|
||||||
|
main_content+="Components: main contrib non-free non-free-firmware\n"
|
||||||
|
main_content+="\n"
|
||||||
|
main_content+="Types: deb\n"
|
||||||
|
main_content+="URIs: https://security.debian.org/debian-security\n"
|
||||||
|
main_content+="Suites: testing-security\n"
|
||||||
|
main_content+="Components: main contrib non-free non-free-firmware\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo mkdir -p /etc/apt/sources.list.d
|
||||||
|
echo -e "$main_content" | sudo tee "$main_file" > /dev/null
|
||||||
|
echo "Wrote $main_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
_branch_migration() {
|
||||||
|
# ── Screen 1: Risk warning ──
|
||||||
|
_msg_red "WARNING: Branch Migration" \
|
||||||
|
"Migrating from Debian Stable to Testing or SID is a\n\
|
||||||
|
MAJOR change and CAN make your system UNBOOTABLE.\n\n\
|
||||||
|
Risks include:\n\
|
||||||
|
• NVIDIA / DKMS drivers may break\n\
|
||||||
|
• System may fail to boot after reboot\n\
|
||||||
|
• Some packages may be removed or replaced\n\
|
||||||
|
• SID (unstable) receives NO security updates\n\n\
|
||||||
|
A full persistent backup will be saved to /var/backups/\n\
|
||||||
|
so you can restore if things go wrong." 16 70
|
||||||
|
|
||||||
|
if ! _confirm "Branch Migration" "Do you want to proceed with the migration?"; then
|
||||||
|
echo "Migration cancelled."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Screen 2: Plan summary ──
|
||||||
|
local plan="This operation will:\n\n"
|
||||||
|
plan+=" 1. Backup current APT sources to /var/backups/\n"
|
||||||
|
plan+=" 2. Remove any backports configuration\n"
|
||||||
|
plan+=" 3. Write new DEB822 sources for the target branch\n"
|
||||||
|
plan+=" 4. Run: apt update\n"
|
||||||
|
plan+=" 5. Run: apt upgrade -y\n"
|
||||||
|
plan+=" 6. Run: apt full-upgrade -y\n"
|
||||||
|
plan+=" 7. Run: apt autoremove -y\n\n"
|
||||||
|
plan+="If apt update fails, the backup is restored immediately."
|
||||||
|
|
||||||
|
_msg_red "Migration Plan" "$plan" 16 70
|
||||||
|
|
||||||
|
if ! _confirm "Migration Plan" "Proceed with the plan?"; then
|
||||||
|
echo "Migration cancelled."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Screen 3: Branch selection ──
|
||||||
|
local branch
|
||||||
|
branch=$(_inputbox "Target Branch" \
|
||||||
|
"Type exactly TESTING or SID (case-sensitive):" 10 60 "")
|
||||||
|
|
||||||
|
[ -z "$branch" ] && { echo "Migration cancelled."; return; }
|
||||||
|
|
||||||
|
if [ "$branch" != "TESTING" ] && [ "$branch" != "SID" ]; then
|
||||||
|
_msg "Invalid Branch" "You typed: $branch\n\nExpected: TESTING or SID (exact, case-sensitive).\nAborting." 10 60
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Normalize to lowercase for internal use
|
||||||
|
local target
|
||||||
|
target=$(echo "$branch" | tr '[:upper:]' '[:lower:]')
|
||||||
|
|
||||||
|
# ── Screen 4: Execution ──
|
||||||
|
echo -e "${YELLOW}Starting branch migration to ${target}...${NC}"
|
||||||
|
|
||||||
|
# 4a. Persistent backup
|
||||||
|
echo "Creating backup..."
|
||||||
|
_persistent_backup_repos || {
|
||||||
|
_msg "Backup Error" "Failed to create backup. Aborting." 8 60
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# 4b. Clean backports
|
||||||
|
echo "Removing backports configuration..."
|
||||||
|
[ -f /etc/apt/sources.list.d/debian-backports.sources ] && sudo rm -f /etc/apt/sources.list.d/debian-backports.sources
|
||||||
|
[ -f /etc/apt/sources.list.d/debian-backports.list ] && sudo rm -f /etc/apt/sources.list.d/debian-backports.list
|
||||||
|
|
||||||
|
# 4c. Remove any old classic source files to avoid conflicts
|
||||||
|
[ -f /etc/apt/sources.list ] && sudo rm -f /etc/apt/sources.list
|
||||||
|
|
||||||
|
# 4d. Write new sources
|
||||||
|
_write_deb822_branch "$target"
|
||||||
|
|
||||||
|
# 4e. SID guardrails: install bug alerts before upgrade
|
||||||
|
if [ "$target" = "sid" ]; then
|
||||||
|
echo -e "${YELLOW}Installing apt-listbugs and apt-listchanges (SID guardrails)...${NC}"
|
||||||
|
sudo apt update -qq 2>/dev/null || true
|
||||||
|
sudo DEBIAN_FRONTEND=noninteractive apt install -y apt-listbugs apt-listchanges || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4f. apt update with rollback on failure
|
||||||
|
echo -e "${YELLOW}Running apt update...${NC}"
|
||||||
|
if ! sudo apt update; then
|
||||||
|
echo -e "${RED}apt update failed. Restoring backup...${NC}"
|
||||||
|
_restore_backup
|
||||||
|
_msg_red "Migration Failed" \
|
||||||
|
"apt update failed. Backup has been restored from:\n\
|
||||||
|
$_MIGRATE_BACKUP\n\n\
|
||||||
|
Your system should be back to its previous state.\n\
|
||||||
|
Run 'sudo apt update' manually to verify." 12 70
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4g. Full upgrade
|
||||||
|
_run_cmd "Upgrade" "sudo apt upgrade -y" "Upgrading packages..."
|
||||||
|
_run_cmd "Full-Upgrade" "sudo apt full-upgrade -y" "Running full-upgrade..."
|
||||||
|
_run_cmd "Autoremove" "sudo apt autoremove -y" "Removing obsolete packages..."
|
||||||
|
|
||||||
|
# 4h. Re-run detection to reflect new branch
|
||||||
|
echo -e "${YELLOW}Re-running system detection for new branch...${NC}"
|
||||||
|
detect_debian_version
|
||||||
|
detect_kernel
|
||||||
|
detect_gpu
|
||||||
|
detect_storage
|
||||||
|
|
||||||
|
echo -e "${GREEN}Branch migration to ${target} completed successfully.${NC}"
|
||||||
|
|
||||||
|
# ── Screen 5: Reboot reminder ──
|
||||||
|
_msg "Migration Complete" \
|
||||||
|
"System has been migrated to ${target}.\n\n\
|
||||||
|
Backup saved at:\n $_MIGRATE_BACKUP\n\n\
|
||||||
|
REBOOT your system.\nIf it fails to boot, restore the backup manually:\n\
|
||||||
|
sudo tar xzf $_MIGRATE_BACKUP -C /\n sudo apt update\n sudo apt upgrade" 16 70
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# rescue.sh — UEFI boot repair and system rescue utilities
|
||||||
|
|
||||||
|
_rescue_boot_sb() {
|
||||||
|
echo -e "${YELLOW}UEFI Secure Boot repair...${NC}"
|
||||||
|
|
||||||
|
if [ ! -d /sys/firmware/efi ]; then
|
||||||
|
echo -e "${RED}Not a UEFI system. Skipping.${NC}"
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local sb_state
|
||||||
|
sb_state=$(mokutil --sb-state 2>/dev/null)
|
||||||
|
if ! echo "$sb_state" | grep -qi "enabled"; then
|
||||||
|
echo -e "${YELLOW}Secure Boot is not enabled. No refirm needed.${NC}"
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _confirm "Secure Boot Repair" \
|
||||||
|
"Secure Boot is enabled.\n\nReinstall and refirm shim-signed + GRUB?\n\nThis fixes boot issues where Debian is skipped\nin UEFI after kernel/driver changes."; then
|
||||||
|
echo "Skipped."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local efi_dir="/boot/efi"
|
||||||
|
[ ! -d "$efi_dir" ] && efi_dir="/boot"
|
||||||
|
|
||||||
|
_run_cmd "Refirm" \
|
||||||
|
"sudo apt install --reinstall -y shim-signed grub-efi-amd64-signed linux-image-amd64" \
|
||||||
|
"Reinstalling signed boot packages..."
|
||||||
|
_run_cmd "GRUB Install" \
|
||||||
|
"sudo grub-install --target=x86_64-efi --efi-directory=$efi_dir --bootloader-id=debian --recheck" \
|
||||||
|
"Reinstalling GRUB to EFI partition..."
|
||||||
|
_run_cmd "GRUB Config" \
|
||||||
|
"sudo update-grub" \
|
||||||
|
"Regenerating GRUB configuration..."
|
||||||
|
|
||||||
|
echo -e "${GREEN}Boot repair complete. Reboot to verify.${NC}"
|
||||||
|
_pause
|
||||||
|
}
|
||||||
|
|
||||||
|
_rescue_initramfs() {
|
||||||
|
if ! _confirm "Initramfs" "Regenerate initramfs for all kernels?\n\nFixes boot issues caused by missing drivers\nor corrupted initrd images."; then
|
||||||
|
echo "Skipped."
|
||||||
|
_pause
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
_run_cmd "Initramfs" "sudo update-initramfs -u -k all" "Regenerating initramfs for all kernels..."
|
||||||
|
echo -e "${GREEN}Initramfs regenerated.${NC}"
|
||||||
|
_pause
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# GRUB helpers
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
_set_grub_var() {
|
||||||
|
local var="$1" val="$2" file="/etc/default/grub"
|
||||||
|
if grep -q "^${var}=" "$file" 2>/dev/null; then
|
||||||
|
sudo sed -i "s/^${var}=.*/${var}=${val}/" "$file"
|
||||||
|
elif grep -q "^#${var}=" "$file" 2>/dev/null; then
|
||||||
|
sudo sed -i "s/^#${var}=.*/${var}=${val}/" "$file"
|
||||||
|
else
|
||||||
|
echo "${var}=${val}" | sudo tee -a "$file" >/dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_apply_grub_setting() {
|
||||||
|
local timeout="$1" style="$2" recordfail="$3" os_prober="$4"
|
||||||
|
local file="/etc/default/grub"
|
||||||
|
local backup="${file}.backup.$(date +%Y%m%d_%H%M%S)"
|
||||||
|
local override="/etc/default/grub.d/99_script_override.cfg"
|
||||||
|
|
||||||
|
sudo cp "$file" "$backup"
|
||||||
|
|
||||||
|
_set_grub_var GRUB_TIMEOUT "$timeout"
|
||||||
|
_set_grub_var GRUB_TIMEOUT_STYLE "$style"
|
||||||
|
_set_grub_var GRUB_RECORDFAIL_TIMEOUT "$recordfail"
|
||||||
|
[ -n "$os_prober" ] && _set_grub_var GRUB_DISABLE_OS_PROBER "$os_prober"
|
||||||
|
|
||||||
|
sudo mkdir -p /etc/default/grub.d
|
||||||
|
if [ -n "$os_prober" ]; then
|
||||||
|
cat << EOF | sudo tee "$override" > /dev/null
|
||||||
|
GRUB_TIMEOUT_STYLE=$style
|
||||||
|
GRUB_TIMEOUT=$timeout
|
||||||
|
GRUB_RECORDFAIL_TIMEOUT=$recordfail
|
||||||
|
GRUB_DISABLE_OS_PROBER=$os_prober
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
cat << EOF | sudo tee "$override" > /dev/null
|
||||||
|
GRUB_TIMEOUT=$timeout
|
||||||
|
GRUB_TIMEOUT_STYLE=$style
|
||||||
|
GRUB_RECORDFAIL_TIMEOUT=$recordfail
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
local summary
|
||||||
|
summary="Settings applied:\n\n"
|
||||||
|
summary+=" GRUB_TIMEOUT=$timeout\n"
|
||||||
|
summary+=" GRUB_TIMEOUT_STYLE=$style\n"
|
||||||
|
summary+=" GRUB_RECORDFAIL_TIMEOUT=$recordfail\n"
|
||||||
|
[ -n "$os_prober" ] && summary+=" GRUB_DISABLE_OS_PROBER=$os_prober\n"
|
||||||
|
summary+="\nRunning update-grub..."
|
||||||
|
|
||||||
|
echo -e "$summary"
|
||||||
|
|
||||||
|
if sudo update-grub >/dev/null 2>&1; then
|
||||||
|
_msg "GRUB Settings" \
|
||||||
|
"GRUB settings applied successfully!\n\nBackup saved: ${backup}\n\nReboot to see the changes."
|
||||||
|
else
|
||||||
|
echo -e "${RED}update-grub failed. Restoring backup...${NC}"
|
||||||
|
sudo cp "$backup" "$file"
|
||||||
|
sudo rm -f "$override"
|
||||||
|
_msg "Error" "update-grub failed.\nBackup restored from ${backup}\nOverride removed: ${override}."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_grub_menu_settings() {
|
||||||
|
while true; do
|
||||||
|
local choice
|
||||||
|
choice=$(_menu "GRUB Boot Menu Settings" \
|
||||||
|
"Configure when and how the GRUB menu appears${SCROLL_HINT}:" \
|
||||||
|
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
|
"1" "Disable GRUB menu on start (Fastest boot)" \
|
||||||
|
"2" "Faster boot (Show 3-sec countdown)" \
|
||||||
|
"3" "Default boot (Show menu for 5 secs)" \
|
||||||
|
"4" "Custom timeout (Input seconds)" \
|
||||||
|
"5" "Back")
|
||||||
|
|
||||||
|
[ -z "$choice" ] && return
|
||||||
|
clear
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
1)
|
||||||
|
if _confirm "Disable GRUB Menu" \
|
||||||
|
"GRUB menu will be hidden entirely for fastest boot.\n\nTo access the menu on next boot, press and hold ESC\nimmediately after powering on.\n\nProceed?"; then
|
||||||
|
_apply_grub_setting 0 hidden 0 true
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
_apply_grub_setting 3 menu 3 ""
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
_apply_grub_setting 5 menu 5 ""
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
local custom_timeout
|
||||||
|
custom_timeout=$(whiptail --title "Custom GRUB Timeout" \
|
||||||
|
--inputbox "Enter the GRUB timeout in seconds.\n\nUse -1 for indefinite wait." \
|
||||||
|
10 60 "" 3>&1 1>&2 2>&3 || true)
|
||||||
|
if [ -n "$custom_timeout" ]; then
|
||||||
|
if [[ "$custom_timeout" =~ ^-?[0-9]+$ ]]; then
|
||||||
|
_apply_grub_setting "$custom_timeout" menu "$custom_timeout" ""
|
||||||
|
else
|
||||||
|
_msg "Invalid Input" "Please enter a valid integer (e.g. 0, 5, -1)."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
5) return ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
rescue_boot() {
|
||||||
|
while true; do
|
||||||
|
local choice
|
||||||
|
choice=$(_menu "Boot Rescue + GRUB Configuration" \
|
||||||
|
"Select an operation${SCROLL_HINT}:" \
|
||||||
|
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
|
"1" "GRUB Boot Menu Settings" \
|
||||||
|
"2" "Refirm Secure Boot (shim + GRUB)" \
|
||||||
|
"3" "Regenerate initramfs (all kernels)" \
|
||||||
|
"4" "Return to main menu")
|
||||||
|
|
||||||
|
[ -z "$choice" ] && return
|
||||||
|
clear
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
1) _grub_menu_settings ;;
|
||||||
|
2) _rescue_boot_sb ;;
|
||||||
|
3) _rescue_initramfs ;;
|
||||||
|
4) return ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
+7
-12
@@ -7,14 +7,13 @@ config_sudo() {
|
|||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
local choice
|
local choice
|
||||||
choice=$(whiptail --title "User Privileges & Feedback" --menu \
|
choice=$(_menu "User Privileges & Feedback" \
|
||||||
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
||||||
"1" "Sudo Group Membership" \
|
"1" "Sudo Group Membership" \
|
||||||
"2" "Passwordless Sudo (maintenance commands)" \
|
"2" "Passwordless Sudo (maintenance commands)" \
|
||||||
"3" "Repair Home Directory Ownership" \
|
"3" "Repair Home Directory Ownership" \
|
||||||
"4" "Sudo Password Feedback (asterisks)" \
|
"4" "Sudo Password Feedback (asterisks)" \
|
||||||
"5" "Back to main menu" \
|
"5" "Back to main menu")
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
|
|
||||||
[ -z "$choice" ] && return
|
[ -z "$choice" ] && return
|
||||||
clear
|
clear
|
||||||
@@ -67,12 +66,11 @@ _configure_nopasswd() {
|
|||||||
- shutdown / reboot / halt (power commands)\n\n\
|
- shutdown / reboot / halt (power commands)\n\n\
|
||||||
Useful for automation but reduces security." 14 70; then
|
Useful for automation but reduces security." 14 70; then
|
||||||
local choices
|
local choices
|
||||||
choices=$(whiptail --title "NOPASSWD Commands" --checklist \
|
choices=$(_checklist "NOPASSWD Commands" \
|
||||||
"Select commands to allow without password:" 12 60 3 \
|
"Select commands to allow without password:" 12 60 3 \
|
||||||
"apt" "APT package management" ON \
|
"apt" "APT package management" ON \
|
||||||
"systemctl" "Systemd service management" ON \
|
"systemctl" "Systemd service management" ON \
|
||||||
"power" "Shutdown, reboot, halt" ON \
|
"power" "Shutdown, reboot, halt" ON)
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
[ -z "$choices" ] && { echo "No commands selected."; return; }
|
[ -z "$choices" ] && { echo "No commands selected."; return; }
|
||||||
@@ -93,12 +91,10 @@ Useful for automation but reduces security." 14 70; then
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
echo -e "$content" | sudo tee "$nopasswd_file" > /dev/null
|
local content_str; content_str=$(echo -e "$content")
|
||||||
sudo chmod 0440 "$nopasswd_file"
|
if _validate_sudoers "$content_str" "$nopasswd_file"; then
|
||||||
if [ -f "$nopasswd_file" ]; then
|
|
||||||
echo -e "${GREEN}Passwordless sudo configured for selected commands.${NC}"
|
echo -e "${GREEN}Passwordless sudo configured for selected commands.${NC}"
|
||||||
else
|
else
|
||||||
echo -e "${RED}Failed to configure passwordless sudo.${NC}"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -148,10 +144,9 @@ _toggle_pwfeedback() {
|
|||||||
else
|
else
|
||||||
if _confirm "Password Feedback" \
|
if _confirm "Password Feedback" \
|
||||||
"Show asterisks when typing the sudo password?"; then
|
"Show asterisks when typing the sudo password?"; then
|
||||||
if echo 'Defaults pwfeedback' | sudo tee "$fb_file" > /dev/null 2>&1; then
|
if _validate_sudoers 'Defaults pwfeedback' "$fb_file"; then
|
||||||
echo -e "${GREEN}Password feedback enabled.${NC}"
|
echo -e "${GREEN}Password feedback enabled.${NC}"
|
||||||
else
|
else
|
||||||
echo -e "${RED}Failed to create $fb_file${NC}"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
+185
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# swap.sh — Disk-based swap management (swapfile + swappiness)
|
||||||
|
# Independent of zram.sh. Uses pri=10 to coexist with ZRAM priority=100.
|
||||||
|
|
||||||
|
readonly SWAP_FILE="/swapfile"
|
||||||
|
readonly SWAP_FSTAB_TAG="# debianito-managed-swap"
|
||||||
|
readonly SWAP_PRIORITY="10"
|
||||||
|
readonly SWAP_CONF="/etc/sysctl.d/99-swappiness-debianito.conf"
|
||||||
|
readonly SWAP_LOCK="/run/lock/debianito-swap.lock"
|
||||||
|
|
||||||
|
# ── Helpers ──
|
||||||
|
|
||||||
|
_swap_valid_fstab() {
|
||||||
|
local tmp="$1"
|
||||||
|
sudo findmnt --verify --fstab "$tmp" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
_swap_safe_write_fstab() {
|
||||||
|
local line="$1"
|
||||||
|
local tmp
|
||||||
|
tmp=$(mktemp) || return 1
|
||||||
|
sudo cp /etc/fstab "$tmp"
|
||||||
|
sudo sed -i "/$SWAP_FSTAB_TAG/d" "$tmp"
|
||||||
|
[ -n "$line" ] && printf '%s\n' "$line" >> "$tmp"
|
||||||
|
if _swap_valid_fstab "$tmp"; then
|
||||||
|
sudo install -o root -g root -m 0644 "$tmp" /etc/fstab
|
||||||
|
else
|
||||||
|
local err
|
||||||
|
err=$(sudo findmnt --verify --fstab "$tmp" 2>&1 || true)
|
||||||
|
rm -f "$tmp"
|
||||||
|
_msg "fstab Error" "Validation failed — changes NOT applied.\n\n$err" 12 70
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
rm -f "$tmp"
|
||||||
|
}
|
||||||
|
|
||||||
|
_swap_recommend_gb() {
|
||||||
|
if [ -z "${RAM_GB:-}" ]; then
|
||||||
|
echo 2
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local ram
|
||||||
|
ram=$(echo "$RAM_GB" | awk '{print int($1)}')
|
||||||
|
if [ "$ram" -ge 16 ]; then
|
||||||
|
echo 2
|
||||||
|
elif [ "$ram" -ge 8 ]; then
|
||||||
|
echo 4
|
||||||
|
else
|
||||||
|
local rec
|
||||||
|
rec=$((ram * 2))
|
||||||
|
[ "$rec" -lt 1 ] && rec=1
|
||||||
|
echo "$rec"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Menu options ──
|
||||||
|
|
||||||
|
_swap_current_status() {
|
||||||
|
local info="── Current swap ──\n"
|
||||||
|
info+="$(sudo swapon --show 2>/dev/null || echo '(none active)')\n\n"
|
||||||
|
info+="swappiness: $(cat /proc/sys/vm/swappiness)\n\n"
|
||||||
|
info+="fstab swap entries:\n"
|
||||||
|
info+="$(grep -E 'swap|SWAP' /etc/fstab 2>/dev/null || echo '(none in fstab)')"
|
||||||
|
_msg "Swap Status" "$info" 14 65
|
||||||
|
}
|
||||||
|
|
||||||
|
_swap_create_file() {
|
||||||
|
local fstype rec_gb
|
||||||
|
fstype=$(stat -f -c %T "$(dirname "$SWAP_FILE")" 2>/dev/null || echo "ext4")
|
||||||
|
rec_gb=$(_swap_recommend_gb)
|
||||||
|
|
||||||
|
local warn=""
|
||||||
|
if [ "$fstype" = "btrfs" ]; then
|
||||||
|
warn="Filesystem: Btrfs\nSwapfile on Btrfs needs extra steps (nodatacow).\nHibernation requires swap ≥ RAM and manual resume= config.\n\n"
|
||||||
|
fi
|
||||||
|
warn+="ZRAM (priority 100) is used first.\nDisk swap (priority $SWAP_PRIORITY) is only consumed after ZRAM fills."
|
||||||
|
|
||||||
|
_msg "Swapfile Info" "$warn" 14 65
|
||||||
|
|
||||||
|
local size_gb
|
||||||
|
size_gb=$(_inputbox "Swapfile Size" "Size in GB for $SWAP_FILE:" 10 60 "$rec_gb")
|
||||||
|
[ -z "$size_gb" ] && return
|
||||||
|
[[ "$size_gb" =~ ^[0-9]+$ ]] && [ "$size_gb" -gt 0 ] || {
|
||||||
|
_msg "Error" "Enter a positive integer." 8 40
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -f "$SWAP_FILE" ]; then
|
||||||
|
_confirm "Swapfile exists" "$SWAP_FILE already exists.\nRecreate it (${size_gb} GB)?" || return
|
||||||
|
sudo swapoff "$SWAP_FILE" 2>/dev/null || true
|
||||||
|
sudo rm -f "$SWAP_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YELLOW}Allocating ${size_gb}G swapfile...${NC}"
|
||||||
|
if [ "$fstype" = "btrfs" ]; then
|
||||||
|
sudo touch "$SWAP_FILE"
|
||||||
|
sudo chattr +C "$SWAP_FILE" 2>/dev/null || true
|
||||||
|
sudo dd if=/dev/zero of="$SWAP_FILE" bs=1M count=$((size_gb * 1024)) status=progress
|
||||||
|
else
|
||||||
|
sudo fallocate -l "${size_gb}G" "$SWAP_FILE" || \
|
||||||
|
sudo dd if=/dev/zero of="$SWAP_FILE" bs=1M count=$((size_gb * 1024)) status=progress
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo chmod 600 "$SWAP_FILE"
|
||||||
|
sudo mkswap "$SWAP_FILE" >/dev/null
|
||||||
|
sudo swapon "$SWAP_FILE"
|
||||||
|
|
||||||
|
local fstab_line
|
||||||
|
fstab_line="$SWAP_FILE none swap sw,pri=$SWAP_PRIORITY 0 0 $SWAP_FSTAB_TAG # pri=$SWAP_PRIORITY (below zram 100)"
|
||||||
|
if _swap_safe_write_fstab "$fstab_line"; then
|
||||||
|
_msg "Swapfile" "Swapfile created and added to fstab (persistent).\n\nPriority: $SWAP_PRIORITY (below ZRAM 100)." 12 65
|
||||||
|
else
|
||||||
|
sudo swapoff "$SWAP_FILE" 2>/dev/null || true
|
||||||
|
sudo rm -f "$SWAP_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_swap_remove_file() {
|
||||||
|
local has_tag
|
||||||
|
has_tag=$(grep -c "$SWAP_FSTAB_TAG" /etc/fstab 2>/dev/null || echo 0)
|
||||||
|
[ "$has_tag" -eq 0 ] && [ ! -f "$SWAP_FILE" ] && {
|
||||||
|
_msg "Swap" "No managed swapfile found." 8 50
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_confirm "Remove Swapfile" "Disable and delete $SWAP_FILE?\n\nRemoves fstab entry and deletes the file." || return
|
||||||
|
|
||||||
|
sudo swapoff "$SWAP_FILE" 2>/dev/null || true
|
||||||
|
_swap_safe_write_fstab ""
|
||||||
|
sudo rm -f "$SWAP_FILE"
|
||||||
|
_msg "Swap" "Swapfile removed and fstab entry cleaned." 8 60
|
||||||
|
}
|
||||||
|
|
||||||
|
_swap_set_swappiness() {
|
||||||
|
local cur val
|
||||||
|
cur=$(cat /proc/sys/vm/swappiness 2>/dev/null || echo 60)
|
||||||
|
val=$(_inputbox "Swappiness" "Current value: $cur\nEnter new value (0-100):" 10 60 "$cur")
|
||||||
|
[ -z "$val" ] && return
|
||||||
|
[[ "$val" =~ ^[0-9]+$ ]] && [ "$val" -le 100 ] || {
|
||||||
|
_msg "Error" "Value must be 0-100." 8 40
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
local tmp
|
||||||
|
tmp=$(mktemp) || return
|
||||||
|
printf 'vm.swappiness=%s\n' "$val" > "$tmp"
|
||||||
|
sudo install -o root -g root -m 0644 "$tmp" "$SWAP_CONF"
|
||||||
|
sudo sysctl -w "vm.swappiness=$val" >/dev/null
|
||||||
|
rm -f "$tmp"
|
||||||
|
_msg "Swappiness" "swappiness set to $val (persistent)." 8 60
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Entry point ──
|
||||||
|
|
||||||
|
manage_swap() {
|
||||||
|
exec 9>"$SWAP_LOCK"
|
||||||
|
flock -n 9 || {
|
||||||
|
_msg "Busy" "Another swap operation is already running." 8 55
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
local choice
|
||||||
|
choice=$(_menu "Swap Management" \
|
||||||
|
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
||||||
|
"1" "Show current swap & swappiness" \
|
||||||
|
"2" "Create / resize swapfile" \
|
||||||
|
"3" "Remove swapfile" \
|
||||||
|
"4" "Change swappiness" \
|
||||||
|
"5" "Back to main menu")
|
||||||
|
|
||||||
|
[ -z "$choice" ] && break
|
||||||
|
clear
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
1) _swap_current_status ;;
|
||||||
|
2) _swap_create_file ;;
|
||||||
|
3) _swap_remove_file ;;
|
||||||
|
4) _swap_set_swappiness ;;
|
||||||
|
5) break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
exec 9>&-
|
||||||
|
}
|
||||||
+139
-34
@@ -45,53 +45,158 @@ _show_sysinfo() {
|
|||||||
fi
|
fi
|
||||||
msg+="\n"
|
msg+="\n"
|
||||||
|
|
||||||
# ── Network Block ──
|
# ── Network Block (PCI class + live interfaces) ──
|
||||||
msg+="─── Network ───\n"
|
msg+="─── Network ───\n"
|
||||||
local has_network=false
|
|
||||||
local i
|
# ── 1. Detect ALL Ethernet chipsets (class 0x0200) ──
|
||||||
|
declare -a pci_eth_lines=()
|
||||||
|
while IFS= read -r line; do
|
||||||
|
pci_eth_lines+=("$line")
|
||||||
|
done < <(lspci -d ::0200 2>/dev/null || true)
|
||||||
|
|
||||||
|
# ── 2. Detect ALL WiFi chipsets (class 0x0280 + vendor fallbacks) ──
|
||||||
|
declare -a pci_wifi_lines=()
|
||||||
|
while IFS= read -r line; do
|
||||||
|
pci_wifi_lines+=("$line")
|
||||||
|
done < <(lspci -d ::0280 2>/dev/null || true)
|
||||||
|
|
||||||
|
# Broadcom vendor-ID fallback (14e4) — include only if not already captured
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if echo "$line" | grep -qi '14e4:'; then
|
||||||
|
local already=false
|
||||||
|
for existing in "${pci_wifi_lines[@]}"; do
|
||||||
|
[ "$existing" = "$line" ] && already=true && break
|
||||||
|
done
|
||||||
|
! $already && pci_wifi_lines+=("$line")
|
||||||
|
fi
|
||||||
|
done < <(lspci -nn 2>/dev/null || true)
|
||||||
|
|
||||||
|
# USB WiFi fallback
|
||||||
|
local usb_wifi_lines=()
|
||||||
|
while IFS= read -r line; do
|
||||||
|
usb_wifi_lines+=("$line")
|
||||||
|
done < <(lsusb 2>/dev/null | grep -iE 'wireless|wifi|wlan|802\.11' || true)
|
||||||
|
|
||||||
|
# ── 3. Build chipset description arrays ──
|
||||||
|
local -a eth_descs=()
|
||||||
|
local -a wifi_descs=()
|
||||||
|
local line desc
|
||||||
|
|
||||||
|
for line in "${pci_eth_lines[@]}"; do
|
||||||
|
desc=$(echo "$line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
|
||||||
|
eth_descs+=("$desc")
|
||||||
|
done
|
||||||
|
for line in "${pci_wifi_lines[@]}"; do
|
||||||
|
desc=$(echo "$line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
|
||||||
|
wifi_descs+=("$desc")
|
||||||
|
done
|
||||||
|
for line in "${usb_wifi_lines[@]}"; do
|
||||||
|
desc=$(echo "$line" | sed 's/^.*ID //')
|
||||||
|
wifi_descs+=("$desc")
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── 4. Enumerate live interfaces ──
|
||||||
|
local -a shown_eth_descs=()
|
||||||
|
local -a shown_wifi_descs=()
|
||||||
|
local has_eth=false has_wifi=false has_other=false
|
||||||
|
|
||||||
if ! command -v ip &>/dev/null; then
|
if ! command -v ip &>/dev/null; then
|
||||||
msg+="(install iproute2 for interface details)\n"
|
msg+="(install iproute2 for interface details)\n"
|
||||||
else
|
else
|
||||||
for i in "${!ETH_NAMES[@]}"; do
|
while IFS= read -r line; do
|
||||||
has_network=true
|
local iface state ip4 ssid
|
||||||
local e_iface="${ETH_NAMES[$i]}"
|
iface=$(echo "$line" | awk -F': ' '{print $2}' | sed 's/@.*//')
|
||||||
local e_desc="${ETH_DESCS[$i]:-$ETH_DESC}"
|
state=$(echo "$line" | awk '{print $9}')
|
||||||
local e_state="${ETH_STATES[$i]}"
|
|
||||||
local e_ip4="${ETH_IPS[$i]}"
|
|
||||||
if [ "$e_state" = "UP" ]; then
|
|
||||||
msg+="${e_iface}: ${e_desc}\n ↑ ${e_ip4:-no IP}\n"
|
|
||||||
else
|
|
||||||
msg+="${e_iface}: ${e_desc}\n ↓\n"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
local found_active_wifi=false
|
case "$iface" in
|
||||||
for i in "${!WIFI_NAMES[@]}"; do
|
lo|docker*|veth*|br-*|virbr*|tun*|tap*|bond*) continue ;;
|
||||||
found_active_wifi=true
|
esac
|
||||||
has_network=true
|
|
||||||
local w_iface="${WIFI_NAMES[$i]}"
|
ip4=$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}')
|
||||||
local w_desc="${WIFI_DESCS[$i]:-$WIFI_DESC}"
|
|
||||||
local w_state="${WIFI_STATES[$i]}"
|
# Determine type by PCI class (most reliable)
|
||||||
local w_ip4="${WIFI_IPS[$i]}"
|
local pci_class=""
|
||||||
local w_ssid="${WIFI_SSIDS[$i]}"
|
pci_class=$(cat "/sys/class/net/${iface}/device/class" 2>/dev/null || true)
|
||||||
if [ "$w_state" = "UP" ]; then
|
|
||||||
msg+="${w_iface}: ${w_desc}\n ↑ ${w_ip4:-no IP}"
|
case "$pci_class" in
|
||||||
[ -n "$w_ssid" ] && msg+=" \"${w_ssid}\""
|
0x0200*)
|
||||||
|
has_eth=true
|
||||||
|
desc="${eth_descs[0]:-Unknown Ethernet chipset}"
|
||||||
|
shown_eth_descs+=("${eth_descs[0]}")
|
||||||
|
;;
|
||||||
|
0x0280*)
|
||||||
|
has_wifi=true
|
||||||
|
desc="${wifi_descs[0]:-Unknown WiFi chipset}"
|
||||||
|
shown_wifi_descs+=("${wifi_descs[0]}")
|
||||||
|
ssid=""
|
||||||
|
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Fallback: classify by interface name pattern
|
||||||
|
case "$iface" in
|
||||||
|
wl*|wlp*|wlo*|wlan*)
|
||||||
|
has_wifi=true
|
||||||
|
desc="${wifi_descs[0]:-Unknown WiFi chipset}"
|
||||||
|
shown_wifi_descs+=("${wifi_descs[0]}")
|
||||||
|
ssid=""
|
||||||
|
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
|
||||||
|
;;
|
||||||
|
eth*|enp*|ens*|enx*|eno*)
|
||||||
|
has_eth=true
|
||||||
|
desc="${eth_descs[0]:-Unknown Ethernet chipset}"
|
||||||
|
shown_eth_descs+=("${eth_descs[0]}")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
has_other=true
|
||||||
|
desc="(network interface)"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$state" = "UP" ]; then
|
||||||
|
msg+="${iface}: ${desc}\n ↑ ${ip4:-no IP}"
|
||||||
|
if [ "$pci_class" = "0x0280" ] || [[ "$iface" == wl* ]]; then
|
||||||
|
[ -n "${ssid:-}" ] && msg+=" \"${ssid}\""
|
||||||
|
fi
|
||||||
msg+="\n"
|
msg+="\n"
|
||||||
else
|
else
|
||||||
msg+="${w_iface}: ${w_desc}\n ↓\n"
|
msg+="${iface}: ${desc}\n ↓\n"
|
||||||
|
fi
|
||||||
|
done < <(ip -o link show 2>/dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 5. Show chipsets without an active interface ──
|
||||||
|
local chip
|
||||||
|
|
||||||
|
for chip in "${eth_descs[@]}"; do
|
||||||
|
local found=false
|
||||||
|
for shown in "${shown_eth_descs[@]}"; do
|
||||||
|
[ "$chip" = "$shown" ] && found=true && break
|
||||||
|
done
|
||||||
|
if ! $found; then
|
||||||
|
msg+="Ethernet: ${chip}\n (no active interface)\n"
|
||||||
|
shown_eth_descs+=("$chip")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if ! $found_active_wifi && [ -n "$WIFI_DESC" ]; then
|
for chip in "${wifi_descs[@]}"; do
|
||||||
has_network=true
|
local found=false
|
||||||
msg+="WiFi: ${WIFI_DESC}\n"
|
for shown in "${shown_wifi_descs[@]}"; do
|
||||||
msg+=" (no driver — install firmware)\n"
|
[ "$chip" = "$shown" ] && found=true && break
|
||||||
|
done
|
||||||
|
if ! $found; then
|
||||||
|
msg+="WiFi: ${chip}\n (no active interface)\n"
|
||||||
|
shown_wifi_descs+=("$chip")
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
if ! $has_network; then
|
# ── 6. Nothing at all ──
|
||||||
msg+="No active interfaces detected\n"
|
if ! $has_eth && ! $has_wifi && ! $has_other && [ ${#eth_descs[@]} -eq 0 ] && [ ${#wifi_descs[@]} -eq 0 ]; then
|
||||||
|
if command -v ip &>/dev/null; then
|
||||||
|
msg+="No network interfaces detected\n"
|
||||||
|
else
|
||||||
|
msg+="(install iproute2 for interface details)\n"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+195
-37
@@ -43,12 +43,12 @@ check_sudo() {
|
|||||||
# Time sync detection + NTP
|
# Time sync detection + NTP
|
||||||
# --------------------------------
|
# --------------------------------
|
||||||
check_system_time() {
|
check_system_time() {
|
||||||
if ! command -v timedatectl &> /dev/null; then
|
command -v timedatectl &>/dev/null || return
|
||||||
return
|
|
||||||
fi
|
|
||||||
local year
|
local year
|
||||||
year=$(date +%Y)
|
year=$(date +%Y)
|
||||||
if [ "$year" -lt 2026 ]; then
|
|
||||||
|
if [ "$year" -lt 2025 ]; then
|
||||||
local msg="System date/time appears to be incorrect\n"
|
local msg="System date/time appears to be incorrect\n"
|
||||||
msg+="($(date '+%Y-%m-%d %H:%M')). This will prevent Debian\n"
|
msg+="($(date '+%Y-%m-%d %H:%M')). This will prevent Debian\n"
|
||||||
msg+="repositories from working properly.\n\n"
|
msg+="repositories from working properly.\n\n"
|
||||||
@@ -56,31 +56,40 @@ check_system_time() {
|
|||||||
msg+="(requires network access and timedatectl)"
|
msg+="(requires network access and timedatectl)"
|
||||||
if _confirm "System Date" "$msg"; then
|
if _confirm "System Date" "$msg"; then
|
||||||
sync_system_time
|
sync_system_time
|
||||||
local new_year
|
|
||||||
new_year=$(date +%Y)
|
|
||||||
if [ "$new_year" -ge 2026 ]; then
|
|
||||||
echo -e "${GREEN}Time synced: $(date '+%Y-%m-%d %H:%M')${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}Could not sync time automatically.${NC}"
|
|
||||||
echo "You may need to set it manually: sudo date --set \"YYYY-MM-DD HH:MM:SS\""
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
echo -e "${YELLOW}Warning: System time is incorrect. Package installations may fail.${NC}"
|
echo -e "${YELLOW}Warning: System time is incorrect. Package installations may fail.${NC}"
|
||||||
fi
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ntp_active
|
||||||
|
ntp_active=$(timedatectl show --property=NTP --value 2>/dev/null || echo "no")
|
||||||
|
if [ "$ntp_active" != "yes" ]; then
|
||||||
|
sync_system_time
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_system_time() {
|
sync_system_time() {
|
||||||
if command -v timedatectl &> /dev/null; then
|
command -v timedatectl &>/dev/null || return
|
||||||
local ntp_active
|
|
||||||
ntp_active=$(timedatectl show --property=NTP --value 2>/dev/null || echo "no")
|
if ! is_installed systemd-timesyncd; then
|
||||||
if [ "$ntp_active" != "yes" ]; then
|
sudo DEBIAN_FRONTEND=noninteractive apt install -y systemd-timesyncd || true
|
||||||
echo -e "${YELLOW}NTP not active. Attempting to enable time sync...${NC}"
|
|
||||||
sudo timedatectl set-ntp true 2>/dev/null || true
|
|
||||||
sleep 4
|
|
||||||
fi
|
fi
|
||||||
elif command -v hwclock &> /dev/null && command -v ntpd &> /dev/null; then
|
|
||||||
sudo hwclock --hctosys 2>/dev/null || true
|
if ! systemctl is-enabled systemd-timesyncd &>/dev/null; then
|
||||||
|
sudo systemctl enable systemd-timesyncd || true
|
||||||
|
fi
|
||||||
|
if ! systemctl is-active systemd-timesyncd &>/dev/null; then
|
||||||
|
sudo systemctl start systemd-timesyncd || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo timedatectl set-ntp true || true
|
||||||
|
sleep 4
|
||||||
|
|
||||||
|
if timedatectl show --property=NTPSynchronized --value 2>/dev/null | grep -q yes; then
|
||||||
|
echo -e "${GREEN}Time synchronized: $(date '+%Y-%m-%d %H:%M')${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}NTP sync did not complete.${NC}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,9 +102,8 @@ detect_debian_version() {
|
|||||||
DEBIAN_CODENAME=$(grep -oP 'VERSION_CODENAME=\K\w+' /etc/os-release 2>/dev/null || echo "")
|
DEBIAN_CODENAME=$(grep -oP 'VERSION_CODENAME=\K\w+' /etc/os-release 2>/dev/null || echo "")
|
||||||
fi
|
fi
|
||||||
if [ -z "$DEBIAN_CODENAME" ]; then
|
if [ -z "$DEBIAN_CODENAME" ]; then
|
||||||
echo -e "${YELLOW}Installing lsb-release...${NC}"
|
sync_system_time || true
|
||||||
sync_system_time
|
sudo apt update -qq 2>/dev/null && sudo apt install -y -qq lsb-release || true
|
||||||
sudo apt update -qq 2>/dev/null && sudo apt install -y -qq lsb-release
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ -z "$DEBIAN_CODENAME" ]; then
|
if [ -z "$DEBIAN_CODENAME" ]; then
|
||||||
@@ -150,6 +158,10 @@ is_installed() {
|
|||||||
dpkg -l "$1" 2>/dev/null | grep -q '^ii'
|
dpkg -l "$1" 2>/dev/null | grep -q '^ii'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_state() {
|
||||||
|
is_installed "$1" && echo "ON" || echo "OFF"
|
||||||
|
}
|
||||||
|
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
# Package version lookup
|
# Package version lookup
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
@@ -275,11 +287,29 @@ detect_network() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local wifi_line
|
local wifi_line
|
||||||
wifi_line=$(lspci -nn | grep -i 'Network controller' | head -n1) || true
|
# Layer 1: grep by PCI class description text
|
||||||
|
wifi_line=$(lspci -nn 2>/dev/null | grep -iE 'network controller|wireless|wi-fi|wlan|802\.11' | head -n1) || true
|
||||||
|
# Layer 2: grep by exact PCI class code 0x0280 (Network controller)
|
||||||
|
if [ -z "$wifi_line" ]; then
|
||||||
|
wifi_line=$(lspci -d ::0280 2>/dev/null | head -n1) || true
|
||||||
|
fi
|
||||||
|
# Layer 3: Broadcom vendor ID fallback (14e4)
|
||||||
|
if [ -z "$wifi_line" ]; then
|
||||||
|
wifi_line=$(lspci -nn 2>/dev/null | grep -i '14e4:' | head -n1) || true
|
||||||
|
fi
|
||||||
if [ -n "$wifi_line" ]; then
|
if [ -n "$wifi_line" ]; then
|
||||||
WIFI_CHIPSET="$wifi_line"
|
WIFI_CHIPSET="$wifi_line"
|
||||||
WIFI_DESC=$(echo "$wifi_line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
|
WIFI_DESC=$(echo "$wifi_line" | sed -E 's/^.*\]: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev [0-9a-fA-F]+\)//')
|
||||||
fi
|
fi
|
||||||
|
# Layer 4: USB WiFi adapter (no PCI device)
|
||||||
|
if [ -z "$wifi_line" ] && command -v lsusb &>/dev/null; then
|
||||||
|
local usb_wifi
|
||||||
|
usb_wifi=$(lsusb 2>/dev/null | grep -iE 'wireless|wifi|wlan|802\.11' | head -n1) || true
|
||||||
|
if [ -n "$usb_wifi" ]; then
|
||||||
|
WIFI_CHIPSET="$usb_wifi"
|
||||||
|
WIFI_DESC=$(echo "$usb_wifi" | sed 's/^.*ID //')
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# ── Safeguard: if ip is not installed, skip runtime parsing ──
|
# ── Safeguard: if ip is not installed, skip runtime parsing ──
|
||||||
if ! command -v ip &>/dev/null; then
|
if ! command -v ip &>/dev/null; then
|
||||||
@@ -299,7 +329,7 @@ detect_network() {
|
|||||||
ETH_IPS+=("${ip4:-}")
|
ETH_IPS+=("${ip4:-}")
|
||||||
ETH_DESCS+=("${ETH_DESC:-}")
|
ETH_DESCS+=("${ETH_DESC:-}")
|
||||||
;;
|
;;
|
||||||
wl*|wlp*|wlo*)
|
wl*|wlp*|wlo*|wlan*)
|
||||||
ip4=$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}')
|
ip4=$(ip -4 -o addr show "$iface" 2>/dev/null | awk '{print $4}')
|
||||||
ssid=""
|
ssid=""
|
||||||
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
|
[ "$state" = "UP" ] && ssid=$(iwgetid -r "$iface" 2>/dev/null || true)
|
||||||
@@ -335,23 +365,31 @@ detect_displayserver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Storage summary via lsblk (NVMe / SSD / HDD)
|
# Storage summary via lsblk (NVMe / SSD / HDD / USB-SD)
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
detect_storage() {
|
detect_storage() {
|
||||||
local parts=()
|
local parts=()
|
||||||
local name size rota type
|
local name size rota type rm
|
||||||
|
|
||||||
while read -r name size rota; do
|
while read -r name size rota type; do
|
||||||
[ "$name" = "NAME" ] && continue
|
[ "$name" = "NAME" ] && continue
|
||||||
|
echo "$name" | grep -q "zram" && continue
|
||||||
|
[ "$type" = "loop" ] || [ "$type" = "rom" ] && continue
|
||||||
|
|
||||||
if echo "$name" | grep -q "nvme"; then
|
if echo "$name" | grep -q "nvme"; then
|
||||||
type="NVMe"
|
type="NVMe"
|
||||||
elif [ "$rota" = "1" ]; then
|
elif [ "$rota" = "1" ]; then
|
||||||
type="HDD"
|
type="HDD"
|
||||||
|
else
|
||||||
|
rm=$(cat /sys/block/"$name"/removable 2>/dev/null || echo 0)
|
||||||
|
if [ "$rm" = "1" ]; then
|
||||||
|
type="USB/SD"
|
||||||
else
|
else
|
||||||
type="SSD"
|
type="SSD"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
parts+=("${size} ${type}")
|
parts+=("${size} ${type}")
|
||||||
done < <(lsblk -d -o NAME,SIZE,ROTA 2>/dev/null || true)
|
done < <(lsblk -d -o NAME,SIZE,ROTA,TYPE -e 7,11 2>/dev/null || true)
|
||||||
|
|
||||||
if [ ${#parts[@]} -eq 0 ]; then
|
if [ ${#parts[@]} -eq 0 ]; then
|
||||||
STORAGE_SUMMARY="No disks detected"
|
STORAGE_SUMMARY="No disks detected"
|
||||||
@@ -505,16 +543,56 @@ _confirm_custom() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_msg() {
|
_msg() {
|
||||||
whiptail --title "$1" --msgbox "$2" "${3:-10}" "${4:-65}"
|
whiptail --title "$1" --msgbox "$2" "${3:-10}" "${4:-65}" || true
|
||||||
}
|
}
|
||||||
|
|
||||||
# Blocks 2-4: clear → run → pause
|
_msg_red() {
|
||||||
|
whiptail --colors --title "\Z1$1\Zn" --msgbox "\Z1$2\Zn" "${3:-12}" "${4:-70}" || true
|
||||||
|
}
|
||||||
|
|
||||||
|
_menu() {
|
||||||
|
local title="$1" text="$2" h="$3" w="$4" lh="$5"; shift 5
|
||||||
|
whiptail --title "$title" --menu "$text" "$h" "$w" "$lh" "$@" 3>&1 1>&2 2>&3 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
_checklist() {
|
||||||
|
local title="$1" text="$2" h="$3" w="$4" lh="$5"; shift 5
|
||||||
|
whiptail --title "$title" --checklist "$text" "$h" "$w" "$lh" "$@" 3>&1 1>&2 2>&3 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
_inputbox() {
|
||||||
|
whiptail --title "$1" --inputbox "$2" "${3:-10}" "${4:-60}" "${5:-}" 3>&1 1>&2 2>&3 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
_validate_sudoers() {
|
||||||
|
local content="$1" dest="$2"
|
||||||
|
local tmpfile
|
||||||
|
tmpfile=$(mktemp) || return 1
|
||||||
|
echo "$content" > "$tmpfile"
|
||||||
|
if ! /usr/sbin/visudo -cf "$tmpfile" &>/dev/null; then
|
||||||
|
local err
|
||||||
|
err=$(/usr/sbin/visudo -cf "$tmpfile" 2>&1 || true)
|
||||||
|
rm -f "$tmpfile"
|
||||||
|
_msg "Sudoers Error" "Invalid sudoers syntax in:\n\n${err}\n\nFile was NOT written.\nThis prevents broken sudo access." 12 70
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
sudo cp "$tmpfile" "$dest"
|
||||||
|
sudo chmod 0440 "$dest"
|
||||||
|
rm -f "$tmpfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
_pause() {
|
||||||
|
local msg="${1:-Press Enter to continue...}"
|
||||||
|
echo -e "$msg"
|
||||||
|
read -r || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# Blocks 2-4: run → pause
|
||||||
_run_cmd() {
|
_run_cmd() {
|
||||||
local title="$1" command="$2" success_msg="${3:-Running...}"
|
local title="$1" command="$2" success_msg="${3:-Running...}"
|
||||||
clear
|
|
||||||
echo -e "${GREEN}[+]${NC} $success_msg"
|
echo -e "${GREEN}[+]${NC} $success_msg"
|
||||||
echo "──────────────────────────────────────────────"
|
echo "──────────────────────────────────────────────"
|
||||||
eval "$command"
|
bash -c "$command"
|
||||||
local rc=$?
|
local rc=$?
|
||||||
echo "──────────────────────────────────────────────"
|
echo "──────────────────────────────────────────────"
|
||||||
if [ $rc -eq 0 ]; then
|
if [ $rc -eq 0 ]; then
|
||||||
@@ -522,11 +600,10 @@ _run_cmd() {
|
|||||||
else
|
else
|
||||||
echo -e "${RED}[-]${NC} Failed (exit code: $rc)."
|
echo -e "${RED}[-]${NC} Failed (exit code: $rc)."
|
||||||
fi
|
fi
|
||||||
echo "Press [ENTER] to continue..."
|
_pause
|
||||||
read -r
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Blocks 1-4: confirm → clear → run → pause
|
# Blocks 1-4: confirm → run → pause
|
||||||
_run() {
|
_run() {
|
||||||
if _confirm "$1" "$2"; then
|
if _confirm "$1" "$2"; then
|
||||||
_run_cmd "$1" "$3" "$4"
|
_run_cmd "$1" "$3" "$4"
|
||||||
@@ -581,3 +658,84 @@ get_backports_kernel_version() {
|
|||||||
echo "unknown"
|
echo "unknown"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# Language helpers
|
||||||
|
# ----------------------------------
|
||||||
|
_detect_lang() {
|
||||||
|
local sys_lang
|
||||||
|
sys_lang=$(echo "${LANG:-en}" | cut -c1-2 | tr '[:upper:]' '[:lower:]')
|
||||||
|
echo "$sys_lang"
|
||||||
|
}
|
||||||
|
|
||||||
|
_detect_lang_pkg() {
|
||||||
|
local base="$1"
|
||||||
|
local lang2
|
||||||
|
lang2=$(_detect_lang)
|
||||||
|
|
||||||
|
[ "$lang2" = "en" ] && echo "" && return
|
||||||
|
|
||||||
|
local full="${LANG%%.*}"
|
||||||
|
local hyphenated_full
|
||||||
|
hyphenated_full=$(echo "$full" | tr '[:upper:]' '[:lower:]' | tr '_' '-')
|
||||||
|
local pkg
|
||||||
|
|
||||||
|
pkg=$(apt-cache search "^${base}-${hyphenated_full}$" 2>/dev/null | awk 'NR==1{print $1}')
|
||||||
|
[ -z "$pkg" ] && pkg=$(apt-cache search "^${base}-${lang2}$" 2>/dev/null | awk 'NR==1{print $1}')
|
||||||
|
[ -z "$pkg" ] && pkg=$(apt-cache search "^${base}-all$" 2>/dev/null | awk 'NR==1{print $1}')
|
||||||
|
|
||||||
|
echo "$pkg"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# Network connectivity check
|
||||||
|
# ----------------------------------
|
||||||
|
_check_network() {
|
||||||
|
local target="${1:-deb.debian.org}"
|
||||||
|
|
||||||
|
if command -v ping &>/dev/null; then
|
||||||
|
ping -c 1 -W 3 "$target" &>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v wget &>/dev/null; then
|
||||||
|
wget -q --timeout=5 --spider "http://${target}" &>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v curl &>/dev/null; then
|
||||||
|
curl -s --connect-timeout 5 -o /dev/null "http://${target}" &>/dev/null && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------
|
||||||
|
# LightDM configuration
|
||||||
|
# ----------------------------------
|
||||||
|
_configure_lightdm() {
|
||||||
|
command -v lightdm &>/dev/null || return 0
|
||||||
|
|
||||||
|
if _confirm "LightDM" "Configure LightDM to show the user list on the login screen?\n\nThis disables greeter-hide-users."; then
|
||||||
|
if ! is_installed lightdm-gtk-greeter-settings; then
|
||||||
|
echo -e "${YELLOW}Installing lightdm-gtk-greeter-settings...${NC}"
|
||||||
|
sudo DEBIAN_FRONTEND=noninteractive apt install -y lightdm-gtk-greeter-settings
|
||||||
|
fi
|
||||||
|
|
||||||
|
local conf_dir="/etc/lightdm/lightdm.conf.d"
|
||||||
|
local conf_file="${conf_dir}/99-show-users.conf"
|
||||||
|
|
||||||
|
if [ -f "$conf_file" ] && grep -q '^greeter-hide-users=false' "$conf_file"; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo mkdir -p "$conf_dir"
|
||||||
|
printf '[Seat:*]\ngreeter-hide-users=false\n' | sudo tee "$conf_file" > /dev/null
|
||||||
|
echo -e "${GREEN}LightDM configured to show user list.${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Lazy system state refresh ──
|
||||||
|
refresh_system_state() {
|
||||||
|
detect_debian_version
|
||||||
|
detect_gpu
|
||||||
|
detect_cpu_ram
|
||||||
|
}
|
||||||
|
|||||||
+6
-13
@@ -12,18 +12,11 @@ install_zram() {
|
|||||||
local half_ram_mb=$(( ((RAM_KB / 1024 / 1024 + 1) / 2) * 1024 ))
|
local half_ram_mb=$(( ((RAM_KB / 1024 / 1024 + 1) / 2) * 1024 ))
|
||||||
|
|
||||||
local algo
|
local algo
|
||||||
algo=$(whiptail --title "ZRAM Compression" --menu \
|
algo=$(_menu "ZRAM Configuration" \
|
||||||
"ZRAM compresses a portion of RAM into compressed swap,\
|
"ZRAM creates a compressed block device in RAM to use as swap. This reduces disk I/O and can significantly improve responsiveness on systems with limited memory (e.g., 4GB RAM or less), at the cost of a small amount of CPU usage." \
|
||||||
effectively increasing available memory.
|
|
||||||
|
|
||||||
Useful for systems with limited RAM or when you need
|
|
||||||
more swap space without disk writes.
|
|
||||||
|
|
||||||
Choose compression algorithm:" \
|
|
||||||
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||||
"lz4" "Fastest, low CPU (recommended)" \
|
"lz4" "Fastest compression/decompression. Lowest CPU overhead. (Default)" \
|
||||||
"zstd" "Better ratio, more CPU" \
|
"zstd" "Higher compression ratio. Saves slightly more memory but uses more CPU.")
|
||||||
3>&1 1>&2 2>&3)
|
|
||||||
|
|
||||||
if [ -z "$algo" ]; then
|
if [ -z "$algo" ]; then
|
||||||
echo "ZRAM configuration cancelled."
|
echo "ZRAM configuration cancelled."
|
||||||
@@ -34,8 +27,7 @@ Choose compression algorithm:" \
|
|||||||
if _confirm "ZRAM Size" "Use recommended size for ZRAM? (${half_ram_mb} MB out of ${RAM_SUMMARY})"; then
|
if _confirm "ZRAM Size" "Use recommended size for ZRAM? (${half_ram_mb} MB out of ${RAM_SUMMARY})"; then
|
||||||
zram_size=$half_ram_mb
|
zram_size=$half_ram_mb
|
||||||
else
|
else
|
||||||
zram_size=$(whiptail --title "ZRAM Size" --inputbox \
|
zram_size=$(_inputbox "ZRAM Size" "Enter ZRAM size in MB:" 8 60 "$half_ram_mb")
|
||||||
"Enter ZRAM size in MB:" 8 60 "$half_ram_mb" 3>&1 1>&2 2>&3)
|
|
||||||
if [ -z "$zram_size" ] || ! [[ "$zram_size" =~ ^[0-9]+$ ]] || [ "$zram_size" -eq 0 ]; then
|
if [ -z "$zram_size" ] || ! [[ "$zram_size" =~ ^[0-9]+$ ]] || [ "$zram_size" -eq 0 ]; then
|
||||||
echo "ZRAM configuration cancelled."
|
echo "ZRAM configuration cancelled."
|
||||||
return 0
|
return 0
|
||||||
@@ -65,4 +57,5 @@ EOF
|
|||||||
sudo zramctl
|
sudo zramctl
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${GREEN}You can verify with: sudo zramctl${NC}"
|
echo -e "${GREEN}You can verify with: sudo zramctl${NC}"
|
||||||
|
_pause
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user