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…
fix(medio): el medio arrancaba a una consola de texto, con el escritorio adentro
1#!/bin/sh
2# probar-medio-armado.sh — ¿el medio que acabo de armar SIRVE?
3#
4# «Armado» y «sirve» no son lo mismo, y la diferencia se paga en un arranque: cada cosa de esta
5# lista fue un defecto real medido en metal entre el 14 y el 15 de octubre de 2026, con su síntoma
6# al lado. Corre sobre el ÁRBOL COMPUESTO (lo que va al `.img`), así que no hace falta montar nada
7# ni tener root.
8#
9# sh scripts/probar-medio-armado.sh [/store/.perfiles/mirada-usb]
10set -eu
11
12C="${1:-}"
13if [ -z "$C" ]; then
14 for c in /store/.perfiles/mirada-usb /store/.perfiles/mirada-run; do
15 [ -d "$c" ] && { C="$c"; break; }
16 done
17fi
18[ -n "$C" ] && [ -d "$C" ] || { echo "no encuentro el árbol compuesto (pasalo como argumento)"; exit 2; }
19echo "══ sobre $C ════════════════════════════════════════════════════════════════"
20
21mal=0
22# ok <qué> <condición-ya-evaluada> <por qué importa>
23hay() { # hay <ruta> <por qué>
24 if [ -e "$C/$1" ]; then printf ' ✓ %-40s\n' "$1"
25 else printf ' ✗ %-40s FALTA — %s\n' "$1" "$2"; mal=$((mal + 1)); fi
26}
27modo() { # modo <ruta> <modo esperado> <por qué>
28 if [ ! -e "$C/$1" ]; then printf ' ✗ %-40s FALTA — %s\n' "$1" "$3"; mal=$((mal + 1)); return; fi
29 m=$(stat -c%a "$C/$1" 2>/dev/null || echo 0)
30 if [ "$m" = "$2" ]; then printf ' ✓ %-40s %s\n' "$1" "$m"
31 else printf ' ✗ %-40s es %s y debería ser %s — %s\n' "$1" "$m" "$2" "$3"; mal=$((mal + 1)); fi
32}
33nolink() { # nolink <ruta> <por qué>
34 if [ -L "$C/$1" ]; then
35 printf ' ✗ %-40s sigue siendo un symlink a %s — %s\n' "$1" "$(readlink "$C/$1")" "$2"
36 mal=$((mal + 1))
37 elif [ -f "$C/$1" ]; then printf ' ✓ %-40s binario real\n' "$1"
38 else printf ' ✗ %-40s FALTA — %s\n' "$1" "$2"; mal=$((mal + 1)); fi
39}
40
41echo "── el escritorio pinta y tiene con qué trabajar ──"
42# Sin un .ttf el compositor no pinta un solo rótulo, y se CALLA (memoria del 14-oct).
43if [ -n "$(find "$C/usr/share/fonts" -name '*.ttf' 2>/dev/null | head -1)" ]; then
44 printf ' ✓ %-40s %s fuentes\n' "usr/share/fonts/**.ttf" "$(find "$C/usr/share/fonts" -name '*.ttf' 2>/dev/null | wc -l)"
45else printf ' ✗ %-40s FALTA — el compositor no pinta ningún rótulo y no lo dice\n' "una .ttf"; mal=$((mal + 1)); fi
46hay usr/bin/foot "ninguna terminal en la imagen"
47hay usr/bin/mirada-compositor "no hay escritorio"
48hay usr/bin/mirada-greeter "nadie puede iniciar sesión"
49hay usr/bin/pata-llimphi "el riel de la barra"
50hay usr/share/X11/xkb "XKB_CONFIG_ROOT apunta acá; vacío = el teclado no responde"
51hay usr/share/terminfo "dentro de foot, nada sabe pintar"
52hay etc/fonts/fonts.conf "fontconfig; sin esto el riel muere al cargar"
53
54echo "── la máquina tiene red ──"
55hay lib/firmware/intel/iwlwifi "wifi Intel: el caso más común de todos"
56hay lib/firmware/amdgpu "sin su firmware amdgpu no inicializa y la pantalla queda muerta"
57hay lib/firmware/rtl_nic "el ethernet de media gama"
58hay lib/firmware/regulatory.db "sin la base regulatoria el supplicant no elige canal"
59hay usr/sbin/wpa_supplicant "WPA2 no se asocia sin supplicant"
60hay usr/bin/netup "DHCP + ruta + resolv.conf"
61
62echo "── los accesorios en caliente ──"
63hay usr/bin/uevent-relay "sin él, lo que se enchufa después de arrancar no aparece NUNCA"
64hay usr/lib/libudev.so.1 "libudev-zero: sin él libinput descarta todo por falta de ID_INPUT"
65
66echo "── se puede ser root, y entrar ──"
67modo usr/bin/doas 4755 "sin el bit, doas no escala ni con la contraseña correcta"
68# `unix_chkpwd` es con lo que PAM verifica una contraseña cuando el que pregunta NO es root: sin su
69# bit el greeter rechaza a todo el mundo diciendo que la contraseña está mal.
70modo sbin/unix_chkpwd 4755 "el greeter no podría autenticar a NADIE"
71# Y éstos son el arreglo del 15-oct: el symlink a busybox del piso los tapaba.
72nolink bin/su "el symlink del piso tapa al de shadow y queda sin bit"
73nolink usr/bin/passwd "ídem: nadie podría cambiar su contraseña"
74modo bin/su 4755 "su sin bit dice «must be suid to work properly»"
75modo usr/bin/passwd 4755 "passwd sin bit no puede escribir /etc/shadow"
76modo usr/bin/ping 4755 "ping sin bit sale 1 y se lee como «no hay red»"
77
78echo "── el instalador pregunta por una cuenta ──"
79# ⚠ Hay DOS instaladores y cada medio lleva el suyo: el ISO inyecta `/usr/bin/takana-install`
80# (`iso-image.sh`), y el USB de variantes arranca `takana-install-partition.sh` desde el initramfs
81# del instalador, que viaja aparte. Exigir el del ISO en un medio que usa el otro es ruido con forma
82# de defecto, y un verificador que marca en rojo lo que no corresponde se desactiva solo.
83_inst=""
84for _c in usr/bin/takana-install instalador/takana-install-partition.sh; do
85 [ -r "$C/$_c" ] && { _inst="$_c"; break; }
86done
87if [ -z "$_inst" ]; then
88 printf ' · %-40s (este árbol no lleva instalador: lo trae el initramfs del medio, aparte)\n' "instalador"
89else
90 printf ' ✓ %-40s\n' "$_inst"
91 if grep -q "cuenta_aplicar" "$C/$_inst" 2>/dev/null; then
92 printf ' ✓ %-40s llama a cuenta_aplicar\n' "$(basename "$_inst")"
93 else
94 printf ' ✗ %-40s NO llama a cuenta_aplicar — instalaría sin cuenta\n' "$(basename "$_inst")"; mal=$((mal + 1))
95 fi
96 for _l in cuenta.sh firmware-initramfs.sh; do
97 if [ -r "$C/usr/lib/takana/$_l" ] || [ -r "$C/instalador/lib/$_l" ]; then
98 printf ' ✓ %-40s\n' "lib/$_l"
99 else
100 printf ' ✗ %-40s FALTA — el instalador la sourcea y sin ella no hace su parte\n' "lib/$_l"; mal=$((mal + 1))
101 fi
102 done
103fi
104
105echo "── lo que arranca solo ──"
106# Dos formas de arrancar el escritorio, y el medio usa UNA: por Card en la semilla (lo que hace un
107# sistema instalado) o por un `/sbin/init` que lo lanza (lo que hace el medio live, `mirada-usb.sh`).
108# Se mira la que este árbol usa de verdad.
109if [ -r "$C/sbin/init" ] && grep -q "mirada-compositor" "$C/sbin/init" 2>/dev/null; then
110 printf ' ✓ %-40s el lanzador del medio live arranca el compositor\n' "sbin/init"
111 grep -q "uevent-relay" "$C/sbin/init" 2>/dev/null \
112 && printf ' ✓ %-40s y también el reenviador de uevents\n' "sbin/init" \
113 || printf ' ⚠ %-40s el lanzador NO arranca uevent-relay: en el MEDIO el hotplug no andaría\n' "sbin/init"
114elif [ -r "$C/ente/seed.card.json" ]; then
115 for e in mirada seatd uevent-relay; do
116 if grep -q "\"$e\"" "$C/ente/seed.card.json" 2>/dev/null; then printf ' ✓ %-40s en la semilla\n' "Ente $e"
117 else printf ' ✗ %-40s NO está en la semilla\n' "Ente $e"; mal=$((mal + 1)); fi
118 done
119else
120 printf ' ✗ %-40s ni /sbin/init ni semilla: nada arrancaría el escritorio\n' "arranque"; mal=$((mal + 1))
121fi
122
123echo "═════════════════════════════════════════════════════════════════════════════"
124if [ "$mal" = 0 ]; then
125 echo "✓✓ el medio sirve: pinta, tiene red, ve lo que se enchufa, deja ser root y pregunta por una cuenta"
126else
127 echo "✗ $mal comprobación(es) en rojo — ese medio va a fallar en metal, y arriba está en qué"
128 exit 1
129fi