20e0643a02
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.
285 lines
16 KiB
Plaintext
285 lines
16 KiB
Plaintext
# ============================================================================
|
|
# FWS — interactive-defaults.ks
|
|
#
|
|
# Kickstart de base, lu AUTOMATIQUEMENT par Anaconda quand l'install est
|
|
# lancée en mode interactif (chemin fixe codé en dur dans Anaconda :
|
|
# /usr/share/anaconda/interactive-defaults.ks). Aucun inst.ks= n'est requis.
|
|
#
|
|
# RÔLE : empêcher Anaconda d'installer Fedora.
|
|
# ----------------------------------------------------------------------------
|
|
# Sans payload défini, Anaconda utilise DNF → des RPM depuis les dépôts
|
|
# Fedora = il installe Fedora. Anaconda n'a AUCUN backend pacman. La seule
|
|
# façon de poser FWS/Arch est le payload « liveimg » : il recopie une image
|
|
# de système de fichiers (ici le squashfs du live = FWS) sur le disque, puis
|
|
# on finalise nous-mêmes (grub, mkinitcpio, bureau) en %post. C'est le modèle
|
|
# « Sabayon » : le système installé EST une copie du live.
|
|
#
|
|
# L'utilisateur garde la main dans le GUI sur tout ce qui N'EST PAS fixé ici :
|
|
# partitionnement, fuseau, clavier, langue, création d'utilisateur, mot de
|
|
# passe root, etc.
|
|
# ============================================================================
|
|
|
|
# --- Source d'installation : l'image du live (FWS), surtout pas Fedora -------
|
|
# Squashfs archiso sur le média booté :
|
|
# /run/archiso/bootmnt/<install_dir>/<arch>/airootfs.sfs
|
|
# install_dir=fws, arch=x86_64, airootfs_image_type=squashfs (cf. profiledef.sh).
|
|
# Anaconda loop-monte ce .sfs et rsync son contenu vers la cible.
|
|
#
|
|
# ⚠ À VALIDER sur ISO réelle : certaines versions d'Anaconda attendent une
|
|
# structure « LiveOS/rootfs.img » à l'intérieur du squashfs (format Fedora
|
|
# Live) et non un squashfs « plat » comme celui d'archiso. Si l'install
|
|
# échoue à monter la source, basculer sur un tarball de rootfs dédié :
|
|
# liveimg --url=file:///run/archiso/bootmnt/fws/x86_64/fws-rootfs.tar.gz
|
|
# (un build-rootfs.sh produirait alors ce tar via pacstrap).
|
|
liveimg --url=file:///run/archiso/bootmnt/fws/x86_64/airootfs.sfs
|
|
|
|
# --- Disque : repartir d'un disque PROPRE, même s'il a déjà servi ------------
|
|
# Sans ça, une réinstallation sur un disque déjà partitionné (typiquement une
|
|
# install FWS précédente : partitions + VG LVM « anaconda_archiso ») pose deux
|
|
# problèmes : le partitionnement auto n'a plus d'espace libre, et blivet
|
|
# rescanne/auto-active un LVM existant au boot du live → l'installateur se
|
|
# comporte mal voire plante au 2e passage (alors qu'un disque vierge passe).
|
|
# zerombr : réinitialise toute table de partitions invalide
|
|
# (répond « oui » au lieu de bloquer sur un disque
|
|
# non reconnu).
|
|
# clearpart --all : supprime TOUTES les partitions de TOUS les disques.
|
|
# --initlabel : réécrit une étiquette de disque neuve.
|
|
# --disklabel=msdos : force une table MBR (et non GPT). CRUCIAL en BIOS :
|
|
# en BIOS+GPT, GRUB i386-pc exige une partition « BIOS
|
|
# Boot » (~1 Mo, type EF02) pour embarquer core.img,
|
|
# qu'Anaconda NE crée PAS avec « bootloader --disabled
|
|
# » → « this GPT partition label contains no BIOS Boot
|
|
# Partition; embedding won't be possible » →
|
|
# grub-install échoue. En MBR, core.img se loge dans
|
|
# l'espace post-MBR, aucune partition dédiée requise.
|
|
# ⚠ Ce choix vise le BIOS (cas VMware actuel). Pour l'UEFI il faudra du GPT
|
|
# (+ ESP) — à rendre dépendant du firmware (%pre) le jour où on cible l'UEFI.
|
|
# L'utilisateur garde la main dans le GUI (il peut repasser en manuel), mais le
|
|
# DÉFAUT est désormais un disque net → réinstall fiable à chaque fois.
|
|
# ⚠ VM mono-disque : « --all » efface le seul disque, c'est voulu. Sur une
|
|
# machine multi-disques il faudrait cibler avec « --drives=sda ».
|
|
zerombr
|
|
clearpart --all --initlabel --disklabel=msdos
|
|
|
|
# --- Bootloader : géré à la main en %post ------------------------------------
|
|
# Anaconda lancerait « grub2-install » / « grub2-mkconfig » (binaires Fedora,
|
|
# préfixe grub2-) qui n'existent pas dans un rootfs Arch (lequel fournit
|
|
# grub-install / grub-mkconfig). On désactive donc l'étape native d'Anaconda.
|
|
# L'ESP (UEFI) ou la partition bios_boot (BIOS/GPT) reste créée par le
|
|
# partitionnement (auto ou manuel) car la plateforme l'impose.
|
|
bootloader --disabled
|
|
|
|
# Pas de section %packages : le payload liveimg n'installe aucun paquet
|
|
# (il copie une image). Toute installation de paquets se fait en %post.
|
|
|
|
|
|
# ============================================================================
|
|
# %post --nochroot — s'exécute dans le LIVE, la cible montée sous /mnt/sysroot
|
|
# But : déposer dans la cible ce dont le %post chrooté aura besoin (DNS pour
|
|
# pacman, choix de bureau écrit par l'addon de sélection).
|
|
# ============================================================================
|
|
%post --nochroot --log=/tmp/fws-post-nochroot.log
|
|
set -x
|
|
|
|
# Selon la version d'Anaconda la cible est sous /mnt/sysroot (récent) ou
|
|
# /mnt/sysimage (ancien).
|
|
SYSROOT=/mnt/sysroot
|
|
[ -d "$SYSROOT" ] || SYSROOT=/mnt/sysimage
|
|
|
|
# DNS pour que « pacman -S <bureau> » fonctionne dans le chroot.
|
|
cp -f /etc/resolv.conf "$SYSROOT/etc/resolv.conf" 2>/dev/null || true
|
|
|
|
# Choix du bureau (écrit par l'addon « Choix du bureau », à venir ; valeur lue
|
|
# par le %post chrooté ci-dessous). « cli » par défaut si absent.
|
|
if [ -f /tmp/fws-desktop ]; then
|
|
cp -f /tmp/fws-desktop "$SYSROOT/tmp/fws-desktop" 2>/dev/null || true
|
|
fi
|
|
|
|
# --- Noyau : archiso RETIRE /boot/vmlinuz-linux du squashfs ------------------
|
|
# mkarchiso boote le noyau depuis l'ISO et l'EXCLUT de l'airootfs squashfs (gain
|
|
# de place). Conséquence : le payload LiveOS recopie un rootfs SANS noyau →
|
|
# « mkinitcpio: /boot/vmlinuz-linux must be readable » puis aucun OS à booter
|
|
# (« Operating System not found »). On récupère donc le noyau depuis le média
|
|
# booté (/run/archiso/bootmnt/<install_dir>/boot/<arch>/vmlinuz-linux) et on le
|
|
# dépose dans la cible. Les modules (/usr/lib/modules) sont, eux, dans le
|
|
# squashfs → déjà recopiés. Avec le noyau présent, le %post chrooté peut bâtir
|
|
# l'initramfs (mkinitcpio) et GRUB trouve de quoi booter.
|
|
SRC_KERN="$(find /run/archiso/bootmnt -name 'vmlinuz-linux' 2>/dev/null | head -1)"
|
|
if [ -n "$SRC_KERN" ]; then
|
|
cp -f "$SRC_KERN" "$SYSROOT/boot/vmlinuz-linux"
|
|
else
|
|
echo "[FWS] AVERTISSEMENT : noyau vmlinuz-linux introuvable sur le média"
|
|
fi
|
|
%end
|
|
|
|
|
|
# ============================================================================
|
|
# %post (chroot) — DANS le rootfs FWS recopié. pacman, grub-install,
|
|
# mkinitcpio existent ici : ce sont les outils Arch de l'image copiée.
|
|
# Log persistant : /var/log/fws-post.log sur le système installé.
|
|
# ============================================================================
|
|
%post --log=/var/log/fws-post.log
|
|
set -x
|
|
|
|
# --- 1) Purge des résidus « live » (modèle Sabayon = live copié tel quel) ----
|
|
# Ce qui est propre au live casserait ou pollue le système installé.
|
|
rm -f /etc/mkinitcpio.conf.d/archiso.conf
|
|
rm -f /etc/systemd/system/getty@tty1.service.d/autologin.conf
|
|
for svc in choose-mirror.service pacman-init.service \
|
|
livecd-talk.service livecd-alsa-unmuter.service \
|
|
etc-pacman.d-gnupg.mount; do
|
|
rm -f "/etc/systemd/system/$svc"
|
|
rm -f /etc/systemd/system/*.target.wants/"$svc"
|
|
done
|
|
# cloud-init (présent dans l'airootfs archiso) : inutile sur un poste installé.
|
|
rm -f /etc/systemd/system/cloud-init.target.wants/* 2>/dev/null || true
|
|
# Hooks initramfs archiso, s'ils ont été recopiés en tant que paquet.
|
|
if pacman -Q mkinitcpio-archiso &>/dev/null; then
|
|
pacman -Rns --noconfirm mkinitcpio-archiso || true
|
|
fi
|
|
|
|
# --- 2) initramfs propre (preset Arch standard, sans archiso) ----------------
|
|
# Le live fournit un preset 'archiso' (/etc/mkinitcpio.d/linux.preset qui pointe
|
|
# vers conf.d/archiso.conf + hooks archiso) → inadapté à un disque normal. On
|
|
# pose un preset Arch standard (config par défaut /etc/mkinitcpio.conf).
|
|
cat > /etc/mkinitcpio.d/linux.preset <<'PRESET'
|
|
ALL_kver="/boot/vmlinuz-linux"
|
|
PRESETS=('default' 'fallback')
|
|
default_image="/boot/initramfs-linux.img"
|
|
fallback_image="/boot/initramfs-linux-fallback.img"
|
|
fallback_options="-S autodetect"
|
|
PRESET
|
|
# Le partitionnement auto d'Anaconda met « / » sur LVM (/dev/mapper/...-root).
|
|
# Sans le hook 'lvm2' dans l'initramfs, le VG n'est pas activé au boot → la
|
|
# racine est introuvable → kernel panic. On l'insère avant 'filesystems' s'il
|
|
# manque (inoffensif si la racine n'est finalement pas sur LVM).
|
|
if ! grep -qE '^HOOKS=.*\blvm2\b' /etc/mkinitcpio.conf; then
|
|
sed -i -E 's/^(HOOKS=\(.*)\bfilesystems\b/\1lvm2 filesystems/' /etc/mkinitcpio.conf
|
|
fi
|
|
mkinitcpio -P || echo "[FWS] AVERTISSEMENT : mkinitcpio a échoué"
|
|
|
|
# --- 3) GRUB installé à la main (cf. bootloader --disabled) ------------------
|
|
install_grub() {
|
|
if [ -d /sys/firmware/efi ]; then
|
|
# UEFI. efibootmgr crée l'entrée NVRAM « FWS », mais il peut MANQUER de
|
|
# l'airootfs et son install dépend du réseau → on ne BLOQUE pas dessus.
|
|
pacman -Q efibootmgr &>/dev/null || pacman -Sy --noconfirm efibootmgr || true
|
|
# (a) Entrée NVRAM dédiée (best effort, si efibootmgr dispo) :
|
|
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
|
|
--bootloader-id=FWS --recheck || true
|
|
# (b) Chemin de SECOURS EFI/BOOT/BOOTX64.EFI (--removable) : boote SANS
|
|
# aucune entrée NVRAM. INDISPENSABLE en VM / sans réseau / firmware
|
|
# qui « oublie » l'entrée — c'est lui qui garantit le 1er boot UEFI.
|
|
grub-install --target=x86_64-efi --efi-directory=/boot/efi \
|
|
--bootloader-id=FWS --removable --recheck
|
|
else
|
|
# BIOS : installer GRUB dans le MBR du DISQUE physique (PAS une partition)
|
|
# portant « / », même quand « / » est sur du LVM (chaîne
|
|
# LV → PV partition → disque). « lsblk -s » descend vers le physique ; on
|
|
# prend la ligne de type « disk ». ATTENTION : « lsblk -s » dessine un
|
|
# ARBRE → les caractères de branche (└─) se collent au chemin (on
|
|
# obtenait disk='-/dev/sda' → « grub-install: cannot find a GRUB drive
|
|
# for `-/dev/sda' »). On EXTRAIT donc le chemin propre avec grep.
|
|
local rootsrc disk
|
|
rootsrc="$(findmnt -no SOURCE / 2>/dev/null)"
|
|
disk="$(lsblk -spno NAME,TYPE "$rootsrc" 2>/dev/null \
|
|
| awk '$2=="disk"{print $1; exit}' | grep -oE '/dev/[a-z0-9]+')"
|
|
[ -n "$disk" ] || { echo "[FWS] Disque BIOS introuvable pour '$rootsrc'"; return 1; }
|
|
grub-install --target=i386-pc --recheck "$disk"
|
|
fi
|
|
}
|
|
if install_grub; then
|
|
grub-mkconfig -o /boot/grub/grub.cfg || echo "[FWS] grub-mkconfig a échoué"
|
|
else
|
|
echo "[FWS] AVERTISSEMENT : grub-install a échoué — bootloader à refaire à la main"
|
|
fi
|
|
|
|
# --- 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=""
|
|
case "$DESK" in
|
|
kde) PKGS="plasma-meta sddm konsole dolphin"; DM="sddm" ;;
|
|
gnome) PKGS="gnome gdm"; DM="gdm" ;;
|
|
xfce) PKGS="xfce4 xfce4-goodies lightdm lightdm-gtk-greeter"; DM="lightdm" ;;
|
|
hyprland) PKGS="hyprland kitty wofi waybar sddm"; DM="sddm" ;;
|
|
cli|*) PKGS="" ;;
|
|
esac
|
|
if [ -n "$PKGS" ]; then
|
|
pacman-key --init &>/dev/null || true
|
|
pacman-key --populate archlinux &>/dev/null || true
|
|
if pacman -Sy --noconfirm $PKGS; then
|
|
[ -n "$DM" ] && systemctl enable "$DM" || true
|
|
systemctl set-default graphical.target || true
|
|
else
|
|
echo "[FWS] Bureau '$DESK' non installé (réseau ?) — à refaire après le 1er boot."
|
|
fi
|
|
fi
|
|
|
|
# --- 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
|
|
|
|
# --- 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
|
|
|
|
|
|
# ============================================================================
|
|
# %post --nochroot (FINAL) — exfiltre le log du %post chrooté vers le LIVE.
|
|
# À ce stade la cible est ENCORE montée sous /mnt/sysroot (l'unmount n'a pas
|
|
# encore eu lieu). On copie /var/log/fws-post.log (résultat de grub-install /
|
|
# mkinitcpio) vers le live /tmp pour que le harnais de debug (.xinitrc)
|
|
# l'affiche SANS avoir à remonter le disque démonté — c'est ce log qui dit si
|
|
# le disque va booter.
|
|
# ============================================================================
|
|
%post --nochroot
|
|
SYSROOT=/mnt/sysroot
|
|
[ -d "$SYSROOT" ] || SYSROOT=/mnt/sysimage
|
|
cp -f "$SYSROOT/var/log/fws-post.log" /tmp/fws-post-chroot.log 2>/dev/null || true
|
|
%end
|