Files
debianito-post-install/modules/repos.sh
T
stornic56 8c922ee424 dual-gpu fix & lspci cache
- Replaced the restrictive Broadcom firmware installation flow with a persistent, step-by-step process in modules/firmware.sh. Now installs dkms, wireless-tools, and linux-headers-amd64 separately, then applies blacklist configuration, updates initramfs, and loads conflicting modules properly.
- Fixed conky package name across system.sh and bullseye/extras.sh. Changed from "conky" to "conky-all" with corresponding state variable updates for correct installation via apt.
- Corrected broken GRUB sed command in modules/gpu.sh for AMD GCN support. Added grep guard to prevent duplicate parameter insertion and fixed regex pattern for proper cmdline modification.
- Added whiptail pre-flight check in debianito.sh. Auto-installs required TUI dependencies if missing before the main menu, preventing runtime failures.
- Fixed home directory path resolution bug in modules/sudo_config.sh. Replaced eval echo "~$USER" with getent passwd approach for reliable user home detection across SUDO_USER contexts.
- Implemented global lspci output caching across 18+ locations. Single cache population via _init_lspci_cache() before detect_gpu, all subsequent reads use LSPCI_OUTPUT variable to eliminate redundant hardware polling calls.
- Added apt update deduplication helper in modules/utils.sh. _ensure_apt_updated() with APT_UPDATED flag bypasses redundant package list refreshes across extras/, gaming/, firmware/, and desktop_display/ modules while preserving transactional rollback paths in repos.sh.
- Fixed STATE_REFRESHED logic in debianito.sh main_menu case statement. Added STATE_REFRESHED=true to branches 3, 5, 7, 9, 11, 12, and 13 that mutate system state, ensuring refresh_system_state() triggers correctly after configuration changes.
- Removed dead REPOS_CONFIGURED variable from debianito.sh and modules/repos.sh. Variable was written but never read, eliminated to clean up global namespace without affecting repository functionality.
2026-08-27 01:41:33 -05:00

