#!/usr/bin/env bash # =========================================================================== # Distribution Detection & Common Variables # Sourced by 00-envcheck.sh, then available to all subsequent stages. # # After sourcing this, use these variables instead of hardcoding commands: # $PKG_INSTALL — Install packages # $PKG_UPDATE — Update package cache # $PKG_REMOVE — Remove packages # $PKG_GROUP_INSTALL — Install package group # $DISTRO_FAMILY — "debian" or "fedora" # $DISTRO_ID — "pop", "ubuntu", "fedora", etc. # $DISTRO_VERSION — "24.04", "41", etc. # See full list below. # =========================================================================== # ---- Detect distribution ---- DISTRO_ID="" DISTRO_VERSION="" DISTRO_FAMILY="" # "debian" (apt) or "fedora" (dnf) DISTRO_LIKE="" # from ID_LIKE in os-release if [ -f /etc/os-release ]; then . /etc/os-release DISTRO_ID="${ID:-}" DISTRO_VERSION="${VERSION_ID:-}" DISTRO_LIKE="${ID_LIKE:-}" fi # ---- Determine distro family ---- case "$DISTRO_ID" in fedora|rhel|centos) DISTRO_FAMILY="fedora" ;; pop|ubuntu|debian|linuxmint|elementary|zorin) DISTRO_FAMILY="debian" ;; *) # Fall back to ID_LIKE case "$DISTRO_LIKE" in *fedora*) DISTRO_FAMILY="fedora" ;; *debian*) DISTRO_FAMILY="debian" ;; *) DISTRO_FAMILY="unknown" ;; esac ;; esac # ---- Fail early on unknown distro ---- if [ "$DISTRO_FAMILY" = "unknown" ]; then echo "[ERROR] Unknown distribution: $DISTRO_ID (ID_LIKE=$DISTRO_LIKE)" echo " Edit lib/distro.sh to add support." exit 1 fi # =========================================================================== # Package Manager Commands # =========================================================================== if [ "$DISTRO_FAMILY" = "debian" ]; then PKG_MGR="apt" PKG_UPDATE="sudo apt update" PKG_INSTALL="sudo apt install -y" PKG_INSTALL_NO_REC="sudo apt install -y --no-install-recommends" PKG_REMOVE="sudo apt remove -y" PKG_PURGE="sudo apt purge -y" PKG_AUTOREMOVE="sudo apt autoremove -y" PKG_SEARCH="apt search" PKG_LIST_INSTALLED="dpkg -l" # Repo management REPO_ADD_PPA="sudo add-apt-repository -y" REPO_APT_KEY="sudo apt-key add -" # legacy, use signed-by when possible REPO_ADD_LIST="sudo tee /etc/apt/sources.list.d" # Service / boot SERVICE_ENABLE="sudo systemctl enable --now" GRUB_UPDATE="sudo update-grub" GRUB_FILE="/etc/default/grub" # Desktop environment detection # Pop uses COSMIC; Ubuntu uses GNOME; Kubuntu uses KDE case "$DISTRO_ID" in pop) DEFAULT_DE="COSMIC" ;; ubuntu|debian) DEFAULT_DE="GNOME" ;; *) DEFAULT_DE="" ;; # unknown esac elif [ "$DISTRO_FAMILY" = "fedora" ]; then PKG_MGR="dnf" PKG_UPDATE="sudo dnf makecache" PKG_INSTALL="sudo dnf install -y" PKG_INSTALL_NO_REC="sudo dnf install -y" # dnf has no --no-install-recommends equivalent PKG_REMOVE="sudo dnf remove -y" PKG_PURGE="sudo dnf remove -y" PKG_AUTOREMOVE="sudo dnf autoremove -y" PKG_SEARCH="dnf search" PKG_LIST_INSTALLED="dnf list installed" # Repo management REPO_ADD_COPR="sudo dnf copr enable -y" REPO_ADD_RPM="sudo dnf config-manager addrepo --from-repofile=" # Note: use as function call, see repo_add_rpm below # Service / boot SERVICE_ENABLE="sudo systemctl enable --now" GRUB_UPDATE="sudo grub2-mkconfig -o /boot/grub2/grub.cfg" GRUB_EFI_UPDATE="sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg" GRUB_FILE="/etc/default/grub" # Desktop environment detection DEFAULT_DE="GNOME" # Fedora Workstation defaults to GNOME fi # =========================================================================== # Helper function: add RPM repo via DNF5 config-manager addrepo # =========================================================================== repo_add_rpm() { local url="$1" local repo_file repo_file="/etc/yum.repos.d/$(basename "$url")" shift if [ "$DISTRO_FAMILY" = "fedora" ]; then # Skip if repo file already exists (idempotent) if [ -f "$repo_file" ]; then return 0 fi sudo dnf config-manager addrepo --from-repofile="$url" "$@" 2>/dev/null || return 1 # Disable repo_gpgcheck to avoid interactive GPG prompts in automated provisioning # Package signatures are still verified via gpgcheck if [ -f "$repo_file" ]; then sudo sed -i 's/repo_gpgcheck=1/repo_gpgcheck=0/' "$repo_file" 2>/dev/null || true fi else return 0 fi } # =========================================================================== # Helper function: install package(s), silently skip if already installed # =========================================================================== pkg_install() { if [ "$DISTRO_FAMILY" = "debian" ]; then sudo apt install -y "$@" 2>/dev/null || return 1 else sudo dnf install -y "$@" 2>/dev/null || return 1 fi } # Wrapper for group installs (ignored on apt systems) pkg_group_install() { if [ "$DISTRO_FAMILY" = "fedora" ]; then sudo dnf group install -y "$@" 2>/dev/null || return 1 else # On Debian, groups aren't a thing — just skip return 0 fi } # =========================================================================== # Package Name Mappings (Debian → Fedora and vice versa) # Usage: pkg_name_fedora="foo" pkg_name_debian="bar" # pkg_name "$pkg_name_fedora" "$pkg_name_debian" # Or use the shorthand below for known differences. # =========================================================================== # Known package name differences resolve_pkg() { local debian_name="$1" local fedora_name="$2" if [ "$DISTRO_FAMILY" = "debian" ]; then echo "$debian_name" else echo "$fedora_name" fi } # Convenience: install a package that may have different names pkg_install_mapped() { local debian_name="$1" local fedora_name="$2" if [ "$DISTRO_FAMILY" = "debian" ]; then pkg_install "$debian_name" else pkg_install "$fedora_name" fi } # Export all variables so sourced stages can use them export DISTRO_FAMILY DISTRO_ID DISTRO_VERSION DISTRO_LIKE export PKG_MGR PKG_UPDATE PKG_INSTALL PKG_INSTALL_NO_REC export PKG_REMOVE PKG_PURGE PKG_AUTOREMOVE export PKG_SEARCH PKG_LIST_INSTALLED export SERVICE_ENABLE GRUB_UPDATE GRUB_EFI_UPDATE GRUB_FILE export DEFAULT_DE # Export helpers export -f pkg_install pkg_group_install pkg_install_mapped resolve_pkg repo_add_rpm