diff --git a/VERSION b/VERSION index 3eefcb9..be14282 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 +0.5.3 diff --git a/configs/baseline/airootfs/root/.xinitrc b/configs/baseline/airootfs/root/.xinitrc index 914da48..b7b050e 100644 --- a/configs/baseline/airootfs/root/.xinitrc +++ b/configs/baseline/airootfs/root/.xinitrc @@ -29,23 +29,29 @@ if command -v liveinst >/dev/null 2>&1; then # planté. On ne se fie donc PAS à $rc : en phase debug on regroupe TOUS les # logs et on les affiche systématiquement (zenity). Le traceback Python d'un # crash d'import précoce n'est QUE dans $LIVEINST_LOG (stderr capturé). - # Le %post chrooté (grub-install / mkinitcpio = ce qui rend le disque - # BOOTABLE) écrit /var/log/fws-post.log SUR LE DISQUE INSTALLÉ, qu'Anaconda - # a démonté. On réactive le LVM et on remonte (lecture seule) le 1er système - # qui contient ce log : c'est LUI qui dit si le bootloader a bien été posé. - FWS_POST="" - vgchange -ay >/dev/null 2>&1 || true - udevadm settle --timeout=10 >/dev/null 2>&1 || true - mkdir -p /run/fws-installed - for _dev in /dev/mapper/*-root /dev/mapper/* /dev/sd*[0-9] /dev/vd*[0-9] /dev/nvme*n*p*; do - [ -b "$_dev" ] || continue - mount -o ro "$_dev" /run/fws-installed 2>/dev/null || continue - if [ -f /run/fws-installed/var/log/fws-post.log ]; then - FWS_POST=/run/fws-installed/var/log/fws-post.log - break - fi - umount /run/fws-installed 2>/dev/null || true - done + # Log du %post chrooté (grub-install / mkinitcpio) = CE qui rend le disque + # bootable. Le kickstart en copie une version dans le LIVE + # (/tmp/fws-post-chroot.log, via un %post --nochroot final, cible encore + # montée → fiable). SECOURS si absent : on réactive le LVM (pvscan/vgscan + # rescannent les PV qu'Anaconda a désactivés) et on remonte le disque pour + # le lire. + if [ ! -s /tmp/fws-post-chroot.log ]; then + pvscan --cache >/dev/null 2>&1 || true + vgscan --mknodes >/dev/null 2>&1 || true + vgchange -ay >/dev/null 2>&1 || true + udevadm settle --timeout=10 >/dev/null 2>&1 || true + mkdir -p /run/fws-installed + for _dev in /dev/mapper/*-root /dev/mapper/* /dev/sd*[0-9] /dev/vd*[0-9] /dev/nvme*n*p*; do + [ -b "$_dev" ] || continue + mount -o ro "$_dev" /run/fws-installed 2>/dev/null || continue + if [ -f /run/fws-installed/var/log/fws-post.log ]; then + cp -f /run/fws-installed/var/log/fws-post.log /tmp/fws-post-chroot.log 2>/dev/null + umount /run/fws-installed 2>/dev/null || true + break + fi + umount /run/fws-installed 2>/dev/null || true + done + fi DBG=/tmp/fws-debug.txt { @@ -54,13 +60,9 @@ if command -v liveinst >/dev/null 2>&1; then echo "########## sortie liveinst (stdout+stderr) ##########" cat "$LIVEINST_LOG" 2>/dev/null echo - echo "########## %post chrooté = grub-install / mkinitcpio (/var/log/fws-post.log) ##########" + echo "########## %post chrooté = grub-install / mkinitcpio ##########" echo "########## >>> C'EST CE BLOC QUI DIT SI LE DISQUE VA BOOTER <<< ##########" - if [ -n "$FWS_POST" ]; then - cat "$FWS_POST" 2>/dev/null - else - echo "(log introuvable — disque installé non remonté)" - fi + cat /tmp/fws-post-chroot.log 2>/dev/null || echo "(log introuvable)" echo echo "########## %post --nochroot (/tmp/fws-post-nochroot.log) ##########" cat /tmp/fws-post-nochroot.log 2>/dev/null || echo "(absent)" @@ -72,12 +74,29 @@ if command -v liveinst >/dev/null 2>&1; then done } >"$DBG" 2>&1 - if command -v zenity >/dev/null 2>&1; then - zenity --text-info --title="FWS — logs Anaconda (sortie $rc)" \ - --filename="$DBG" --width=1100 --height=720 2>/dev/null & + # Succès d'install = les DEUX étapes qui rendent le disque bootable ont + # réussi dans le %post : mkinitcpio (« Initcpio image generation successful ») + # ET grub-install (« Installation finished. No error reported. »). Si oui → + # on montre un écran de RÉUSSITE et on éteint (l'utilisateur retire l'ISO puis + # rallume sur FWS). Sinon → on affiche tous les logs de debug (comportement + # debug). Les lignes cosmétiques (load_policy, warnings GTK…) n'influent PAS + # sur cette détection : on ne regarde que le log du %post. + if grep -q 'Initcpio image generation successful' /tmp/fws-post-chroot.log 2>/dev/null \ + && grep -q 'Installation finished. No error reported.' /tmp/fws-post-chroot.log 2>/dev/null; then + if command -v zenity >/dev/null 2>&1; then + zenity --info --width=480 --title="FWS — installation réussie ✅" \ + --text="FWS est installé sur le disque.\n\n1. Clique OK pour éteindre la machine.\n2. Retire l'ISO (lecteur CD/DVD).\n3. Rallume → FWS démarre." \ + 2>/dev/null + fi + systemctl poweroff + else + # Échec (ou install non terminée) : on montre les logs pour diagnostiquer. + if command -v zenity >/dev/null 2>&1; then + zenity --text-info --title="FWS — logs Anaconda (sortie $rc)" \ + --filename="$DBG" --width=1100 --height=720 2>/dev/null & + fi + wait "$_OB_PID" fi - - wait "$_OB_PID" else echo "[FWS] Anaconda absent de l'ISO — à builder (setup-aur.sh) + ajouter à packages.x86_64." >&2 exec openbox diff --git a/configs/baseline/airootfs/usr/bin/load_policy b/configs/baseline/airootfs/usr/bin/load_policy new file mode 100755 index 0000000..e036a0d --- /dev/null +++ b/configs/baseline/airootfs/usr/bin/load_policy @@ -0,0 +1,11 @@ +#!/bin/sh +# FWS — stub no-op de load_policy. +# +# À sa fermeture, le module Runtime d'Anaconda appelle /usr/sbin/load_policy +# pour recharger la politique SELinux. Arch N'EST PAS SELinux → le vrai binaire +# n'existe pas → « AnacondaError: ... '/usr/sbin/load_policy' » dans un atexit +# callback (« Exception ignored »). C'est cosmétique (exit 0 quand même), mais +# ça affiche un traceback rouge. Ce stub renvoie 0 → plus aucune erreur. +# (/usr/sbin est un lien vers /usr/bin sur Arch usr-merge → ce fichier répond +# aussi pour /usr/sbin/load_policy.) +exit 0 diff --git a/configs/baseline/airootfs/usr/bin/setstatus b/configs/baseline/airootfs/usr/bin/setstatus new file mode 100755 index 0000000..0545d98 --- /dev/null +++ b/configs/baseline/airootfs/usr/bin/setstatus @@ -0,0 +1,8 @@ +#!/bin/sh +# FWS — stub no-op de setstatus. +# +# Le script Fedora « liveinst » appelle « setstatus » (ligne ~154) pour publier +# un statut SELinux/systemd. Cet outil n'existe pas sur Arch → +# « /usr/bin/liveinst: line 154: setstatus: command not found » (cosmétique, +# liveinst continue). Ce stub renvoie 0 → l'avertissement disparaît. +exit 0 diff --git a/configs/releng/airootfs/usr/share/anaconda/interactive-defaults.ks b/configs/releng/airootfs/usr/share/anaconda/interactive-defaults.ks index 1b8400d..191ad0a 100644 --- a/configs/releng/airootfs/usr/share/anaconda/interactive-defaults.ks +++ b/configs/releng/airootfs/usr/share/anaconda/interactive-defaults.ks @@ -43,14 +43,23 @@ liveimg --url=file:///run/archiso/bootmnt/fws/x86_64/airootfs.sfs # (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 (GPT/MBR -# selon la plateforme). +# --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 +clearpart --all --initlabel --disklabel=msdos # --- Bootloader : géré à la main en %post ------------------------------------ # Anaconda lancerait « grub2-install » / « grub2-mkconfig » (binaires Fedora, @@ -85,6 +94,22 @@ cp -f /etc/resolv.conf "$SYSROOT/etc/resolv.conf" 2>/dev/null || true 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//boot//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 @@ -113,7 +138,24 @@ if pacman -Q mkinitcpio-archiso &>/dev/null; then pacman -Rns --noconfirm mkinitcpio-archiso || true fi -# --- 2) initramfs propre (sans le hook « archiso ») -------------------------- +# --- 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) ------------------ @@ -134,11 +176,14 @@ install_grub() { # 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 1re ligne de type « disk ». (L'ancien « lsblk -no pkname » - # renvoyait la PARTITION sda2 → grub-install échouait sur un root LVM.) + # 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}')" + 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 @@ -182,3 +227,18 @@ fi # 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 diff --git a/configs/releng/profiledef.sh b/configs/releng/profiledef.sh index 429e6f2..b9d8a31 100644 --- a/configs/releng/profiledef.sh +++ b/configs/releng/profiledef.sh @@ -22,4 +22,6 @@ file_permissions=( ["/usr/local/bin/choose-mirror"]="0:0:755" ["/usr/local/bin/Installation_guide"]="0:0:755" ["/usr/local/bin/livecd-sound"]="0:0:755" + ["/usr/bin/load_policy"]="0:0:755" + ["/usr/bin/setstatus"]="0:0:755" )