#!/bin/bash # ============================================================================ # FWS — réparation d'une installation existante depuis le live (« point de # restauration à la Windows »). Lancé par l'entrée de boot « Réparer FWS » # (paramètre noyau fws.recovery=1 → hook dans /root/.zprofile) ou à la main. # # Étapes : détecte les installations FWS sur les disques (LVM compris), # monte la cible + /boot + ESP (fstab), puis menu : réinstaller GRUB, # régénérer l'initramfs, réparer pacman, shell chroot. # arch-chroot (arch-install-scripts, présent sur le live) gère les binds. # ============================================================================ set -u say() { printf '\n\033[1;34m==> %s\033[0m\n' "$*"; } warn() { printf '\033[1;33m ⚠ %s\033[0m\n' "$*"; } MNT=/mnt/fws-recovery [ "$(id -u)" -eq 0 ] || { echo "root requis"; exit 1; } cleanup() { umount -R "$MNT" 2>/dev/null } trap cleanup EXIT say "Recherche des installations FWS…" # Réactive un éventuel LVM (partitionnement auto d'Anaconda : / sur LVM). vgscan --mknodes >/dev/null 2>&1 vgchange -ay >/dev/null 2>&1 udevadm settle --timeout=10 >/dev/null 2>&1 mkdir -p "$MNT" CANDIDATES=() while read -r dev; do [ -b "$dev" ] || continue mount -o ro "$dev" "$MNT" 2>/dev/null || continue if [ -f "$MNT/etc/os-release" ] && [ -d "$MNT/boot" ] \ && grep -qiE '^(ID|NAME)=.*fws' "$MNT/etc/os-release" 2>/dev/null; then name="$(. "$MNT/etc/os-release" 2>/dev/null; echo "${PRETTY_NAME:-FWS}")" CANDIDATES+=("$dev|$name") fi umount "$MNT" 2>/dev/null done < <(lsblk -rpno NAME,TYPE | awk '$2=="part"||$2=="lvm"{print $1}') if [ "${#CANDIDATES[@]}" -eq 0 ]; then warn "Aucune installation FWS trouvée sur les disques." warn "Disques visibles :" lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS read -rp "Entrée pour ouvrir un shell (exit pour redémarrer). " _ bash exit 0 fi echo i=1 for c in "${CANDIDATES[@]}"; do echo " $i) ${c%%|*} — ${c##*|}" i=$((i+1)) done read -rp "Installation à réparer [1] : " pick pick="${pick:-1}" ROOTDEV="${CANDIDATES[$((pick-1))]%%|*}" || exit 1 say "Montage de $ROOTDEV…" mount "$ROOTDEV" "$MNT" || { warn "montage impossible"; exit 1; } # /boot et l'ESP depuis le fstab de la cible (montage par la source UUID/dev). for mp in /boot /boot/efi; do src="$(awk -v mp="$mp" '$2==mp && $1!~/^#/{print $1; exit}' "$MNT/etc/fstab" 2>/dev/null)" [ -n "$src" ] || continue mount "$(findfs "$src" 2>/dev/null || echo "$src")" "$MNT$mp" 2>/dev/null \ && echo " $mp monté" || warn "$mp non monté (continuer quand même)" done fix_grub() { say "Réinstallation de GRUB…" if [ -d /sys/firmware/efi ]; then arch-chroot "$MNT" grub-install --target=x86_64-efi \ --efi-directory=/boot/efi --bootloader-id=FWS --recheck || true arch-chroot "$MNT" grub-install --target=x86_64-efi \ --efi-directory=/boot/efi --bootloader-id=FWS --removable --recheck else local rootsrc disk rootsrc="$ROOTDEV" disk="$(lsblk -spno NAME,TYPE "$rootsrc" 2>/dev/null \ | awk '$2=="disk"{print $1; exit}' | grep -oE '/dev/[a-z0-9]+')" [ -n "$disk" ] || { warn "disque BIOS introuvable"; return 1; } arch-chroot "$MNT" grub-install --target=i386-pc --recheck "$disk" fi arch-chroot "$MNT" grub-mkconfig -o /boot/grub/grub.cfg } fix_initramfs() { say "Régénération de l'initramfs (mkinitcpio -P)…" arch-chroot "$MNT" mkinitcpio -P } fix_pacman() { say "Réparation de pacman…" rm -f "$MNT/var/lib/pacman/db.lck" && echo " verrou db.lck retiré (s'il existait)" arch-chroot "$MNT" pacman-key --init arch-chroot "$MNT" pacman-key --populate archlinux read -rp " Lancer aussi une mise à jour complète (réseau requis) ? [o/N] " _u case "$_u" in o|O|oui) cp -f /etc/resolv.conf "$MNT/etc/resolv.conf" 2>/dev/null arch-chroot "$MNT" pacman -Syu ;; esac } while :; do cat <<'MENU' ╔════════════════════════════════════════════════════════╗ ║ FWS — Réparation du système ║ ╠════════════════════════════════════════════════════════╣ ║ 1) Réinstaller GRUB (le système ne démarre plus) ║ ║ 2) Régénérer l'initramfs (mkinitcpio -P) ║ ║ 3) Réparer pacman (verrou, clés, mise à jour) ║ ║ 4) Tout réparer (2 puis 1) ║ ║ 5) Ouvrir un shell DANS le système (chroot) ║ ║ q) Quitter et redémarrer ║ ╚════════════════════════════════════════════════════════╝ MENU read -rp " Choix : " choice case "$choice" in 1) fix_grub ;; 2) fix_initramfs ;; 3) fix_pacman ;; 4) fix_initramfs && fix_grub ;; 5) say "Shell chroot — « exit » pour revenir au menu." arch-chroot "$MNT" /bin/bash ;; q|Q) break ;; *) warn "choix inconnu" ;; esac done cleanup trap - EXIT say "Réparation terminée." read -rp "Redémarrer maintenant ? [O/n] " _r case "$_r" in n|N) bash ;; *) systemctl reboot ;; esac