4 Commits

Author SHA1 Message Date
nocode 20e0643a02 feat(anaconda): add automatic hardware detection and driver installation
Add hardware detection and automatic driver installation during system installation. This includes:

- Virtualization platform detection with automatic guest tools configuration
- Automatic GPU driver installation (NVIDIA, AMD, Intel)
- Removal of incompatible guest tools for other hypervisors
- Network-resilient installation (non-blocking if network unavailable)

The detection uses the fws-hw-detect script which provides the same hardware information shown to the user in the live environment summary screen. This ensures what was announced to the user is what gets applied during installation.

Update section numbering in kickstart file to accommodate the new hardware configuration step.
2026-07-03 03:24:28 +02:00
nocode 071cc307b4 chore(baseline): add file permission for fws-hw-detect binary 2026-07-03 03:24:20 +02:00
nocode 1917a3321b feat(xinitrc): add hardware detection summary before installer launch
Add fws-hw-detect integration to display hardware information in a dialog before launching the installer. This allows users to review detected hardware (GPU drivers, hypervisor guest tools, disk info) before proceeding.

The summary is shown via zenity if available, with options to launch the installer or power off. Also includes the hardware summary in the installation logs for debugging purposes.
2026-07-03 03:24:14 +02:00
nocode 19c16006fb feat(baseline): add fws-hw-detect script for hardware detection and configuration
Add new fws-hw-detect script that detects hypervisor type and GPU hardware, outputting either machine-readable environment variables for kickstart processing or human-readable French text summary for live environment.

The script serves as the single source of truth for hardware detection, consumed by:
- Live environment display via zenity before installation starts
- Anaconda %post chroot to apply appropriate guest tools and GPU drivers

Supported hypervisors: VMware, VirtualBox, QEMU/KVM, and physical machines
Supported GPUs: NVIDIA, AMD, Intel, and VMware/VirtualBox virtual graphics

