#!/bin/bash # ============================================================================= # repair-base-from-cache.sh – ratunek po destrukcyjnym rollbacku `pag`. # # BŁĄD (pag <= 3.3.18): przy instalacji pakietu, którego pag NIE miał w bazie # (pliki bazowe z ISO/rootfs), pag nadpisywał istniejące pliki BEZ backupu. # Gdy transakcja padła, rollback usuwał „nowe” pliki – czyli także te bazowe. # Tak zniknęły libpam.so.0 (sudo), /lib/systemd/systemd (init!), passwd/su/login. # # Ten skrypt odtwarza wskazane pakiety z lokalnego cache paga # (/var/cache/pag/*.pag) – bez sieci, bez paga. Uruchom jako ROOT, np. z GRUB: # init=/bin/bash → mount -o remount,rw / → ./repair-base-from-cache.sh # # Użycie: # ./repair-base-from-cache.sh # domyślnie: pam shadow systemd # ./repair-base-from-cache.sh pam shadow systemd hwdata # ROOT=/mnt ./repair-base-from-cache.sh ... # naprawa z live ISO (chroot) # ./repair-base-from-cache.sh --dry-run # tylko pokaż, co by zrobił # ============================================================================= set -euo pipefail CACHE="${CACHE:-/var/cache/pag}" ROOT="${ROOT:-/}" DRY=0 ARGS=() for a in "$@"; do case "$a" in --dry-run) DRY=1 ;; *) ARGS+=("$a") ;; esac done PKGS=("${ARGS[@]}") [[ ${#PKGS[@]} -gt 0 ]] || PKGS=(pam shadow systemd) [[ $EUID -eq 0 ]] || { echo "❌ Wymagane uprawnienia root." >&2; exit 1; } [[ -d "$CACHE" ]] || { echo "❌ Brak cache: $CACHE" >&2; exit 1; } newest_cached() { # $1 = nazwa pakietu -> najnowszy plik .pag ls -1 "$CACHE/$1"-*.pag 2>/dev/null | sort -V | tail -1 } restored=0 for base in "${PKGS[@]}"; do f="$(newest_cached "$base" || true)" if [[ -z "$f" ]]; then echo "⚠ brak w cache: $base-*.pag – pomijam" continue fi if [[ $DRY -eq 1 ]]; then echo "→ odtworzyłbym $base z $(basename "$f")" restored=$((restored + 1)) continue fi tmp="$(mktemp -d)" tar -xJf "$f" -C "$tmp" tar -xJf "$tmp/data.tar.xz" -C "$ROOT" rm -rf "$tmp" echo "✓ odtworzono $base z $(basename "$f")" restored=$((restored + 1)) done if [[ $DRY -eq 1 ]]; then echo "(dry-run: nic nie zmieniono; pakietów do odtworzenia: $restored)" exit 0 fi # Odśwież cache ładowania bibliotek (dla chroot: ldconfig -r ROOT) if command -v ldconfig >/dev/null 2>&1; then if [[ "$ROOT" == "/" ]]; then ldconfig else ldconfig -r "$ROOT" fi fi echo echo "Odtworzono pakietów: $restored" echo "Kontrola krytycznych ścieżek:" for p in /sbin/init /lib/systemd/systemd /usr/lib/libpam.so.0 /usr/bin/passwd /usr/bin/su /usr/bin/systemctl; do [[ -e "$ROOT$p" ]] && echo " OK $p" || echo " BRAK $p" done echo echo "Jeśli /sbin/init i /lib/systemd/systemd są OK: uruchom 'exec /sbin/init'" echo "albo 'reboot -f'. Po powrocie do systemu NAJPIERW zainstaluj poprawionego" echo "paga (z rollbackiem robiącym backup), a dopiero potem wznów 'pag install'."