#!/usr/bin/env bash # complete-closure.sh — completa el cierre RUNTIME de un FHS hidratado: escanea los `NEEDED` (DT_NEEDED) # de cada ELF del rootfs y, por cada soname AUSENTE, proyecta del store SELLADO el artefacto que lo # provee (`takana hydrate`). Itera hasta punto fijo. Resuelve las deps runtime que el índice del repo NO # lista (p.ej. libmount.so.1 de util-linux, dep de build de kcoreaddons pero .so runtime de libKF6CoreAddons). # # Sonames del SUSTRATO base (musl libc, loader, libgcc) NO se hidratan: los provee la base soberana del # sistema destino. El resto se toma del store (mtime artefacto (hash) del store, sólo mtime indexando sonames del store (mtime<$(date -d @$CUTOFF 2>/dev/null||echo $CUTOFF))…" declare -A PROV while IFS= read -r d; do hash="${d##*/}"; hash="${hash%%-*}" while IFS= read -r so; do b="${so##*/}" [ -z "${PROV[$b]:-}" ] && PROV[$b]="$hash" done < <(find "$d" -name "*.so*" -printf '%f\n' 2>/dev/null) done < <(find "$STORE" -maxdepth 1 -type d -name "*-*" -printf '%T@ %p\n' 2>/dev/null | awk -v c="$CUTOFF" '$1/dev/null) # NEEDED de todos los ELF del rootfs declare -A NEED=() while IFS= read -r bin; do while IFS= read -r n; do NEED["$n"]=1; done < <(readelf -d "$bin" 2>/dev/null | grep NEEDED | grep -oE '\[[^]]+\]' | tr -d '[]') done < <(find "$RFS" -type f \( -name "*.so*" -o -path "*/bin/*" -o -path "*/libexec/*" \) 2>/dev/null) # faltantes missing=(); for n in "${!NEED[@]}"; do [ -n "${HAVE[$n]:-}" ] && continue is_base "$n" && continue missing+=("$n") done if [ ${#missing[@]} -eq 0 ]; then echo "==> ronda $round: cierre COMPLETO, 0 sonames faltantes"; break; fi echo "==> ronda $round: ${#missing[@]} sonames faltantes" did=0; declare -A HYDRATED=() for n in "${missing[@]}"; do h="${PROV[$n]:-}" if [ -z "$h" ]; then printf " ? %-32s (ningún artefacto lo provee)\n" "$n"; continue; fi [ -n "${HYDRATED[$h]:-}" ] && continue if "$HAMMER" --store "$STORE" hydrate "$h" --into "$RFS" --link "$LINK" >/dev/null 2>&1; then printf " + %-32s ← %s\n" "$n" "${h:0:12}"; HYDRATED[$h]=1; did=$((did+1)) else printf " ✗ %-32s hydrate falló (%s)\n" "$n" "${h:0:12}" fi done unset HAVE NEED [ $did -eq 0 ] && { echo "==> ronda $round: nada nuevo hidratado (faltantes irresolubles), corto"; break; } done echo "==> .so totales: $(find "$RFS" -name '*.so*'|wc -l); binarios: $(find "$RFS" -path '*/bin/*' -type f|wc -l)"