feat(recovery): add fws-recovery script for system repair from live environment
Add a comprehensive system recovery tool that: - Detects FWS installations on disks including LVM volumes - Mounts target root filesystem with /boot and ESP partitions - Provides interactive menu for common repair operations: - GRUB reinstallation (UEFI and BIOS support) - Initramfs regeneration via mkinitcpio - Pacman database repair and system updates - Interactive chroot shell for manual intervention The script handles automatic LVM activation, filesystem detection via os-release, and proper cleanup on exit.
This commit is contained in:
+138
@@ -0,0 +1,138 @@
|
|||||||
|
#!/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
|
||||||
Reference in New Issue
Block a user