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 1572Shell 203Rust 109Markdown 993728 Definitions

⎇ main scripts/cosmic/atuq-en-cosmic.sh Shell · 172 lines · 8.8 KB History raw

atuq: el compositor NO era la causa — con cosmic-comp nesteado el navegador pinta 756ed9c6a · Sergio ·

1#!/bin/sh
2# atuq-en-cosmic.sh — ¿el navegador PINTA SU VENTANA bajo `cosmic-comp`? (SDD 26 §6.10.ter)
3#
4#   scripts/cosmic/atuq-en-cosmic.sh              # atuq dentro de cosmic-comp
5#   scripts/cosmic/atuq-en-cosmic.sh --control    # el MISMO atuq, pero directo sobre sway
6#
7# ── POR QUÉ EXISTE ────────────────────────────────────────────────────────────────────────────
8# El 2026-09-14 se arrancó por primera vez una IMAGEN DE DISCO con COSMIC y `atuq` adentro: el
9# navegador arranca, sus extensiones corren, WebRender inicializa… y la ventana no aparece nunca.
10# Bajo `sway` headless el mismo artefacto pinta perfecto. Entre los dos casos cambian DOS cosas a la
11# vez —el compositor (cosmic-comp+llvmpipe contra sway+pixman) y el arranque real contra `bwrap`—,
12# así que ninguna medición de las que había separa una de la otra.
13#
14# Este arnés cambia UNA sola: el compositor. Todo lo demás —el mismo cierre `escritorio-cosmic`
15# hidratado, el mismo binario de `atuq`, la misma jaula— queda fijo, y `--control` corre ese mismo
16# `atuq` sobre sway sin tocar nada más. Cuesta ~2 min por vuelta en vez de armar una imagen de 12 G
17# y arrancarla en QEMU sin KVM.
18#
19# ── LA CADENA ─────────────────────────────────────────────────────────────────────────────────
20#   sway (headless, pixman)  →  cosmic-comp (winit, cliente de sway)  →  atuq
21#   `grim` captura del lado de SWAY, o sea que fotografía la ventana de cosmic-comp con lo que haya
22#   dentro. sway es andamio: no lo prueba nada, sólo le da a cosmic-comp una pantalla donde vivir.
23#
24# ── LA EVIDENCIA ES UN DIFF DE PÍXELES, Y ADEMÁS SE MIRA EL ÁRBOL ─────────────────────────────
25# Se captura ANTES de lanzar el navegador y DESPUÉS. Un log en verde es compatible con una pantalla
26# vacía —es exactamente lo que pasó en la imagen— así que el veredicto es cuántos píxeles cambiaron.
27# Y se guarda el `MOZ_LOG` del widget: si la ventana se crea pero nunca recibe su `configure`, eso
28# sólo se ve ahí.
29#
30#   env:  RFS_COSMIC  (def /mnt/cosecha/cosmic-rootfs)              cierre de escritorio-cosmic
31#         RFS_SWAY    (def /mnt/cosecha/escritorios/sway-rootfs)    el andamio
32#         MESA        (def el artefacto vigente de mesa-llvmpipe)   GL por software para cosmic-comp
33#         ESPERA      (def 60)                                      segundos para que el navegador pinte
34#         OUT         (def un temporal)                             dónde quedan capturas y logs
35set -eu
36ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
37RFS_COSMIC="${RFS_COSMIC:-/mnt/cosecha/cosmic-rootfs}"
38RFS_SWAY="${RFS_SWAY:-/mnt/cosecha/escritorios/sway-rootfs}"
39ALPINE="$ROOT/.dev-fs/alpine"
40ESPERA="${ESPERA:-60}"
41CONTROL=0
42for a in "$@"; do
43  case "$a" in
44    --control) CONTROL=1 ;;
45    *) echo "✗ opción desconocida: $a" >&2; exit 1 ;;
46  esac
47done
48
49# mesa-llvmpipe por HASH VIGENTE, no por el más reciente del store (con dos artefactos del mismo
50# paquete conviviendo, la fecha miente). Es el mismo criterio de cosmic-nested.sh.
51if [ -z "${MESA+x}" ]; then
52  MH=$(./target/release/takana --store /mnt/cosecha/store hash recipes/mesa-llvmpipe.toml 2>/dev/null | tr -d '\n' | sed 's/b3://')
53  MESA=$(ls -d /mnt/cosecha/store/"$MH"-mesa-llvmpipe 2>/dev/null || true)
54fi
55[ -d "$RFS_COSMIC" ] || { echo "✗ falta el cierre de cosmic en $RFS_COSMIC" >&2
56  echo "  scripts/hydrate-profile.py escritorio-cosmic --store /mnt/cosecha/store --into $RFS_COSMIC" >&2; exit 1; }
57[ -d "$RFS_SWAY" ] || { echo "✗ falta el rootfs de sway en $RFS_SWAY" >&2; exit 1; }
58[ -x "$RFS_COSMIC/usr/bin/atuq" ] || { echo "✗ el cierre no trae /usr/bin/atuq" >&2; exit 1; }
59[ -n "${MESA:-}" ] || echo "   ⚠ sin mesa-llvmpipe sellado: cosmic-comp no va a poder iniciar EGL" >&2
60
61OUT="${OUT:-$(mktemp -d)}"; mkdir -p "$OUT"
62echo "== salida: $OUT"
63
64# Una página de UN SOLO COLOR imposible de confundir con nada del escritorio: si aparece, apareció
65# la ventana del navegador y no un repintado de cosmic.
66cat > "$OUT/pagina.html" <<'HTML'
67<!doctype html><meta charset="utf-8"><title>atuq en cosmic</title>
68<body style="margin:0;background:#ff00ff">
69<h1 style="color:#000;font:40px monospace;padding:40px">ATUQ PINTA</h1>
70<script>if (window.dump) { dump("ATUQ-PAGINA cargada\n");
71  setInterval(() => dump("ATUQ-PAGINA viva\n"), 10000); }</script>
72HTML
73mkdir -p "$OUT/perfil"
74cat > "$OUT/perfil/user.js" <<'JS'
75user_pref("browser.dom.window.dump.enabled", true);
76user_pref("browser.shell.checkDefaultBrowser", false);
77JS
78
79cat > "$OUT/dentro.sh" <<'ADENTRO'
80#!/bin/sh
81export XDG_RUNTIME_DIR=/run/user/0 HOME=/root LANG=C XDG_DATA_DIRS=/usr/share
82export XDG_CURRENT_DESKTOP=COSMIC XDG_SESSION_TYPE=wayland RUST_BACKTRACE=1
83export LIBGL_ALWAYS_SOFTWARE=1 LIBGL_DRIVERS_PATH=/usr/lib/dri
84mkdir -p "$XDG_RUNTIME_DIR" /root /dev/shm /etc; chmod 700 "$XDG_RUNTIME_DIR"
85[ -s /etc/passwd ] || echo "root:x:0:0:root:/root:/bin/sh" > /etc/passwd
86[ -s /etc/machine-id ] || tr -d - < /proc/sys/kernel/random/uuid > /etc/machine-id
87
88lanzar_atuq() {   # $1 = WAYLAND_DISPLAY donde tiene que pintar
89  WAYLAND_DISPLAY="$1" \
90  MOZ_ENABLE_WAYLAND=1 GDK_BACKEND=wayland \
91  MOZ_DISABLE_CONTENT_SANDBOX=1 MOZ_DISABLE_RDD_SANDBOX=1 MOZ_DISABLE_UTILITY_SANDBOX=1 \
92  MOZ_DISABLE_GMP_SANDBOX=1 MOZ_DISABLE_SOCKET_PROCESS_SANDBOX=1 \
93  MOZ_LOG='Widget:5,WidgetWayland:5,WaylandBackend:5,timestamp' \
94  MOZ_LOG_FILE=/salida/moz \
95    /usr/bin/atuq --no-remote --profile /salida/perfil file:///salida/pagina.html \
96      > /salida/atuq.log 2>&1 &
97  echo "@@ atuq lanzado (pid $!) contra $1"
98}
99
100(
101  i=0
102  while [ ! -S /run/user/0/wayland-1 ] && [ $i -lt 60 ]; do sleep 1; i=$((i+1)); done
103  [ -S /run/user/0/wayland-1 ] || { echo "@@ sin socket de sway"; exit 1; }
104  export WAYLAND_DISPLAY=wayland-1
105  /usr/bin/swaybg -c '#1a4b8c' >/dev/null 2>&1 &
106  sleep 2
107  export DBUS_SESSION_BUS_ADDRESS=$(/usr/bin/dbus-daemon --session --fork --print-address 2>/dev/null)
108  echo "@@ dbus=${DBUS_SESSION_BUS_ADDRESS:-VACIO}"
109
110  if [ "${CONTROL:-0}" = "1" ]; then
111    echo "@@ CONTROL: el navegador va directo sobre sway (sin cosmic-comp)"
112    DEST=wayland-1
113  else
114    echo "@@ arrancando cosmic-comp nesteado sobre sway…"
115    cosmic-comp >/salida/cosmic.log 2>&1 &
116    CC=$!
117    i=0; WD=""
118    while [ $i -lt 60 ]; do
119      WD=$(ls /run/user/0/wayland-* 2>/dev/null | grep -v lock | grep -v 'wayland-1$' | head -1)
120      [ -n "$WD" ] && break
121      kill -0 $CC 2>/dev/null || { echo "@@ cosmic-comp murió antes del socket:"; tail -25 /salida/cosmic.log; exit 1; }
122      i=$((i+1)); sleep 1
123    done
124    [ -n "$WD" ] || { echo "@@ cosmic-comp sin socket en 60 s:"; tail -25 /salida/cosmic.log; exit 1; }
125    DEST=$(basename "$WD")
126    echo "@@ cosmic-comp OK ($DEST)"
127    sleep 5
128  fi
129
130  /usr/bin/grim /salida/antes.png && echo "@@ captura ANTES"
131  lanzar_atuq "$DEST"
132  sleep "${ESPERA:-60}"
133  /usr/bin/grim /salida/despues.png && echo "@@ captura DESPUES"
134  echo "@@ procesos atuq: $(ps -o comm= 2>/dev/null | grep -c atuq)"
135  sleep 1
136  /usr/bin/swaymsg exit 2>/dev/null
137) &
138
139export WLR_BACKENDS=headless WLR_HEADLESS_OUTPUTS=1 WLR_RENDERER=pixman
140exec /usr/bin/sway -d 2>&1
141ADENTRO
142
143# El ORDEN de los overlays manda: alpine trae la libc, sway el andamio, el cierre de cosmic pisa lo
144# que comparta con él, y mesa-llvmpipe va ÚLTIMO porque el cierre trae la mesa de Intel real
145# (iris_dri) y en una máquina sin GPU eso no inicia EGL.
146TIEMPO=$((ESPERA + 180))
147timeout "$TIEMPO" bwrap \
148  --overlay-src "$ALPINE" --overlay-src "$RFS_SWAY" --overlay-src "$RFS_COSMIC" \
149  ${MESA:+--overlay-src "$MESA"} --tmp-overlay / \
150  --bind "$OUT" /salida --dev /dev --proc /proc --tmpfs /run --tmpfs /tmp \
151  --dev-bind-try /dev/dri /dev/dri \
152  --unshare-pid --unshare-uts --hostname atuq-en-cosmic \
153  --uid 0 --gid 0 --die-with-parent \
154  --setenv PATH /usr/bin:/bin:/usr/sbin:/sbin \
155  --setenv CONTROL "$CONTROL" --setenv ESPERA "$ESPERA" \
156  /bin/sh /salida/dentro.sh > "$OUT/log.txt" 2>&1 || true
157
158grep -a '@@' "$OUT/log.txt" || true
159[ -f "$OUT/antes.png" ] && [ -f "$OUT/despues.png" ] || {
160  echo "✗ no hubo capturas — mirá $OUT/log.txt" >&2; tail -20 "$OUT/log.txt" >&2; exit 1; }
161
162python3 - "$OUT/antes.png" "$OUT/despues.png" <<'PY'
163import sys
164from PIL import Image, ImageChops
165a, b = (Image.open(p).convert("RGB") for p in sys.argv[1:3])
166d = ImageChops.difference(a, b).convert("L")
167cambiados = d.width * d.height - d.histogram()[0]
168magenta = sum(n for n, c in b.getcolors(maxcolors=1 << 24) if c == (255, 0, 255))
169print(f"  píxeles cambiados: {cambiados}   magenta de la página: {magenta}")
170PY
171echo "  capturas: $OUT/antes.png  $OUT/despues.png"
172echo "  logs: $OUT/atuq.log  $OUT/cosmic.log  $OUT/moz.*"