Files
takana/scripts/kde/complete-closure.sh
Sergio 476168bb07 takana etapa 5c: comentarios de scripts, MOTD, y un BUG que introdujo la etapa 4
250 líneas de comentario en 151 scripts. Control verificado: el diff no toca
NI UNA línea que no empiece por #, y la sintaxis de los 151 pasa.

El barrido saltea heredocs y cadenas triples, y el guardián DISPARÓ 3 veces:
las tres eran el MOTD que el script escribe DENTRO de la imagen construida —
texto del producto, no comentario del script. Se cambiaron aparte y a
propósito, que es rebranding, no limpieza.

Y el hallazgo caro:  casaba contra ,
que es el TARGET de tracing — o sea el module_path!, o sea el nombre del crate.
La etapa 4 lo movió a  y el script quedó casando NADA. No fallaba:
imprimía cero atribuciones, indistinguible de un log sin problemas. Comprobado
con el binario (RUST_LOG=info sobre zlib), no deducido. Ahora acepta las dos, y
tiene que seguir aceptándolas porque los logs viejos en disco dicen la vieja.

Además 14 rutas de módulo  en docs, que el barrido anterior no tocó
porque  no es frontera de palabra.
2026-09-09 19:28:48 +00:00

65 lines
3.3 KiB
Bash

#!/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<CUTOFF = cosecha coherente).
set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
STORE="${STORE:-./store}"; RFS="${RFS:-work/kde-store-rootfs}"; LINK="${LINK:-static}"
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
CUTOFF="${CUTOFF:-$(date -d 'today 00:00' +%s 2>/dev/null || echo 9999999999)}"
# sonames provistos por la base (no soberanos aún / runtime del sistema): no hidratar.
BASE_SONAMES="libc.so libc.musl-x86_64.so.1 ld-musl-x86_64.so.1 libc.so.6 ld-linux-x86-64.so.2 libm.so.6 libdl.so.2 libpthread.so.0 librt.so.1 libresolv.so.2"
is_base(){ case " $BASE_SONAMES " in *" $1 "*) return 0;; esac; return 1; }
# índice soname -> artefacto (hash) del store, sólo mtime<CUTOFF (set coherente).
echo "==> 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<c{print $2}')
echo " sonames en el store: ${#PROV[@]}"
round=0
while :; do
round=$((round+1))
# presentes en el rootfs
declare -A HAVE=()
while IFS= read -r f; do HAVE["${f##*/}"]=1; done < <(find "$RFS" -name "*.so*" 2>/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)"