From c843f5289bd17da530a43b524cceb38fa0b1d092 Mon Sep 17 00:00:00 2001 From: Sandwich Date: Sat, 30 May 2026 18:05:05 +0200 Subject: [PATCH] feat: hardware/firmware/gpu/peripherals detection and packages --- roles/bootstrap/defaults/main.yml | 5 +- roles/bootstrap/tasks/_dnf_family.yml | 4 +- roles/bootstrap/tasks/_hardware.yml | 14 ++-- roles/bootstrap/tasks/debian.yml | 3 + roles/bootstrap/vars/hardware.yml | 87 ++----------------------- roles/bootstrap/vars/main.yml | 70 -------------------- roles/environment/defaults/main.yml | 2 +- roles/global_defaults/defaults/main.yml | 25 ++++--- roles/global_defaults/tasks/main.yml | 2 +- roles/global_defaults/tasks/system.yml | 2 +- 10 files changed, 30 insertions(+), 184 deletions(-) diff --git a/roles/bootstrap/defaults/main.yml b/roles/bootstrap/defaults/main.yml index 83d62cd..a063428 100644 --- a/roles/bootstrap/defaults/main.yml +++ b/roles/bootstrap/defaults/main.yml @@ -1,15 +1,12 @@ --- -# OS → task file mapping for bootstrap dispatch. +# OS -> task file mapping for bootstrap dispatch. # Each key matches a supported `os` value; value is the task file to include. bootstrap_os_task_map: almalinux: _dnf_family.yml - alpine: alpine.yml archlinux: archlinux.yml debian: debian.yml fedora: _dnf_family.yml - opensuse: opensuse.yml rocky: _dnf_family.yml rhel: rhel.yml ubuntu: ubuntu.yml ubuntu-lts: ubuntu.yml - void: void.yml diff --git a/roles/bootstrap/tasks/_dnf_family.yml b/roles/bootstrap/tasks/_dnf_family.yml index df9ff7b..01e4a11 100644 --- a/roles/bootstrap/tasks/_dnf_family.yml +++ b/roles/bootstrap/tasks/_dnf_family.yml @@ -13,7 +13,7 @@ block: - name: "Install base system for {{ os | capitalize }}" ansible.builtin.command: >- - dnf --releasever={{ os_version }} --best {{ _dnf_repos }} + dnf --releasever={{ os_version_major }} --best {{ _dnf_repos }} --installroot=/mnt --setopt=install_weak_deps=False groupinstall -y {{ _dnf_groups }} register: bootstrap_dnf_base_result @@ -31,7 +31,7 @@ - name: Install extra packages ansible.builtin.command: >- - {{ chroot_command }} dnf --releasever={{ os_version }} --setopt=install_weak_deps=False + {{ chroot_command }} dnf --releasever={{ os_version_major }} --setopt=install_weak_deps=False install -y {{ _dnf_extra }} register: bootstrap_dnf_extra_result changed_when: bootstrap_dnf_extra_result.rc == 0 diff --git a/roles/bootstrap/tasks/_hardware.yml b/roles/bootstrap/tasks/_hardware.yml index 06d1871..7f49814 100644 --- a/roles/bootstrap/tasks/_hardware.yml +++ b/roles/bootstrap/tasks/_hardware.yml @@ -15,8 +15,8 @@ '{{ os_family }}'. Extend roles/bootstrap/vars/hardware.yml. quiet: true -# nvidia_driver: auto → open (Turing+) → proprietary (older, if family ships it) -# → nouveau (fallback). Explicit value falls back to nouveau when +# nvidia_driver: auto -> open (Turing+) -> proprietary (older, if family ships it) +# -> nouveau (fallback). Explicit value falls back to nouveau when # the family lacks packages for it. - name: Resolve Nvidia driver flavor vars: @@ -163,25 +163,19 @@ nvidia_driver={{ _nvidia_driver_resolved }}, wireless={{ hardware_profile_active.wireless | default([]) | join(',') | default('-', true) }}, fingerprint={{ hardware_profile_active.fingerprint | default(false) }} - → {{ _hardware_packages | length }} package(s) + -> {{ _hardware_packages | length }} package(s) - name: Install hardware packages when: _hardware_packages | length > 0 vars: _install_commands: RedHat: >- - {{ chroot_command }} dnf --releasever={{ os_version }} + {{ chroot_command }} dnf --releasever={{ os_version_major }} --setopt=install_weak_deps=False install -y {{ _hardware_packages | join(' ') }} Debian: >- {{ chroot_command }} apt install -y {{ _hardware_packages | join(' ') }} Archlinux: >- pacstrap /mnt {{ _hardware_packages | join(' ') }} - Suse: >- - {{ chroot_command }} zypper install -y {{ _hardware_packages | join(' ') }} - Alpine: >- - {{ chroot_command }} apk add {{ _hardware_packages | join(' ') }} - Void: >- - {{ chroot_command }} xbps-install -Sy {{ _hardware_packages | join(' ') }} ansible.builtin.command: "{{ _install_commands[os_family] }}" register: _hardware_install_result changed_when: _hardware_install_result.rc == 0 diff --git a/roles/bootstrap/tasks/debian.yml b/roles/bootstrap/tasks/debian.yml index 6555617..55e3c14 100644 --- a/roles/bootstrap/tasks/debian.yml +++ b/roles/bootstrap/tasks/debian.yml @@ -66,7 +66,10 @@ register: bootstrap_debian_extra_result changed_when: bootstrap_debian_extra_result.rc == 0 + # Printing (libcups2) and mDNS (libavahi*) are needed by a desktop session, + # so keep them when a desktop is requested. - name: Remove unnecessary packages + when: not (system_cfg.features.desktop.enabled | bool) ansible.builtin.command: "{{ chroot_command }} apt remove -y libcups2 libavahi-common3 libavahi-common-data" register: bootstrap_debian_remove_result changed_when: bootstrap_debian_remove_result.rc == 0 diff --git a/roles/bootstrap/vars/hardware.yml b/roles/bootstrap/vars/hardware.yml index 3647ea1..42a22e5 100644 --- a/roles/bootstrap/vars/hardware.yml +++ b/roles/bootstrap/vars/hardware.yml @@ -38,7 +38,8 @@ bootstrap_hardware_packages: gpu_nvidia: open: [nvidia-open-dkms, nvidia-utils] proprietary: [nvidia-dkms, nvidia-utils] - nouveau: [xf86-video-nouveau, vulkan-nouveau] + # Wayland-only: kernel nouveau module + mesa/gbm drive the display; no Xorg DDX. + nouveau: [vulkan-nouveau] peripherals_base: [v4l-utils] peripherals_fingerprint: [fprintd, libfprint] peripherals_displaylink: [] # AUR only; user must wire in AUR helper @@ -69,7 +70,8 @@ bootstrap_hardware_packages: # the proprietary nvidia-driver. Both come from the non-free component. open: [nvidia-open-kernel-dkms, nvidia-driver, nvidia-vulkan-icd] proprietary: [nvidia-driver, nvidia-vulkan-icd] - nouveau: [xserver-xorg-video-nouveau] + # Wayland-only: kernel module + mesa (gpu_base) cover it; no Xorg DDX, no extra pkg. + nouveau: [] peripherals_base: [v4l-utils] peripherals_fingerprint: [fprintd, libpam-fprintd] peripherals_displaylink: [evdi-dkms] # userspace driver still needs vendor .run @@ -99,85 +101,8 @@ bootstrap_hardware_packages: # akmod packages from RPMFusion non-free; repo enabled by _hardware.yml. open: [akmod-nvidia-open, xorg-x11-drv-nvidia, xorg-x11-drv-nvidia-cuda] proprietary: [akmod-nvidia, xorg-x11-drv-nvidia, xorg-x11-drv-nvidia-cuda] - nouveau: [xorg-x11-drv-nouveau] + # Wayland-only: kernel module + mesa (gpu_base) cover it; no Xorg DDX, no extra pkg. + nouveau: [] peripherals_base: [v4l-utils] peripherals_fingerprint: [fprintd, fprintd-pam] peripherals_displaylink: [evdi] # COPR-supplied; repo enablement deferred - - Suse: - cpu_microcode: - intel: [ucode-intel] - amd: [ucode-amd] - firmware_base: [kernel-firmware-all] - firmware: {} - gpu_base: [Mesa, Mesa-libGL1, libvulkan1] - gpu: - intel: [libvulkan_intel] - amd: [libvulkan_radeon] - gpu_nvidia: - # NVIDIA SUSE repo packages; repo enablement out of scope for v1. - open: [nvidia-open-driver-G06-signed-kmp-default] - proprietary: [x11-video-nvidiaG06] - nouveau: [xf86-video-nouveau] - peripherals_base: [v4l-utils] - peripherals_fingerprint: [fprintd, libfprint-2-2] - peripherals_displaylink: [] - - Alpine: - cpu_microcode: - intel: [intel-ucode] - amd: [amd-ucode] - firmware_base: [] - firmware: - intel: [linux-firmware-other, linux-firmware-i915] - amd: [linux-firmware-amdgpu] - nvidia: [linux-firmware-nvidia] - atheros: [linux-firmware-ath10k_pci, linux-firmware-ath11k] - broadcom: [linux-firmware-brcm] - mediatek: [linux-firmware-mediatek] - marvell: [linux-firmware-mrvl] - realtek: [linux-firmware-rtl_nic, linux-firmware-rtlwifi] - qcom: [linux-firmware-qcom] - cirrus: [linux-firmware-cirrus] - other: [linux-firmware-other] - gpu_base: [mesa, mesa-dri-gallium] - gpu: - intel: [mesa-vulkan-intel, intel-media-driver] - amd: [mesa-vulkan-ati, mesa-va-gallium] - gpu_nvidia: - # Alpine ships only the open-kernel-modules variant in community. - open: [nvidia-open-gpu-kernel-modules] - proprietary: [] # not packaged on Alpine - nouveau: [mesa-vulkan-nouveau] - peripherals_base: [v4l-utils] - peripherals_fingerprint: [fprintd, libfprint] - peripherals_displaylink: [] - - Void: - cpu_microcode: - intel: [intel-ucode] - amd: [linux-firmware-amd] - firmware_base: [linux-firmware] - firmware: - intel: [linux-firmware-intel, linux-firmware-network] - amd: [linux-firmware-amd] - nvidia: [linux-firmware-nvidia] - atheros: [linux-firmware-network] - broadcom: [linux-firmware-broadcom] - mediatek: [linux-firmware-network] - marvell: [linux-firmware-network] - realtek: [linux-firmware-network] - qcom: [linux-firmware-network] - cirrus: [linux-firmware] - other: [linux-firmware] - gpu_base: [mesa, mesa-dri] - gpu: - intel: [mesa-vulkan-intel, intel-video-accel] - amd: [mesa-vulkan-radeon, mesa-vaapi] - gpu_nvidia: - open: [nvidia-open] # in nonfree repo - proprietary: [nvidia] # in nonfree repo - nouveau: [xf86-video-nouveau] - peripherals_base: [v4l-utils] - peripherals_fingerprint: [fprintd, libfprint] - peripherals_displaylink: [] diff --git a/roles/bootstrap/vars/main.yml b/roles/bootstrap/vars/main.yml index 340b6f6..18db7c0 100644 --- a/roles/bootstrap/vars/main.yml +++ b/roles/bootstrap/vars/main.yml @@ -328,73 +328,3 @@ bootstrap_archlinux: + (['sbctl'] if system_cfg.features.secure_boot.enabled | bool else []) + (bootstrap_common_conditional | reject('equalto', 'nftables') | list) }} - -bootstrap_alpine: - base: - - alpine-base - extra: - - btrfs-progs - - chrony - - curl - - e2fsprogs - - linux-lts - - logrotate - - lvm2 - - python3 - - rsync - - sudo - - util-linux - - vim - - xfsprogs - conditional: >- - {{ - (['openssh'] if system_cfg.features.ssh.enabled | bool else []) - + bootstrap_common_conditional - }} - -bootstrap_opensuse: - base: - - patterns-base-base - extra: - - btrfs-progs - - chrony - - curl - - e2fsprogs - - glibc-locale - - kernel-default - - logrotate - - lvm2 - - NetworkManager - - python3 - - rsync - - sudo - - vim - - xfsprogs - conditional: >- - {{ - (['openssh'] if system_cfg.features.ssh.enabled | bool else []) - + bootstrap_common_conditional - }} - -bootstrap_void: - base: - - base-system - - void-repo-nonfree - extra: - - btrfs-progs - - chrony - - curl - - dhcpcd - - e2fsprogs - - logrotate - - lvm2 - - python3 - - rsync - - sudo - - vim - - xfsprogs - conditional: >- - {{ - (['openssh'] if system_cfg.features.ssh.enabled | bool else []) - + bootstrap_common_conditional - }} diff --git a/roles/environment/defaults/main.yml b/roles/environment/defaults/main.yml index 80e9454..69520c6 100644 --- a/roles/environment/defaults/main.yml +++ b/roles/environment/defaults/main.yml @@ -9,7 +9,7 @@ environment_pacman_lock_timeout: 120 environment_pacman_retries: 4 environment_pacman_retry_delay: 15 -# PCI vendor IDs → vendor codes used by hardware detection. +# PCI vendor IDs -> vendor codes used by hardware detection. # Only vendors that drive distinct firmware/driver packages are mapped. environment_pci_vendor_map: "8086": intel diff --git a/roles/global_defaults/defaults/main.yml b/roles/global_defaults/defaults/main.yml index 40cfc0d..c36434f 100644 --- a/roles/global_defaults/defaults/main.yml +++ b/roles/global_defaults/defaults/main.yml @@ -1,5 +1,5 @@ --- -# OS family lists — single source of truth for platform detection and validation +# OS family lists - single source of truth for platform detection and validation os_family_rhel: - almalinux - fedora @@ -10,33 +10,27 @@ os_family_debian: - ubuntu - ubuntu-lts -# OS → family mapping — aligns with the main project's ansible_os_family pattern. +# OS -> family mapping - aligns with the main project's ansible_os_family pattern. # Enables platform_config dict lookups per role instead of inline when: is_rhel chains. os_family_map: almalinux: RedHat - alpine: Alpine archlinux: Archlinux debian: Debian fedora: RedHat - opensuse: Suse rhel: RedHat rocky: RedHat ubuntu: Debian ubuntu-lts: Debian - void: Void os_supported: - almalinux - - alpine - archlinux - debian - fedora - - opensuse - rhel - rocky - ubuntu - ubuntu-lts - - void # User input. Normalized into hypervisor_cfg + hypervisor_type. hypervisor: @@ -125,7 +119,7 @@ system_defaults: motd: false sudo: true rhel_repo: - source: "iso" # iso|satellite|none — how RHEL systems get packages post-install + source: "iso" # iso|satellite|none - how RHEL systems get packages post-install url: "" # Satellite/custom repo URL when source=satellite chroot: tool: "arch-chroot" # arch-chroot|chroot|systemd-nspawn @@ -133,8 +127,11 @@ system_defaults: generator: "" # auto-detected; override: dracut|mkinitcpio|initramfs-tools desktop: enabled: false - environment: "" # gnome|kde|xfce|sway|hyprland|cinnamon|mate|lxqt|budgie - display_manager: "" # auto from environment when empty; override: gdm|sddm|lightdm|greetd + environment: "" # gnome|kde|sway|hyprland + display_manager: "" # auto from environment when empty; override: gdm|sddm|greetd + autologin: false # false | username from system.users + session: "" # session name/command for the autologin user + groups: [] # opt-in package groups (keys of desktop_package_groups) secure_boot: enabled: false method: "" # arch only: sbctl (default) or uki; ignored for other distros @@ -142,7 +139,7 @@ system_defaults: enabled: "auto" # auto = on for physical, off for virtual microcode: "auto" gpu: - enabled: false + enabled: "auto" # auto = follows desktop.enabled nvidia_driver: "auto" # auto | open | proprietary | nouveau peripherals: enabled: "auto" # auto = follows desktop.enabled @@ -152,7 +149,7 @@ system_defaults: hardware: profile: {} # empty = autodetect; set to override (golden image) -# Per-hypervisor required fields — drives data-driven validation. +# Per-hypervisor required fields - drives data-driven validation. # All virtual types additionally require network bridge or interfaces. hypervisor_required_fields: proxmox: @@ -176,7 +173,7 @@ hypervisor_disk_device_map: proxmox: "/dev/sd" vmware: "/dev/sd" -# Mountpoints managed by the partitioning role — forbidden for extra disks. +# Mountpoints managed by the partitioning role - forbidden for extra disks. reserved_mounts: - /boot - /boot/efi diff --git a/roles/global_defaults/tasks/main.yml b/roles/global_defaults/tasks/main.yml index e94a517..52ffee0 100644 --- a/roles/global_defaults/tasks/main.yml +++ b/roles/global_defaults/tasks/main.yml @@ -1,5 +1,5 @@ --- -# Centralized normalization — all input dicts (system, hypervisor, disks) +# Centralized normalization - all input dicts (system, hypervisor, disks) # are normalized here into system_cfg, hypervisor_cfg, etc. # Downstream roles consume these computed facts directly and do NOT need # per-role _normalize.yml (except CIS, which has its own input dict). diff --git a/roles/global_defaults/tasks/system.yml b/roles/global_defaults/tasks/system.yml index 990f6d5..4d54f84 100644 --- a/roles/global_defaults/tasks/system.yml +++ b/roles/global_defaults/tasks/system.yml @@ -56,7 +56,7 @@ - _bootstrap_needs_enrichment | default(false) | bool - system_cfg.mirror | default('') | string | trim | length == 0 vars: - # Same as _normalize_system.yml — kept in sync manually. + # Same as _normalize_system.yml - kept in sync manually. _mirror_defaults: debian: "https://deb.debian.org/debian/" ubuntu: "http://archive.ubuntu.com/ubuntu/"