No hard dependencies; gracefully degrades when lspci and ip are unavailable.
2026-07-03 03:21:31 +02:00
4 changed files with 240 additions and 3 deletions
+23
View File
@@ -20,6 +20,26 @@ _OB_PID=$!
# boucle (symptôme « fond bleu qui clignote/reboote »). On NE rend jamais la main
# à startx : on reste sur Openbox pour lire les logs / rebooter proprement.
if command -v liveinst >/dev/null 2>&1; then
# Chantier D : RÉCAPITULATIF matériel AVANT de lancer l'installateur.
# fws-hw-detect est la MÊME source de vérité que le %post du kickstart
# (mode --env) → ce que cet écran annonce = ce que l'install appliquera
# (drivers GPU, guest tools de l'hyperviseur, effacement des disques…).
# « Éteindre » est le seul moyen propre d'annuler : on ne rend jamais la
# main à startx (cf. plus bas), et liveinst n'a pas encore touché au disque.
# Tout est best-effort : sans script ou sans zenity, on installe comme avant.
if command -v fws-hw-detect >/dev/null 2>&1; then
fws-hw-detect --text >/tmp/fws-hw-summary.txt 2>/dev/null || true
if command -v zenity >/dev/null 2>&1 && [ -s /tmp/fws-hw-summary.txt ]; then
if ! zenity --text-info --title="FWS — Récapitulatif avant installation" \
--filename=/tmp/fws-hw-summary.txt \
--ok-label="Lancer l'installateur" --cancel-label="Éteindre" \
--width=800 --height=700 2>/dev/null; then
systemctl poweroff
exit 0
fi
fi
fi
LIVEINST_LOG=/tmp/fws-liveinst.log
liveinst >"$LIVEINST_LOG" 2>&1
rc=$?
@@ -66,6 +86,9 @@ if command -v liveinst >/dev/null 2>&1; then
echo
echo "########## %post --nochroot (/tmp/fws-post-nochroot.log) ##########"
cat /tmp/fws-post-nochroot.log 2>/dev/null || echo "(absent)"
echo
echo "########## Récapitulatif matériel montré avant l'install ##########"
cat /tmp/fws-hw-summary.txt 2>/dev/null || echo "(absent)"
for f in /tmp/anaconda.log /tmp/syslog /tmp/program.log \
/tmp/storage.log /tmp/dbus.log /tmp/packaging.log /tmp/X.log; do
echo
@@ -0,0 +1,173 @@
#!/bin/bash
# ============================================================================
# fws-hw-detect — détection matériel FWS (hyperviseur + GPU).
#
# SOURCE UNIQUE de vérité, consommée par DEUX endroits :
# • l'écran « Récapitulatif avant installation » du live (--text, affiché
# par /root/.xinitrc via zenity juste avant de lancer liveinst) ;
# • le %post chrooté du kickstart Anaconda (--env), qui APPLIQUE :
# activation des guest tools du bon hyperviseur, purge des autres,
# installation des drivers GPU.
# → ce que l'écran ANNONCE = ce que l'install FERA (aucune divergence
# possible, la détection vit ici et nulle part ailleurs).
#
# Fonctionne dans le LIVE comme dans le CHROOT d'Anaconda : celui-ci
# bind-monte /sys et /proc du live → même matériel visible. Le script est
# livré par l'airootfs (/usr/local/bin) → recopié dans la cible par le
# payload liveimg → présent dans le chroot du %post. Aucune dépendance
# dure : lspci (pciutils) et ip (iproute2) ne servent qu'aux libellés
# humains de --text, avec repli si absents.
#
# Usage : fws-hw-detect --env lignes FWS_*='…' à eval par le kickstart
# fws-hw-detect --text récapitulatif humain en français (zenity)
# ============================================================================
set -u
MODE="${1:---text}"
# --- Hyperviseur --------------------------------------------------------------
# systemd-detect-virt lit CPUID/DMI → OK en chroot, sans systemd actif.
# ATTENTION : hors VM il AFFICHE « none » ET sort en code ≠ 0 → surtout pas de
# « || echo none » DANS le $() (on récolterait « none » en double).
VIRT="$(systemd-detect-virt 2>/dev/null | head -n1)"
[ -n "$VIRT" ] || VIRT=none
# Les guest tools des 3 hyperviseurs sont DÉJÀ dans l'image live
# (packages.x86_64 : open-vm-tools, virtualbox-guest-utils-nox,
# qemu-guest-agent) → activer un service marche HORS LIGNE ; on retire ceux
# des autres hyperviseurs (inutiles sur cette machine).
VIRT_SVC="" VIRT_RM="" VIRT_LABEL=""
case "$VIRT" in
vmware)
VIRT_LABEL="VMware"
VIRT_SVC="vmtoolsd.service vmware-vmblock-fuse.service"
VIRT_RM="virtualbox-guest-utils-nox qemu-guest-agent" ;;
oracle) # = VirtualBox (nom renvoyé par systemd-detect-virt)
VIRT_LABEL="VirtualBox"
VIRT_SVC="vboxservice.service"
VIRT_RM="open-vm-tools qemu-guest-agent" ;;
kvm|qemu)
VIRT_LABEL="QEMU/KVM"
VIRT_SVC="qemu-guest-agent.service"
VIRT_RM="open-vm-tools virtualbox-guest-utils-nox" ;;
none)
VIRT_LABEL="aucune (machine physique)"
VIRT_RM="open-vm-tools virtualbox-guest-utils-nox qemu-guest-agent" ;;
*) # Hyperviseur non géré (hyper-v…) : aucun de nos guest tools ne sert.
VIRT_LABEL="$VIRT (intégration non gérée)"
VIRT_RM="open-vm-tools virtualbox-guest-utils-nox qemu-guest-agent" ;;
esac
# --- GPU ----------------------------------------------------------------------
# Classe PCI 0x03xxxx = contrôleur d'affichage ; lecture DIRECTE de /sys, pas
# besoin de lspci. Vendors : 0x10de NVIDIA, 0x1002 AMD, 0x8086 Intel,
# 0x15ad VMware (le VMSVGA de VirtualBox porte AUSSI 0x15ad → couvert).
# QEMU virtio-gpu/QXL et VBoxVGA : modesetting + mesa (déjà tirés par
# xorg-server dans l'image) suffisent → rien à installer.
DRV_PKGS="" GPU_TEXT=""
for _dev in /sys/bus/pci/devices/*; do
case "$(cat "$_dev/class" 2>/dev/null)" in 0x03*) ;; *) continue ;; esac
_vendor="$(cat "$_dev/vendor" 2>/dev/null)"
_pkgs=""
case "$_vendor" in
# NVIDIA : le module des dépôts est bâti pour le NOYAU des dépôts →
# « linux » DOIT partir dans la même transaction pacman (le noyau
# installé est celui du live, plus vieux), sinon module ≠ noyau au
# 1er boot. Les chemins /boot/* sont stables → grub.cfg reste bon.
0x10de) _pkgs="linux nvidia nvidia-utils" ;;
0x1002) _pkgs="mesa vulkan-radeon xf86-video-amdgpu" ;;
0x8086) _pkgs="mesa vulkan-intel" ;;
0x15ad) _pkgs="mesa xf86-video-vmware" ;;
esac
# Libellé humain : lspci si dispo, sinon adresse PCI + vendor brut.
_name=""
if command -v lspci >/dev/null 2>&1; then
_name="$(lspci -s "${_dev##*/}" 2>/dev/null | head -n1 \
| cut -d: -f3- | sed 's/^ //')"
fi
[ -n "$_name" ] || _name="GPU PCI ${_dev##*/} (vendor $_vendor)"
if [ -n "$_pkgs" ]; then
GPU_TEXT="${GPU_TEXT} • ${_name}\n → paquets : ${_pkgs}\n"
DRV_PKGS="$DRV_PKGS $_pkgs"
else
GPU_TEXT="${GPU_TEXT} • ${_name}\n → rien à installer (modesetting + mesa, déjà dans l'image)\n"
fi
done
# Dédoublonnage (machine multi-GPU : « mesa » listé 2× ferait échouer pacman
# sur « duplicate target »).
if [ -n "$DRV_PKGS" ]; then
DRV_PKGS="$(printf '%s\n' $DRV_PKGS | sort -u | tr '\n' ' ')"
DRV_PKGS="${DRV_PKGS% }"
fi
# --- Mode machine : sortie shell pour le kickstart ----------------------------
if [ "$MODE" = "--env" ]; then
printf "FWS_VIRT='%s'\n" "$VIRT"
printf "FWS_VIRT_SVC='%s'\n" "$VIRT_SVC"
printf "FWS_VIRT_RM='%s'\n" "$VIRT_RM"
printf "FWS_DRV_PKGS='%s'\n" "$DRV_PKGS"
exit 0
fi
# --- Mode humain : récapitulatif --text (zenity, avant liveinst) ---------------
CPU="$(awk -F': +' '/^model name/{print $2; exit}' /proc/cpuinfo)"
[ -n "$CPU" ] || CPU="inconnu"
case "$(awk -F': +' '/^vendor_id/{print $2; exit}' /proc/cpuinfo)" in
GenuineIntel) UCODE="intel-ucode" ;;
AuthenticAMD) UCODE="amd-ucode" ;;
*) UCODE="" ;;
esac
RAM="$(awk '/^MemTotal/{printf "%.1f Gio", $2/1048576}' /proc/meminfo)"
if [ -d /sys/firmware/efi ]; then
BOOT="UEFI — GRUB x86_64-efi + entrée de secours EFI/BOOT/BOOTX64.EFI"
else
BOOT="BIOS hérité — GRUB i386-pc, table de partitions MBR forcée"
fi
if command -v ip >/dev/null 2>&1 && ip route get 1.1.1.1 >/dev/null 2>&1; then
NET="disponible ✔"
else
NET="INDISPONIBLE ✖ — drivers GPU et bureau ne s'installeront PAS (rattrapable au 1er boot)"
fi
# Type « disk » uniquement (exclut lecteur ISO sr0/loop). La clé USB du live,
# elle, EST un disque → il est juste qu'elle apparaisse sous l'avertissement
# d'effacement (clearpart --all du kickstart efface bien TOUS les disques).
DISKS="$(lsblk -dno NAME,SIZE,MODEL,TYPE 2>/dev/null \
| awk '$NF=="disk"{NF--; print " • " $0}')"
[ -n "$DISKS" ] || DISKS=" (aucun disque détecté)"
[ -n "$GPU_TEXT" ] || GPU_TEXT=" (aucune carte graphique détectée)\n"
printf '%b' \
"══════════════════════════════════════════════════════════
FWS — RÉCAPITULATIF AVANT INSTALLATION
══════════════════════════════════════════════════════════
MACHINE
• Démarrage : ${BOOT}
• Virtualisation : ${VIRT_LABEL}
• Processeur : ${CPU}"
[ -n "$UCODE" ] && printf '%b' "
• Microcode : ${UCODE} — déjà intégré à l'image, rien à faire"
printf '%b' "
• Mémoire : ${RAM}
• Réseau : ${NET}
DISQUES DÉTECTÉS
⚠ Par défaut, TOUS les disques ci-dessous seront ENTIÈREMENT
EFFACÉS (partitionnement automatique). Le partitionnement
manuel reste possible dans l'installateur.
${DISKS}
CARTES GRAPHIQUES → drivers installés AUTOMATIQUEMENT en fin d'install
${GPU_TEXT}
INTÉGRATION HYPERVISEUR (automatique, fonctionne hors ligne)
• Services activés : ${VIRT_SVC:-aucun}
• Guest tools retirés (inutiles) : ${VIRT_RM:-aucun}
DÉROULEMENT DE L'INSTALLATION
1. Réglages dans Anaconda : langue, clavier, fuseau, disque, utilisateur
2. Copie du système live FWS sur le disque (payload liveimg)
3. Noyau + initramfs régénérés (mkinitcpio), GRUB installé
4. Drivers GPU + intégration hyperviseur appliqués (voir ci-dessus)
5. Bureau choisi installé (réseau requis)
« Lancer l'installateur » pour continuer — « Éteindre » pour annuler.
"
+1
View File
@@ -24,6 +24,7 @@ file_permissions=(
["/root/.automated_script.sh"]="0:0:755"
["/root/.gnupg"]="0:0:700"
["/usr/local/bin/choose-mirror"]="0:0:755"
["/usr/local/bin/fws-hw-detect"]="0:0:755"
["/usr/local/bin/Installation_guide"]="0:0:755"
["/usr/local/bin/livecd-sound"]="0:0:755"
)
@@ -194,7 +194,47 @@ else
echo "[FWS] AVERTISSEMENT : grub-install a échoué — bootloader à refaire à la main"
fi
# --- 4) Bureau choisi : pacman -S du DE (non bloquant si pas de réseau) -------
# --- 4) Drivers matériels : détection + activation/installation AUTO ----------
# Toute la DÉTECTION vit dans /usr/local/bin/fws-hw-detect : livré par
# l'airootfs → recopié dans la cible par le payload liveimg → présent dans ce
# chroot. C'est la MÊME source de vérité que l'écran « Récapitulatif avant
# installation » du live (.xinitrc, mode --text) : ce qui a été ANNONCÉ à
# l'utilisateur = ce qu'on APPLIQUE ici. La détection marche en chroot car
# Anaconda bind-monte le /sys et le /proc du LIVE (le code plus haut s'appuie
# déjà dessus : /sys/firmware/efi, findmnt) → on voit le VRAI matériel.
# Variables produites par --env :
# FWS_VIRT hyperviseur (vmware/oracle/kvm/qemu/none…)
# FWS_VIRT_SVC services invité à activer (paquets DÉJÀ dans l'image → OK
# hors ligne ; c'était le chaînon manquant, rien n'activait
# vmtoolsd & co sur le système installé)
# FWS_VIRT_RM guest tools des AUTRES hyperviseurs, à purger
# FWS_DRV_PKGS paquets GPU à installer, dédoublonnés. NVIDIA embarque
# « linux » dans la même transaction : le module des dépôts
# est bâti pour le noyau des dépôts, pas celui du live ; les
# chemins /boot/* étant stables, le grub.cfg de l'étape 3
# reste valable (le hook pacman de nvidia relance mkinitcpio).
# NB : microcode CPU (amd-ucode/intel-ucode) et linux-firmware sont DÉJÀ dans
# l'image → recopiés, et grub-mkconfig (étape 3) a généré les initrd qui vont
# bien. Rien à faire pour eux.
if [ -x /usr/local/bin/fws-hw-detect ]; then
eval "$(/usr/local/bin/fws-hw-detect --env)"
# (a) Hyperviseur : activer le bon service invité, purger les autres.
[ -n "$FWS_VIRT_SVC" ] && { systemctl enable $FWS_VIRT_SVC || true; }
[ -n "$FWS_VIRT_RM" ] && { pacman -Rns --noconfirm $FWS_VIRT_RM || true; }
# (b) GPU : install réseau, NON bloquante (même philosophie que le
# bureau). --needed : ne réinstalle pas ce que l'image a déjà (mesa…).
if [ -n "$FWS_DRV_PKGS" ]; then
pacman-key --init &>/dev/null || true
pacman-key --populate archlinux &>/dev/null || true
if ! pacman -Sy --noconfirm --needed $FWS_DRV_PKGS; then
echo "[FWS] Drivers non installés ($FWS_DRV_PKGS) — réseau ? À refaire au 1er boot."
fi
fi
else
echo "[FWS] fws-hw-detect introuvable — drivers/guest tools NON configurés."
fi
# --- 5) Bureau choisi : pacman -S du DE (non bloquant si pas de réseau) -------
DESK="cli"
[ -f /tmp/fws-desktop ] && DESK="$(tr -d '[:space:]' < /tmp/fws-desktop)"
DM=""
@@ -216,14 +256,14 @@ if [ -n "$PKGS" ]; then
fi
fi
# --- 5) Sécurité : verrouiller root s'il est resté SANS mot de passe ----------
# --- 6) Sécurité : verrouiller root s'il est resté SANS mot de passe ----------
# L'airootfs live a souvent un root sans mot de passe ; si l'utilisateur n'en a
# pas défini dans le GUI, on verrouille plutôt que de laisser le compte ouvert.
if passwd -S root 2>/dev/null | grep -qE '\bNP\b'; then
passwd -l root || true
fi
# --- 6) Le resolv.conf du live ne doit pas rester figé -----------------------
# --- 7) Le resolv.conf du live ne doit pas rester figé -----------------------
# NetworkManager (activé sur le système installé) régénère /etc/resolv.conf.
rm -f /tmp/fws-desktop /etc/resolv.conf 2>/dev/null || true
%end