feat(bootstrap): install vendor-matched hardware packages
This commit is contained in:
187
roles/bootstrap/tasks/_hardware.yml
Normal file
187
roles/bootstrap/tasks/_hardware.yml
Normal file
@@ -0,0 +1,187 @@
|
||||
---
|
||||
# Installs vendor-matched microcode/firmware/GPU/peripheral packages into /mnt
|
||||
# based on hardware_profile_active set by environment/_detect_hardware.yml.
|
||||
- name: Load hardware package definitions
|
||||
ansible.builtin.include_vars:
|
||||
file: hardware.yml
|
||||
|
||||
- name: Validate hardware support for current os_family
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- os_family in bootstrap_hardware_packages
|
||||
- hardware_profile_active is defined
|
||||
fail_msg: >-
|
||||
Hardware feature requested but no package map for os_family
|
||||
'{{ 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
|
||||
# the family lacks packages for it.
|
||||
- name: Resolve Nvidia driver flavor
|
||||
vars:
|
||||
_family: "{{ bootstrap_hardware_packages[os_family] }}"
|
||||
_user_driver: "{{ system_cfg.features.gpu.nvidia_driver | default('auto') }}"
|
||||
_has_nvidia: "{{ 'nvidia' in (hardware_profile_active.gpus | default([])) }}"
|
||||
_supports_open: "{{ hardware_profile_active.nvidia_supports_open | default(true) | bool }}"
|
||||
_open_pkgs: "{{ _family.gpu_nvidia.open | default([]) }}"
|
||||
_prop_pkgs: "{{ _family.gpu_nvidia.proprietary | default([]) }}"
|
||||
_auto_choice: >-
|
||||
{{
|
||||
('open' if _supports_open and _open_pkgs | length > 0
|
||||
else ('proprietary' if _prop_pkgs | length > 0
|
||||
else 'nouveau'))
|
||||
}}
|
||||
_user_choice: >-
|
||||
{{
|
||||
_auto_choice if _user_driver == 'auto'
|
||||
else (_user_driver
|
||||
if (_family.gpu_nvidia[_user_driver] | default([]) | length > 0)
|
||||
else 'nouveau')
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
_nvidia_driver_resolved: "{{ _user_choice if _has_nvidia else 'nouveau' }}"
|
||||
|
||||
# Fedora's akmod-nvidia* packages live in RPMFusion non-free, which is not
|
||||
# enabled out of the box; install the release RPM before the package step.
|
||||
- name: Enable RPMFusion non-free for Fedora Nvidia install
|
||||
when:
|
||||
- os_family == 'RedHat'
|
||||
- os == 'fedora'
|
||||
- system_cfg.features.gpu.enabled | bool
|
||||
- _nvidia_driver_resolved in ['open', 'proprietary']
|
||||
ansible.builtin.command: >-
|
||||
{{ chroot_command }} dnf install -y
|
||||
https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ os_version_major }}.noarch.rpm
|
||||
https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ os_version_major }}.noarch.rpm
|
||||
register: _rpmfusion_result
|
||||
changed_when: _rpmfusion_result.rc == 0
|
||||
|
||||
- name: Resolve hardware package set
|
||||
vars:
|
||||
_family: "{{ bootstrap_hardware_packages[os_family] }}"
|
||||
_cpu: "{{ hardware_profile_active.cpu | default('') | string }}"
|
||||
_gpus: "{{ hardware_profile_active.gpus | default([]) | list }}"
|
||||
_wifi: "{{ hardware_profile_active.wireless | default([]) | list }}"
|
||||
_fp_detected: "{{ hardware_profile_active.fingerprint | default(false) | bool }}"
|
||||
_firmware_on: "{{ system_cfg.features.firmware.enabled | bool }}"
|
||||
_microcode_on: "{{ _firmware_on and (system_cfg.features.firmware.microcode | bool) }}"
|
||||
_gpu_on: "{{ system_cfg.features.gpu.enabled | bool }}"
|
||||
_peripherals_on: "{{ system_cfg.features.peripherals.enabled | bool }}"
|
||||
_webcam_pref: "{{ system_cfg.features.peripherals.webcam | default('auto') }}"
|
||||
_fp_pref: "{{ system_cfg.features.peripherals.fingerprint | default('auto') }}"
|
||||
_dl_on: "{{ system_cfg.features.peripherals.displaylink | bool }}"
|
||||
_webcam_on: >-
|
||||
{{
|
||||
_peripherals_on
|
||||
and (_webcam_pref == 'true' or (_webcam_pref == 'auto' and _peripherals_on))
|
||||
}}
|
||||
_fp_on: >-
|
||||
{{
|
||||
_peripherals_on
|
||||
and (_fp_pref == 'true' or (_fp_pref == 'auto' and _fp_detected))
|
||||
}}
|
||||
# Union of GPU/wireless/CPU vendors; CPU vendor is included so Intel-CPU
|
||||
# systems pull i915/iwlwifi firmware via the same vendor split.
|
||||
_cpu_vendor_list: "{{ ([_cpu] if (_cpu | length > 0) else []) | list }}"
|
||||
_firmware_vendors: >-
|
||||
{{
|
||||
(_firmware_on | ternary(
|
||||
(_gpus + _wifi + _cpu_vendor_list)
|
||||
| reject('equalto', '') | unique | list,
|
||||
[]
|
||||
))
|
||||
}}
|
||||
_microcode_pkgs: >-
|
||||
{{
|
||||
((_microcode_on and _cpu | length > 0) | ternary(
|
||||
_family.cpu_microcode[_cpu] | default([]),
|
||||
[]
|
||||
)) | list
|
||||
}}
|
||||
_firmware_pkgs: >-
|
||||
{{
|
||||
(_firmware_on | ternary(
|
||||
(_family.firmware_base | default([]) | list)
|
||||
+ (_firmware_vendors
|
||||
| map('extract', _family.firmware | default({}))
|
||||
| select('truthy')
|
||||
| list
|
||||
| sum(start=[])),
|
||||
[]
|
||||
)) | list
|
||||
}}
|
||||
_gpu_base_pkgs: "{{ (_gpu_on | ternary(_family.gpu_base | default([]), [])) | list }}"
|
||||
_gpu_vendor_pkgs: >-
|
||||
{{
|
||||
(_gpu_on | ternary(
|
||||
(_gpus | reject('equalto', 'nvidia') | list)
|
||||
| map('extract', _family.gpu | default({}))
|
||||
| select('truthy')
|
||||
| list
|
||||
| sum(start=[]),
|
||||
[]
|
||||
)) | list
|
||||
}}
|
||||
_gpu_nvidia_pkgs: >-
|
||||
{{
|
||||
((_gpu_on and ('nvidia' in _gpus)) | ternary(
|
||||
_family.gpu_nvidia[_nvidia_driver_resolved] | default([]),
|
||||
[]
|
||||
)) | list
|
||||
}}
|
||||
_peripherals_base_pkgs: >-
|
||||
{{
|
||||
(_webcam_on | ternary(_family.peripherals_base | default([]), [])) | list
|
||||
}}
|
||||
_peripherals_fingerprint_pkgs: >-
|
||||
{{
|
||||
(_fp_on | ternary(_family.peripherals_fingerprint | default([]), [])) | list
|
||||
}}
|
||||
_peripherals_displaylink_pkgs: >-
|
||||
{{
|
||||
(_dl_on | ternary(_family.peripherals_displaylink | default([]), [])) | list
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
_hardware_packages: >-
|
||||
{{
|
||||
(_microcode_pkgs + _firmware_pkgs
|
||||
+ _gpu_base_pkgs + _gpu_vendor_pkgs + _gpu_nvidia_pkgs
|
||||
+ _peripherals_base_pkgs + _peripherals_fingerprint_pkgs
|
||||
+ _peripherals_displaylink_pkgs)
|
||||
| reject('equalto', '')
|
||||
| unique
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: Report hardware package selection
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Hardware install ({{ os_family }}):
|
||||
cpu={{ hardware_profile_active.cpu | default('-') }},
|
||||
gpus={{ hardware_profile_active.gpus | default([]) | join(',') | default('-', true) }},
|
||||
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)
|
||||
|
||||
- name: Install hardware packages
|
||||
when: _hardware_packages | length > 0
|
||||
vars:
|
||||
_install_commands:
|
||||
RedHat: >-
|
||||
{{ chroot_command }} dnf --releasever={{ os_version }}
|
||||
--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
|
||||
Reference in New Issue
Block a user