kde/Plasma: LANDMARK — kwin+plasmashell corren headless end-to-end (software, rootfs soberano)

- Fix clave: bwrap con rootfs merged como / (el hack loader --library-path rompía el dlopen
  de plugins de kwin → QPA create() core-dump). Paths FHS nativos + LD_LIBRARY_PATH lib64.
- kwin_wayland --virtual LEVANTA el compositor (socket wayland-0, compositing software tras
  fallar gbm); plasmashell CONECTA y arranca (QtQuick software). Stack Plasma 6 soberano
  (musl/zig-cc) EJECUTA end-to-end SIN GPU real.
- Bloqueo a H-shell: falta el shell org.kde.plasma.desktop (paquete plasma-desktop, no
  construido) → 'invalid corona'. Próximo: construir plasma-desktop + kpipewire + baloo.
- run-plasma-headless.sh reescrito con la sesión bwrap validada (dbus+kwin+cliente).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 00:02:46 -04:00
co-authored by Claude Opus 4.8
parent 725adbd487
commit c813664497
2 changed files with 59 additions and 47 deletions
+23 -8
View File
@@ -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:
+36 -39
View File
@@ -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
'