mirror of
https://github.com/stornic56/debianito-post-install.git
synced 2026-07-16 05:49:49 +00:00
add Java JDK/JRE selection and patches
- Created dedicated `extras/java.sh` module for modular Temurin/Adoptium repository handling and isolated GPG key management. - Implemented selective JRE/JDK installation paths: Gaming (Minecraft) vs Development environments with version control selectors. - Enhanced user group membership logic (`_ensure_sudo_group`) to auto-configure administrative privileges on fresh installs. - Introduced maintenance-friendly passwordless sudo for `apt`, `systemctl`, and shutdown commands via `/etc/sudoers.d/`. - Added home directory ownership repair utility to fix root-owned files in user directories after improper `sudo` usage. - Enabled visual password feedback (`pwfeedback`) toggle for enhanced terminal usability during authentication prompts. - Refactored Debian 13/Trixie repository sourcing logic to ensure idempotency and prevent backports/duplicate sources conflicts. - Updated Bullseye legacy modules (extras.sh, repos.sh) to exclude deprecated packages (`hx`, `vscodium`) and enforce Firefox ESR defaults. - Cleaned repository configurations by removing obsolete `bullseye-updates` source entries to prevent dependency conflicts. - Implemented NVTOP conditional detection logic ensuring display only on active Nvidia drivers or supported architectures (Trixie/Bookworm). - Corrected `/modules/bullseye/extras.sh` menu mappings (Programming, Dev Tools) and verified package lists excluding incompatible tools (`hx`, `vscodium`). - Integrated ClamAV security module with daemon state management and background scan execution flows in all Security menus. - update README.md
This commit is contained in:
+236
-150
@@ -49,43 +49,34 @@ Instalar?"; then
|
||||
# ======================================================================
|
||||
|
||||
_cat_customization_bullseye() {
|
||||
local items=()
|
||||
if [ -f "${MODULES_DIR}/extras/themes/icons/icons.sh" ]; then
|
||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
||||
local sub
|
||||
sub=$(whiptail --title "Customization (Bullseye)" --menu \
|
||||
"Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
||||
"1" "Desktop Themes (GTK/KDE)" \
|
||||
"2" "Icon Themes" \
|
||||
"3" "Cursor Themes" \
|
||||
"4" "Fonts" \
|
||||
3>&1 1>&2 2>&3)
|
||||
[ -z "$sub" ] && return
|
||||
case $sub in
|
||||
1) _cat_themes_bullseye ;;
|
||||
2) _cat_icons_bullseye ;;
|
||||
3) _cat_cursors_bullseye ;;
|
||||
4) _cat_fonts_bullseye ;;
|
||||
esac
|
||||
else
|
||||
_msg "Customization" "Themes submodules not found." 8 50
|
||||
fi
|
||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
||||
local sub
|
||||
sub=$(whiptail --title "Customization (Bullseye)" --menu \
|
||||
"Select type:" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
||||
"1" "Desktop Themes (GTK/KDE)" \
|
||||
"2" "Icon Themes" \
|
||||
"3" "Cursor Themes" \
|
||||
"4" "Fonts" \
|
||||
3>&1 1>&2 2>&3)
|
||||
[ -z "$sub" ] && return
|
||||
case $sub in
|
||||
1) _cat_themes_bullseye ;;
|
||||
2) _cat_icons_bullseye ;;
|
||||
3) _cat_cursors_bullseye ;;
|
||||
4) _cat_fonts_bullseye ;;
|
||||
esac
|
||||
}
|
||||
|
||||
_cat_themes_bullseye() {
|
||||
local theme_state; theme_state=$(_state "breeze")
|
||||
local numix_state; numix_state=$(_state "numix-gtk-theme")
|
||||
|
||||
if [ "$theme_state" = "OFF" ] && [ "$numix_state" = "OFF" ]; then
|
||||
theme_state="ON"
|
||||
fi
|
||||
|
||||
local choices
|
||||
choices=$(whiptail --title "Desktop Themes (Bullseye)" --checklist \
|
||||
"Available themes in Bullseye repos ($TUI_ALTO linea):" \
|
||||
$TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"breeze" "Breeze GTK theme (KDE)$(_inst breeze)" "$theme_state" \
|
||||
"numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$numix_state" \
|
||||
"Select desktop themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"arc-theme" "Arc GTK theme$(_inst arc-theme)" "$(_state arc-theme)" \
|
||||
"blackbird-gtk-theme" "Blackbird GTK theme$(_inst blackbird-gtk-theme)" "$(_state blackbird-gtk-theme)" \
|
||||
"bluebird-gtk-theme" "Bluebird GTK theme$(_inst bluebird-gtk-theme)" "$(_state bluebird-gtk-theme)" \
|
||||
"breeze-gtk-theme" "Breeze GTK theme (KDE port)$(_inst breeze-gtk-theme)" "$(_state breeze-gtk-theme)" \
|
||||
"greybird-gtk-theme" "Greybird GTK theme$(_inst greybird-gtk-theme)" "$(_state greybird-gtk-theme)" \
|
||||
"numix-gtk-theme" "Numix GTK theme$(_inst numix-gtk-theme)" "$(_state numix-gtk-theme)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
@@ -97,19 +88,21 @@ _cat_themes_bullseye() {
|
||||
}
|
||||
|
||||
_cat_icons_bullseye() {
|
||||
_msg "Icon Themes (Bullseye)" \
|
||||
"Adwaita, Humanity, DMZ y otros temas de iconos\n\
|
||||
están disponibles desde los repos oficiales.\n\n\
|
||||
Seleccione desde el menú de GNOME/KDE o instale\n\
|
||||
el paquete 'gnome-icon-theme' o 'breeze-icon-theme'." 12 60
|
||||
|
||||
local items=(
|
||||
"breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$(_state breeze-icon-theme)"
|
||||
"deepin-icon-theme" "Deepin icon theme$(_inst deepin-icon-theme)" "$(_state deepin-icon-theme)"
|
||||
"moka-icon-theme" "Moka icon theme$(_inst moka-icon-theme)" "$(_state moka-icon-theme)"
|
||||
"numix-icon-theme" "Numix icon theme$(_inst 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)"
|
||||
"obsidian-icon-theme" "Obsidian icon theme$(_inst obsidian-icon-theme)" "$(_state obsidian-icon-theme)"
|
||||
"papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$(_state papirus-icon-theme)"
|
||||
"paper-icon-theme" "Paper icon theme$(_inst paper-icon-theme)" "$(_state paper-icon-theme)"
|
||||
"suru-icon-theme" "Suru icon theme$(_inst suru-icon-theme)" "$(_state suru-icon-theme)"
|
||||
)
|
||||
local choices
|
||||
choices=$(whiptail --title "Icon Themes (Bullseye)" --checklist \
|
||||
"Available icon themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"gnome-icon-theme" "GNOME icon theme$(_inst gnome-icon-theme)" "$(_state gnome-icon-theme)" \
|
||||
"breeze-icon-theme" "Breeze icon theme$(_inst breeze-icon-theme)" "$(_state breeze-icon-theme)" \
|
||||
"papirus-icon-theme" "Papirus icon theme$(_inst papirus-icon-theme)" "$(_state papirus-icon-theme)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
"Select icon themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"${items[@]}" 3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||
@@ -122,10 +115,12 @@ el paquete 'gnome-icon-theme' o 'breeze-icon-theme'." 12 60
|
||||
_cat_cursors_bullseye() {
|
||||
local choices
|
||||
choices=$(whiptail --title "Cursor Themes (Bullseye)" --checklist \
|
||||
"Available cursor themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"dmz-cursor-theme" "DMZ cursor theme$(_inst dmz-cursor-theme)" "$(_state dmz-cursor-theme)" \
|
||||
"breeze-cursor-theme" "Breeze cursor theme$(_inst breeze-cursor-theme)" "$(_state breeze-cursor-theme)" \
|
||||
"oxygen-cursor-theme" "Oxygen cursor theme$(_inst oxygen-cursor-theme)" "$(_state oxygen-cursor-theme)" \
|
||||
"Select cursor themes:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"breeze-cursor-theme" "Breeze cursors (KDE)$(_inst breeze-cursor-theme)" "$(_state breeze-cursor-theme)" \
|
||||
"chameleon-cursor-theme" "Chameleon cursors$(_inst chameleon-cursor-theme)" "$(_state chameleon-cursor-theme)" \
|
||||
"dmz-cursor-theme" "DMZ cursors$(_inst dmz-cursor-theme)" "$(_state dmz-cursor-theme)" \
|
||||
"oxygencursors" "Oxygen cursors (KDE legacy)$(_inst oxygencursors)" "$(_state oxygencursors)" \
|
||||
"xcursor-themes" "X11 base cursors$(_inst xcursor-themes)" "$(_state xcursor-themes)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
@@ -155,19 +150,32 @@ _cat_fonts_bullseye() {
|
||||
}
|
||||
|
||||
_cat_download_bullseye() {
|
||||
local choices
|
||||
choices=$(whiptail --title "Download & Torrent (Bullseye)" --checklist \
|
||||
local choices1 choices2=""
|
||||
|
||||
choices1=$(whiptail --title "Downloaders" --checklist \
|
||||
"Select download tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$(_state aria2)" \
|
||||
"filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$(_state filezilla)" \
|
||||
"qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$(_state qbittorrent)" \
|
||||
"transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$(_state transmission-gtk)" \
|
||||
"transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$(_state transmission-qt)" \
|
||||
"deluge" "BitTorrent client (GTK)$(_inst deluge)" "$(_state deluge)" \
|
||||
"aria2" "Multiprotocol downloader (CLI)$(_inst aria2)" "$(_state aria2)" \
|
||||
"filezilla" "FTP/SFTP client (GUI)$(_inst filezilla)" "$(_state filezilla)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||
|
||||
choices2=$(whiptail --title "Torrent Clients" --checklist \
|
||||
"Select torrent clients:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"deluge" "BitTorrent client (GTK)$(_inst deluge)" "$(_state deluge)" \
|
||||
"deluged" "BitTorrent daemon/server$(_inst deluged)" "$(_state deluged)" \
|
||||
"mktorrent" "Torrent metainfo creator (CLI)$(_inst mktorrent)" "$(_state mktorrent)" \
|
||||
"qbittorrent" "BitTorrent client (Qt)$(_inst qbittorrent)" "$(_state qbittorrent)" \
|
||||
"qbittorrent-nox" "BitTorrent WebUI/CLI$(_inst qbittorrent-nox)" "$(_state qbittorrent-nox)" \
|
||||
"transmission-cli" "BitTorrent client (CLI)$(_inst transmission-cli)" "$(_state transmission-cli)" \
|
||||
"transmission-gtk" "BitTorrent client (GTK)$(_inst transmission-gtk)" "$(_state transmission-gtk)" \
|
||||
"transmission-qt" "BitTorrent client (Qt)$(_inst transmission-qt)" "$(_state transmission-qt)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
|
||||
local cleaned
|
||||
cleaned=$(echo "$choices1 $choices2" | tr -d '"')
|
||||
[ -z "$cleaned" ] && { echo "No download tools selected."; return; }
|
||||
|
||||
for pkg in $cleaned; do
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
@@ -175,35 +183,46 @@ _cat_download_bullseye() {
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
done
|
||||
echo -e "${GREEN}Download tools installed.${NC}"
|
||||
echo -e "${GREEN}Download & network tools installed.${NC}"
|
||||
}
|
||||
|
||||
_cat_internet_bullseye() {
|
||||
local ff_state; ff_state=$(_state "firefox-esr")
|
||||
local tbird_state; tbird_state=$(_state "thunderbird")
|
||||
local chr_state; chr_state=$(_state "chromium")
|
||||
|
||||
local choices
|
||||
choices=$(whiptail --title "Internet (Bullseye)" --checklist \
|
||||
"Select browsers, email:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"firefox-esr" "Firefox ESR (official Debian)$(_inst firefox-esr)" "$ff_state" \
|
||||
"chromium" "Chromium web browser$(_inst chromium)" "$chr_state" \
|
||||
"thunderbird" "Email client$(_inst thunderbird)" "$tbird_state" \
|
||||
"dillo" "Lightweight graphical browser$(_inst dillo)" "$(_state dillo)" \
|
||||
"elinks" "Text-mode web browser$(_inst elinks)" "$(_state elinks)" \
|
||||
"konqueror" "KDE file manager / web browser$(_inst konqueror)" "$(_state konqueror)" \
|
||||
"w3m" "Text-mode browser + deps$(_inst w3m)" "$(_state w3m)" \
|
||||
"torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$(_state torbrowser-launcher)" \
|
||||
"chromium" "Chromium web browser$(_inst chromium)" "$(_state chromium)" \
|
||||
"dillo" "Lightweight graphical browser$(_inst dillo)" "$(_state dillo)" \
|
||||
"elinks" "Text-mode web browser$(_inst elinks)" "$(_state elinks)" \
|
||||
"epiphany-browser" "GNOME web browser$(_inst epiphany-browser)" "$(_state epiphany-browser)" \
|
||||
"falkon" "KDE web browser (QtWebEngine)$(_inst falkon)" "$(_state falkon)" \
|
||||
"firefox-esr" "Firefox ESR (official Debian)$(_inst firefox-esr)" "$(_state firefox-esr)" \
|
||||
"konqueror" "KDE file manager / web browser$(_inst konqueror)" "$(_state konqueror)" \
|
||||
"qutebrowser" "Keyboard-driven browser (Qt)$(_inst qutebrowser)" "$(_state qutebrowser)" \
|
||||
"thunderbird" "Email client$(_inst thunderbird)" "$(_state thunderbird)" \
|
||||
"torbrowser-launcher" "Tor Browser launcher$(_inst torbrowser-launcher)" "$(_state torbrowser-launcher)" \
|
||||
"w3m" "Text-mode browser + deps$(_inst w3m)" "$(_state w3m)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||
for pkg in $cleaned; do
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
else
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
case $pkg in
|
||||
w3m)
|
||||
local need=()
|
||||
! is_installed "w3m" && need+=("w3m")
|
||||
! is_installed "w3m-img" && need+=("w3m-img")
|
||||
! is_installed "ca-certificates" && need+=("ca-certificates")
|
||||
! is_installed "xsel" && need+=("xsel")
|
||||
[ ${#need[@]} -gt 0 ] && _run_install_batch "${need[@]}" || echo "Already installed."
|
||||
;;
|
||||
*)
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
else
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo -e "${GREEN}Internet tools installed.${NC}"
|
||||
}
|
||||
@@ -232,14 +251,19 @@ _cat_design_bullseye() {
|
||||
local choices
|
||||
choices=$(whiptail --title "Multimedia & Design (Bullseye)" --checklist \
|
||||
"Select multimedia and design tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"audacity" "Audio editor/recorder$(_inst audacity)" "$(_state audacity)" \
|
||||
"blender" "3D modeling/animation suite$(_inst blender)" "$(_state blender)" \
|
||||
"ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$(_state ffmpeg)" \
|
||||
"gimp" "Image editor$(_inst gimp)" "$(_state gimp)" \
|
||||
"inkscape" "Vector graphics editor$(_inst inkscape)" "$(_state inkscape)" \
|
||||
"kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$(_state kdenlive)" \
|
||||
"obs-studio" "Streaming/recording studio$(_inst obs-studio)" "$(_state obs-studio)" \
|
||||
"scribus" "Desktop publishing$(_inst scribus)" "$(_state scribus)" \
|
||||
"ardour" "Digital audio workstation$(_inst ardour)" "$(_state ardour)" \
|
||||
"audacity" "Audio editor/recorder$(_inst audacity)" "$(_state audacity)" \
|
||||
"blender" "3D modeling/animation suite$(_inst blender)" "$(_state blender)" \
|
||||
"ffmpeg" "Multimedia framework (CLI)$(_inst ffmpeg)" "$(_state ffmpeg)" \
|
||||
"gimp" "Image editor$(_inst gimp)" "$(_state gimp)" \
|
||||
"handbrake" "Video transcoder (DVD ripper)$(_inst handbrake)" "$(_state handbrake)" \
|
||||
"inkscape" "Vector graphics editor$(_inst inkscape)" "$(_state inkscape)" \
|
||||
"kdenlive" "Video editor (KDE)$(_inst kdenlive)" "$(_state kdenlive)" \
|
||||
"krita" "Digital painting/illustration$(_inst krita)" "$(_state krita)" \
|
||||
"obs-studio" "Screen recording/streaming$(_inst obs-studio)" "$(_state obs-studio)" \
|
||||
"openshot-qt" "Video editor (simple)$(_inst openshot-qt)" "$(_state openshot-qt)" \
|
||||
"scribus" "Desktop publishing (DTP)$(_inst scribus)" "$(_state scribus)" \
|
||||
"shotcut" "Video editor (cross-platform)$(_inst shotcut)" "$(_state shotcut)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
@@ -251,24 +275,22 @@ _cat_design_bullseye() {
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
done
|
||||
echo -e "${GREEN}Design tools installed.${NC}"
|
||||
echo -e "${GREEN}Multimedia & design tools installed.${NC}"
|
||||
}
|
||||
|
||||
_cat_programming_bullseye() {
|
||||
local choices
|
||||
choices=$(whiptail --title "Programming (Bullseye)" --checklist \
|
||||
"Select programming tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"build-essential" "GCC/Clang compilers$(_inst build-essential)" "$(_state build-essential)" \
|
||||
"python3" "Python 3 interpreter$(_inst python3)" "$(_state python3)" \
|
||||
"python3-pip" "Python 3 package manager$(_inst python3-pip)" "$(_state python3-pip)" \
|
||||
"nodejs" "Node.js (Debian repo)$(_inst nodejs)" "$(_state nodejs)" \
|
||||
"npm" "Node.js package manager$(_inst npm)" "$(_state npm)" \
|
||||
"openjdk-17-jdk" "OpenJDK 17 JDK$(_inst openjdk-17-jdk)" "$(_state openjdk-17-jdk)" \
|
||||
"git" "Version control system$(_inst git)" "$(_state git)" \
|
||||
"vim" "Text editor (Vim)$(_inst vim)" "$(_state vim)" \
|
||||
"nano" "Text editor (Nano)$(_inst nano)" "$(_state nano)" \
|
||||
"geany" "Lightweight IDE$(_inst geany)" "$(_state geany)" \
|
||||
"codeblocks" "Cross-platform IDE$(_inst codeblocks)" "$(_state codeblocks)" \
|
||||
choices=$(whiptail --title "Code Editors & IDEs (Bullseye)" --checklist \
|
||||
"Select editors and IDEs:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"vim" "Classic terminal editor$(_inst vim)" "$(_state vim)" \
|
||||
"vim-gtk3" "Vim with GTK3 GUI$(_inst vim-gtk3)" "$(_state vim-gtk3)" \
|
||||
"neovim" "Modern vim fork$(_inst neovim)" "$(_state neovim)" \
|
||||
"nano" "Simple terminal editor$(_inst nano)" "$(_state nano)" \
|
||||
"emacs" "Extensible editor / IDE$(_inst emacs)" "$(_state emacs)" \
|
||||
"kate" "KDE advanced text editor$(_inst kate)" "$(_state kate)" \
|
||||
"mousepad" "Xfce text editor$(_inst mousepad)" "$(_state mousepad)" \
|
||||
"gedit" "GNOME text editor$(_inst gedit)" "$(_state gedit)" \
|
||||
"geany" "Lightweight IDE$(_inst geany)" "$(_state geany)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
@@ -280,57 +302,120 @@ _cat_programming_bullseye() {
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
done
|
||||
echo -e "${GREEN}Programming tools installed.${NC}"
|
||||
echo -e "${GREEN}Code editors & IDEs installed.${NC}"
|
||||
}
|
||||
|
||||
_cat_dev_bullseye() {
|
||||
local choices
|
||||
choices=$(whiptail --title "Servers & Dev Tools (Bullseye)" --checklist \
|
||||
"Select development tools and servers:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"apache2" "Apache web server$(_inst apache2)" "$(_state apache2)" \
|
||||
"build-essential" "C/C++ build tools (gcc, make)$(_inst build-essential)" "$(_state build-essential)" \
|
||||
"docker" "Docker container runtime$(_inst docker.io)" "$(_state docker.io)" \
|
||||
"mariadb-server" "MariaDB database server$(_inst mariadb-server)" "$(_state mariadb-server)" \
|
||||
"netcat-openbsd" "TCP/IP networking utility$(_inst netcat-openbsd)" "$(_state netcat-openbsd)" \
|
||||
"nginx" "Nginx web server$(_inst nginx)" "$(_state nginx)" \
|
||||
"openssh-server" "SSH server$(_inst openssh-server)" "$(_state openssh-server)" \
|
||||
"openssl" "OpenSSL cryptography toolkit$(_inst openssl)" "$(_state openssl)" \
|
||||
"postgresql" "PostgreSQL database server$(_inst postgresql)" "$(_state postgresql)" \
|
||||
"python3-pip" "Python 3 pip + venv + dev$(_inst python3-pip)" "$(_state python3-pip)" \
|
||||
"redis-server" "Redis key-value store$(_inst redis-server)" "$(_state redis-server)" \
|
||||
"sqlite3" "SQLite database engine$(_inst sqlite3)" "$(_state sqlite3)" \
|
||||
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)$(_any_jdk_installed_desc)" "$(_any_jdk_state)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||
for pkg in $cleaned; do
|
||||
case $pkg in
|
||||
docker)
|
||||
local need=()
|
||||
! is_installed "docker.io" && need+=("docker.io")
|
||||
! is_installed "docker-compose" && need+=("docker-compose")
|
||||
if [ ${#need[@]} -gt 0 ]; then
|
||||
_run_install_batch "${need[@]}"
|
||||
else
|
||||
echo "Docker already installed."
|
||||
fi
|
||||
;;
|
||||
python3-pip)
|
||||
local need=()
|
||||
! is_installed "python3-pip" && need+=("python3-pip")
|
||||
! is_installed "python3-venv" && need+=("python3-venv")
|
||||
! is_installed "python3-dev" && need+=("python3-dev")
|
||||
if [ ${#need[@]} -gt 0 ]; then
|
||||
_run_install_batch "${need[@]}"
|
||||
else
|
||||
echo "Python 3 tools already installed."
|
||||
fi
|
||||
;;
|
||||
openjdk-dev-env)
|
||||
_install_dev_java
|
||||
;;
|
||||
*)
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
else
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo -e "${GREEN}Servers & dev tools installed.${NC}"
|
||||
}
|
||||
|
||||
_cat_security_bullseye() {
|
||||
local choices
|
||||
choices=$(whiptail --title "Security & Networking (Bullseye)" --checklist \
|
||||
"Select security tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"nmap" "Network scanner$(_inst nmap)" "$(_state nmap)" \
|
||||
"wireshark" "Packet analyzer$(_inst wireshark)" "$(_state wireshark)" \
|
||||
"nikto" "Web server scanner$(_inst nikto)" "$(_state nikto)" \
|
||||
"sqlmap" "SQL injection tool$(_inst sqlmap)" "$(_state sqlmap)" \
|
||||
"gobuster" "Directory/file brute-forcer$(_inst gobuster)" "$(_state gobuster)" \
|
||||
"hydra" "Login cracker$(_inst hydra)" "$(_state hydra)" \
|
||||
"john" "John the Ripper password cracker$(_inst john)" "$(_state john)" \
|
||||
"aircrack-ng" "Wireless security tool$(_inst aircrack-ng)" "$(_state aircrack-ng)" \
|
||||
"Select security and networking tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"wireshark" "Network protocol analyzer (GUI)$(_inst wireshark)" "$(_state wireshark)" \
|
||||
"tcpdump" "Command-line packet analyzer$(_inst tcpdump)" "$(_state tcpdump)" \
|
||||
"fail2ban" "Brute-force protection daemon$(_inst fail2ban)" "$(_state fail2ban)" \
|
||||
"ufw" "Uncomplicated firewall$(_inst ufw)" "$(_state ufw)" \
|
||||
"clamav" "Antivirus engine (ClamAV)$(_inst clamav)" "$(_state clamav)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||
for pkg in $cleaned; do
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
else
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
case $pkg in
|
||||
clamav)
|
||||
_install_clamav
|
||||
;;
|
||||
*)
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
else
|
||||
echo "$pkg already installed."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
echo -e "${GREEN}Security tools installed.${NC}"
|
||||
echo -e "${GREEN}Security & networking tools installed.${NC}"
|
||||
}
|
||||
|
||||
_cat_general_bullseye() {
|
||||
local choices
|
||||
choices=$(whiptail --title "System Tools (Bullseye)" --checklist \
|
||||
"Select system utilities:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"compress" "Compression tools (zip, unrar, p7zip)$(_inst zip)" "$(_state zip)" \
|
||||
"conky" "System monitor for desktop$(_inst conky)" "$(_state conky)" \
|
||||
"cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$(_state cpu-x)" \
|
||||
"curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$(_state curl)" \
|
||||
"flatpak" "Flatpak sandbox (Bullseye native)$(_inst flatpak)" "$(_state flatpak)" \
|
||||
"fwupd" "Firmware update daemon$(_inst fwupd)" "$(_state fwupd)" \
|
||||
"gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$(_state gnome-disk-utility)" \
|
||||
"gparted" "Partition editor$(_inst gparted)" "$(_state gparted)" \
|
||||
"htop" "Interactive process viewer$(_inst htop)" "$(_state htop)" \
|
||||
"inxi" "System information tool$(_inst inxi)" "$(_state inxi)" \
|
||||
"kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$(_state virt-manager)" \
|
||||
"lshw" "List hardware details$(_inst lshw)" "$(_state lshw)" \
|
||||
"mc" "Midnight Commander$(_inst mc)" "$(_state mc)" \
|
||||
"ncdu" "Disk usage analyzer$(_inst ncdu)" "$(_state ncdu)" \
|
||||
"psensor" "Temperature monitor$(_inst psensor)" "$(_state psensor)" \
|
||||
"timeshift" "System restore snapshots$(_inst timeshift)" "$(_state timeshift)" \
|
||||
"tmux" "Terminal multiplexer$(_inst tmux)" "$(_state tmux)" \
|
||||
"wine" "Windows compatibility layer$(_inst wine)" "$(_state wine)" \
|
||||
"compress" "Compression tools (zip, unrar, p7zip)$(_inst zip)" "$(_state zip)" \
|
||||
"conky" "System monitor for desktop$(_inst conky)" "$(_state conky)" \
|
||||
"cpu-x" "CPU-X (alternative to CPU-Z)$(_inst cpu-x)" "$(_state cpu-x)" \
|
||||
"curl-wget" "HTTP transfer tools (curl, wget)$(_inst curl)" "$(_state curl)" \
|
||||
"flatpak" "Flatpak sandbox (Bullseye native)$(_inst flatpak)" "$(_state flatpak)" \
|
||||
"fwupd" "Firmware update daemon$(_inst fwupd)" "$(_state fwupd)" \
|
||||
"gnome-disk-utility" "Disk management GUI$(_inst gnome-disk-utility)" "$(_state gnome-disk-utility)" \
|
||||
"gparted" "Partition editor$(_inst gparted)" "$(_state gparted)" \
|
||||
"htop" "Interactive process viewer$(_inst htop)" "$(_state htop)" \
|
||||
"inxi" "System information tool$(_inst inxi)" "$(_state inxi)" \
|
||||
"kvm" "QEMU/KVM virtualization$(_inst virt-manager)" "$(_state virt-manager)" \
|
||||
"lshw" "List hardware details$(_inst lshw)" "$(_state lshw)" \
|
||||
"mc" "Midnight Commander$(_inst mc)" "$(_state mc)" \
|
||||
"ncdu" "Disk usage analyzer$(_inst ncdu)" "$(_state ncdu)" \
|
||||
"psensor" "Temperature monitor$(_inst psensor)" "$(_state psensor)" \
|
||||
"timeshift" "System restore snapshots$(_inst timeshift)" "$(_state timeshift)" \
|
||||
"tmux" "Terminal multiplexer$(_inst tmux)" "$(_state tmux)" \
|
||||
"wine" "Windows compatibility layer$(_inst wine)" "$(_state wine)" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
[ -z "$choices" ] && return
|
||||
@@ -345,9 +430,7 @@ _cat_general_bullseye() {
|
||||
! is_installed "unrar" && need+=("unrar")
|
||||
! is_installed "p7zip-full" && need+=("p7zip-full")
|
||||
! is_installed "p7zip-rar" && need+=("p7zip-rar")
|
||||
if [ ${#need[@]} -gt 0 ]; then
|
||||
_run_install_batch "${need[@]}"
|
||||
fi
|
||||
[ ${#need[@]} -gt 0 ] && _run_install_batch "${need[@]}"
|
||||
;;
|
||||
curl-wget)
|
||||
local need=()
|
||||
@@ -409,7 +492,7 @@ _cat_general_bullseye() {
|
||||
|
||||
_cat_fetch_bullseye() {
|
||||
local items=(
|
||||
"neofetch" "System info fetcher$(_inst neofetch)" "$(_state neofetch)"
|
||||
"neofetch" "System info fetcher$(_inst neofetch)" "$(_state neofetch)"
|
||||
"screenfetch" "System info (BSD/Linux)$(_inst screenfetch)" "$(_state screenfetch)"
|
||||
"linuxlogo" "Linux logo + system info$(_inst linuxlogo)" "$(_state linuxlogo)"
|
||||
)
|
||||
@@ -436,22 +519,24 @@ _cat_fetch_bullseye() {
|
||||
# ======================================================================
|
||||
install_extras_bullseye() {
|
||||
echo -e "${YELLOW}Extra software — Bullseye mode (official repos only).${NC}"
|
||||
_load_extras
|
||||
|
||||
while true; do
|
||||
local cat_choice
|
||||
cat_choice=$(whiptail --title "Extra Software — Bullseye" --menu \
|
||||
"Select a category:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
"0" "Essential Pack" \
|
||||
"1" "Customization System" \
|
||||
"2" "Download & Network" \
|
||||
"3" "Internet (Browsers, Email)" \
|
||||
"4" "Media Players" \
|
||||
"5" "Multimedia & Design" \
|
||||
"6" "Programming Applications" \
|
||||
"7" "Security & Networking" \
|
||||
"8" "System Tools" \
|
||||
"9" "Fetch / System Info" \
|
||||
"10" "Back to main menu" \
|
||||
"0" "Essential Pack" \
|
||||
"1" "Customization System" \
|
||||
"2" "Download & Network" \
|
||||
"3" "Internet (Browsers, Email)" \
|
||||
"4" "Media Players" \
|
||||
"5" "Multimedia & Design" \
|
||||
"6" "Code Editors & IDEs" \
|
||||
"7" "Servers & Dev Tools" \
|
||||
"8" "Security & Networking" \
|
||||
"9" "System Tools" \
|
||||
"10" "Fetch / System Info" \
|
||||
"11" "Back to main menu" \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
[ -z "$cat_choice" ] && return
|
||||
@@ -465,10 +550,11 @@ install_extras_bullseye() {
|
||||
4) _cat_players_bullseye ;;
|
||||
5) _cat_design_bullseye ;;
|
||||
6) _cat_programming_bullseye ;;
|
||||
7) _cat_security_bullseye ;;
|
||||
8) _cat_general_bullseye ;;
|
||||
9) _cat_fetch_bullseye ;;
|
||||
10) return ;;
|
||||
7) _cat_dev_bullseye ;;
|
||||
8) _cat_security_bullseye ;;
|
||||
9) _cat_general_bullseye ;;
|
||||
10) _cat_fetch_bullseye ;;
|
||||
11) return ;;
|
||||
esac
|
||||
clear
|
||||
done
|
||||
|
||||
+18
-16
@@ -116,18 +116,18 @@ install_gaming_bullseye() {
|
||||
|
||||
local enable_32bit=false
|
||||
if _confirm "32-bit Support" \
|
||||
"Habilitar arquitectura i386 para juegos?\n\n\
|
||||
Requieren los juegos nativos de 32 bits y ciertas\n\
|
||||
bibliotecas de emulación."; then
|
||||
"Enable i386 architecture for 32-bit games?\n\n\
|
||||
Required by Steam/Proton for 32-bit games.\n\
|
||||
Installs matching 32-bit graphics drivers."; then
|
||||
enable_32bit=true
|
||||
fi
|
||||
|
||||
if $enable_32bit; then
|
||||
echo "Activando soporte multiarquitectura i386..."
|
||||
echo "Enabling i386 multi-architecture support..."
|
||||
if ! dpkg --print-foreign-architectures | grep -q i386; then
|
||||
sudo dpkg --add-architecture i386
|
||||
fi
|
||||
_run_cmd "APT Update" "sudo apt update" "Actualizando listas..."
|
||||
_run_cmd "APT Update" "sudo apt update" "Updating package lists..."
|
||||
|
||||
if [ "$GPU_TYPE" = "nvidia" ]; then
|
||||
local nv32_pkg="nvidia-driver-libs:i386"
|
||||
@@ -139,10 +139,10 @@ bibliotecas de emulación."; then
|
||||
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}" \
|
||||
"Instalando librerías NVIDIA 32-bit..."
|
||||
"Installing NVIDIA 32-bit libraries..."
|
||||
fi
|
||||
else
|
||||
echo "nvidia-driver-libs:i386 no disponible en Bullseye."
|
||||
echo "nvidia-driver-libs:i386 not available on Bullseye."
|
||||
fi
|
||||
else
|
||||
# Mesa 32-bit
|
||||
@@ -158,20 +158,20 @@ bibliotecas de emulación."; then
|
||||
awk 'NR==3 {print $2; exit}')
|
||||
local comp_line="Components: Vulkan:i386, OpenGL:i386, GLX:i386, EGL:i386, VA-API:i386"
|
||||
|
||||
local msg="Mesa 32-bit drivers para gaming.\n\n"
|
||||
local msg="Mesa 32-bit drivers for gaming.\n\n"
|
||||
msg+="Source: Debian Bullseye Stable\n"
|
||||
msg+="Mesa ${ref_ver}\n"
|
||||
msg+="${comp_line}\n\n"
|
||||
msg+="Instalar drivers 32-bit?"
|
||||
msg+="Install 32-bit drivers?"
|
||||
|
||||
if _confirm "Mesa 32-bit" "$msg" 14 70; then
|
||||
_run_cmd "Mesa 32-bit" "sudo apt install -y ${mesa_32[*]}" \
|
||||
"Instalando Mesa 32-bit..."
|
||||
"Installing Mesa 32-bit..."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Gaming tools checklist (sin Steam ni Heroic)
|
||||
# Gaming tools checklist (no Steam, no Heroic)
|
||||
local choices
|
||||
choices=$(whiptail --title "Gaming Tools — Bullseye" --checklist \
|
||||
"Select gaming optimization tools:" $TUI_ALTO $TUI_ANCHO $TUI_ALTO_LISTA \
|
||||
@@ -179,6 +179,7 @@ bibliotecas de emulación."; then
|
||||
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
|
||||
"goverlay" "MangoHud config GUI" ON \
|
||||
"lutris" "Game launcher/manager" OFF \
|
||||
"java" "Java Runtimes (8, 17, 21)" OFF \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
if [ -z "$choices" ]; then
|
||||
@@ -192,20 +193,21 @@ bibliotecas de emulación."; then
|
||||
for pkg in $cleaned; do
|
||||
case $pkg in
|
||||
mangohud)
|
||||
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Instalando MangoHud..."
|
||||
_run_cmd "MangoHud" "sudo apt install -y mangohud" "Installing MangoHud..."
|
||||
if $enable_32bit; then
|
||||
local mh32_ver
|
||||
mh32_ver=$(apt-cache policy mangohud:i386 2>/dev/null | \
|
||||
awk 'NR==3 {print $2; exit}')
|
||||
if [ -n "$mh32_ver" ] && [ "$mh32_ver" != "(none)" ]; then
|
||||
_run_cmd "MangoHud" "sudo apt install -y mangohud:i386" \
|
||||
"Instalando MangoHud 32-bit..."
|
||||
"Installing MangoHud 32-bit..."
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
gamemode) _run_cmd "GameMode" "sudo apt install -y gamemode" "Instalando GameMode..." ;;
|
||||
goverlay) _run_cmd "GOverlay" "sudo apt install -y goverlay" "Instalando GOverlay..." ;;
|
||||
lutris) _run_cmd "Lutris" "sudo apt install -y lutris" "Instalando Lutris..." ;;
|
||||
gamemode) _run_cmd "GameMode" "sudo apt install -y gamemode" "Installing GameMode..." ;;
|
||||
goverlay) _run_cmd "GOverlay" "sudo apt install -y goverlay" "Installing GOverlay..." ;;
|
||||
lutris) _run_cmd "Lutris" "sudo apt install -y lutris" "Installing Lutris..." ;;
|
||||
java) _install_gaming_java ;;
|
||||
*) _run_install "$pkg" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
+12
-16
@@ -5,19 +5,19 @@
|
||||
configure_repos_bullseye() {
|
||||
echo -e "${YELLOW}Repository configuration — Debian 11 Bullseye${NC}"
|
||||
|
||||
local info="Configuración de repositorios para Debian 11 Bullseye.\n\n"
|
||||
info+="Se usarán los repositorios oficiales con componentes\n"
|
||||
info+="main, contrib y non-free (sin non-free-firmware).\n"
|
||||
info+="No se utiliza formato DEB822.\n"
|
||||
local info="Repository configuration for Debian 11 Bullseye.\n\n"
|
||||
info+="Official repositories will be used with components\n"
|
||||
info+="main, contrib and non-free (non-free-firmware excluded).\n"
|
||||
info+="DEB822 format is not used.\n"
|
||||
if $BULLSEYE_USE_ARCHIVE; then
|
||||
info+="\nModo Archive: Las URLs apuntarán a archive.debian.org\n"
|
||||
info+="(Bullseye LTS finalizó el 31 Ago 2026)."
|
||||
info+="\nArchive Mode: URLs will point to archive.debian.org\n"
|
||||
info+="(Bullseye LTS ended on 31 Aug 2026)."
|
||||
fi
|
||||
_msg "Repositorios — Bullseye" "$info" 12 65
|
||||
_msg "Repositories — Bullseye" "$info" 12 65
|
||||
|
||||
if [ -f /etc/apt/sources.list ]; then
|
||||
if ! _confirm "Repositorios" "Ya existe /etc/apt/sources.list.\n\nSobrescribir con la configuración de Bullseye?"; then
|
||||
echo "Manteniendo configuración actual."
|
||||
if ! _confirm "Repositories" "/etc/apt/sources.list already exists.\n\nOverwrite with Bullseye configuration?"; then
|
||||
echo "Keeping current configuration."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
@@ -34,21 +34,17 @@ configure_repos_bullseye() {
|
||||
content+="deb ${base_uri} bullseye main contrib non-free\n"
|
||||
content+="#deb-src ${base_uri} bullseye main contrib non-free\n\n"
|
||||
|
||||
content+="# Updates\n"
|
||||
content+="deb ${base_uri} bullseye-updates main contrib non-free\n"
|
||||
content+="#deb-src ${base_uri} bullseye-updates main contrib non-free\n\n"
|
||||
|
||||
content+="# Security\n"
|
||||
content+="deb ${security_uri} bullseye-security main contrib non-free\n"
|
||||
content+="#deb-src ${security_uri} bullseye-security main contrib non-free\n"
|
||||
|
||||
echo -e "$content" | sudo tee /etc/apt/sources.list > /dev/null
|
||||
|
||||
echo "Actualizando listas de paquetes..."
|
||||
echo "Updating package lists..."
|
||||
if sudo apt update; then
|
||||
echo -e "${GREEN}Repositorios de Debian 11 Bullseye configurados.${NC}"
|
||||
echo -e "${GREEN}Debian 11 Bullseye repositories configured.${NC}"
|
||||
else
|
||||
echo -e "${RED}apt update falló. Revise su conexión de red.${NC}"
|
||||
echo -e "${RED}apt update failed. Check your network connection.${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
+11
-9
@@ -35,11 +35,12 @@ install_extras() {
|
||||
"3" "Internet (Browsers, Email, VPN)" \
|
||||
"4" "Media Players" \
|
||||
"5" "Multimedia & Design" \
|
||||
"6" "Programming Applications" \
|
||||
"7" "Security & Networking" \
|
||||
"8" "System Tools" \
|
||||
"9" "Fetch / System Info" \
|
||||
"10" "Back to main menu" \
|
||||
"6" "Code Editors & IDEs" \
|
||||
"7" "Servers & Dev Tools" \
|
||||
"8" "Security & Networking" \
|
||||
"9" "System Tools" \
|
||||
"10" "Fetch / System Info" \
|
||||
"11" "Back to main menu" \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
[ -z "$cat_choice" ] && return
|
||||
@@ -53,10 +54,11 @@ install_extras() {
|
||||
4) _cat_players ;;
|
||||
5) _cat_design ;;
|
||||
6) _cat_programming ;;
|
||||
7) _cat_security ;;
|
||||
8) _cat_general ;;
|
||||
9) _cat_fetch ;;
|
||||
10) return ;;
|
||||
7) _cat_dev ;;
|
||||
8) _cat_security ;;
|
||||
9) _cat_general ;;
|
||||
10) _cat_fetch ;;
|
||||
11) return ;;
|
||||
esac
|
||||
clear
|
||||
done
|
||||
|
||||
@@ -8,3 +8,24 @@ _inst() {
|
||||
_state() {
|
||||
is_installed "$1" && echo "ON" || echo "OFF"
|
||||
}
|
||||
|
||||
_install_clamav() {
|
||||
if is_installed "clamav"; then
|
||||
echo "ClamAV already installed."
|
||||
return
|
||||
fi
|
||||
_run_install "clamav"
|
||||
echo -e "${GREEN}ClamAV installed.${NC}"
|
||||
|
||||
if _confirm "ClamAV" "Update virus signatures now (freshclam)?"; then
|
||||
sudo systemctl stop clamav-freshclam 2>/dev/null || true
|
||||
sudo freshclam || true
|
||||
sudo systemctl start clamav-freshclam 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if _confirm "ClamAV" "Run quick scan on /bin to verify engine works?"; then
|
||||
echo "Running background scan on /bin..."
|
||||
sudo clamscan --recursive --infected /bin &
|
||||
echo "Scan running in background (PID $!). Check results later."
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ _cat_dev() {
|
||||
local pip_state; pip_state=$(_state "python3-pip")
|
||||
local redis_state; redis_state=$(_state "redis-server")
|
||||
local sqlite_state; sqlite_state=$(_state "sqlite3")
|
||||
local jdk_desc; jdk_desc=$(_any_jdk_installed_desc)
|
||||
local jdk_state; jdk_state=$(_any_jdk_state)
|
||||
|
||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
||||
local choices
|
||||
@@ -35,6 +37,7 @@ _cat_dev() {
|
||||
"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" \
|
||||
"openjdk-dev-env" "Adoptium Temurin JDK (17, 21, 25 LTS)${jdk_desc}" "${jdk_state}" \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
|
||||
@@ -65,6 +68,9 @@ _cat_dev() {
|
||||
echo "Docker already installed."
|
||||
fi
|
||||
;;
|
||||
openjdk-dev-env)
|
||||
_install_dev_java
|
||||
;;
|
||||
*)
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
# java.sh — Adoptium Temurin repository setup and Java version selectors
|
||||
# License GPL v3
|
||||
|
||||
_ensure_adoptium_repo() {
|
||||
[ -f /etc/apt/sources.list.d/adoptium.list ] && return 0
|
||||
|
||||
local deps=()
|
||||
! is_installed "wget" && deps+=("wget")
|
||||
! is_installed "apt-transport-https" && deps+=("apt-transport-https")
|
||||
! is_installed "gpg" && deps+=("gpg")
|
||||
[ ${#deps[@]} -gt 0 ] && _run_install_batch "${deps[@]}"
|
||||
|
||||
wget -qO - "https://packages.adoptium.net/artifactory/api/gpg/key/public" \
|
||||
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/adoptium.gpg 2>/dev/null
|
||||
|
||||
local codename
|
||||
codename=$(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release)
|
||||
echo "deb https://packages.adoptium.net/artifactory/deb ${codename} main" \
|
||||
| sudo tee /etc/apt/sources.list.d/adoptium.list > /dev/null
|
||||
|
||||
sudo apt update \
|
||||
-o Dir::Etc::sourcelist=/etc/apt/sources.list.d/adoptium.list \
|
||||
-o Dir::Etc::sourceparts="-" \
|
||||
2>/dev/null || true
|
||||
}
|
||||
|
||||
_install_gaming_java() {
|
||||
local ver
|
||||
ver=$(whiptail --title "Java Runtimes for Gaming" --menu \
|
||||
"Select Java version:" 12 65 3 \
|
||||
"8" "Java 8 — For classic mods & Minecraft <= 1.16.5" \
|
||||
"17" "Java 17 — For Minecraft era 1.17 to 1.20.4" \
|
||||
"21" "Java 21 — For modern Minecraft >= 1.20.5 & 1.21+" \
|
||||
3>&1 1>&2 2>&3)
|
||||
[ -z "$ver" ] && { echo "No Java version selected."; return; }
|
||||
_ensure_adoptium_repo
|
||||
_run_install "temurin-${ver}-jre"
|
||||
}
|
||||
|
||||
_install_dev_java() {
|
||||
local ver
|
||||
ver=$(whiptail --title "Java Development Kits (JDK)" --menu \
|
||||
"Select JDK version:" 12 60 3 \
|
||||
"17" "Java 17 LTS Development Kit" \
|
||||
"21" "Java 21 LTS Development Kit" \
|
||||
"25" "Java 25 LTS Development Kit" \
|
||||
3>&1 1>&2 2>&3)
|
||||
[ -z "$ver" ] && { echo "No JDK version selected."; return; }
|
||||
_ensure_adoptium_repo
|
||||
_run_install "temurin-${ver}-jdk"
|
||||
}
|
||||
|
||||
_any_jdk_installed_desc() {
|
||||
local inst
|
||||
inst=$(dpkg -l 'temurin-*-jdk' 2>/dev/null | awk '/^ii/ {print $2; exit}')
|
||||
[ -n "$inst" ] && echo " ($inst installed)" || echo ""
|
||||
}
|
||||
|
||||
_any_jdk_state() {
|
||||
dpkg -l 'temurin-*-jdk' 2>/dev/null | grep -q '^ii' && echo "ON" || echo "OFF"
|
||||
}
|
||||
@@ -9,16 +9,18 @@ _cat_security() {
|
||||
local zenmap_state; zenmap_state=$(_state "zenmap")
|
||||
local fail2ban_state; fail2ban_state=$(_state "fail2ban")
|
||||
local ufw_state; ufw_state=$(_state "ufw")
|
||||
local clamav_state; clamav_state=$(_state "clamav")
|
||||
|
||||
local TUI_ANCHO_REFORZADO=$((TUI_ANCHO + 6))
|
||||
local choices
|
||||
choices=$(whiptail --title "Security & Networking" --checklist \
|
||||
"Select security and networking tools (5 items):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
||||
"Select security and networking tools (6 items):" $TUI_ALTO $TUI_ANCHO_REFORZADO $TUI_ALTO_LISTA \
|
||||
"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
|
||||
|
||||
@@ -31,6 +33,9 @@ _cat_security() {
|
||||
zenmap)
|
||||
install_backports_or_stable zenmap
|
||||
;;
|
||||
clamav)
|
||||
_install_clamav
|
||||
;;
|
||||
*)
|
||||
if ! is_installed "$pkg"; then
|
||||
_run_install "$pkg"
|
||||
|
||||
@@ -128,6 +128,7 @@ install_gaming() {
|
||||
"gamemode" "Game performance optimization" ON \
|
||||
"mangohud" "Performance overlay (Vulkan/OpenGL)" ON \
|
||||
"heroic" "Heroic Launcher (Epic/GOG)" OFF \
|
||||
"java-jre" "Java Runtimes (8, 17, 21)" OFF \
|
||||
"goverlay" "MangoHud config GUI" ON \
|
||||
"lutris" "Game launcher/manager" OFF \
|
||||
3>&1 1>&2 2>&3)
|
||||
@@ -157,6 +158,7 @@ install_gaming() {
|
||||
fi
|
||||
;;
|
||||
heroic) install_heroic ;;
|
||||
java) _install_gaming_java ;;
|
||||
mangohud) install_mangohud ;;
|
||||
gamemode) install_gamemode ;;
|
||||
goverlay) install_goverlay ;;
|
||||
|
||||
@@ -134,6 +134,12 @@ install_mesa_stable() {
|
||||
}
|
||||
|
||||
offer_generic_tools() {
|
||||
if [ "$DEBIAN_VERSION" = "11" ]; then
|
||||
if ! lsmod 2>/dev/null | grep -q "^nvidia "; then
|
||||
echo "nvtop skipped on Bullseye — NVIDIA driver not loaded."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
local tool_pkgs
|
||||
tool_pkgs=$(pkg_versions nvtop vainfo)
|
||||
if _confirm "GPU Tools" "Install monitoring and info tools?\n\n${tool_pkgs}"; then
|
||||
|
||||
@@ -20,7 +20,11 @@ offer_amd_tools() {
|
||||
fi
|
||||
|
||||
local pkgs
|
||||
pkgs=$(pkg_versions "${amd_tools[@]}" nvtop vainfo)
|
||||
if [ "$DEBIAN_VERSION" = "11" ]; then
|
||||
pkgs=$(pkg_versions "${amd_tools[@]}" vainfo)
|
||||
else
|
||||
pkgs=$(pkg_versions "${amd_tools[@]}" nvtop vainfo)
|
||||
fi
|
||||
if $corectrl_available; then
|
||||
local ctrl_ver
|
||||
ctrl_ver=$(apt-cache policy corectrl 2>/dev/null | awk 'NR==3 {print $2; exit}')
|
||||
@@ -32,7 +36,11 @@ offer_amd_tools() {
|
||||
return
|
||||
fi
|
||||
|
||||
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} nvtop vainfo" "Installing AMD tools..."
|
||||
if [ "$DEBIAN_VERSION" = "11" ]; then
|
||||
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} vainfo" "Installing AMD tools..."
|
||||
else
|
||||
_run_cmd "AMD Tools" "sudo apt install -y ${amd_tools[*]} nvtop vainfo" "Installing AMD tools..."
|
||||
fi
|
||||
vainfo
|
||||
|
||||
if $corectrl_available; then
|
||||
@@ -73,7 +81,18 @@ offer_intel_tools() {
|
||||
[ -d "/sys/bus/pci/drivers/xe" ] && has_xe=true
|
||||
[ -d "/sys/bus/pci/drivers/i915" ] && has_i915=true
|
||||
|
||||
if $has_xe; then
|
||||
if [ "$DEBIAN_VERSION" = "11" ]; then
|
||||
if $has_xe; then
|
||||
echo "Intel Xe GPU detected. No monitoring tools available on Bullseye."
|
||||
return
|
||||
elif $has_i915; then
|
||||
driver_info="Classic Intel GPU detected (i915 driver)."
|
||||
pkg_list=("intel-gpu-tools")
|
||||
else
|
||||
echo "Intel GPU driver not identified. No monitoring tools available on Bullseye."
|
||||
return
|
||||
fi
|
||||
elif $has_xe; then
|
||||
driver_info="Modern Intel GPU detected (Xe driver).\nintel-gpu-tools is NOT compatible with Xe.\nOnly nvtop will be offered."
|
||||
pkg_list=("nvtop")
|
||||
elif $has_i915; then
|
||||
|
||||
+312
-86
@@ -5,9 +5,11 @@ REPO_BACKUP_DIR=""
|
||||
|
||||
backup_current_repos() {
|
||||
REPO_BACKUP_DIR=$(mktemp -d)
|
||||
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources; do
|
||||
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources \
|
||||
/etc/apt/sources.list.d/debian-backports.list /etc/apt/sources.list.d/debian-backports.sources; do
|
||||
if [ -f "$f" ]; then
|
||||
cp "$f" "$REPO_BACKUP_DIR/$(basename "$f")"
|
||||
mkdir -p "$REPO_BACKUP_DIR/$(dirname "${f#/etc/apt/}")"
|
||||
cp "$f" "$REPO_BACKUP_DIR/$(dirname "${f#/etc/apt/}")/$(basename "$f")"
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -17,17 +19,22 @@ restore_previous_repos() {
|
||||
return
|
||||
fi
|
||||
echo -e "${RED}Restoring previous repository configuration...${NC}"
|
||||
if [ -f "$REPO_BACKUP_DIR/sources.list" ]; then
|
||||
sudo cp "$REPO_BACKUP_DIR/sources.list" /etc/apt/sources.list
|
||||
else
|
||||
sudo rm -f /etc/apt/sources.list
|
||||
local found=false
|
||||
for f in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources \
|
||||
/etc/apt/sources.list.d/debian-backports.list /etc/apt/sources.list.d/debian-backports.sources; do
|
||||
local rel="${f#/etc/apt/}"
|
||||
local backup_file="$REPO_BACKUP_DIR/$rel"
|
||||
if [ -f "$backup_file" ]; then
|
||||
sudo cp "$backup_file" "$f"
|
||||
found=true
|
||||
elif [ -f "$f" ]; then
|
||||
sudo rm -f "$f"
|
||||
found=true
|
||||
fi
|
||||
done
|
||||
if $found; then
|
||||
sudo rm -f /etc/apt/sources.list.disabled
|
||||
fi
|
||||
if [ -f "$REPO_BACKUP_DIR/debian.sources" ]; then
|
||||
sudo cp "$REPO_BACKUP_DIR/debian.sources" /etc/apt/sources.list.d/debian.sources
|
||||
else
|
||||
sudo rm -f /etc/apt/sources.list.d/debian.sources
|
||||
fi
|
||||
sudo rm -f /etc/apt/sources.list.disabled
|
||||
rm -rf "$REPO_BACKUP_DIR"
|
||||
REPO_BACKUP_DIR=""
|
||||
}
|
||||
@@ -39,40 +46,312 @@ cleanup_repo_backup() {
|
||||
fi
|
||||
}
|
||||
|
||||
finalize_deb822() {
|
||||
if [ -f /etc/apt/sources.list ]; then
|
||||
sudo mv /etc/apt/sources.list /etc/apt/sources.list.disabled
|
||||
echo "Classic sources.list disabled (renamed to sources.list.disabled)"
|
||||
# ---------------------------------------------------------------------------
|
||||
# Cleanup helpers for embedded backports
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_clean_embedded_backports_classic() {
|
||||
local codename="$1"
|
||||
local file="/etc/apt/sources.list"
|
||||
[ ! -f "$file" ] && return
|
||||
grep -qE "^[^#]*${codename}-backports\b" "$file" 2>/dev/null || return
|
||||
if _confirm "Clean Classic Sources" "Remove backports line from ${file}?"; then
|
||||
sudo sed -i "/${codename}-backports/d" "$file"
|
||||
echo "Removed backports from ${file}"
|
||||
fi
|
||||
cleanup_repo_backup
|
||||
}
|
||||
|
||||
configure_repos() {
|
||||
echo -e "${YELLOW}Repository configuration...${NC}"
|
||||
_clean_embedded_backports_deb822() {
|
||||
local codename="$1"
|
||||
local file="/etc/apt/sources.list.d/debian.sources"
|
||||
[ ! -f "$file" ] && return
|
||||
|
||||
local use_deb822=false
|
||||
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
||||
if whiptail --title "Repository Format" --defaultno --yesno "Use deb822 format (modern .sources)?" 8 60; then
|
||||
use_deb822=true
|
||||
# Only proceed if the Suites line contains the backports token
|
||||
grep -qE "^Suites:.*${codename}-backports\b" "$file" 2>/dev/null || return
|
||||
|
||||
if _confirm "Clean deb822 Sources" "Remove backports suite from ${file}?"; then
|
||||
# Remove only the backports token, leaving other suites intact
|
||||
sudo sed -i "s/[[:space:]]*${codename}-backports[[:space:]]*/ /g" "$file"
|
||||
# Clean up whitespace on Suites lines
|
||||
sudo sed -i '/^Suites:[[:space:]]*$/d' "$file" 2>/dev/null || true
|
||||
echo "Removed backports suite from ${file}"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Write functions – idempotent, with _confirm dialogs
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_write_deb822() {
|
||||
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
|
||||
|
||||
local main_file="/etc/apt/sources.list.d/debian.sources"
|
||||
local main_content=""
|
||||
main_content+="Types: deb\n"
|
||||
main_content+="URIs: https://deb.debian.org/debian\n"
|
||||
main_content+="Suites: ${codename} ${codename}-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: ${codename}-security\n"
|
||||
main_content+="Components: main contrib non-free non-free-firmware\n"
|
||||
|
||||
if content_differs "$main_file" "$main_content"; then
|
||||
if _confirm "Deb822 Sources" "Write main deb822 configuration to ${main_file}?"; then
|
||||
sudo mkdir -p /etc/apt/sources.list.d
|
||||
echo -e "$main_content" | sudo tee "$main_file" > /dev/null
|
||||
echo "Wrote ${main_file}"
|
||||
else
|
||||
echo "Main repository configuration skipped."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
local enable_backports=false
|
||||
if _confirm "Backports" "Enable backports repository?\n\nProvides newer kernel, drivers, Mesa."; then
|
||||
enable_backports=true
|
||||
# Backports: always in separate file
|
||||
if [ "$bp_enabled" = true ]; then
|
||||
_write_deb822_backports "$codename"
|
||||
else
|
||||
_remove_deb822_backports "$codename"
|
||||
fi
|
||||
|
||||
# On migration from classic, disable the old file
|
||||
if [ "$action" = "migrate" ] && [ "$bp_location" = "embedded-classic" -o "$bp_location" = "standalone-classic" ]; then
|
||||
if [ -f /etc/apt/sources.list ]; then
|
||||
if _confirm "Disable Classic" "Migrating to deb822. Disable /etc/apt/sources.list?"; then
|
||||
sudo mv /etc/apt/sources.list /etc/apt/sources.list.disabled
|
||||
echo "Classic sources.list disabled (renamed to sources.list.disabled)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clean embedded backports from old classic file if they existed there
|
||||
if [ "$bp_location" = "embedded-classic" ]; then
|
||||
_clean_embedded_backports_classic "$codename"
|
||||
fi
|
||||
}
|
||||
|
||||
_write_deb822_backports() {
|
||||
local codename="$1"
|
||||
local bp_file="/etc/apt/sources.list.d/debian-backports.sources"
|
||||
local bp_content=""
|
||||
bp_content+="Types: deb\n"
|
||||
bp_content+="URIs: https://deb.debian.org/debian\n"
|
||||
bp_content+="Suites: ${codename}-backports\n"
|
||||
bp_content+="Components: main contrib non-free non-free-firmware\n"
|
||||
|
||||
if content_differs "$bp_file" "$bp_content"; then
|
||||
if _confirm "Deb822 Backports" "Write backports to ${bp_file}?"; then
|
||||
sudo mkdir -p /etc/apt/sources.list.d
|
||||
echo -e "$bp_content" | sudo tee "$bp_file" > /dev/null
|
||||
echo "Wrote ${bp_file}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If backports were formerly embedded in debian.sources, clean them
|
||||
grep -qE "^Suites:.*${codename}-backports\b" /etc/apt/sources.list.d/debian.sources 2>/dev/null && \
|
||||
_clean_embedded_backports_deb822 "$codename"
|
||||
}
|
||||
|
||||
_remove_deb822_backports() {
|
||||
local codename="$1"
|
||||
local bp_file="/etc/apt/sources.list.d/debian-backports.sources"
|
||||
|
||||
if [ -f "$bp_file" ]; then
|
||||
if _confirm "Remove Backports" "Remove ${bp_file}?"; then
|
||||
sudo rm -f "$bp_file"
|
||||
echo "Removed ${bp_file}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Also clean any embedded backports in main debian.sources
|
||||
grep -qE "^Suites:.*${codename}-backports\b" /etc/apt/sources.list.d/debian.sources 2>/dev/null && \
|
||||
_clean_embedded_backports_deb822 "$codename"
|
||||
|
||||
# Clean embedded backports from classic file too (safety net)
|
||||
_clean_embedded_backports_classic "$codename"
|
||||
}
|
||||
|
||||
_write_classic() {
|
||||
local codename="$1" action="$2" bp_enabled="$3" bp_location="$4"
|
||||
|
||||
local main_file="/etc/apt/sources.list"
|
||||
local main_content=""
|
||||
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-src https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n"
|
||||
main_content+="\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-src https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n"
|
||||
main_content+="\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-src https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n"
|
||||
|
||||
if content_differs "$main_file" "$main_content"; then
|
||||
if _confirm "Classic Sources" "Write main classic configuration to ${main_file}?"; then
|
||||
echo -e "$main_content" | sudo tee "$main_file" > /dev/null
|
||||
echo "Wrote ${main_file}"
|
||||
else
|
||||
echo "Main repository configuration skipped."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Backports: always in separate file
|
||||
if [ "$bp_enabled" = true ]; then
|
||||
_write_classic_backports "$codename"
|
||||
else
|
||||
_remove_classic_backports "$codename"
|
||||
fi
|
||||
|
||||
# On migration from deb822, disable the old file
|
||||
if [ "$action" = "migrate" ]; then
|
||||
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
|
||||
if _confirm "Disable Deb822" "Migrating to classic format. Disable /etc/apt/sources.list.d/debian.sources?"; then
|
||||
sudo mv /etc/apt/sources.list.d/debian.sources /etc/apt/sources.list.d/debian.sources.disabled
|
||||
echo "Deb822 sources disabled (renamed to debian.sources.disabled)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Clean embedded backports from old deb822 file if they existed there
|
||||
if [ "$bp_location" = "embedded-deb822" ]; then
|
||||
_clean_embedded_backports_deb822 "$codename"
|
||||
fi
|
||||
}
|
||||
|
||||
_write_classic_backports() {
|
||||
local codename="$1"
|
||||
local bp_file="/etc/apt/sources.list.d/debian-backports.list"
|
||||
local bp_content=""
|
||||
bp_content+="# Backports\n"
|
||||
bp_content+="deb https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
|
||||
|
||||
if content_differs "$bp_file" "$bp_content"; then
|
||||
if _confirm "Classic Backports" "Write backports to ${bp_file}?"; then
|
||||
sudo mkdir -p /etc/apt/sources.list.d
|
||||
echo -e "$bp_content" | sudo tee "$bp_file" > /dev/null
|
||||
echo "Wrote ${bp_file}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If backports were formerly embedded in sources.list, clean them
|
||||
grep -qE "^[^#]*${codename}-backports\b" /etc/apt/sources.list 2>/dev/null && \
|
||||
_clean_embedded_backports_classic "$codename"
|
||||
}
|
||||
|
||||
_remove_classic_backports() {
|
||||
local codename="$1"
|
||||
local bp_file="/etc/apt/sources.list.d/debian-backports.list"
|
||||
|
||||
if [ -f "$bp_file" ]; then
|
||||
if _confirm "Remove Backports" "Remove ${bp_file}?"; then
|
||||
sudo rm -f "$bp_file"
|
||||
echo "Removed ${bp_file}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Also clean any embedded backports in main sources.list
|
||||
grep -qE "^[^#]*${codename}-backports\b" /etc/apt/sources.list 2>/dev/null && \
|
||||
_clean_embedded_backports_classic "$codename"
|
||||
|
||||
# Clean embedded backports from deb822 file too (safety net)
|
||||
_clean_embedded_backports_deb822 "$codename"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Main entry point
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
configure_repos() {
|
||||
echo -e "${YELLOW}Repository configuration...${NC}"
|
||||
|
||||
if [ -z "$DEBIAN_CODENAME" ]; then
|
||||
echo -e "${RED}Error: Could not detect Debian codename. Aborting.${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Detect current state
|
||||
local current_format
|
||||
current_format=$(detect_repo_format)
|
||||
local bp_status
|
||||
if detect_backports_status "$DEBIAN_CODENAME"; then
|
||||
bp_status="enabled"
|
||||
else
|
||||
bp_status="disabled"
|
||||
fi
|
||||
local bp_location
|
||||
bp_location=$(detect_backports_location "$DEBIAN_CODENAME")
|
||||
|
||||
echo "Current format: ${current_format:-none}"
|
||||
echo "Backports: $bp_status (location: $bp_location)"
|
||||
|
||||
# Choose format (only Trixie gets the choice)
|
||||
local use_deb822=false
|
||||
if [ "$DEBIAN_CODENAME" = "trixie" ]; then
|
||||
local default_text="no"
|
||||
[ "$current_format" = "deb822" ] && default_text="yes"
|
||||
if whiptail --title "Repository Format" --defaultno --yesno "Use deb822 format (modern .sources)?" 8 60; then
|
||||
use_deb822=true
|
||||
fi
|
||||
elif [ "$current_format" = "deb822" ]; then
|
||||
use_deb822=true
|
||||
fi
|
||||
|
||||
# Choose backports
|
||||
local enable_backports=false
|
||||
if _confirm "Backports" "Enable backports repository?\n\nProvides newer kernel, drivers, Mesa."; then
|
||||
enable_backports=true
|
||||
fi
|
||||
|
||||
# Determine what to do
|
||||
local target_format
|
||||
$use_deb822 && target_format="deb822" || target_format="classic"
|
||||
|
||||
if [ "$current_format" = "none" ]; then
|
||||
local action="write"
|
||||
elif [ "$target_format" != "$current_format" ]; then
|
||||
local action="migrate"
|
||||
else
|
||||
local action="update"
|
||||
fi
|
||||
|
||||
# If nothing changed (same format + same backports state), skip
|
||||
if [ "$action" = "update" ] && [ "$enable_backports" = "$bp_status" ]; then
|
||||
# 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
|
||||
|
||||
if $use_deb822; then
|
||||
generate_deb822_sources "$DEBIAN_CODENAME" "$enable_backports"
|
||||
_write_deb822 "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
|
||||
else
|
||||
generate_classic_sources "$DEBIAN_CODENAME" "$enable_backports"
|
||||
_write_classic "$DEBIAN_CODENAME" "$action" "$enable_backports" "$bp_location"
|
||||
fi
|
||||
|
||||
echo "Updating package lists..."
|
||||
@@ -83,11 +362,14 @@ configure_repos() {
|
||||
echo -e "${GREEN}Repositories configured and updated successfully.${NC}"
|
||||
|
||||
if $use_deb822; then
|
||||
finalize_deb822
|
||||
# Remove any leftover disabled files from old classic format
|
||||
[ -f /etc/apt/sources.list.disabled ] && sudo rm -f /etc/apt/sources.list.disabled
|
||||
else
|
||||
cleanup_repo_backup
|
||||
[ -f /etc/apt/sources.list.d/debian.sources.disabled ] && sudo rm -f /etc/apt/sources.list.d/debian.sources.disabled
|
||||
fi
|
||||
|
||||
cleanup_repo_backup
|
||||
|
||||
local upgradable
|
||||
upgradable=$(apt list --upgradable 2>/dev/null | grep -c /)
|
||||
if [ "$upgradable" -gt 0 ]; then
|
||||
@@ -108,59 +390,3 @@ configure_repos() {
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
generate_classic_sources() {
|
||||
local codename="$1"
|
||||
local backports="$2"
|
||||
|
||||
local content=""
|
||||
content="# Official repository\n"
|
||||
content+="deb https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n"
|
||||
content+="# deb-src https://deb.debian.org/debian ${codename} main contrib non-free non-free-firmware\n\n"
|
||||
|
||||
content+="# Updates\n"
|
||||
content+="deb https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n"
|
||||
content+="# deb-src https://deb.debian.org/debian ${codename}-updates main contrib non-free non-free-firmware\n\n"
|
||||
|
||||
content+="# Security\n"
|
||||
content+="deb https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n"
|
||||
content+="# deb-src https://security.debian.org/debian-security ${codename}-security main contrib non-free non-free-firmware\n\n"
|
||||
|
||||
if $backports; then
|
||||
content+="# Backports (active)\n"
|
||||
content+="deb https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
|
||||
content+="# deb-src https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
|
||||
else
|
||||
content+="# Backports (not enabled)\n"
|
||||
content+="# deb https://deb.debian.org/debian ${codename}-backports main contrib non-free non-free-firmware\n"
|
||||
fi
|
||||
|
||||
echo -e "$content" | sudo tee /etc/apt/sources.list > /dev/null
|
||||
}
|
||||
|
||||
generate_deb822_sources() {
|
||||
local codename="$1"
|
||||
local backports="$2"
|
||||
|
||||
sudo mkdir -p /etc/apt/sources.list.d
|
||||
|
||||
local content=""
|
||||
content="Types: deb\n"
|
||||
content+="URIs: https://deb.debian.org/debian\n"
|
||||
content+="Suites: ${codename} ${codename}-updates\n"
|
||||
content+="Components: main contrib non-free non-free-firmware\n\n"
|
||||
|
||||
content+="Types: deb\n"
|
||||
content+="URIs: https://security.debian.org/debian-security\n"
|
||||
content+="Suites: ${codename}-security\n"
|
||||
content+="Components: main contrib non-free non-free-firmware\n\n"
|
||||
|
||||
if $backports; then
|
||||
content+="Types: deb\n"
|
||||
content+="URIs: https://deb.debian.org/debian\n"
|
||||
content+="Suites: ${codename}-backports\n"
|
||||
content+="Components: main contrib non-free non-free-firmware\n"
|
||||
fi
|
||||
|
||||
echo -e "$content" | sudo tee /etc/apt/sources.list.d/debian.sources > /dev/null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# shellcheck disable=SC2148
|
||||
# repo_detect.sh – Detection-only helpers for idempotent repository configuration.
|
||||
# Part A of the two-part architecture. No user dialogs, no writes.
|
||||
|
||||
# Detect the format of the main repo file
|
||||
# Returns: "deb822", "classic", or "none"
|
||||
detect_repo_format() {
|
||||
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
|
||||
echo "deb822"
|
||||
elif [ -f /etc/apt/sources.list ]; then
|
||||
echo "classic"
|
||||
else
|
||||
echo "none"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check whether backports are currently enabled (any format)
|
||||
# Returns: 0 if enabled, 1 otherwise
|
||||
detect_backports_status() {
|
||||
local codename="$1"
|
||||
|
||||
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
|
||||
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian.sources 2>/dev/null && return 0
|
||||
fi
|
||||
if [ -f /etc/apt/sources.list ]; then
|
||||
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list 2>/dev/null && return 0
|
||||
fi
|
||||
if [ -f /etc/apt/sources.list.d/debian-backports.sources ]; then
|
||||
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian-backports.sources 2>/dev/null && return 0
|
||||
fi
|
||||
if [ -f /etc/apt/sources.list.d/debian-backports.list ]; then
|
||||
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list.d/debian-backports.list 2>/dev/null && return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Locate where backports are configured
|
||||
# Returns: "standalone-deb822" (debian-backports.sources),
|
||||
# "standalone-classic" (debian-backports.list),
|
||||
# "embedded-deb822" (inside debian.sources),
|
||||
# "embedded-classic" (inside sources.list),
|
||||
# "none"
|
||||
detect_backports_location() {
|
||||
local codename="$1"
|
||||
|
||||
if [ -f /etc/apt/sources.list.d/debian-backports.sources ] && \
|
||||
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian-backports.sources 2>/dev/null; then
|
||||
echo "standalone-deb822"
|
||||
elif [ -f /etc/apt/sources.list.d/debian-backports.list ] && \
|
||||
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list.d/debian-backports.list 2>/dev/null; then
|
||||
echo "standalone-classic"
|
||||
elif [ -f /etc/apt/sources.list.d/debian.sources ] && \
|
||||
grep -qE "^Suites:.*${codename}-backports" /etc/apt/sources.list.d/debian.sources 2>/dev/null; then
|
||||
echo "embedded-deb822"
|
||||
elif [ -f /etc/apt/sources.list ] && \
|
||||
grep -qE "^[^#]*${codename}-backports" /etc/apt/sources.list 2>/dev/null; then
|
||||
echo "embedded-classic"
|
||||
else
|
||||
echo "none"
|
||||
fi
|
||||
}
|
||||
|
||||
# Compare generated content vs existing file (idempotency check)
|
||||
# Returns: 0 if content differs, 1 if identical
|
||||
content_differs() {
|
||||
local file="$1"
|
||||
local content="$2"
|
||||
|
||||
if [ ! -f "$file" ]; then
|
||||
return 0
|
||||
fi
|
||||
local current
|
||||
current=$(cat "$file")
|
||||
local generated
|
||||
generated=$(echo -e "$content")
|
||||
if [ "$current" = "$generated" ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
+143
-14
@@ -1,30 +1,159 @@
|
||||
#!/usr/bin/env bash
|
||||
# Adds user to sudo group and optionally enables pwfeedback
|
||||
# sudo_config.sh — User Privileges & Feedback submenu
|
||||
# License GPL v3
|
||||
|
||||
config_sudo() {
|
||||
echo -e "${YELLOW}Configuring sudo...${NC}"
|
||||
echo -e "${YELLOW}User Privileges & Feedback${NC}"
|
||||
|
||||
while true; do
|
||||
local choice
|
||||
choice=$(whiptail --title "User Privileges & Feedback" --menu \
|
||||
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
|
||||
"1" "Sudo Group Membership" \
|
||||
"2" "Passwordless Sudo (maintenance commands)" \
|
||||
"3" "Repair Home Directory Ownership" \
|
||||
"4" "Sudo Password Feedback (asterisks)" \
|
||||
"5" "Back to main menu" \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
[ -z "$choice" ] && return
|
||||
clear
|
||||
|
||||
case "$choice" in
|
||||
1) _check_sudo_group ;;
|
||||
2) _configure_nopasswd ;;
|
||||
3) _repair_home_ownership ;;
|
||||
4) _toggle_pwfeedback ;;
|
||||
5) return ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# ── Option 1: Sudo Group Membership ──
|
||||
_check_sudo_group() {
|
||||
if groups "$USER" | grep -qE '\bsudo\b'; then
|
||||
echo "User is already in the sudo group."
|
||||
_msg "Sudo Group" "User '$USER' is already in the sudo group."
|
||||
else
|
||||
echo "Adding user '$USER' to sudo group..."
|
||||
if sudo usermod -aG sudo "$USER"; then
|
||||
echo -e "${GREEN}Done. Note: you need to log out and back in for group changes to take effect.${NC}"
|
||||
if _confirm "Sudo Group" \
|
||||
"User '$USER' is NOT in the sudo group.\n\nAdd to sudo group?"; then
|
||||
if sudo usermod -aG sudo "$USER"; then
|
||||
_msg "Sudo Group" \
|
||||
"User added to sudo group.\n\nLog out and back in for\ngroup changes to take effect." 10 60
|
||||
else
|
||||
_msg "Sudo Group" "Failed to add user to sudo group." 7 60
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Option 2: Passwordless Sudo (NOPASSWD) ──
|
||||
_configure_nopasswd() {
|
||||
local nopasswd_file="/etc/sudoers.d/${USER}-nopasswd"
|
||||
|
||||
if [ -f "$nopasswd_file" ]; then
|
||||
if _confirm "NOPASSWD" \
|
||||
"Passwordless sudo is already configured.\n\nRemove it to restore password prompts?"; then
|
||||
sudo rm -f "$nopasswd_file"
|
||||
echo -e "${GREEN}Passwordless sudo removed.${NC}"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if _confirm "NOPASSWD" \
|
||||
"Configure passwordless sudo for maintenance commands?\n\n\
|
||||
- apt / apt-get (package management)\n\
|
||||
- systemctl (service management)\n\
|
||||
- shutdown / reboot / halt (power commands)\n\n\
|
||||
Useful for automation but reduces security." 14 70; then
|
||||
local choices
|
||||
choices=$(whiptail --title "NOPASSWD Commands" --checklist \
|
||||
"Select commands to allow without password:" 12 60 3 \
|
||||
"apt" "APT package management" ON \
|
||||
"systemctl" "Systemd service management" ON \
|
||||
"power" "Shutdown, reboot, halt" ON \
|
||||
3>&1 1>&2 2>&3)
|
||||
clear
|
||||
|
||||
[ -z "$choices" ] && { echo "No commands selected."; return; }
|
||||
local cleaned; cleaned=$(echo "$choices" | tr -d '"')
|
||||
|
||||
local content=""
|
||||
for cmd in $cleaned; do
|
||||
case $cmd in
|
||||
apt)
|
||||
content+="${USER} ALL=(root) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /bin/apt, /bin/apt-get\n"
|
||||
;;
|
||||
systemctl)
|
||||
content+="${USER} ALL=(root) NOPASSWD: /usr/bin/systemctl, /bin/systemctl\n"
|
||||
;;
|
||||
power)
|
||||
content+="${USER} ALL=(root) NOPASSWD: /usr/sbin/shutdown, /sbin/shutdown, /usr/sbin/reboot, /sbin/reboot, /usr/sbin/halt, /sbin/halt\n"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo -e "$content" | sudo tee "$nopasswd_file" > /dev/null
|
||||
sudo chmod 0440 "$nopasswd_file"
|
||||
if [ -f "$nopasswd_file" ]; then
|
||||
echo -e "${GREEN}Passwordless sudo configured for selected commands.${NC}"
|
||||
else
|
||||
echo -e "${RED}Failed to add user to sudo group.${NC}"
|
||||
echo -e "${RED}Failed to configure passwordless sudo.${NC}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
if _confirm "Sudo Password Feedback" "Show asterisks when typing the sudo password?"; then
|
||||
echo 'Defaults pwfeedback' | sudo tee /etc/sudoers.d/pwfeedback > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}Password feedback enabled.${NC}"
|
||||
else
|
||||
echo -e "${RED}Failed to create /etc/sudoers.d/pwfeedback.${NC}"
|
||||
# ── Option 3: Repair Home Directory Ownership ──
|
||||
_repair_home_ownership() {
|
||||
local home
|
||||
home=$(eval echo "~$USER")
|
||||
|
||||
if [ ! -d "$home" ]; then
|
||||
_msg "Home Directory" "Home directory '$home' does not exist." 8 60
|
||||
return 1
|
||||
fi
|
||||
|
||||
local uid uid_owner
|
||||
uid=$(id -u "$USER" 2>/dev/null)
|
||||
uid_owner=$(stat -c '%u' "$home" 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$uid_owner" != "$uid" ]; then
|
||||
local expected_user
|
||||
expected_user=$(id -nu "$uid_owner" 2>/dev/null || echo "UID $uid_owner")
|
||||
if _confirm "Home Permissions" \
|
||||
"Home directory '$home' is owned by\n'$expected_user' (expected: '$USER').\n\nRepair ownership?" 12 65; then
|
||||
if sudo chown -R "$USER:$USER" "$home"; then
|
||||
echo -e "${GREEN}Home directory ownership repaired.${NC}"
|
||||
else
|
||||
echo -e "${RED}Failed to repair home directory ownership.${NC}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Skipping password feedback setting."
|
||||
_msg "Home Permissions" "Home directory ownership is correct\n(owner: $USER)." 8 60
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Option 4: Sudo Password Feedback (pwfeedback) ──
|
||||
_toggle_pwfeedback() {
|
||||
local fb_file="/etc/sudoers.d/pwfeedback"
|
||||
|
||||
if [ -f "$fb_file" ]; then
|
||||
if _confirm "Password Feedback" \
|
||||
"Asterisks are currently ENABLED when typing sudo password.\n\nDisable them?"; then
|
||||
sudo rm -f "$fb_file"
|
||||
echo -e "${GREEN}Password feedback disabled.${NC}"
|
||||
fi
|
||||
else
|
||||
if _confirm "Password Feedback" \
|
||||
"Show asterisks when typing the sudo password?"; then
|
||||
if echo 'Defaults pwfeedback' | sudo tee "$fb_file" > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}Password feedback enabled.${NC}"
|
||||
else
|
||||
echo -e "${RED}Failed to create $fb_file${NC}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user