🔒 Repository is read-only – file editing is disabled.

PaganLinux/repair-base-from-cache.sh main

85 linii Raw ← Powrót
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
#!/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'."