mirror of
https://github.com/stornic56/debianito-post-install.git
synced 2026-10-31 13:08:06 +00:00
21e9973c2f
- Verified the repository backup rc in migrate.sh. `_persistent_backup_repos()` now aborts before any destructive step when the tar archive is missing or corrupt, removing the invalid backup itself. - Verified the restore rc in migrate.sh. `_restore_backup()` now reports failure instead of printing a green "Backup restored" message, and its caller distinguishes a restored backup from a failed restore. - Made the upgrade phases fail honestly. `apt upgrade` and `apt full-upgrade` now abort with `apt --fix-broken install` + `dpkg --configure -a` instructions instead of reporting "completed successfully" over a partially-upgraded system. - Made repository source writes atomic. Both writers tee into a `.tmp` file and move into place, and the `/etc/apt/sources.list` removal now happens after the write. - Corrected the SID warning text in migrate.sh to reflect that security fixes arrive via package uploads rather than a nonexistent sid-security suite. - Added exit-path cleanup traps for the temp `.deb` files: `trap 'rm -f "$deb_path"' RETURN` in `heroic.sh`and `tools.sh`. - Tightened Heroic download handling: the API fetch uses `curl -fsS --connect-timeout 10 --max-time 30`, the download uses `curl -fsSL --max-time 300`, and the `.deb` is validated with both `dpkg-deb --info` and `dpkg-deb --contents`; `sudo apt install` is guarded with `if !` before the temporary file is deleted. - Tightened the OpenRGB install path: the Codeberg API fetch uses `curl -fsS --connect-timeout 10 --max-time 30` and the download `curl -fsSL --max-time 300`, with the same dual `dpkg-deb` integrity check as the Heroic fallback. - Guarded the OpenRGB post-install side effects: the script now aborts after removing the failed `.deb` if `sudo apt install` returns non-zero, so `modprobe i2c-dev`, `/etc/modules`, the `i2c` group membership, `udevadm`, and the `setcap` step no longer run when the package is absent.
432 lines
17 KiB
Bash
432 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 dev_id
|
|
bcm_id=$(echo "$dev" | grep -oP '14e4:[0-9a-fA-F]+' || true)
|
|
[ -z "$bcm_id" ] && continue
|
|
dev_id=$(echo "$bcm_id" | cut -d: -f2 | tr '[:upper:]' '[:lower:]')
|
|
|
|
# --- 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 ! ls /lib/modules/$(uname -r)/updates/dkms/wl.ko* 2>/dev/null | grep -q .; 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 ls /lib/modules/$(uname -r)/updates/dkms/wl.ko* 2>/dev/null | grep -q .; 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
|
|
|
|
# --- Verificación de carga ---
|
|
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
|
|
}
|