633 lines
22 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
source "${MODULES_DIR}/repos/migrate.sh" 2>/dev/null || true
# State for backup/restore
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 \
/etc/apt/sources.list.d/debian-backports.list /etc/apt/sources.list.d/debian-backports.sources; do
if [ -f "$f" ]; then
mkdir -p "$REPO_BACKUP_DIR/$(dirname "${f#/etc/apt/}")"
cp "$f" "$REPO_BACKUP_DIR/$(dirname "${f#/etc/apt/}")/$(basename "$f")"
fi
done
}
restore_previous_repos() {
if [ -z "$REPO_BACKUP_DIR" ] || [ ! -d "$REPO_BACKUP_DIR" ]; then
return
fi
echo -e "${RED}Restoring previous repository configuration...${NC}"
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
rm -rf "$REPO_BACKUP_DIR"
REPO_BACKUP_DIR=""
}
cleanup_repo_backup() {
if [ -n "$REPO_BACKUP_DIR" ] && [ -d "$REPO_BACKUP_DIR" ]; then
rm -rf "$REPO_BACKUP_DIR"
REPO_BACKUP_DIR=""
fi
}
# ---------------------------------------------------------------------------
# Cleanup helpers for embedded backports
# ---------------------------------------------------------------------------
_clean_embedded_backports_classic() {
local codename="$1"
local file="/etc/apt/sources.list"
[ ! -f "$file" ] && return 0
grep -qE "^[^#]*${codename}-backports\b" "$file" 2>/dev/null || return 0
if _confirm "Clean Classic Sources" "Remove backports line from ${file}?"; then
sudo sed -i "/${codename}-backports/d" "$file"
echo "Removed backports from ${file}"
fi
}
_clean_embedded_backports_deb822() {
local codename="$1"
local file="/etc/apt/sources.list.d/debian.sources"
[ ! -f "$file" ] && return 0
# Only proceed if the Suites line contains the backports token
grep -qE "^Suites:.*${codename}-backports\b" "$file" 2>/dev/null || return 0
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 components="${5:-main contrib non-free non-free-firmware}"
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: ${components}\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: ${components}\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
# Backports: always in separate file
if [ "$bp_enabled" = true ]; then
_write_deb822_backports "$codename" || true
else
_remove_deb822_backports "$codename" || true
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}"
else
return 1
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" || true
}
_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}"
else
return 1
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 components="${5:-main contrib non-free non-free-firmware}"
local main_file="/etc/apt/sources.list"
local main_content=""
main_content+="# Official repository\n"
main_content+="deb https://deb.debian.org/debian ${codename} ${components}\n"
main_content+="# deb-src https://deb.debian.org/debian ${codename} ${components}\n"
main_content+="\n"
main_content+="# Updates\n"
main_content+="deb https://deb.debian.org/debian ${codename}-updates ${components}\n"
main_content+="# deb-src https://deb.debian.org/debian ${codename}-updates ${components}\n"
main_content+="\n"
main_content+="# Security\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 ${components}\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" || true
else
_remove_classic_backports "$codename" || true
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}"
else
return 1
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" || true
}
_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}"
else
return 1
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
# ── Repositories submenu ──
while true; do
local repo_choice
if [ "$DEBIAN_CODENAME" = "sid" ]; then
repo_choice=$(_menu "Configure Repositories" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "Enable Contrib & Non-Free Components" \
"2" "Migrate traditional sources.list to DEB822 format" \
"3" "Back to main menu")
else
repo_choice=$(_menu "Configure Repositories" \
"Select an option:" $TUI_ALTO $TUI_ANCHO 6 \
"1" "Enable Contrib & Non-Free Components" \
"2" "Migrate traditional sources.list to DEB822 format" \
"3" "Setup/Update Backports repositories" \
"4" "[ADVANCED] Upgrade system branch (Testing / SID)" \
"5" "Back to main menu")
fi
[ -z "$repo_choice" ] && break
clear
case "$repo_choice" in
1) _repos_enable_components ;;
2) _repos_migrate_format ;;
3)
if [ "$DEBIAN_CODENAME" = "sid" ]; then
break
else
_repos_setup_backports
fi
;;
4) _branch_migration || true ;;
5) break ;;
esac
done
}
# ---------------------------------------------------------------------------
# Submenu helpers
# ---------------------------------------------------------------------------
_components_enabled() {
if [ -f /etc/apt/sources.list.d/debian.sources ]; then
for c in $(grep "^Components:" /etc/apt/sources.list.d/debian.sources 2>/dev/null | cut -d: -f2-); do
[ "$c" = "contrib" ] || [ "$c" = "non-free" ] && return 0
done
fi
if [ -f /etc/apt/sources.list ]; then
local components
components=$(grep "^[^#]*deb .* main" /etc/apt/sources.list 2>/dev/null | head -1 | sed 's/.*main\s*//')
for c in $components; do
[ "$c" = "contrib" ] || [ "$c" = "non-free" ] && return 0
done
fi
return 1
}
_repos_offer_upgrade() {
local upgradable
upgradable=$(apt list --upgradable 2>/dev/null | grep -c /)
if [ "$upgradable" -gt 0 ]; then
if _confirm "Upgrade System" "$upgradable packages can be upgraded. Upgrade now?"; then
sudo apt-mark hold tzdata 2>/dev/null || true
_run_cmd "Upgrade" "sudo apt upgrade -y" "Upgrading system..."
sudo apt-mark unhold tzdata 2>/dev/null || true
sudo apt autoremove -y
sudo apt autoclean
echo -e "${GREEN}System upgraded.${NC}"
else
echo "Skipping upgrade."
fi
fi
}
# Bootstrap a complete repository configuration from scratch when no active
# sources exist. Caller must run backup_current_repos() first so that a failed
# apt update can restore the previous state.
# Returns: 0 on success, 1 if skipped, declined or failed
bootstrap_repositories() {
local components="$1"
local bp_enabled="${2:-false}"
local bp_location="${3:-none}"
if [ -z "$DEBIAN_CODENAME" ]; then
_msg "Error" "Cannot bootstrap repositories: Debian codename unknown." 10 65
return 1
fi
# non-free-firmware does not exist on Bullseye
if [ "$DEBIAN_VERSION" = "11" ]; then
components=$(echo "$components" | sed 's/ non-free-firmware//g')
fi
if ! _confirm "Bootstrap Repositories" \
"No active APT sources were found (empty or missing sources.list).\n\n\
Configure repositories from scratch?" 10 65; then
echo "Repository configuration skipped."
cleanup_repo_backup
return 1
fi
if has_active_deb_sources; then
if ! _confirm "Custom Sources Found" \
"Active sources exist in other files (e.g. sources.list.d/*.sources).\n\n\
Adding deb.debian.org may duplicate your current mirror configuration. Continue?" 10 65; then
cleanup_repo_backup
return 1
fi
fi
# DEB822 is Trixie-only; Debian 11/12 always use classic
local use_deb822=false
if [ "$DEBIAN_VERSION" = "13" ]; then
local choice
choice=$(_menu "Repo Format" "Choose the repository format:" 12 60 3 \
"deb822" "Native DEB822 format (sources.list.d/debian.sources)" \
"classic" "Classic format (/etc/apt/sources.list)")
if [ "$choice" = "deb822" ]; then
use_deb822=true
fi
fi
if $use_deb822; then
_write_deb822 "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components" || {
cleanup_repo_backup
return 1
}
else
_write_classic "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components" || {
cleanup_repo_backup
return 1
}
fi
# Tidy: with deb822 chosen, an empty classic file is no longer needed
if $use_deb822 && [ -f /etc/apt/sources.list ] && ! grep -qE '^[^#]*\bdeb\b' /etc/apt/sources.list 2>/dev/null; then
if _confirm "Disable Classic" "An empty /etc/apt/sources.list is no longer needed. Move it aside (sources.list.disabled)?"; then
sudo mv /etc/apt/sources.list /etc/apt/sources.list.disabled
echo "Empty sources.list renamed to sources.list.disabled"
fi
fi
echo "Updating package lists..."
if sudo apt update; then
cleanup_repo_backup
echo -e "${GREEN}Repository components configured.${NC}"
return 0
else
restore_previous_repos
echo -e "${RED}apt update failed. Previous configuration restored.${NC}"
return 1
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
components="main"
else
components=$(detect_active_components)
echo "Keeping current components: $components"
fi
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
if [ "$DEBIAN_VERSION" = "11" ]; then
components="main contrib non-free"
else
components="main contrib non-free non-free-firmware"
fi
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" = "none" ]; then
if ! bootstrap_repositories "$components" "$bp_enabled" "$bp_location"; then
_pause
return
fi
_repos_offer_upgrade
echo -e "${GREEN}Cleaning old packages...${NC}"
sudo apt autoremove -y
sudo apt autoclean
echo -e "${GREEN}System packages cleaned.${NC}"
_pause
return
fi
echo "Verifying repository configuration (main, updates, security)..."
if [ "$current_format" = "deb822" ]; then
# Mixed-state guard: active classic lines alongside deb822 would duplicate sources
if [ -f /etc/apt/sources.list ] && grep -qE '^[^#]*\bdeb\b' /etc/apt/sources.list 2>/dev/null; then
if ! _confirm "Duplicate Config" \
"Active classic sources were also found in /etc/apt/sources.list.\n\n\
Writing debian.sources may duplicate your configuration. Continue?" 10 65; then
echo "No changes made."
_pause
return
fi
fi
if ! _write_deb822 "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components"; then
echo "No changes made."
_pause
return
fi
else
if ! _write_classic "$DEBIAN_CODENAME" "write" "$bp_enabled" "$bp_location" "$components"; then
echo "No changes made."
_pause
return
fi
fi
echo "Updating package lists..."
if sudo apt update; then
cleanup_repo_backup
echo -e "${GREEN}Repository components configured.${NC}"
_repos_offer_upgrade
echo -e "${GREEN}Cleaning old packages...${NC}"
sudo apt autoremove -y
sudo apt autoclean
echo -e "${GREEN}System packages cleaned.${NC}"
else
restore_previous_repos
echo -e "${RED}apt update failed. Previous configuration restored.${NC}"
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
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 Debian testing branch, recompiled to run stably on your current system.\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
local write_ok=true
if $enable_backports; then
if [ "$current_format" = "deb822" ]; then
_write_deb822_backports "$DEBIAN_CODENAME" || write_ok=false
else
_write_classic_backports "$DEBIAN_CODENAME" || write_ok=false
fi
elif [ "$current_format" = "deb822" ]; then
_remove_deb822_backports "$DEBIAN_CODENAME" || write_ok=false
else
_remove_classic_backports "$DEBIAN_CODENAME" || write_ok=false
fi
if ! $write_ok; then
echo "No changes made."
_pause
return
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
}