# Option 4: Repository Configuration ### 1. What Does This Component Do? The repository configuration module sets up and maintains the APT sources of your Debian system. Each change is written atomically, backed up beforehand and rolled back automatically if the following `apt update` fails. It: - Detects your current repository format (Classic `.list` vs modern DEB822 `.sources`) - Backs up existing configurations before any modifications - Enables the non-free components required for hardware drivers and proprietary software - Integrates Debian Backports to access newer kernels and firmware packages - Validates changes through `apt update` with automatic restoration on failure Every other configuration option (GPU drivers, kernel upgrades, gaming setup) needs this module to work first. --- ### 2. Supported Injection Formats The script adapts to your Debian version and existing repository structure: #### Classic Format (`/etc/apt/sources.list`) - **Structure**: Human-readable text with `deb` lines - **Use Case**: Debian 11 (Bullseye) through Debian 12 (Bookworm) default - **Characteristics**: Linear, comment-friendly, widely understood by all APT tools - **Example**: ```bash deb https://deb.debian.org/debian bookworm main contrib non-free non-free-firmware ``` #### Modern DEB822 Format (`/etc/apt/sources.list.d/debian.sources`) - **Structure**: Declarative RFC-822 style format with `Types`, `URIs`, and `Suites` blocks - **Use Case**: Debian 13 (Trixie) default, future-proofing for newer releases - **Characteristics**: Machine-parseable, structured, supports complex repository hierarchies - **Example**: ```yaml Types: deb URIs: https://deb.debian.org/debian Suites: trixie trixie-updates Components: main contrib non-free non-free-firmware ``` #### Migration Logic The script automatically detects your current format and offers migration options: - On Debian 13 (Trixie): Prompts to migrate TO DEB822 or stay with Classic - Format changes are atomic: a backup is created before any modification - Old files are renamed with `.disabled` extension rather than deleted --- ### 3. Logical Decision Tree (Step-by-Step Execution Flow) The `configure_repos()` function in `repos.sh` executes the following sequence: ```bash ┌─────────────────────────────────────────────────────────────┐ │ INITIAL DETECTION PHASE │ ├─────────────────────────────────────────────────────────────┤ │ 1. Detect Debian Codename (DEBIAN_CODENAME) │ │ └── If empty → Abort with error │ │ │ │ 2. Detect Current Format │ │ ├── detect_repo_format() → "deb822" | "classic" | "none" │ │ └── Display: "Current format: [format]" │ │ │ │ 3. Detect Backports Status │ │ ├── detect_backports_status() → enabled/disabled │ │ └── Detect Location: embedded vs standalone │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ USER INTERACTION PHASE │ ├─────────────────────────────────────────────────────────────┤ │ 4. Repository Menu Loop (while true) │ │ └── _menu: Select action from multiple options │ │ │ │ Options Available: │ │ ├── Debian 13+ (Trixie): │ │ │ ├── 1. Enable Contrib & Non-Free Components │ │ │ ├── 2. Migrate traditional sources.list to DEB822 │ │ │ ├── 3. Setup/Update Backports repositories │ │ │ ├── 4. [ADVANCED] Upgrade system branch (Testing/SID)│ │ │ └── 5. Back to main menu │ │ │ │ └── Other Versions: │ │ ├── 1-3 same as above │ │ └── No option 4 (branch upgrade not available) │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ DECISION MATRIX PHASE │ ├─────────────────────────────────────────────────────────────┤ │ 5. Determine Action Type (per menu selection) │ │ ├── If format changed → "migrate" │ │ ├── If nothing changed → "skip" (idempotent) │ │ └── Otherwise → "write" │ │ │ │ 6. Idempotency Check │ │ └── content_differs() compares generated vs existing │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ EXECUTION PHASE │ ├─────────────────────────────────────────────────────────────┤ │ 7. Backup Current Repositories │ │ └── backup_current_repos() → temp directory │ │ │ │ 8. Write Configuration │ │ ├── _write_deb822() OR _write_classic() │ │ ├── Creates appropriate file(s) │ │ └── Includes main + backports if enabled │ │ │ │ 8b. Branch Migration (if applicable) │ │ ├── _write_branch_sources() → writes new branch sources │ │ ├── If failure → _restore_backup() || true │ │ └── return 1 │ │ │ │ 9. Update Package Lists │ │ └── sudo apt update │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ POST-EXECUTION PHASE │ ├─────────────────────────────────────────────────────────────┤ │ 10. Success Path │ │ ├── Cleanup disabled files │ │ └── Optional: Upgrade system if packages available │ │ │ │ 11. Failure Path (apt update failed) │ │ └── restore_previous_repos() → rollback to backup │ └─────────────────────────────────────────────────────────────┘ ``` **Key Safety Mechanisms:** - **Atomic Operations**: Backup created before any write operation - **Idempotency Check**: `content_differs()` prevents unnecessary modifications - **Rollback on Failure**: If `apt update` fails, original configuration is restored via `restore_previous_repos()` - **Branch Migration Rollback**: `_write_branch_sources()` failure triggers `_restore_backup() || true` - **Disabled File Extension**: Old formats renamed with `.disabled` rather than deleted --- ### 4. Software Components Activated The script enables specific APT component branches that are essential for hardware functionality and software availability: | Component | Purpose | Critical For | Debian Version Notes | | ----------- | --------- | -------------- | --------------------- | | **main** | Free, open-source software (Debian official) | All packages | Always enabled | | **contrib** | Free software that uses non-free components | Proprietary codecs, drivers | Enabled in all versions | | **non-free** | Non-free firmware and proprietary software | NVIDIA GPU drivers, Wi-Fi firmware | Required for hardware support | | **non-free-firmware** | Firmware blobs (Wi-Fi, Bluetooth, etc.) | Wireless adapters, embedded chips | **Critical from Debian 12+** | #### Why `non-free-firmware` Is Required (Debian 12+) Starting with Debian Bookworm (12.0), the `non-free-firmware` component was separated into its own repository branch: ```bash # Before Debian 12 (Bookworm) deb https://deb.debian.org/debian bullseye main contrib non-free # After Debian 12 (Bookworm+) - SEPARATE COMPONENTS deb https://deb.debian.org/debian bookworm main contrib non-free non-free-firmware ``` **Impact of Missing `non-free-firmware`:** - Wi-Fi adapters won't work without firmware blobs - Bluetooth devices may fail to initialize - Some GPU drivers require proprietary microcode - Embedded hardware (Raspberry Pi, etc.) becomes unusable The script ensures all four components are present because: 1. **Hardware Compatibility**: Modern Debian kernels depend on these for out-of-the-box functionality 2. **Security Updates**: `non-free-firmware` receives security patches separately 3. **Future-Proofing**: Newer hardware releases firmware in this component exclusively --- ### 5. Support for Debian Backports Backports give access to newer, tested packages without compromising system stability: #### Detection Logic (`detect_backports_status` & `detect_backports_location`) ```bash # Checks ALL possible locations for backports configuration ├── /etc/apt/sources.list.d/debian-backports.sources (DEB822 standalone) ├── /etc/apt/sources.list.d/debian-backports.list (Classic standalone) ├── /etc/apt/sources.list.d/debian.sources (Embedded in DEB822) └── /etc/apt/sources.list (Embedded in Classic) ``` **Return Values:** - `"standalone-deb822"` → Separate `.sources` file (recommended) - `"standalone-classic"` → Separate `.list` file - `"embedded-deb822"` → Inside `debian.sources` - `"embedded-classic"` → Inside `sources.list` - `"none"` → Not configured #### Backports Injection Process ```bash ┌─────────────────────────────────────────────────────────────┐ │ 1. User Selects: Enable Backports? │ │ └── whiptail confirm with explanation │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 2. Determine Format │ │ ├── If DEB822 → _write_deb822_backports() │ │ └── If Classic → _write_classic_backports() │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 3. Create Backports File │ │ ├── Location: /etc/apt/sources.list.d/ │ │ └── Name: debian-backports.sources or .list │ │ │ │ Content Example (DEB822): │ │ Types: deb │ │ URIs: https://deb.debian.org/debian │ │ Suites: bookworm-backports │ │ Components: main contrib non-free non-free-firmware │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 4. Cleanup Embedded Backports (Safety Net) │ │ └── If backports existed in main file, remove them │ └─────────────────────────────────────────────────────────────┘ ``` #### Why Enable Backports? The script explains this in its confirmation dialog because backports change what you get for three components: | Feature | Without Backports | With Backports | | --------- | ------------------- | ---------------- | | **Linux Kernel** | Stable kernel only (e.g., 6.1-6.12) | Newer kernels (e.g., 6.x/7.x series) | | **GPU "Drivers"** | Latest Mesa from stable | Latest Mesa from testing | | **Wi-Fi Firmware** | Older firmware versions | Newest firmware for modern cards | | **System Stability** | Maximum stability | Tested-but-newer packages | #### Backports Warning System The script includes safeguards: - Only enabled if user explicitly confirms - Warns about potential compatibility issues - Can be disabled anytime via Option 3 again - Automatically detected in other modules (kernel, GPU) --- ### Technical Implementation Notes **Idempotency Guarantee:** ```bash # content_differs() ensures no duplicate writes if [ "$current" = "$generated" ]; then return 1 # No changes needed fi return 0 # Changes required ``` **Atomic Backup Mechanism:** ```bash backup_current_repos() { REPO_BACKUP_DIR=$(mktemp -d) for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.sources; do cp "$f" "$REPO_BACKUP_DIR/" 2>/dev/null || true done } # Rollback on failure: restore_previous_repos() { sudo cp "$backup_file" "$original_path" # Restore from temp backup rm -rf "$REPO_BACKUP_DIR" # Clean up after success/failure } ``` **Component Activation Pattern:** All four components are written in a single operation to prevent partial configurations: ```bash Components: main contrib non-free non-free-firmware # Atomic write # Not written as separate lines to avoid merge conflicts ``` ---