ec442193f5
Add memory check warning for systems with less than 2GB RAM. Replace simple pulsing splash with active monitoring that displays: - Real-time anaconda activity from log files - Elapsed time and current operation - Stall detection after 4 minutes of inactivity - Automatic diagnostic report collection (journal, dmesg, udev status) - Detection of GUI readiness to auto-hide splash Add anaconda branding environment variables (ANACONDA_PRODUCTNAME, ANACONDA_PRODUCTVERSION, ANACONDA_ISFINAL) to show "FWS" instead of "Fedora" in installer headers and logs. Improve splash cleanup to handle both feeder process and optional diagnostic dialogs.
243 lines
12 KiB
Bash
243 lines
12 KiB
Bash
#!/bin/sh
|
|
# Lancé par startx (cf. /root/.zprofile), uniquement dans le live FWS.
|
|
if [ ! -d /run/archiso ]; then
|
|
exit 0
|
|
fi
|
|
|
|
xsetroot -solid "#1a1a2e"
|
|
|
|
# Openbox en arrière-plan : gestionnaire de fenêtres pour l'installateur.
|
|
openbox &
|
|
_OB_PID=$!
|
|
|
|
# Chantier C : lance l'installateur Anaconda en mode live s'il est présent.
|
|
# « liveinst » re-exécute anaconda (ici on est déjà root → pas de pkexec/polkit).
|
|
#
|
|
# DEBUG (premier run réel) : on CAPTURE stdout+stderr — un plantage d'import
|
|
# précoce de Python n'apparaît QUE là, pas dans /tmp/anaconda.log — et, si
|
|
# liveinst quitte en erreur, on regroupe tous les logs Anaconda et on les AFFICHE
|
|
# (zenity) au lieu de laisser startx rendre la main → .zprofile relancerait X en
|
|
# 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
|
|
# Payload LiveOS : avec --liveinst (passé par liveinst), Anaconda IGNORE le
|
|
# payload du kickstart (anaconda.py teste opts.liveinst AVANT le type du
|
|
# payload DBus — un « liveimg » dans le ks serait du code mort) et détecte
|
|
# l'image live sur des chemins Fedora/dracut : /dev/mapper/live-base,
|
|
# /dev/mapper/live-osimg-min ou /run/rootfsbase — tous ABSENTS d'archiso →
|
|
# « SourceSetupError: No Live OS image found! » = crash au démarrage
|
|
# (reproduit hors VM dans un chroot de l'airootfs). On expose donc le
|
|
# squashfs archiso (monté ro sur /run/archiso/airootfs) là où Anaconda le
|
|
# cherche : findmnt y résout le loop device → montage → rsync vers la cible.
|
|
if [ -d /run/archiso/airootfs ] && [ ! -e /run/rootfsbase ]; then
|
|
mkdir -p /run/rootfsbase
|
|
mount --bind /run/archiso/airootfs /run/rootfsbase || rmdir /run/rootfsbase
|
|
fi
|
|
|
|
# GARDE-FOU RAM : le live n'a que le zram comme marge — en dessous de
|
|
# ~2 Go, Anaconda (GUI Python + squashfs) peut geler la machine en plein
|
|
# « Préparation de l'installateur ». On prévient AVANT plutôt que de
|
|
# laisser l'utilisateur croire à un bug.
|
|
_MEMKB=$(awk '/^MemTotal:/{print $2}' /proc/meminfo 2>/dev/null)
|
|
if [ -n "$_MEMKB" ] && [ "$_MEMKB" -lt 2000000 ] && command -v zenity >/dev/null 2>&1; then
|
|
zenity --warning --width=460 --title="FWS — mémoire insuffisante ?" \
|
|
--text="<b>Cette machine n'a que $(( _MEMKB / 1024 )) Mo de RAM.</b>\n\nL'installateur graphique peut geler en dessous de 2 Go.\nEn VM : augmente la mémoire (4 Go recommandés) puis redémarre.\n\nOK pour tenter quand même." 2>/dev/null
|
|
fi
|
|
|
|
# ÉCRAN D'ATTENTE immédiat : le démarrage d'anaconda peut prendre 2 à
|
|
# 4 minutes (observé en VM VMware : un worker udev se bloque au boot et
|
|
# n'est tué par udevd qu'après 45 s — udev.event_timeout). Sans feedback,
|
|
# l'utilisateur croit à une panne alors que TOUT va bien. Le splash montre
|
|
# EN DIRECT ce que fait anaconda : un nourrisseur écrit sur stdin de
|
|
# zenity --progress (« # texte » = mise à jour du libellé) le log anaconda
|
|
# le plus récemment modifié + son dernier message + un chrono. Si les logs
|
|
# ne bougent plus (vrai blocage), le libellé le DIT (au lieu d'une barre
|
|
# qui pulse pour rien) et, au-delà de 4 min d'inactivité, on collecte
|
|
# journal+dmesg dans /tmp/fws-stall.txt et on l'affiche : l'écran devient
|
|
# lui-même le rapport de bug. Le nourrisseur meurt par SIGPIPE quand le
|
|
# splash est tué à la sortie de liveinst.
|
|
_SPLASH_PID=""
|
|
if command -v zenity >/dev/null 2>&1; then
|
|
(
|
|
_el=0; _quiet=0; _prevstamp=""
|
|
while :; do
|
|
sleep 3
|
|
# GUI d'anaconda à l'écran (marqueur ui.gui) → le splash n'a
|
|
# plus de raison d'être et le watchdog DOIT se désarmer : des
|
|
# logs silencieux pendant que l'utilisateur remplit les écrans
|
|
# sont NORMAUX (bug vécu : le rapport « préparation bloquée »
|
|
# s'affichait PAR-DESSUS l'installateur au bout de 4 min).
|
|
if grep -q 'ui\.gui' /tmp/anaconda.log 2>/dev/null; then
|
|
pkill -f 'zenity --progress' 2>/dev/null
|
|
exit 0
|
|
fi
|
|
# Compteurs en itérations (pas d'heure murale : l'horloge du
|
|
# guest SAUTE en VM — resynchro RTC — et gonflerait les âges,
|
|
# vu en vrai : « 242 s d'inactivité » 90 s après le boot).
|
|
_el=$(( _el + 3 ))
|
|
_last=$(ls -t /tmp/storage.log /tmp/anaconda.log /tmp/program.log /tmp/dbus.log 2>/dev/null | head -n1)
|
|
if [ -z "$_last" ]; then
|
|
printf '# Démarrage d'"'"'Anaconda… (%d min %02d s)\n' $(( _el / 60 )) $(( _el % 60 )) || exit 0
|
|
continue
|
|
fi
|
|
_stamp=$(stat -c %Y "$_last" 2>/dev/null)
|
|
if [ "$_stamp" = "$_prevstamp" ]; then
|
|
_quiet=$(( _quiet + 3 ))
|
|
else
|
|
_quiet=0; _prevstamp="$_stamp"
|
|
fi
|
|
# Rebranding d'affichage : anaconda (installateur Fedora) parle
|
|
# de Fedora/Arch dans ses logs — on ne montre pas ça à l'écran.
|
|
_msg=$(tail -n1 "$_last" 2>/dev/null | tr -d '\r' \
|
|
| sed -E 's/Fedora( Linux)?/FWS/g; s/Arch Linux/FWS/g; s/\<Arch\>/FWS/g' \
|
|
| cut -c1-90)
|
|
if [ "$_quiet" -ge 240 ] && [ ! -f /tmp/fws-stall.txt ]; then
|
|
{
|
|
echo "=== FWS : préparation bloquée (aucune activité log depuis ${_quiet}s) ==="
|
|
echo "--- dernier log actif : $_last"; tail -n 25 "$_last" 2>/dev/null
|
|
echo "--- udev (workers bloqués ?)"; udevadm settle --timeout=0 2>&1
|
|
echo "--- journal (fin)"; journalctl -b --no-pager 2>/dev/null | tail -n 60
|
|
echo "--- dmesg (fin)"; dmesg 2>/dev/null | tail -n 40
|
|
} > /tmp/fws-stall.txt 2>&1
|
|
zenity --text-info --title="FWS — préparation bloquée : diagnostic" \
|
|
--filename=/tmp/fws-stall.txt --width=1000 --height=650 2>/dev/null &
|
|
fi
|
|
if [ "$_quiet" -ge 60 ]; then
|
|
printf '# ⚠ Aucune activité depuis %d s (%s) — dernier message : %s\n' "$_quiet" "$(basename "$_last")" "$_msg" || exit 0
|
|
else
|
|
printf '# Préparation (%d min %02d s) — %s : %s\n' $(( _el / 60 )) $(( _el % 60 )) "$(basename "$_last")" "$_msg" || exit 0
|
|
fi
|
|
done
|
|
) | zenity --progress --pulsate --no-cancel \
|
|
--title="FWS" \
|
|
--text="<b>Préparation de l'installateur FWS…</b>\n\nAnalyse du matériel et des disques en cours.\nEncore une à deux minutes, c'est normal." \
|
|
--width=560 2>/dev/null &
|
|
_SPLASH_PID=$!
|
|
fi
|
|
|
|
# Hub Résumé SANS le libellé « We won't touch your disks… » : notre glade
|
|
# modifié NE PEUT PAS être livré directement à son chemin final —
|
|
# mkarchiso pose l'overlay airootfs AVANT pacstrap, et pacman refuse
|
|
# alors d'installer anaconda par-dessus (« exists in filesystem »). On le
|
|
# livre donc sous /usr/local/share/fws et on ÉCRASE ici, au boot du live
|
|
# (l'overlay du live est inscriptible), le fichier du paquet.
|
|
if [ -f /usr/local/share/fws/anaconda-summary-hub.glade ]; then
|
|
cp -f /usr/local/share/fws/anaconda-summary-hub.glade \
|
|
/usr/share/anaconda/ui/hubs/summary.glade 2>/dev/null || true
|
|
fi
|
|
|
|
# BRANDING : sans /.buildstamp, anaconda s'appelle « anaconda bluesky »
|
|
# (défauts de pyanaconda/core/product.py) et ses logs parlent de Fedora.
|
|
# Les variables d'environnement ANACONDA_* ont priorité → l'en-tête
|
|
# devient « FWS 1.0 INSTALLATION » et le log « anaconda … for FWS started ».
|
|
# (Les mentions Fedora PROFONDES dans les logs — GeoIP, profils — restent :
|
|
# ce sont des chaînes internes de l'installateur, sans effet sur l'install.)
|
|
export ANACONDA_PRODUCTNAME="$(. /etc/os-release 2>/dev/null; echo "${NAME:-FWS}")"
|
|
export ANACONDA_PRODUCTVERSION="$(. /etc/os-release 2>/dev/null; echo "${VERSION_ID:-1.0}")"
|
|
export ANACONDA_ISFINAL=true
|
|
|
|
LIVEINST_LOG=/tmp/fws-liveinst.log
|
|
# Bus D-Bus de SESSION : au démarrage (--liveinst), inhibit_screensaver()
|
|
# de pyanaconda se connecte au bus de session. S'il n'y en a AUCUN (notre
|
|
# startx root minimal n'en garantit pas), Gio lève une GLib.GError que
|
|
# pyanaconda n'attrape PAS (il n'attrape que DBusError) → crash immédiat
|
|
# (2e crash reproduit hors VM). dbus-run-session fournit un bus de session
|
|
# pour toute la durée de l'installateur ; avec un bus présent, l'absence du
|
|
# service ScreenSaver est attrapée (simple warning dans anaconda.log).
|
|
if command -v dbus-run-session >/dev/null 2>&1 && [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
|
|
dbus-run-session -- liveinst >"$LIVEINST_LOG" 2>&1
|
|
else
|
|
liveinst >"$LIVEINST_LOG" 2>&1
|
|
fi
|
|
rc=$?
|
|
|
|
# liveinst terminé (install finie ou échec) : le splash n'a plus de raison
|
|
# d'être — kill de zenity ; le nourrisseur meurt de SIGPIPE à son
|
|
# prochain printf. Idem pour un éventuel dialogue de diagnostic de stall.
|
|
if [ -n "$_SPLASH_PID" ]; then
|
|
pkill -P "$_SPLASH_PID" 2>/dev/null
|
|
kill "$_SPLASH_PID" 2>/dev/null
|
|
fi
|
|
pkill -f "fws-stall.txt" 2>/dev/null
|
|
|
|
# ATTENTION : liveinst NE propage PAS le code de sortie d'anaconda — il
|
|
# enchaîne son propre nettoyage et sort souvent 0 même quand anaconda a
|
|
# 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é).
|
|
# 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
|
|
{
|
|
echo "===== liveinst sorti (code $rc) — logs Anaconda ====="
|
|
echo
|
|
echo "########## sortie liveinst (stdout+stderr) ##########"
|
|
cat "$LIVEINST_LOG" 2>/dev/null
|
|
echo
|
|
echo "########## %post chrooté = grub-install / mkinitcpio ##########"
|
|
echo "########## >>> C'EST CE BLOC QUI DIT SI LE DISQUE VA BOOTER <<< ##########"
|
|
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)"
|
|
echo
|
|
echo "########## Récapitulatif (page GUI fws_recap, avant install) ##########"
|
|
cat /tmp/fws-hw-summary.txt 2>/dev/null || echo "(absent — page récap pas atteinte)"
|
|
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
|
|
echo "########## $f ##########"
|
|
tail -n 200 "$f" 2>/dev/null || echo "(absent)"
|
|
done
|
|
} >"$DBG" 2>&1
|
|
|
|
# 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="<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
|
|
else
|
|
echo "[FWS] Anaconda absent de l'ISO — à builder (setup-aur.sh) + ajouter à packages.x86_64." >&2
|
|
exec openbox
|
|
fi
|