Files
Pathfinder 065a8cd0ae Add GPU-detected NVIDIA driver module
modules/user/nvidia.sh detects the card via lspci and installs the branch
that matches it: current (Turing+), 580xx (Volta/Pascal/Maxwell), 470xx
(Kepler), 390xx (Fermi); pre-Fermi is refused with an explanation.

- no prompt for a detected GPU (--nvidia=no is the opt-out, wired in setup.sh)
- Secure Boot gate: with enforcement on, the akmods key is generated and
  imported and the module stops BEFORE installing the driver, so nobody gets
  the documented unsigned-module black screen; off/setup-mode skips signing
  entirely (a MOK import is never processed when enforcement is off)
- bounded wait for the kmod build, so a reboot cannot land mid-build
- dnf mark user on the akmod; VA-API/vulkan offered as an opt-in extra
- never sets nvidia-drm.modeset=1 (RPM Fusion enables KMS; the flag conflicts
  with Fedora's simpledrm patch)
- branch chosen from the chip family in the PCI name, not the device-id
  ranges, which overlap between families

Tested with a stub harness (38 assertions, 14 scenarios): all four branch
mappings, multi-GPU warning, Optimus, pre-Fermi refusal, SB on/off/setup,
unparseable name fallback, idempotent re-run, build timeout.
2026-11-13 12:18:23 +01:00

8.4 KiB
Raw Permalink Blame History

Fedora Unified Config

Unified configuration for bare/minimal Fedora 44 and newer. Pick a desktop environment and optionally a tiling window manager; the script wires up repos, packages, the greeter and the session entry.

This repo is the Fedora-only successor to starburst. Everything multi-distro (Arch, Debian, Ubuntu branches, OS guessing, per-distro package helpers) is gone on purpose.

Usage

git clone https://git.ku-it.org/yuri/fedora.git
cd fedora
./setup.sh                      # interactive: choose DE, then TWM
./setup.sh --debug              # same, but pause after each section

Non-interactive:

./setup.sh --yes --de=none --twm=niri
./setup.sh --yes --de=gnome --twm=none

Run as your normal user, not root. sudo is used where needed.

Layout

setup.sh                  entrypoint: args, preconditions, base setup, menus, dispatch
lib/common.sh             colours, logging, dnf helpers, rpmfusion/terra, nerd fonts
lib/session.sh            display-manager detection/switching, session entries
modules/de/{gnome,plasma,xfce}.sh
modules/twm/{niri,hyprland,mango,chadwm}.sh
modules/user/dotfiles.sh   bare-repo dotfiles checkout
modules/user/nvidia.sh     GPU-detected NVIDIA driver install

Modules are separate processes, not sourced into setup.sh. That means a module's own set -e cannot leak into the caller, and every module can be run on its own for testing:

DE=none TWM=niri DEBUG_MODE=false bash modules/twm/niri.sh

Each module pulls in lib/ by relative path, so it works both ways.

Selection matrix

DE TWM Result
any any DE provides the session; TWM is added alongside it
none any TWM-only machine, SDDM installed as the greeter
any none plain desktop, no tiling WM
none none refused — that is not a graphical system

Desktop environments

DE dnf group (tried in order) native greeter
gnome gnome-desktop, gnome-desktop-environment, workstation-product-environment gdm
plasma kde-desktop, kde-desktop-environment sddm
xfce xfce-desktop, xfce-desktop-environment sddm

Tiling window managers

TWM Source Session type Notes
niri Fedora repos Wayland noctalia is packaged since F44; ships its own session entry
hyprland COPR (lionheartp, then hermitfeather, then solopasha) Wayland Retired from Fedora repos after F42; first COPR with a chroot for your release wins
mango Terra repo only Wayland Session entry written if the package lacks one
chadwm built from source X11 dwm fork; not packaged anywhere for Fedora

chadwm is the only X11 entry in the menu. The other three are Wayland compositors — do not expect the same config story from it.

GPU drivers (NVIDIA)

modules/user/nvidia.sh runs on detected hardware, no question asked: the card in the machine decides what is installed. Opt out with --nvidia=no (e.g. to stay on nouveau).

Branch selection comes from the chip family in the name lspci prints, because the numeric device-id ranges overlap between families and a wrong guess installs a module the card cannot use:

Chip family in the name Driver branch Packages
GB/AD/GA/TU (Turing and newer) current akmod-nvidia + xorg-x11-drv-nvidia-cuda
GV/GP/GM (Volta, Pascal, Maxwell) 580xx akmod-nvidia-580xx + xorg-x11-drv-nvidia-580xx{,-cuda}
GK (Kepler) 470xx akmod-nvidia-470xx + xorg-x11-drv-nvidia-470xx{,-cuda}
GF (Fermi) 390xx akmod-nvidia-390xx + xorg-x11-drv-nvidia-390xx{,-cuda}
pre-Fermi (G92, GT200, ...) none refused: 340xx is EOL and needs a longterm kernel

If the name cannot be parsed, the module asks for the branch instead of guessing.

Secure Boot. With enforcement on, the akmods key is generated and imported, and the module then stops before installing the driver — installing an unsigned module while Secure Boot enforces is the documented way to get a black screen, because the driver package blacklists nouveau as it lands. Enrol the key in MokManager at the next boot, then run the setup again. With Secure Boot off or in Setup mode, no signing happens at all: shim skips MokManager when enforcement is off, so an import request would just sit in the efivars.

After the transaction the module waits (bounded, 5 min) for the akmod to build so you cannot reboot into a driverless boot, runs dnf mark user on the akmod (so dnf autoremove cannot take it), and offers VA-API decode + vulkan as an opt-in extra. Nothing here sets nvidia-drm.modeset=1: RPM Fusion's kernel package already enables KMS, and the flag now conflicts with Fedora's simpledrm early-boot patch.

Display manager policy

  • A DE module leaves the DE's own greeter alone (GNOME→gdm, Plasma→sddm, XFCE→sddm). It never fights a desktop over its own login screen.
  • A TWM module enforces SDDM, because it is the only greeter that lists Wayland compositors and X11 sessions in one menu.
  • Either way graphical.target becomes the default.

System settings

Between base setup and the DE menu, the script asks two questions:

  1. Disable SELinux permanently? — default no. Writes SELINUX=disabled to /etc/selinux/config (backup kept); a reboot applies it. Recommended answer is no.
  2. Snapper + grub-btrfs + zstd compression — only asked when / is btrfs, default yes. Runs, in order:
    • btrfs subvolume list / and the fstab btrfs entries are shown
    • every fstab btrfs entry with a subvol= but no compress= gets ,compress=zstd:1 appended (fstab backed up first; re-runs cannot stack duplicate options)
    • the SysGuides installer sets up snapper (root + home), grub-btrfs, and DNF5 pre/post snapshot hooks, so every dnf transaction is snapshotted and snapper undochange works.

Unattended equivalents: --selinux=keep|disabled and --snapper=yes|no.

Design rules

  1. Fail loudly, early. set -e is on unless --debug. Unsupported distro, release below 44, DE=none + TWM=none, and a missing module all abort with an explanation instead of half-installing.
  2. Be idempotent. Re-running must be safe. Repos are checked with rpm -q before being added, the Nerd Font is skipped if already present, and session entries are not overwritten.
  3. Prefer official repos, then Terra, then a source build. That order is why only mango and chadwm need special handling.
  4. No silent optional failures. install_optional warns and continues for nice-to-haves; everything load-bearing uses install_packages and aborts.
  5. Guard anything environment-dependent. clear needs || true (no TERM under cron/pipes), os-release fields are defaulted, and /usr/share/xsessions is created before writing into it.

Testing

The script was verified on a non-Fedora host with a stateful stub harness (fake sudo/dnf/rpm/systemctl/git/make/curl, a fake os-release, and sandboxed /usr + $HOME). Covered: every DE×(TWM|none) combination, the refusal paths, --help/bad args, interactive menus, --debug abort, and re-running for idempotency.

OS_RELEASE_FILE is overridable purely so the preconditions can be tested:

OS_RELEASE_FILE=/tmp/fake-os-release ./setup.sh --yes --de=xfce --twm=chadwm

Known limitations

  • mangowc comes from Terra (added in the base section) and hyprland from a COPR — third-party sources whose layout is not guaranteed across Fedora releases; mango aborts with build-from-source instructions if the package is missing. noctalia has been in the Fedora repos since F44, so the niri module needs no third-party repo.
  • Package names are not verified by installation in this repo's test harness — only control flow is. First real run on a fresh F44 box is the actual proof.
  • gnome-tweaks/gnome-extensions-app, wofi, waybar, hyprlock and friends are installed with install_optional, so a rename will warn rather than fail.

Roadmap

  • Profile files (--profile=laptop) instead of individual flags
  • Optional dotfiles layer (noctalia/hyprland/niri configs)
  • --dry-run that prints the dnf transaction without applying it
  • Pre-flight report: what is already installed, what would change

License

See LICENSE.