feat(anaconda): improve installation process and post-install handling
- Add kernel copy step in %pre to ensure vmlinuz-linux is available for mkinitcpio - Refactor xinitrc post-install log detection to use /tmp/fws-post-chroot.log copied by kickstart - Add success detection based on mkinitcpio and grub-install log markers - Display success screen and poweroff on successful installation, show debug logs on failure - Add load_policy and setstatus stub scripts to suppress SELinux-related Anaconda warnings - Force MBR partition table (--disklabel=msdos) for BIOS boot compatibility - Create standard mkinitcpio preset to replace archiso-specific configuration - Automatically inject lvm2 hook when root is on LVM - Fix GRUB installation to properly extract disk path from lsblk output - Downgrade version to 0.5.3 (development/testing release)
This commit is contained in:
@@ -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
|
# 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
|
# 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é).
|
# crash d'import précoce n'est QUE dans $LIVEINST_LOG (stderr capturé).
|
||||||
# Le %post chrooté (grub-install / mkinitcpio = ce qui rend le disque
|
# Log du %post chrooté (grub-install / mkinitcpio) = CE qui rend le disque
|
||||||
# BOOTABLE) écrit /var/log/fws-post.log SUR LE DISQUE INSTALLÉ, qu'Anaconda
|
# bootable. Le kickstart en copie une version dans le LIVE
|
||||||
# a démonté. On réactive le LVM et on remonte (lecture seule) le 1er système
|
# (/tmp/fws-post-chroot.log, via un %post --nochroot final, cible encore
|
||||||
# qui contient ce log : c'est LUI qui dit si le bootloader a bien été posé.
|
# montée → fiable). SECOURS si absent : on réactive le LVM (pvscan/vgscan
|
||||||
FWS_POST=""
|
# rescannent les PV qu'Anaconda a désactivés) et on remonte le disque pour
|
||||||
vgchange -ay >/dev/null 2>&1 || true
|
# le lire.
|
||||||
udevadm settle --timeout=10 >/dev/null 2>&1 || true
|
if [ ! -s /tmp/fws-post-chroot.log ]; then
|
||||||
mkdir -p /run/fws-installed
|
pvscan --cache >/dev/null 2>&1 || true
|
||||||
for _dev in /dev/mapper/*-root /dev/mapper/* /dev/sd*[0-9] /dev/vd*[0-9] /dev/nvme*n*p*; do
|
vgscan --mknodes >/dev/null 2>&1 || true
|
||||||
[ -b "$_dev" ] || continue
|
vgchange -ay >/dev/null 2>&1 || true
|
||||||
mount -o ro "$_dev" /run/fws-installed 2>/dev/null || continue
|
udevadm settle --timeout=10 >/dev/null 2>&1 || true
|
||||||
if [ -f /run/fws-installed/var/log/fws-post.log ]; then
|
mkdir -p /run/fws-installed
|
||||||
FWS_POST=/run/fws-installed/var/log/fws-post.log
|
for _dev in /dev/mapper/*-root /dev/mapper/* /dev/sd*[0-9] /dev/vd*[0-9] /dev/nvme*n*p*; do
|
||||||
break
|
[ -b "$_dev" ] || continue
|
||||||
fi
|
mount -o ro "$_dev" /run/fws-installed 2>/dev/null || continue
|
||||||
umount /run/fws-installed 2>/dev/null || true
|
if [ -f /run/fws-installed/var/log/fws-post.log ]; then
|
||||||
done
|
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
|
DBG=/tmp/fws-debug.txt
|
||||||
{
|
{
|
||||||
@@ -54,13 +60,9 @@ if command -v liveinst >/dev/null 2>&1; then
|
|||||||
echo "########## sortie liveinst (stdout+stderr) ##########"
|
echo "########## sortie liveinst (stdout+stderr) ##########"
|
||||||
cat "$LIVEINST_LOG" 2>/dev/null
|
cat "$LIVEINST_LOG" 2>/dev/null
|
||||||
echo
|
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 <<< ##########"
|
echo "########## >>> C'EST CE BLOC QUI DIT SI LE DISQUE VA BOOTER <<< ##########"
|
||||||
if [ -n "$FWS_POST" ]; then
|
cat /tmp/fws-post-chroot.log 2>/dev/null || echo "(log introuvable)"
|
||||||
cat "$FWS_POST" 2>/dev/null
|
|
||||||
else
|
|
||||||
echo "(log introuvable — disque installé non remonté)"
|
|
||||||
fi
|
|
||||||
echo
|
echo
|
||||||
echo "########## %post --nochroot (/tmp/fws-post-nochroot.log) ##########"
|
echo "########## %post --nochroot (/tmp/fws-post-nochroot.log) ##########"
|
||||||
cat /tmp/fws-post-nochroot.log 2>/dev/null || echo "(absent)"
|
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
|
done
|
||||||
} >"$DBG" 2>&1
|
} >"$DBG" 2>&1
|
||||||
|
|
||||||
if command -v zenity >/dev/null 2>&1; then
|
# Succès d'install = les DEUX étapes qui rendent le disque bootable ont
|
||||||
zenity --text-info --title="FWS — logs Anaconda (sortie $rc)" \
|
# réussi dans le %post : mkinitcpio (« Initcpio image generation successful »)
|
||||||
--filename="$DBG" --width=1100 --height=720 2>/dev/null &
|
# 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="<b>FWS est installé sur le disque.</b>\n\n1. Clique OK pour <b>éteindre</b> la machine.\n2. <b>Retire l'ISO</b> (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
|
fi
|
||||||
|
|
||||||
wait "$_OB_PID"
|
|
||||||
else
|
else
|
||||||
echo "[FWS] Anaconda absent de l'ISO — à builder (setup-aur.sh) + ajouter à packages.x86_64." >&2
|
echo "[FWS] Anaconda absent de l'ISO — à builder (setup-aur.sh) + ajouter à packages.x86_64." >&2
|
||||||
exec openbox
|
exec openbox
|
||||||
|
|||||||
+11
@@ -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
|
||||||
Executable
+8
@@ -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
|
||||||
@@ -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
|
# (répond « oui » au lieu de bloquer sur un disque
|
||||||
# non reconnu).
|
# non reconnu).
|
||||||
# clearpart --all : supprime TOUTES les partitions de TOUS les disques.
|
# clearpart --all : supprime TOUTES les partitions de TOUS les disques.
|
||||||
# --initlabel : réécrit une étiquette de disque neuve (GPT/MBR
|
# --initlabel : réécrit une étiquette de disque neuve.
|
||||||
# selon la plateforme).
|
# --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
|
# 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.
|
# 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
|
# ⚠ VM mono-disque : « --all » efface le seul disque, c'est voulu. Sur une
|
||||||
# machine multi-disques il faudrait cibler avec « --drives=sda ».
|
# machine multi-disques il faudrait cibler avec « --drives=sda ».
|
||||||
zerombr
|
zerombr
|
||||||
clearpart --all --initlabel
|
clearpart --all --initlabel --disklabel=msdos
|
||||||
|
|
||||||
# --- Bootloader : géré à la main en %post ------------------------------------
|
# --- Bootloader : géré à la main en %post ------------------------------------
|
||||||
# Anaconda lancerait « grub2-install » / « grub2-mkconfig » (binaires Fedora,
|
# 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
|
if [ -f /tmp/fws-desktop ]; then
|
||||||
cp -f /tmp/fws-desktop "$SYSROOT/tmp/fws-desktop" 2>/dev/null || true
|
cp -f /tmp/fws-desktop "$SYSROOT/tmp/fws-desktop" 2>/dev/null || true
|
||||||
fi
|
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
|
%end
|
||||||
|
|
||||||
|
|
||||||
@@ -113,7 +138,24 @@ if pacman -Q mkinitcpio-archiso &>/dev/null; then
|
|||||||
pacman -Rns --noconfirm mkinitcpio-archiso || true
|
pacman -Rns --noconfirm mkinitcpio-archiso || true
|
||||||
fi
|
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é"
|
mkinitcpio -P || echo "[FWS] AVERTISSEMENT : mkinitcpio a échoué"
|
||||||
|
|
||||||
# --- 3) GRUB installé à la main (cf. bootloader --disabled) ------------------
|
# --- 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)
|
# BIOS : installer GRUB dans le MBR du DISQUE physique (PAS une partition)
|
||||||
# portant « / », même quand « / » est sur du LVM (chaîne
|
# portant « / », même quand « / » est sur du LVM (chaîne
|
||||||
# LV → PV partition → disque). « lsblk -s » descend vers le physique ; on
|
# LV → PV partition → disque). « lsblk -s » descend vers le physique ; on
|
||||||
# prend la 1re ligne de type « disk ». (L'ancien « lsblk -no pkname »
|
# prend la ligne de type « disk ». ATTENTION : « lsblk -s » dessine un
|
||||||
# renvoyait la PARTITION sda2 → grub-install échouait sur un root LVM.)
|
# 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
|
local rootsrc disk
|
||||||
rootsrc="$(findmnt -no SOURCE / 2>/dev/null)"
|
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; }
|
[ -n "$disk" ] || { echo "[FWS] Disque BIOS introuvable pour '$rootsrc'"; return 1; }
|
||||||
grub-install --target=i386-pc --recheck "$disk"
|
grub-install --target=i386-pc --recheck "$disk"
|
||||||
fi
|
fi
|
||||||
@@ -182,3 +227,18 @@ fi
|
|||||||
# NetworkManager (activé sur le système installé) régénère /etc/resolv.conf.
|
# 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
|
rm -f /tmp/fws-desktop /etc/resolv.conf 2>/dev/null || true
|
||||||
%end
|
%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
|
||||||
|
|||||||
@@ -22,4 +22,6 @@ file_permissions=(
|
|||||||
["/usr/local/bin/choose-mirror"]="0:0:755"
|
["/usr/local/bin/choose-mirror"]="0:0:755"
|
||||||
["/usr/local/bin/Installation_guide"]="0:0:755"
|
["/usr/local/bin/Installation_guide"]="0:0:755"
|
||||||
["/usr/local/bin/livecd-sound"]="0:0:755"
|
["/usr/local/bin/livecd-sound"]="0:0:755"
|
||||||
|
["/usr/bin/load_policy"]="0:0:755"
|
||||||
|
["/usr/bin/setstatus"]="0:0:755"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user