#!/bin/sh # probar-medio-armado.sh — ¿el medio que acabo de armar SIRVE? # # «Armado» y «sirve» no son lo mismo, y la diferencia se paga en un arranque: cada cosa de esta # lista fue un defecto real medido en metal entre el 14 y el 15 de octubre de 2026, con su síntoma # al lado. Corre sobre el ÁRBOL COMPUESTO (lo que va al `.img`), así que no hace falta montar nada # ni tener root. # # sh scripts/probar-medio-armado.sh [/store/.perfiles/mirada-usb] set -eu C="${1:-}" if [ -z "$C" ]; then for c in /store/.perfiles/mirada-usb /store/.perfiles/mirada-run; do [ -d "$c" ] && { C="$c"; break; } done fi [ -n "$C" ] && [ -d "$C" ] || { echo "no encuentro el árbol compuesto (pasalo como argumento)"; exit 2; } echo "══ sobre $C ════════════════════════════════════════════════════════════════" mal=0 # ok hay() { # hay if [ -e "$C/$1" ]; then printf ' ✓ %-40s\n' "$1" else printf ' ✗ %-40s FALTA — %s\n' "$1" "$2"; mal=$((mal + 1)); fi } modo() { # modo if [ ! -e "$C/$1" ]; then printf ' ✗ %-40s FALTA — %s\n' "$1" "$3"; mal=$((mal + 1)); return; fi m=$(stat -c%a "$C/$1" 2>/dev/null || echo 0) if [ "$m" = "$2" ]; then printf ' ✓ %-40s %s\n' "$1" "$m" else printf ' ✗ %-40s es %s y debería ser %s — %s\n' "$1" "$m" "$2" "$3"; mal=$((mal + 1)); fi } nolink() { # nolink if [ -L "$C/$1" ]; then printf ' ✗ %-40s sigue siendo un symlink a %s — %s\n' "$1" "$(readlink "$C/$1")" "$2" mal=$((mal + 1)) elif [ -f "$C/$1" ]; then printf ' ✓ %-40s binario real\n' "$1" else printf ' ✗ %-40s FALTA — %s\n' "$1" "$2"; mal=$((mal + 1)); fi } echo "── el escritorio pinta y tiene con qué trabajar ──" # Sin un .ttf el compositor no pinta un solo rótulo, y se CALLA (memoria del 14-oct). if [ -n "$(find "$C/usr/share/fonts" -name '*.ttf' 2>/dev/null | head -1)" ]; then printf ' ✓ %-40s %s fuentes\n' "usr/share/fonts/**.ttf" "$(find "$C/usr/share/fonts" -name '*.ttf' 2>/dev/null | wc -l)" else printf ' ✗ %-40s FALTA — el compositor no pinta ningún rótulo y no lo dice\n' "una .ttf"; mal=$((mal + 1)); fi hay usr/bin/foot "ninguna terminal en la imagen" hay usr/bin/mirada-compositor "no hay escritorio" hay usr/bin/mirada-greeter "nadie puede iniciar sesión" hay usr/bin/pata-llimphi "el riel de la barra" hay usr/share/X11/xkb "XKB_CONFIG_ROOT apunta acá; vacío = el teclado no responde" hay usr/share/terminfo "dentro de foot, nada sabe pintar" hay etc/fonts/fonts.conf "fontconfig; sin esto el riel muere al cargar" echo "── la máquina tiene red ──" hay lib/firmware/intel/iwlwifi "wifi Intel: el caso más común de todos" hay lib/firmware/amdgpu "sin su firmware amdgpu no inicializa y la pantalla queda muerta" hay lib/firmware/rtl_nic "el ethernet de media gama" hay lib/firmware/regulatory.db "sin la base regulatoria el supplicant no elige canal" hay usr/sbin/wpa_supplicant "WPA2 no se asocia sin supplicant" hay usr/bin/netup "DHCP + ruta + resolv.conf" echo "── los accesorios en caliente ──" hay usr/bin/uevent-relay "sin él, lo que se enchufa después de arrancar no aparece NUNCA" hay usr/lib/libudev.so.1 "libudev-zero: sin él libinput descarta todo por falta de ID_INPUT" echo "── se puede ser root, y entrar ──" modo usr/bin/doas 4755 "sin el bit, doas no escala ni con la contraseña correcta" # `unix_chkpwd` es con lo que PAM verifica una contraseña cuando el que pregunta NO es root: sin su # bit el greeter rechaza a todo el mundo diciendo que la contraseña está mal. modo sbin/unix_chkpwd 4755 "el greeter no podría autenticar a NADIE" # Y éstos son el arreglo del 15-oct: el symlink a busybox del piso los tapaba. nolink bin/su "el symlink del piso tapa al de shadow y queda sin bit" nolink usr/bin/passwd "ídem: nadie podría cambiar su contraseña" modo bin/su 4755 "su sin bit dice «must be suid to work properly»" modo usr/bin/passwd 4755 "passwd sin bit no puede escribir /etc/shadow" modo usr/bin/ping 4755 "ping sin bit sale 1 y se lee como «no hay red»" echo "── el instalador pregunta por una cuenta ──" # ⚠ Hay DOS instaladores y cada medio lleva el suyo: el ISO inyecta `/usr/bin/takana-install` # (`iso-image.sh`), y el USB de variantes arranca `takana-install-partition.sh` desde el initramfs # del instalador, que viaja aparte. Exigir el del ISO en un medio que usa el otro es ruido con forma # de defecto, y un verificador que marca en rojo lo que no corresponde se desactiva solo. _inst="" for _c in usr/bin/takana-install instalador/takana-install-partition.sh; do [ -r "$C/$_c" ] && { _inst="$_c"; break; } done if [ -z "$_inst" ]; then printf ' · %-40s (este árbol no lleva instalador: lo trae el initramfs del medio, aparte)\n' "instalador" else printf ' ✓ %-40s\n' "$_inst" if grep -q "cuenta_aplicar" "$C/$_inst" 2>/dev/null; then printf ' ✓ %-40s llama a cuenta_aplicar\n' "$(basename "$_inst")" else printf ' ✗ %-40s NO llama a cuenta_aplicar — instalaría sin cuenta\n' "$(basename "$_inst")"; mal=$((mal + 1)) fi for _l in cuenta.sh firmware-initramfs.sh; do if [ -r "$C/usr/lib/takana/$_l" ] || [ -r "$C/instalador/lib/$_l" ]; then printf ' ✓ %-40s\n' "lib/$_l" else printf ' ✗ %-40s FALTA — el instalador la sourcea y sin ella no hace su parte\n' "lib/$_l"; mal=$((mal + 1)) fi done fi echo "── lo que arranca solo ──" # Dos formas de arrancar el escritorio, y el medio usa UNA: por Card en la semilla (lo que hace un # sistema instalado) o por un `/sbin/init` que lo lanza (lo que hace el medio live, `mirada-usb.sh`). # Se mira la que este árbol usa de verdad. if [ -r "$C/sbin/init" ] && grep -q "mirada-compositor" "$C/sbin/init" 2>/dev/null; then printf ' ✓ %-40s el lanzador del medio live arranca el compositor\n' "sbin/init" grep -q "uevent-relay" "$C/sbin/init" 2>/dev/null \ && printf ' ✓ %-40s y también el reenviador de uevents\n' "sbin/init" \ || printf ' ⚠ %-40s el lanzador NO arranca uevent-relay: en el MEDIO el hotplug no andaría\n' "sbin/init" elif [ -r "$C/ente/seed.card.json" ]; then for e in mirada seatd uevent-relay; do if grep -q "\"$e\"" "$C/ente/seed.card.json" 2>/dev/null; then printf ' ✓ %-40s en la semilla\n' "Ente $e" else printf ' ✗ %-40s NO está en la semilla\n' "Ente $e"; mal=$((mal + 1)); fi done else printf ' ✗ %-40s ni /sbin/init ni semilla: nada arrancaría el escritorio\n' "arranque"; mal=$((mal + 1)) fi echo "═════════════════════════════════════════════════════════════════════════════" if [ "$mal" = 0 ]; then echo "✓✓ el medio sirve: pinta, tiene red, ve lo que se enchufa, deja ser root y pregunta por una cuenta" else echo "✗ $mal comprobación(es) en rojo — ese medio va a fallar en metal, y arriba está en qué" exit 1 fi