mirror of
https://github.com/stornic56/debianito-post-install.git
synced 2026-10-31 13:08:06 +00:00
149fb56e8c
- `.github/workflows/ci.yml` added as a new workflow: job `lint-and-test` on `runs-on: ubuntu-latest` with `container: debian:trixie`, checking out via `actions/checkout@v4`, installing `bats` and `shellcheck`, running `shellcheck --severity=error debianito.sh modules/**/*.sh` (with `shopt -s globstar`) and `bats tests/`.
- `debianito.sh` CLI parser: `AUTO_YES=0`, `ALLOW_DESTRUCTIVE=0` declared after `MODULES_DIR` and before `_boot_mark`; `_usage()` prints `Usage: debianito.sh [OPTIONS]` with `--yes`, `--allow-destructive` and `--help`; the `while [ $# -gt 0 ]` / `case` loop consumes `--yes` and `--allow-destructive`, prints `Unknown option: $1 (run with --help for usage)` to stderr and `exit 2` for unknown flags, and `--help|-h` runs `_usage` then `exit 0`.
- `modules/utils.sh`: new global `_SELECTION_CONFIRMED=0` and `_confirm_install_list()` (utils.sh:756-785), which renders items capped at 15 with `... and N more`, computes `height` capped at 24, calls `_confirm "$title" "$list" "$height" 65`, arms `_SELECTION_CONFIRMED=${#items[@]}` on yes, and returns 1 for an empty list or on decline. `_install_pkg()` (utils.sh:789-804) decrements the countdown instead of prompting, and only prompts via `elif ! _confirm "Install: ${pkg}" "Install ${pkg}\nVersion: ${ver}?"; then return 0`.
- Bulk retrofit in `modules/extras/**/*.sh` (18 sites): `_confirm_install_list "Título" "${array[@]}" || return` placed right after the `whiptail` selection is parsed, the install loop left intact, and `_SELECTION_CONFIRMED=0` after the loop. Files: office/office.sh:101, system/software_centers.sh:29, system/system.sh:133, communication/communication.sh:68, design/design.sh:42, download/download.sh:48+55, terminals/terminals.sh:31, security/security.sh:30, players/players.sh:20, themes/fonts/fonts.sh:32, dev/dev.sh:44, programming/programming.sh:57, themes/desktop-themes/desktop-themes.sh:30, fetch/fetch.sh:41, themes/icons/icons.sh:47, themes/cursors/cursors.sh:28, internet/internet.sh:197, java.
- `modules/bullseye/extras.sh` (13 sites) plus `modules/bullseye/legacy.sh` (1 site, `install_gaming_bullseye`, guarded with `if [ ${#_install_pkgs[@]} -gt 0 ]` so a i386-only selection does not blank the summary) plus `modules/desktop_display.sh` (1 site, XFCE Custom — a no-loop `_run_cmd` batch with the reset immediately after it). Special cases: download.sh and bullseye/download each have two checklists merged into one combined summary; legacy.sh gaming skips the reset when the list is empty; XFCE Custom resets before `_xfce_polkit_rules` so the counter cannot leak.
- `modules/desktops/desktop_gnome.sh` (new): `gnome_menu()` runs a `_radiolist` with "1" "GNOME (Full Desktop)", "2" "GNOME Core (Minimal Install)", "3" "Back", then `_install_gnome_full()` and `_install_gnome_core()`. Each arms `_confirm_install_list "GNOME Full Desktop" gnome gdm3 || return` (core: `gnome-core gdm3`), keeps an already-configured display manager via `_existing_display_manager` by setting `target_dm="$keep_dm"`, writes the preseed `echo "${target_dm} shared/default-x-display-manager select ${target_dm}" | sudo debconf-set-selections`, installs `sudo apt install -y gnome gdm3` / `gnome-core gdm3`, enables `gdm3` only when `target_dm = "gdm3"`, resets `_SELECTION_CONFIRMED=0` and calls `_offer_pipewire_after_desktop`.
- `modules/desktops/desktop_kde.sh` (new): `kde_menu()` runs a `_radiolist` with "1" "KDE Plasma (Full Desktop)", "2" "KDE Plasma Desktop (Minimal)", "3" "Back"; `_install_kde_full()` and `_install_kde_minimal()` arm `_confirm_install_list "KDE Plasma Full" kde-standard sddm || return` (minimal: `kde-plasma-desktop sddm`), preseed `sddm shared/default-x-display-manager select sddm`, install `sudo apt install -y kde-standard sddm` / `kde-plasma-desktop sddm`, enable `sddm` only when it is the target DM, reset the counter and offer PipeWire.
- `modules/desktop_display.sh` `desktop_environment_menu()`: `env_items+=("3" "GNOME")`, `env_items+=("4" "KDE Plasma")`, `env_items+=("5" "Back")`; the case adds `3)` loading `gnome` via `_load_module gnome || continue` and calling `gnome_menu`, and `4)` loading `kde` via `_load_module kde || continue` and calling `kde_menu`; the dead TODO comment was removed.
- PipeWire retrofit in `modules/desktop_display.sh` (6 sites): `_install_lxde_full`, `_install_lxde_core`, `_install_xfce_full`, `_install_xfce_minimal`, `_install_xfce_wayland` and `_install_xfce_custom` each call `_offer_pipewire_after_desktop` after their install block.
- `_offer_pipewire_after_desktop()` and `_existing_display_manager()` added at the end of `modules/desktop_display.sh`: `_offer_pipewire_after_desktop` checks `pipewire-audio` (`pipewire` when `DEBIAN_VERSION = 11`), returns 0 via `is_installed`, otherwise `_confirm "PipeWire Audio" "No PipeWire audio server is installed.\n\nInstall the PipeWire audio stack (recommended)?"` calls `_install_pipewire_standard` and returns 0. `_existing_display_manager` reads `${DM_FILE:-/etc/X11/default-display-manager}`, reads the basename as the DM, and otherwise scans `gdm3 lightdm sddm greetd gdm` with `systemctl is-enabled`, printing nothing when none is found.
- `_ensure_apt_updated` added before the GNOME/KDE `apt install` transactions (4 sites, deduplicated per session); `gnome gdm3` and `kde-standard sddm` are installed alongside even when another display manager is kept as the default.
- Extraction to `modules/desktops/`: `desktop_lxde.sh` (38 lines) and `desktop_xfce.sh` (119 lines) created with the `lxde_menu` / `_install_lxde_full` / `_install_lxde_core` and `xfce_menu` / `_install_xfce_full` / `_install_xfce_minimal` / `_install_xfce_wayland` / `_install_xfce_custom` / `_xfce_polkit_rules` blocks moved verbatim; both carry `# License GPL v3` in their headers.
- `modules/desktop_display.sh` reduced from 542 to 394 lines (−154): lines 55-208 removed, the dispatch (desktop_display.sh:39-46) replaced with `_load_module xfce || continue` / `lxde_menu`, and the file left with `manage_desktop_display`, `desktop_environment_menu`, `display_manager_menu`, `lightdm_config_menu`, `configure_greetd`, `configure_gdm3`, `configure_sddm`, the two shared helpers.
- `modules/utils.sh` `_load_module` map: `xfce)` → `${MODULES_DIR}/desktops/desktop_xfce.sh`, `lxde)` → `${MODULES_DIR}/desktops/desktop_lxde.sh`, `gnome)` → `${MODULES_DIR}/desktops/desktop_gnome.sh`, `kde)` → `${MODULES_DIR}/desktops/desktop_kde.sh`; deps for `xfce`, `lxde`, `gnome` and `kde` are `(desktop_display audio)` and `desktop_display` is `(repos audio)`.
- `modules/desktops/desktop_xfce.sh` `_xfce_polkit_rules()` writes `/etc/polkit-1/rules.d/85-suspend.rules` and `89-backlight.rules` via `sudo tee`, adds the `backlight` group with `groupadd --system` fallback, adds the real login user from `/etc/passwd` to `backlight` and restarts `polkit.service`.
- ES→EN user-facing strings: 14 strings across 4 files — `desktop_display.sh` `lxdе_menu` ("LXDE (Full Desktop)", "LXDE Core (Minimal Install)"), `gpu/nvidia.sh` Kepler legacy-driver notice ("Kepler GPU detected (GKxxx)… Install the legacy driver for Kepler?"), `bullseye/legacy.sh` ("Install NVIDIA driver?", "Skipping NVIDIA driver.", "Installing NVIDIA driver ${gpu_gen}...") and `bullseye/extras.sh` ("firmware-linux-nonfree provides drivers for… Install?").
- ES→EN internal comments: ~35 comments across 9 files — section headers in `_install_nvidia_standard`, `gpu/_helpers.sh` (lines 5, 113), `gpu/nvidia.sh` (lines 8-12, 19-22, 68-70, 167-172, 196, 239-253, 262-263, 275, 291, 336-338, 376), `gpu.sh` (lines 15-17), `bullseye/repos.sh` (line 2), `firmware.sh` (line 235, "--- Load verification ---"), `utils.sh` (lines 129, 132, 153 — timezone Paso 1/2/4) and `utils.sh:546,548`.
- set -e abort fix: `debianito.sh:149` now reads `_system_preferences_menu || true`, consistent with the other dispatch chains (14 of the 15 chains already had the guard); a declined pre-apply summary now leaves the TUI alive instead of terminating the script.
- `docs/desktops_display.md`: 4 hunks — intro now lists GNOME/GNOME Core/KDE Plasma/KDE Plasma Desktop/XFCE/XFCE Wayland/XFCE Custom/LXDE, a new "Modular layout" paragraph describing `modules/desktops/` and lazy loading, Block 1 rewritten into four environments, five new bullets (pre-apply summary, existing-DM preservation, PipeWire offer, stale-lists guard) and a Desktop Environment Packages table.
- `docs/quickstart.md` line 284: Desktop Environment entry expanded to pick from XFCE (full / minimal / Wayland `labwc` on Trixie / custom checklist), LXDE (full / core), GNOME (full / core) or KDE Plasma (full / minimal).
- `_existing_display_manager` now takes the config path via `local dm_file="${DM_FILE:-/etc/X11/default-display-manager}"` so the offline test suite never reads the real system file.
- `tests/test_helper.bash`: added `_mock_systemctl()` for `is-enabled` (units in `MOCK_SYSTEMCTL_ENABLED` report `enabled`, everything else `disabled`), `MOCK_SYSTEMCTL_ENABLED=""`, `WHIPTAIL_CALLS`/`MOCK_WHIPTAIL_OUTPUT`/`MOCK_WHIPTAIL_RC`, `MOCK_DPKG_INSTALLED` and the `systemctl` entry in the mock list and in `mock_reset()`.
- `tests/desktops.bats` created with 16 tests: `_existing_display_manager` (file read, file-preferred over an enabled unit, enabled-unit fallback, candidate order, missing file, nothing configured), `_offer_pipewire_after_desktop` (5 tests: skip-installed, accept-installs, decline-returns-0, Bullseye package name, wrong package name on 11), `_load_module` (4 tests for xfce/lxde/gnome/kde) and an unknown-module case; 17→33 tests total.
- `.github/workflows/ci.yml` shellcheck severity raised from `--severity=error` to `--severity=warning`.
- `debianito.sh`: `RED`, `GREEN`, `YELLOW`, `CYAN` and `NC` plus `AUTO_YES`, `ALLOW_DESTRUCTIVE` and `DEBIAN_CODENAME` are now `export`ed as cross-file globals.
- `modules/utils.sh`: `HAS_NVIDIA`, `DESKTOP_ENV`, `AUDIO_SERVER`, `DEBIAN_VERSION` and the other cross-file globals are `export`ed.
- `modules/extras/system/software_centers.sh` gained a `#!/usr/bin/env bash` shebang.
- `shellcheck` triage (v0.11.0, baseline `--severity=warning` 25 findings → 0): removed two dead-code lines (`headless` in `extras/dev/dev.sh`, orphan `dev_id` in `firmware.sh`); `SC2206` in `extras/dev/essential.sh` fixed by expanding `$comp_pkgs` to `"${comp_pkgs[@]}"`; `SC2010`/`SC2046` (3 sites) replaced `ls … | grep` with `compgen -G "…"`; `SC2155` (2 sites, `gpu.sh` and `rescue.sh`) split command substitutions into separate lines; `SC2166` in `repos.sh` replaced `-o` with `{ … || … }`; `SC2221`/`SC2222` (2 sites, `sysinfo.sh` and `utils.sh`) collapsed the `wl*|wlp*|wlo*|wlan*` alternation to `wl*`; `SC1090` in `extras.sh` gained a justification comment on the disable directive.
- Final verification: `bash -n` on all 15 modified `.sh` files and `set -euo pipefail` at `debianito.sh:3` both intact; `bats tests/` reports 33 ok / 0 failed; invariants `offers 11`, `confirm_install_list 39` and `_SELECTION_CONFIRMED=0 40` hold.
431 lines
17 KiB
Bash
431 lines
17 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# ── Global arrays ──
|
|
# Device arrays (PCI_NET_DEVS, USB_WIFI_DEVS, PCI_BT_DEVS, USB_BT_DEVS)
|
|
# and _FW_PLAN_HW_LINES are declared in hw_detect.sh.
|
|
_DETECTED_FW_PKGS=()
|
|
_FW_PLAN_PKG_LINES=()
|
|
|
|
# ── Firmware package mapping ──
|
|
_detect_firmware_needs() {
|
|
local -A pkg_info
|
|
_DETECTED_FW_PKGS=()
|
|
_FW_PLAN_PKG_LINES=()
|
|
|
|
local dev_list
|
|
dev_list=("${PCI_NET_DEVS[@]}" "${USB_WIFI_DEVS[@]}")
|
|
|
|
for dev in "${dev_list[@]}"; do
|
|
local raw_desc vendor_lc pkg
|
|
raw_desc=$(echo "$dev" | sed -E 's/^[^ ]+ [^:]+: //; s/ \[[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\]//; s/ \(rev.*\)//')
|
|
vendor_lc=$(echo "$dev" | sed -n 's/^.*]: //p' | awk '{print $1}' | tr '[:upper:]' '[:lower:]')
|
|
|
|
[[ "$vendor_lc" != *intel* && "$vendor_lc" != *realtek* && "$vendor_lc" != *atheros* && "$vendor_lc" != *qualcomm* && "$vendor_lc" != *mediatek* ]] && continue
|
|
|
|
case "$vendor_lc" in
|
|
*intel*)
|
|
if echo "$dev" | grep -qiE 'wireless|wi-fi|wlan|802\.11'; then
|
|
pkg="firmware-iwlwifi"
|
|
else
|
|
pkg="firmware-intel-misc"
|
|
fi
|
|
;;
|
|
*realtek*) pkg="firmware-realtek" ;;
|
|
*atheros* | *qualcomm*) pkg="firmware-atheros" ;;
|
|
*mediatek*) pkg="firmware-mediatek" ;;
|
|
esac
|
|
|
|
local short_dev
|
|
short_dev=$(echo "$raw_desc" | sed 's/ *\[[^]]*\]//g; s/ */ /g')
|
|
if [ -z "${pkg_info[$pkg]-}" ]; then
|
|
pkg_info[$pkg]="$short_dev"
|
|
else
|
|
pkg_info[$pkg]+=", $short_dev"
|
|
fi
|
|
done
|
|
|
|
for pkg in "${!pkg_info[@]}"; do
|
|
_DETECTED_FW_PKGS+=("$pkg")
|
|
_FW_PLAN_PKG_LINES+=(" [+] ${pkg} \xe2\x86\x90 ${pkg_info[$pkg]}")
|
|
done
|
|
|
|
mapfile -t _DETECTED_FW_PKGS < <(printf '%s\n' "${_DETECTED_FW_PKGS[@]}" | sort -u)
|
|
}
|
|
|
|
# ── Build plan string ──
|
|
_build_firmware_plan() {
|
|
local plan=""
|
|
plan+="This section installs the essential non-free firmware stack\n"
|
|
plan+="for Debian (including CPU microcode, GPU, network, and core\n"
|
|
plan+="drivers). The script has scanned your hardware to prepare\n"
|
|
plan+="the setup:\n\n"
|
|
|
|
plan+="Detected controllers:\n"
|
|
if [ ${#_FW_PLAN_HW_LINES[@]} -eq 0 ]; then
|
|
plan+=" (none detected)\n"
|
|
else
|
|
for line in "${_FW_PLAN_HW_LINES[@]}"; do
|
|
plan+="${line}\n"
|
|
done
|
|
fi
|
|
|
|
plan+="\nPlanned firmware packages:\n"
|
|
local fw_line
|
|
if is_installed firmware-linux-nonfree; then
|
|
local cur_ver
|
|
cur_ver=$(_get_installed_version "firmware-linux-nonfree")
|
|
fw_line=" [+] firmware-linux-nonfree ${cur_ver} (already installed)"
|
|
else
|
|
fw_line=" [+] firmware-linux-nonfree (base meta-package)"
|
|
fi
|
|
plan+="${fw_line}\n"
|
|
|
|
for line in "${_FW_PLAN_PKG_LINES[@]}"; do
|
|
plan+="${line}\n"
|
|
done
|
|
|
|
local has_bt=false
|
|
[ ${#PCI_BT_DEVS[@]} -gt 0 ] && has_bt=true
|
|
[ ${#USB_BT_DEVS[@]} -gt 0 ] && has_bt=true
|
|
if ! $has_bt; then
|
|
for dev in "${USB_WIFI_DEVS[@]}"; do
|
|
if echo "$dev" | grep -qi 'bluetooth'; then
|
|
has_bt=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
plan+="\nBluetooth:\n"
|
|
if $has_bt; then
|
|
if is_installed bluez; then
|
|
plan+=" [+] bluez (already installed)\n"
|
|
else
|
|
plan+=" [+] bluez + bluez-tools + bluez-obexd (base stack)\n"
|
|
fi
|
|
case "${DESKTOP_ENV:-other}" in
|
|
kde)
|
|
plan+=" [+] bluedevil (KDE applet)\n"
|
|
if [ "${AUDIO_SERVER:-}" = "pipewire" ]; then
|
|
plan+=" → pipewire-pulse + wireplumber (if missing)\n"
|
|
fi
|
|
;;
|
|
gnome) plan+=" (already in gnome-control-center)\n" ;;
|
|
*) plan+=" [+] blueman (GTK Bluetooth manager)\n" ;;
|
|
esac
|
|
plan+=" → Bluetooth service will be enabled\n"
|
|
else
|
|
plan+=" (no Bluetooth hardware detected)\n"
|
|
fi
|
|
|
|
plan+="\nInstallation order:\n"
|
|
plan+=" 1. Base firmware (firmware-linux-nonfree)\n"
|
|
plan+=" 2. Network firmware (realtek, iwlwifi, ...)\n"
|
|
plan+=" 3. Broadcom / Bluetooth firmware\n"
|
|
|
|
echo -e "$plan"
|
|
}
|
|
|
|
# ── Install detected firmware packages ──
|
|
_install_detected_firmware() {
|
|
local to_install=()
|
|
for pkg in "${_DETECTED_FW_PKGS[@]}"; do
|
|
if is_installed "$pkg"; then
|
|
echo " --> $pkg already installed."
|
|
continue
|
|
fi
|
|
local ver
|
|
ver=$(_get_pkg_version "$pkg")
|
|
if [ -z "$ver" ] || [ "$ver" = "(none)" ]; then
|
|
echo " --> $pkg not available in repositories, skipping."
|
|
continue
|
|
fi
|
|
to_install+=("$pkg")
|
|
done
|
|
if [ ${#to_install[@]} -gt 0 ]; then
|
|
_run_cmd "Firmware" "sudo DEBIAN_FRONTEND=noninteractive apt install -y ${to_install[*]}" \
|
|
"Installing network firmware packages..." || true
|
|
fi
|
|
}
|
|
|
|
# ── Wireless handler (Broadcom single-path wl) ──
|
|
_handle_wireless() {
|
|
local installed_any=false
|
|
local wl_build_failed=false
|
|
|
|
if [ ${#PCI_NET_DEVS[@]} -eq 0 ] && [ ${#USB_WIFI_DEVS[@]} -eq 0 ]; then
|
|
_detect_all_network_devices
|
|
fi
|
|
|
|
for dev in "${PCI_NET_DEVS[@]}"; do
|
|
local bcm_id
|
|
bcm_id=$(echo "$dev" | grep -oP '14e4:[0-9a-fA-F]+' || true)
|
|
[ -z "$bcm_id" ] && continue
|
|
|
|
# --- Dependencies verification ---
|
|
if ! is_installed "linux-headers-amd64" || ! is_installed "dkms"; then
|
|
if ! apt-cache show linux-headers-amd64 dkms >/dev/null 2>&1; then
|
|
_msg "Broadcom Error" "linux-headers-amd64 or dkms are not available in your repositories. Cannot compile Broadcom driver.\n\nEnsure repositories are enabled and run:\n sudo apt install linux-headers-amd64 dkms"
|
|
_pause
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# --- Confirmation ---
|
|
if ! _confirm "Broadcom WiFi" "Detected Broadcom wireless device.\n\nInstall broadcom-sta-dkms, dkms, and wireless-tools?"; then
|
|
continue
|
|
fi
|
|
|
|
# --- Step-by-step installation ---
|
|
_run_cmd "Broadcom Deps" "sudo DEBIAN_FRONTEND=noninteractive apt install -y dkms wireless-tools linux-headers-amd64" || true
|
|
_run_cmd "Broadcom Driver" "sudo DEBIAN_FRONTEND=noninteractive apt install -y broadcom-sta-dkms" || true
|
|
|
|
# --- Persist blacklist of conflicting modules ---
|
|
local blacklist_conf="/etc/modprobe.d/blacklist-broadcom.conf"
|
|
local blacklist_content="blacklist b43\nblacklist b43legacy\nblacklist brcmsmac\nblacklist bcma\nblacklist ssb"
|
|
echo -e "$blacklist_content" | sudo tee "$blacklist_conf" >/dev/null || true
|
|
|
|
# --- Update initramfs and load module ---
|
|
_run_cmd "Initramfs" "sudo update-initramfs -u" || true
|
|
_run_cmd "Modprobe" "sudo modprobe -r b43 b43legacy b44 bcma brcmsmac brcmfmac ssb wl 2>/dev/null || true" "Removing conflicting modules" || true
|
|
_run_cmd "Modprobe" "sudo modprobe wl" || true
|
|
|
|
# --- Combo BT (unchanged) ---
|
|
local has_broadcom_bt=false
|
|
local btdev
|
|
for btdev in "${PCI_BT_DEVS[@]}"; do
|
|
if echo "$btdev" | grep -qi 'broadcom'; then
|
|
has_broadcom_bt=true
|
|
break
|
|
fi
|
|
done
|
|
if $has_broadcom_bt; then
|
|
echo -e "${YELLOW}[+] Broadcom WiFi+BT combo card detected.${NC}"
|
|
sudo mkdir -p /etc/modprobe.d
|
|
printf 'softdep wl post: btusb\n' | sudo tee /etc/modprobe.d/broadcom-combo.conf >/dev/null || true
|
|
echo -e "${YELLOW} A reboot may be required for Bluetooth support.${NC}"
|
|
fi
|
|
|
|
# --- Post-DKMS verification (Fix 5, unchanged) ---
|
|
if ! compgen -G "/lib/modules/$(uname -r)/updates/dkms/wl.ko*" >/dev/null; then
|
|
_msg "Broadcom DKMS Build Failed" "The wl module was not built by DKMS.\n\nPossible causes:\n- Missing build tools (build-essential, dkms)\n- Kernel update without headers\n- Incompatible kernel version\n\nTry: sudo dpkg-reconfigure broadcom-sta-dkms"
|
|
if _confirm "Broadcom" "Rebuild the Broadcom driver now?"; then
|
|
_run_cmd "Broadcom" "sudo dpkg-reconfigure broadcom-sta-dkms" || true
|
|
if compgen -G "/lib/modules/$(uname -r)/updates/dkms/wl.ko*" >/dev/null; then
|
|
:
|
|
else
|
|
local dmesg_out
|
|
dmesg_out=$(sudo dmesg | tail -20 2>/dev/null || echo "(dmesg unavailable)")
|
|
_msg "Broadcom DKMS Still Failed" "dpkg-reconfigure did not produce wl.ko either.\n\nLast kernel messages:\n${dmesg_out}\n\nYou may need to check build logs or report a bug against broadcom-sta-dkms."
|
|
_pause
|
|
wl_build_failed=true
|
|
continue
|
|
fi
|
|
else
|
|
wl_build_failed=true
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
_msg "Network Warning" "The script is about to unload current WiFi kernel modules to load the Broadcom driver.\n\nIf you are connected via SSH over WiFi, YOUR CONNECTION WILL DROP. Please reconnect after a few seconds."
|
|
sudo modprobe -r b43 b43legacy b44 bcma brcmsmac brcmfmac ssb wl 2>/dev/null || true
|
|
sudo modprobe wl 2>/dev/null || true
|
|
|
|
# --- Load verification ---
|
|
if lsmod | grep -q '^wl '; then
|
|
echo -e "${GREEN}[+] Broadcom WiFi activated (wl module loaded).${NC}"
|
|
_pause
|
|
installed_any=true
|
|
else
|
|
echo -e "${YELLOW}[+] Broadcom driver installed but wl module did not load.${NC}"
|
|
echo -e "${YELLOW} A system reboot is required.${NC}"
|
|
_pause
|
|
installed_any=true
|
|
fi
|
|
done
|
|
|
|
# --- USB Broadcom (unchanged) ---
|
|
local usb_dev
|
|
for usb_dev in "${USB_WIFI_DEVS[@]}"; do
|
|
if echo "$usb_dev" | grep -qi '0a5c'; then
|
|
_msg "USB Broadcom" "USB Broadcom device detected (0a5c).\n\nLinux does not have native drivers for most USB Broadcom WiFi chips.\nndiswrapper may be needed as a last resort."
|
|
_pause
|
|
fi
|
|
done
|
|
|
|
# --- Mensaje final (unchanged) ---
|
|
if ! $installed_any && ! $wl_build_failed; then
|
|
echo "No special WiFi firmware needed -- base firmware-linux-nonfree covers this system."
|
|
_pause
|
|
fi
|
|
}
|
|
|
|
# ── Ensure non-free repository is enabled ──
|
|
# Token-exact check for the "non-free" component. "non-free-firmware"
|
|
# contains the substring but is a different component, so word-boundary
|
|
# matching (\b) would produce false positives.
|
|
_has_nonfree_component() {
|
|
local file="$1"
|
|
grep -qE '^[^#]*[[:space:]]non-free([[:space:]]|$)' "$file" 2>/dev/null
|
|
}
|
|
|
|
_ensure_nonfree_repo() {
|
|
local nonfree_found=false
|
|
if [ -f /etc/apt/sources.list ] && _has_nonfree_component /etc/apt/sources.list; then
|
|
nonfree_found=true
|
|
fi
|
|
if ! $nonfree_found && [ -d /etc/apt/sources.list.d ]; then
|
|
for f in /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list; do
|
|
[ -f "$f" ] || continue
|
|
if _has_nonfree_component "$f"; then
|
|
nonfree_found=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
if $nonfree_found; then
|
|
return 0
|
|
fi
|
|
|
|
if ! _confirm "non-free Repository" "Component 'non-free' (and 'non-free-firmware') is required for WiFi/Bluetooth/GPU firmware.\n\nAdd them to your APT repositories?"; then
|
|
return 1
|
|
fi
|
|
|
|
# No active sources at all → bootstrap a complete configuration
|
|
if ! has_active_deb_sources; then
|
|
backup_current_repos
|
|
if ! bootstrap_repositories "main contrib non-free non-free-firmware"; then
|
|
return 1
|
|
fi
|
|
else
|
|
if [ -f /etc/apt/sources.list ]; then
|
|
sudo cp /etc/apt/sources.list "/etc/apt/sources.list.backup.$(date +%Y%m%d_%H%M%S)"
|
|
# Add each missing component after the space-delimited "main"
|
|
# component; a bare s/main/ would corrupt mirror URLs that
|
|
# contain "main" (e.g. https://main.example.com).
|
|
sudo sed -i -E '/^deb / { /(^|[[:space:]])non-free([[:space:]]|$)/! s/ main([[:space:]]|$)/ main non-free\1/ }' /etc/apt/sources.list
|
|
# non-free-firmware does not exist on Bullseye
|
|
if [ "$DEBIAN_VERSION" != "11" ]; then
|
|
sudo sed -i -E '/^deb / { /(^|[[:space:]])non-free-firmware([[:space:]]|$)/! s/ main([[:space:]]|$)/ main non-free-firmware\1/ }' /etc/apt/sources.list
|
|
fi
|
|
fi
|
|
if [ -d /etc/apt/sources.list.d ]; then
|
|
for f in /etc/apt/sources.list.d/*.sources; do
|
|
[ -f "$f" ] || continue
|
|
sudo cp "$f" "${f}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
sudo sed -i -E '/^Components:/ { /(^|[[:space:]])non-free([[:space:]]|$)/! s/$/ non-free/ }' "$f"
|
|
if [ "$DEBIAN_VERSION" != "11" ]; then
|
|
sudo sed -i -E '/^Components:/ { /(^|[[:space:]])non-free-firmware([[:space:]]|$)/! s/$/ non-free-firmware/ }' "$f"
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
# Verify the component was actually added before reporting success
|
|
local nonfree_ok=false
|
|
[ -f /etc/apt/sources.list ] && _has_nonfree_component /etc/apt/sources.list && nonfree_ok=true
|
|
if ! $nonfree_ok && [ -d /etc/apt/sources.list.d ]; then
|
|
for f in /etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list; do
|
|
[ -f "$f" ] || continue
|
|
if _has_nonfree_component "$f"; then
|
|
nonfree_ok=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
if ! $nonfree_ok; then
|
|
echo -e "${RED}Failed to enable non-free repository. Check your APT sources.${NC}"
|
|
return 1
|
|
fi
|
|
|
|
_ensure_apt_updated
|
|
echo -e "${GREEN}non-free repository enabled.${NC}"
|
|
return 0
|
|
}
|
|
|
|
# ── Main entry point ──
|
|
install_firmware() {
|
|
# Hardware state is detected on demand; the device
|
|
# arrays and DESKTOP_ENV/AUDIO_SERVER are read below.
|
|
_ensure_state_detected
|
|
|
|
echo -e "${YELLOW}Base firmware check...${NC}"
|
|
|
|
if ! _ensure_nonfree_repo; then
|
|
_msg "Error" "No 'non-free' repositories were enabled and the user declined to add them.\nPlease enable non-free manually or accept the prompt in the Firmware option." 10 65
|
|
return 1
|
|
fi
|
|
|
|
# 1. Detect
|
|
_detect_all_network_devices
|
|
_detect_firmware_needs
|
|
|
|
# 2. Plan
|
|
local plan
|
|
plan=$(_build_firmware_plan)
|
|
_msg "Firmware, Wireless & Bluetooth Setup" "$plan" 22 72
|
|
|
|
# 3. Confirm
|
|
if ! _confirm "Firmware" "Apply the network & firmware plan?"; then
|
|
echo "Firmware installation skipped."
|
|
return
|
|
fi
|
|
|
|
# 4. Install base firmware meta-package (unchanged logic)
|
|
local fw_pkg="firmware-linux-nonfree"
|
|
local fw_bpo
|
|
fw_bpo=$(_get_backports_version "$fw_pkg")
|
|
|
|
local fw_stable
|
|
fw_stable=$(_get_pkg_version "$fw_pkg")
|
|
|
|
if is_installed "$fw_pkg"; then
|
|
if [ -n "$fw_bpo" ]; then
|
|
local current_ver
|
|
current_ver=$(_get_installed_version "$fw_pkg")
|
|
if _confirm "Firmware" "firmware-linux-nonfree ${current_ver} already installed.\n\nUpgrade to backports version ${fw_bpo}?\n\nBackports often includes newer hardware support."; then
|
|
_run_cmd "Firmware" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $fw_pkg" "Upgrading firmware..." || true
|
|
fi
|
|
else
|
|
echo "$fw_pkg already installed."
|
|
fi
|
|
else
|
|
local msg="firmware-linux-nonfree provides hardware drivers for:\n"
|
|
msg+=" WiFi, Bluetooth, GPU, audio, webcams, and more.\n\n"
|
|
if [ -n "$fw_bpo" ]; then
|
|
msg+=" ● Stable: ${fw_stable}\n"
|
|
msg+=" Ultra tested, but may lack support for\n"
|
|
msg+=" very recent hardware.\n\n"
|
|
msg+=" ● Backports: ${fw_bpo} (Recommended)\n"
|
|
msg+=" Updated firmware for modern hardware from\n"
|
|
msg+=" 2025/2026: recent GPUs, processors, WiFi.\n\n"
|
|
msg+="Choose version:"
|
|
if _confirm_custom "Firmware" "$msg" "Backports" "Stable"; then
|
|
_run_cmd "Firmware" "sudo apt install -y -t ${DEBIAN_CODENAME}-backports $fw_pkg" "Installing firmware from backports..." || true
|
|
else
|
|
_run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware from stable..." || true
|
|
fi
|
|
else
|
|
msg+=" Version: ${fw_stable}\n\n"
|
|
msg+="Install it?"
|
|
if _confirm "Firmware" "$msg"; then
|
|
_run_cmd "Firmware" "sudo apt install -y $fw_pkg" "Installing firmware..." || true
|
|
fi
|
|
fi
|
|
echo -e "${GREEN}Base firmware installed.${NC}"
|
|
fi
|
|
|
|
# 5. Install specific network firmware packages
|
|
_install_detected_firmware
|
|
|
|
# 6. Broadcom wireless handler
|
|
_handle_wireless
|
|
|
|
# 7. Bluetooth stack
|
|
_install_bluetooth_stack
|
|
|
|
# 8. Summary
|
|
echo -e "${GREEN}Network & firmware setup complete.${NC}"
|
|
_pause
|
|
}
|