diff --git a/docs/HANDOFF-noche-kde-2026-07-14.md b/docs/HANDOFF-noche-kde-2026-07-14.md index 62a8cfb8..a998d751 100644 --- a/docs/HANDOFF-noche-kde-2026-07-14.md +++ b/docs/HANDOFF-noche-kde-2026-07-14.md @@ -25,16 +25,31 @@ Trabajo desatendido continuando la campaña KDE Plasma 6 tras cerrar H-QML. Esta 4. **`scripts/kde/run-plasma-headless.sh`**: lanzador de la sesión Plasma headless (software EGL/softpipe sobre el KMS del worker). NO funciona aún (ver abajo). -## Bloqueo del "escritorio VIVO headless" (el muro de la noche) +## 🎉 LANDMARK: kwin + plasmashell CORREN HEADLESS end-to-end (software, rootfs soberano) -El worker (VM cloud Hetzner, host Ubuntu/glibc) TIENE `/dev/dri/card1`+`renderD128` (virtio-gpu). Con -mesa-swrast (kms_swrast_dri) intenté levantar `kwin_wayland` con render por software + `LIBSEAT_BACKEND= -builtin` (DRM directo como root). **kwin_wayland linkea perfecto y encuentra su QPA `wayland-org.kde. -kwin.qpa`, pero `create()` del plugin CRASHEA (core dump)** — sin símbolo faltante ni error legible; es un -fallo interno del backend compositor (probable interacción virtio-gpu/EGL-software/seat en musl). Opaco -sin gdb/backtrace. Igual con backend `--virtual`. **No cierra sin depuración interactiva** — por eso paré. +El hack `loader --library-path` rompía el `dlopen` de plugins de kwin (QPA `create()` → core dump). **Fix += bwrap con el rootfs merged como `/`** (`--overlay-src .dev-fs/alpine --overlay-src kde-store-rootfs +--tmp-overlay /` + `LD_LIBRARY_PATH=/usr/lib64:/usr/lib/qt6:/usr/lib:/lib`), paths FHS nativos. Con eso: +- **`kwin_wayland --virtual --width 1280 --height 800` LEVANTA el compositor** (backend virtual, framebuffer + en memoria; gbm sobre renderD128 falla pero cae a compositing por software y sigue) → **`Accepting client + connections on sockets: QList("wayland-0")`**, socket `/run/wayland-0` creado. +- **`plasmashell` CONECTA a wayland-0 y arranca** (proceso vivo, frameworkintegration/QtQuick-software + cargados). El stack Plasma 6 SOBERANO (musl/zig-cc) EJECUTA end-to-end sin GPU real. +- Se traba en `starting invalid corona "org.kde.plasma.desktop"` → **falta el paquete SHELL + `org.kde.plasma.desktop`, que provee `plasma-desktop` (NO construido aún)**. plasma-workspace da el + binario plasmashell, no el shell/corona. Ese es el único gran gap a "escritorio prende" (H-shell). -## Camino recomendado: METAL (tu laptop TigerLake/Intel) +Env que funciona (bwrap): `GALLIUM_DRIVER=swrast LIBGL_ALWAYS_SOFTWARE=1 LIBGL_DRIVERS_PATH=/usr/lib/dri +MESA_LOADER_DRIVER_OVERRIDE=swrast QT_QUICK_BACKEND=software` + mesa-swrast hidratado. Gaps menores +detectados (no-fatales para arrancar, sí para un desktop limpio): D-Bus session (crear `/run/dbus` antes de +`dbus-daemon --session`), xkeyboard-config (`/usr/share/X11/xkb`), breeze-icons (icon theme), fuentes. + +## Próximo directo a H-shell: construir plasma-desktop +`plasma-desktop` (shell org.kde.plasma.desktop) + sus deps faltantes `kpipewire`, `baloo` (el resto del +cierre KF6/Plasma ya está sellado). Es una sub-campaña de varias recetas (de-Alpinizar del APKBUILD, patrón +KF6). Al sellar: hidratar al rootfs + re-correr la sesión bwrap de arriba ⇒ debería cargar la corona. + +## Camino paralelo: METAL (tu laptop TigerLake/Intel) El rootfs está hecho para **GPU Intel real (`iris_dri.so`)**, no software. Donde kwin renderiza de verdad es tu laptop. Para probar H-shell mañana: diff --git a/scripts/kde/run-plasma-headless.sh b/scripts/kde/run-plasma-headless.sh index 194f74a3..f17b5566 100644 --- a/scripts/kde/run-plasma-headless.sh +++ b/scripts/kde/run-plasma-headless.sh @@ -1,45 +1,42 @@ #!/usr/bin/env bash -# run-plasma-headless.sh — intenta levantar la sesión Plasma (kwin_wayland + plasmashell) HEADLESS con -# render por SOFTWARE (mesa-swrast/softpipe) sobre el KMS del worker (/dev/dri/card1), dentro del rootfs -# musl soberano. Objetivo: hito H-shell ("escritorio prende") sin GPU real ni metal. +# run-plasma-headless.sh — levanta la sesión Plasma HEADLESS con render por SOFTWARE (mesa-swrast/swrast) +# dentro del rootfs musl soberano, vía BWRAP (rootfs merged como / — imprescindible: el hack +# loader --library-path rompe el dlopen de plugins de kwin ⇒ QPA create() core-dumpea). # -# Requiere: work/kde-store-rootfs hidratado + cierre completo (hydrate-from-store.sh + complete-closure.sh) -# + mesa-swrast hidratado (kms_swrast_dri.so / softpipe). -# Corre EN el worker (host glibc): binarios musl vía loader del .dev-fs + LD path del rootfs. +# ✅ VALIDADO: kwin_wayland --virtual levanta el compositor (socket wayland-0) y plasmashell CONECTA. +# Bloqueo actual = falta el shell org.kde.plasma.desktop (paquete `plasma-desktop`, no construido). +# +# Requiere (en el worker, host glibc): work/kde-store-rootfs hidratado + complete-closure + mesa-swrast +# hidratado (swap iris→swrast). Correr: scripts/kde/run-plasma-headless.sh set -uo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT" R="${RFS:-$ROOT/work/kde-store-rootfs}"; A="$ROOT/.dev-fs/alpine" -LOADER="$A/lib/ld-musl-x86_64.so.1" -SECS="${SECS:-20}" -export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/tmp/plasma-xdg}"; mkdir -p "$XDG_RUNTIME_DIR"; chmod 700 "$XDG_RUNTIME_DIR" +SECS="${SECS:-30}"; CLIENT="${CLIENT:-plasmashell}" # CLIENT=/usr/bin/foo para probar otro cliente wayland -# LD path = todos los dirs con .so del rootfs + sysroot -LIBS=$(find "$R" "$A" -name "*.so*" -printf '%h\n' 2>/dev/null | sort -u | tr '\n' ':') -# rutas de plugins/qml/datos del rootfs (lib64 y lib) -export QT_PLUGIN_PATH="$R/usr/lib64/qt6/plugins:$R/usr/lib/qt6/plugins" -export QML2_IMPORT_PATH="$R/usr/lib64/qt6/qml:$R/usr/lib/qt6/qml" -export QML_IMPORT_PATH="$QML2_IMPORT_PATH" -export XDG_DATA_DIRS="$R/usr/share" -export XDG_CONFIG_HOME="$XDG_RUNTIME_DIR/config"; mkdir -p "$XDG_CONFIG_HOME" -export QT_QPA_PLATFORM_PLUGIN_PATH="$QT_PLUGIN_PATH/platforms" -# software render: softpipe (mesa-swrast), sin aceleración -export LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=softpipe -export LIBGL_DRIVERS_PATH="$R/usr/lib/dri:$R/usr/lib64/dri" -export __EGL_VENDOR_LIBRARY_DIRS="$R/usr/share/glvnd/egl_vendor.d" -export QT_QUICK_BACKEND=software # QtQuick por software (plasmashell) -export KWIN_COMPOSE="${KWIN_COMPOSE:-Q}" # Q = QPainter (compositing por software, sin GL) si aplica -export QT_LOGGING_RULES="kwin_*.debug=false" - -run() { "$LOADER" --library-path "$LIBS" "$@"; } - -echo "==> lanzando kwin_wayland (drm sw / softpipe) ${SECS}s" -KW=$(find "$R" -name kwin_wayland -type f | head -1) -# --drm sobre el KMS del worker; sin lockscreen; salida virtual si drm falla -run "$KW" --no-lockscreen --width 1280 --height 800 \ - -- "$LOADER" --library-path "$LIBS" "$(find "$R" -name plasmashell -type f|head -1)" \ - >"$ROOT/work/plasma-headless.log" 2>&1 & -KPID=$! -sleep "$SECS" -echo "==> log (kwin+plasmashell):"; tail -40 "$ROOT/work/plasma-headless.log" -echo "==> sockets wayland en XDG_RUNTIME_DIR:"; ls -la "$XDG_RUNTIME_DIR"/wayland-* 2>/dev/null || echo " (ninguno)" -kill "$KPID" 2>/dev/null; pkill -f kwin_wayland 2>/dev/null; pkill -f plasmashell 2>/dev/null +exec bwrap --overlay-src "$A" --overlay-src "$R" --tmp-overlay / \ + --dev-bind /dev /dev --proc /proc --bind /sys /sys --tmpfs /tmp --tmpfs /run \ + --setenv LD_LIBRARY_PATH /usr/lib64:/usr/lib/qt6:/usr/lib:/lib \ + --setenv QT_PLUGIN_PATH /usr/lib64/qt6/plugins:/usr/lib/qt6/plugins \ + --setenv QML2_IMPORT_PATH /usr/lib64/qt6/qml:/usr/lib/qt6/qml \ + --setenv QML_IMPORT_PATH /usr/lib64/qt6/qml:/usr/lib/qt6/qml \ + --setenv XDG_DATA_DIRS /usr/share --setenv XDG_RUNTIME_DIR /run \ + --setenv XDG_CONFIG_HOME /run/cfg --setenv HOME /run \ + --setenv LIBGL_ALWAYS_SOFTWARE 1 --setenv GALLIUM_DRIVER swrast \ + --setenv LIBGL_DRIVERS_PATH /usr/lib/dri --setenv MESA_LOADER_DRIVER_OVERRIDE swrast \ + --setenv QT_QUICK_BACKEND software \ + sh -c ' + set -e + mkdir -p /run/cfg /run/dbus + export DBUS_SESSION_BUS_ADDRESS=$(dbus-daemon --session --fork --print-address 2>/dev/null) + echo "dbus=$DBUS_SESSION_BUS_ADDRESS" + /usr/bin/kwin_wayland --virtual --width 1280 --height 800 >/tmp/kwin.log 2>&1 & + for i in $(seq 1 30); do [ -S /run/wayland-0 ] && break; sleep 0.5; done + [ -S /run/wayland-0 ] && echo "compositor OK (wayland-0)" || { echo "kwin NO arrancó"; tail /tmp/kwin.log; exit 1; } + export WAYLAND_DISPLAY=wayland-0 + '"$CLIENT"' >/tmp/client.log 2>&1 & + sleep '"$SECS"' + echo "=== kwin.log (tail) ==="; tail -15 /tmp/kwin.log + echo "=== '"$CLIENT"'.log (tail) ==="; tail -25 /tmp/client.log + echo "=== procesos ==="; ps axo comm 2>/dev/null | grep -E "kwin|plasma" | sort -u + pkill -f kwin_wayland 2>/dev/null || true + '