🔒 Repository is read-only – file editing is disabled.
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'."