gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 815Rust 56Shell 37Markdown 291229 Definitions

⎇ 8730aad34e868068796f9c85ca4e4c89cfb43fa6 scripts/kde/complete-closure.sh Shell · 64 lines · 3.3 KB History raw

takana etapa 3b: las 49 invocaciones pasan a ./target/release/takana 8730aad34 · Sergio ·

1#!/usr/bin/env bash
2# complete-closure.sh — completa el cierre RUNTIME de un FHS hidratado: escanea los `NEEDED` (DT_NEEDED)
3# de cada ELF del rootfs y, por cada soname AUSENTE, proyecta del store SELLADO el artefacto que lo
4# provee (`hammer hydrate`). Itera hasta punto fijo. Resuelve las deps runtime que el índice del repo NO
5# lista (p.ej. libmount.so.1 de util-linux, dep de build de kcoreaddons pero .so runtime de libKF6CoreAddons).
6#
7# Sonames del SUSTRATO base (musl libc, loader, libgcc) NO se hidratan: los provee la base soberana del
8# sistema destino. El resto se toma del store (mtime<CUTOFF = cosecha coherente).
9set -uo pipefail
10ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
11STORE="${STORE:-./store}"; RFS="${RFS:-work/kde-store-rootfs}"; LINK="${LINK:-static}"
12HAMMER="${HAMMER:-./target/release/takana}"
13CUTOFF="${CUTOFF:-$(date -d 'today 00:00' +%s 2>/dev/null || echo 9999999999)}"
14# sonames provistos por la base (no soberanos aún / runtime del sistema): no hidratar.
15BASE_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"
16
17is_base(){ case " $BASE_SONAMES " in *" $1 "*) return 0;; esac; return 1; }
18
19# índice soname -> artefacto (hash) del store, sólo mtime<CUTOFF (set coherente).
20echo "==> indexando sonames del store (mtime<$(date -d @$CUTOFF 2>/dev/null||echo $CUTOFF))…"
21declare -A PROV
22while IFS= read -r d; do
23  hash="${d##*/}"; hash="${hash%%-*}"
24  while IFS= read -r so; do
25    b="${so##*/}"
26    [ -z "${PROV[$b]:-}" ] && PROV[$b]="$hash"
27  done < <(find "$d" -name "*.so*" -printf '%f\n' 2>/dev/null)
28done < <(find "$STORE" -maxdepth 1 -type d -name "*-*" -printf '%T@ %p\n' 2>/dev/null | awk -v c="$CUTOFF" '$1<c{print $2}')
29echo "   sonames en el store: ${#PROV[@]}"
30
31round=0
32while :; do
33  round=$((round+1))
34  # presentes en el rootfs
35  declare -A HAVE=()
36  while IFS= read -r f; do HAVE["${f##*/}"]=1; done < <(find "$RFS" -name "*.so*" 2>/dev/null)
37  # NEEDED de todos los ELF del rootfs
38  declare -A NEED=()
39  while IFS= read -r bin; do
40    while IFS= read -r n; do NEED["$n"]=1; done < <(readelf -d "$bin" 2>/dev/null | grep NEEDED | grep -oE '\[[^]]+\]' | tr -d '[]')
41  done < <(find "$RFS" -type f \( -name "*.so*" -o -path "*/bin/*" -o -path "*/libexec/*" \) 2>/dev/null)
42  # faltantes
43  missing=(); for n in "${!NEED[@]}"; do
44    [ -n "${HAVE[$n]:-}" ] && continue
45    is_base "$n" && continue
46    missing+=("$n")
47  done
48  if [ ${#missing[@]} -eq 0 ]; then echo "==> ronda $round: cierre COMPLETO, 0 sonames faltantes"; break; fi
49  echo "==> ronda $round: ${#missing[@]} sonames faltantes"
50  did=0; declare -A HYDRATED=()
51  for n in "${missing[@]}"; do
52    h="${PROV[$n]:-}"
53    if [ -z "$h" ]; then printf "   ? %-32s (ningún artefacto lo provee)\n" "$n"; continue; fi
54    [ -n "${HYDRATED[$h]:-}" ] && continue
55    if "$HAMMER" --store "$STORE" hydrate "$h" --into "$RFS" --link "$LINK" >/dev/null 2>&1; then
56      printf "   + %-32s ← %s\n" "$n" "${h:0:12}"; HYDRATED[$h]=1; did=$((did+1))
57    else
58      printf "   ✗ %-32s hydrate falló (%s)\n" "$n" "${h:0:12}"
59    fi
60  done
61  unset HAVE NEED
62  [ $did -eq 0 ] && { echo "==> ronda $round: nada nuevo hidratado (faltantes irresolubles), corto"; break; }
63done
64echo "==> .so totales: $(find "$RFS" -name '*.so*'|wc -l); binarios: $(find "$RFS" -path '*/bin/*' -type f|wc -l)"