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 Sutichaykuna

⎇ main docs/runbooks/kde-qemu-desktop.md Markdown · 183 siq'ikuna · 9.7 KB Ñawpa willay ch'uya

takana etapa 5b: los 59 docs de diseño, runbooks y ADR 97ceb7241 · Sergio ·

1# Runbook — relanzar el escritorio KDE Plasma 6 en QEMU
2
3Plasma 6 renderizado 100% por software (QPainter + llvmpipe) sobre `virtio-gpu`, en la cadena
4soberana de takana (LLVM 18 + mesa desde fuente). Sin GPU real. Cerrado 2026-07-20 tras resolver
55 bugs estructurales + 2 de cursor (ver [[kde-metal-qemu-desktop]] en memoria y `git log` del frente
6`kde/qemu:`). Este runbook es sólo para **relanzar y verificar**, no para rediagnosticar.
7
8## Relanzar (caso normal — la imagen ya existe)
9
10```sh
11cd ~/hammer
12# la ventana gtk necesita el X del laptop (Xwayland de mirada):
13DISPLAY=:0 GDK_BACKEND=x11 TIMEOUT=1800 DISP=gtk bash scripts/kde/run-qemu-desktop.sh
14```
15
16- Abre una ventana gtk con el virtio-gpu. Bootea UEFI → kernel → arje-zero → Plasma pinta solo (~30-45s).
17- `TIMEOUT=1800` = auto-kill a los 30 min (omitir para dejarlo indefinido; matarlo a mano con el kill de abajo).
18- `DISP=none` = headless (sólo serial, para diagnóstico sin ventana ni interferir con mirada).
19- Toda la config que lo hace funcionar (los 7 fixes) vive en `scripts/kde/plasma-start-qemu.sh`, que se
20  hornea en la imagen. No hace falta setear nada a mano.
21
22## Verificar sin mirar la ventana (oráculo screendump)
23
24La ventana gtk **se congela si mirada reinicia su Xwayland** (QEMU sigue vivo por dentro). Para ver el
25scanout REAL del guest, independiente de la ventana:
26
27```sh
28cd ~/hammer
29printf 'screendump %s/shot.ppm\n' "$PWD" | socat - unix-connect:work/qemu-monitor.sock
30magick shot.ppm /tmp/shot.png        # y abrir /tmp/shot.png ; luego: rm shot.ppm
31```
32
33Salud por el serial (no necesita la ventana):
34
35```sh
36grep -a 'STATUS +' work/qemu-desktop-serial.log | tail -3   # kwin=1 plasmashell=1 = vivo
37grep -ac 'código 139' work/qemu-desktop-serial.log          # crashes de kwin (÷3: cada línea sale x3)
38```
39
40## Matar / cerrar
41
42```sh
43pkill -KILL -f 'qemu-sys[t]em-x86_64 -machine q35'          # el [t] evita auto-matar el propio comando
44```
45
46## Reconstruir la imagen (si se tocó una receta KDE, mesa/llvm, o plasma-start)
47
48```sh
49cd ~/hammer
50bash scripts/kde/qemu-desktop-image.sh      # funde base+kde-rootfs, inyecta llvmpipe/musl, hornea plasma-start
51# necesita en store/: *-mesa-llvmpipe, *-llvm18, y los rootfs work/{metal-rootfs,kde-metal-rootfs}
52```
53
54Rebuild ~40s (host-side, hardlinks + artefactos ya sellados; **no** compila nada). Luego relanzar.
55
56## Los 7 fixes que lo hacen andar (por si algo regresa)
57
58Todos en `plasma-start-qemu.sh` salvo `-vga none` (en `run-qemu-desktop.sh`):
59
60| Fix | Sin él |
61|---|---|
62| `GBM_ALWAYS_SOFTWARE=1` | segfault al init (virtio sin 3D tratado como HW → vtable NULL) |
63| `KWIN_DRM_USE_MODIFIERS=0` | negro total (virtio rechaza `AddFB2WithModifiers` con EINVAL) |
64| `KWIN_DRM_DEVICES=<card virtio>` | doble output (efifb+virtio) rompe buffers (redundante con `-vga none`) |
65| `KWIN_COMPOSE=Q` (QPainter) | kwin segfaltea en el rasterizador llvmpipe (`lp_rast_clear_color`) |
66| `-vga none` | **pantalla clavada en TianoCore** (VGA-std por defecto + simpledrm roban el scanout) |
67| `XCURSOR_THEME=breeze_cursors` + `kcminputrc` | `Failed to load cursor theme "default"` (cursor invisible) |
68| `KWIN_FORCE_SW_CURSOR=1` | cursor aparece/desaparece (plano HW de virtio no se presenta) |
69
70## Gotchas de operación
71
72- **Lectura STALE del serial:** no se trunca hasta que el run-script arranca QEMU (tras el rebuild ~40s).
73  Un `until grep 'escritorio arriba'` matchea el run ANTERIOR. Esperá un marcador único del run nuevo:
74  `rm -f work/qemu-monitor.sock` antes de lanzar y `until [ -S work/qemu-monitor.sock ]; do sleep 2; done`.
75- **`pkill -f qemu...` se auto-mata** (el patrón matchea el propio comando) → usar siempre `qemu-sys[t]em`.
76- **"Se queda en TianoCore" tras varios relanzamientos:** el `work/qemu-desktop-OVMF_VARS.fd` persistente
77  acumula boot entries stale → `rm -f work/qemu-desktop-OVMF_VARS.fd` (el run-script lo recrea limpio).
78- **Serial triplicado:** cada línea sale ×3 (`say` tee a console+ttyS0). "139: 3" = 1 crash real.
79- El escritorio queda sólo con wallpaper+panel; sin discos/energía reales (no hay udisksd/upowerd en el
80  rootfs) ni efectos GL pesados (llvmpipe no los soporta). Es esperado, no un fallo.
81
82## Prerrequisitos
83
84- `work/hammer-kde-qemu.img` (la imagen; si falta, reconstruir arriba).
85- OVMF: `/usr/share/edk2/x64/OVMF_CODE.4m.fd` + `OVMF_VARS.4m.fd`.
86- Herramientas host: `qemu-system-x86_64`, `socat`, `magick` (ImageMagick) para el screendump.
87- Para la ventana gtk: sesión gráfica del laptop viva (`DISPLAY=:0`). Headless (`DISP=none`) no la necesita.
88
89Relacionado: memoria [[kde-metal-qemu-desktop]], [[frente-escritorio-kde]], [[arranque-grafo-mirada]].
90
91## 2026-09-03 — verificar el escritorio SIN humano delante (gioser, TCG, sin socat)
92
93Este runbook asumía el laptop: `DISP=gtk` para ver la ventana y `socat` para el monitor. En **gioser
94no hay ninguna de las dos cosas** —es un vServer sin `/dev/kvm` y sin `socat`— y aun así se puede
95verificar todo, incluido **hacer clic**. Las tres piezas:
96
97```sh
98# 1. la imagen y el rootfs viven en el VOLUMEN (/mnt/vvv está al 98%), y el STAGE también:
99#    sin STAGE= el install-image-efi hardlinkea de /mnt/cosecha a work/ y muere con EXDEV.
100E=/mnt/cosecha/escritorios
101BASE=$E/base-rootfs KDE=$E/kde-rootfs MERGED=$E/kde-qemu-rootfs \
102IMG=$E/hammer-kde-qemu.img STAGE=$E/.stage-kde bash scripts/kde/qemu-desktop-image.sh
103
104# 2. arrancar headless (cae solo a TCG: gioser no tiene KVM; Plasma pinta en ~2 min)
105IMG=$E/hammer-kde-qemu.img SERIAL=work/kde-qemu-serial.log MON=work/kde-monitor.sock \
106  VARS=work/kde-OVMF_VARS.fd TIMEOUT=1200 DISP=none bash scripts/kde/run-qemu-desktop.sh &
107```
108
1093. el monitor de QEMU **por socket unix desde python**, que reemplaza a `socat`:
110
111```python
112import socket, time
113s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM); s.connect('work/kde-monitor.sock')
114time.sleep(.5); s.recv(65536)
115def cmd(c, p=.6):
116    s.sendall((c+'\n').encode()); time.sleep(p)
117    try: s.recv(200000)
118    except: pass
119cmd('screendump /mnt/cosecha/escritorios/shot.ppm', 4)   # el scanout REAL del guest
120```
121
122### Hacer CLIC sin ventana — y por qué el ratón es relativo
123
124`info mice` dice `QEMU PS/2 Mouse`: **movimiento RELATIVO**, así que no hay «ir a (x,y)». La
125maniobra que sí funciona es **fijar contra una esquina** y moverse desde ahí:
126
127```python
128cmd('mouse_move -3000 3000', 2)   # clava el puntero en la esquina INFERIOR IZQUIERDA
129cmd('mouse_move 10 -8', 1)        # y desde la esquina, al lanzador del panel
130cmd('mouse_button 1', .5); cmd('mouse_button 0', 8)
131```
132
133`sendkey` también anda (`sendkey alt-f2`, `sendkey k`, …) y **la combinación arranca krunner** —se ve
134en el log de kwin— pero **la ventana de krunner no llegó a pintar** en dos intentos. Queda anotado
135como pendiente propio, separado del bug de abajo.
136
137### Lo que estas dos herramientas destaparon el 2026-09-03
138
1391. **El panel salía con el reloj y nada más, y no era el panel: eran los ICONOS.** Los `.so` de
140   todos los applets estaban instalados; lo que faltaba era `breeze-icons`. Ver el commit
141   «escritorios: KDE y GNOME corrían SIN tema de iconos». Evidencia:
142   `../evidencia/plasma6-qemu-2026-09-03-panel-con-iconos.png` — kickoff, gestor de tareas, bandeja
143   (notificaciones, volumen, teclado, red), reloj y «mostrar escritorio», todos pintando.
144
1452. **El lanzador de aplicaciones NO ABRE**, y el diálogo de error lo dice entero:
146
147   ```
148   qrc:/qt/qml/plasma/applet/org/kde/plasma/kickoff/main.qml:191:25: Type FullRepresentation unavailable
149   .../Header.qml:18:1: module "org.kde.coreaddons" is not installed
150   ```
151
152   `recipes/incoming-kde/kcoreaddons.toml` pasa `-DKCOREADDONS_USE_QML=OFF` (la cabecera lo dice:
153   «QML bindings / python / docs apagados»), así que el módulo QML `org.kde.coreaddons` no se
154   construye. Evidencia: `../evidencia/plasma6-qemu-2026-09-03-kickoff-sin-coreaddons.png`.
155   **`yupana radio kcoreaddons` = 71**, o sea que prenderlo es una campaña de granja, no un ticket.
156
157**Regla que sale de las dos:** una captura donde el escritorio «pinta» NO prueba que el escritorio
158funcione. El barrido barato que sí lo prueba es cruzar los `import` de los `.qml` instalados contra
159los módulos QML con `qmldir` que hay en el rootfs; así salió `org.kde.coreaddons` y, de yapa,
160`org.kde.kscreenlocker` y `org.kde.newstuff.core`, que también faltan.
161
162### El arreglo, verificado con UN build (2026-09-03)
163
164`-DKCOREADDONS_USE_QML=ON` + **un solo** `takana build kcoreaddons` (56 s) instala
165`usr/lib/qt6/qml/org/kde/coreaddons/{libkcoreaddonsplugin.so,qmldir,…}`. Hidratado ESE artefacto en
166el rootfs y rehecha la imagen, el menú **abre**: usuario, buscador, Favoritos / Todas las
167aplicaciones, y las pestañas Aplicaciones / Lugares / Sesión
168(`../evidencia/plasma6-qemu-2026-09-03-menu-abre.png`). Escribiendo `konsole` en el buscador y Enter,
169la terminal arranca y corre — `uname -a` da el kernel 6.16.12 de takana y `konsole --version` da
17025.04.3 (`../evidencia/plasma6-qemu-2026-09-03-konsole-uname.png`).
171
172Es la cadena completa del escritorio por primera vez: **panel → menú → búsqueda → app → shell**.
173
174Se probó con UN build a propósito: la cascada de 71 es de granja y no hacía falta pagarla para saber
175si el arreglo era el correcto. Las 71 quedan como **deuda declarada** —`escritorio-kde 192/263`— y la
176imagen de hoy corre con un `kcoreaddons` más nuevo que aquel contra el que enlazaron sus
177consumidores. Eso es legítimo porque lo que cruza es un **SONAME** (misma versión, misma ABI, sólo se
178suma un módulo QML); es la misma regla que decidió la promoción de pipewire. Lo que NO se puede es
179hidratar dos artefactos distintos en la misma ruta.
180
181⚠ El aviso rojo `Could not find '', starting '/bin/sh' instead` de konsole era real y NO venía de
182`/etc/passwd` (que dice `/bin/sh`): konsole lee **`$SHELL`**, y este getty no es un login shell.
183Arreglado exportándolo en `plasma-start-qemu.sh`.

kde-qemu-desktop.md

Runbook — relanzar el escritorio KDE Plasma 6 en QEMU

Plasma 6 renderizado 100% por software (QPainter + llvmpipe) sobre virtio-gpu, en la cadena soberana de takana (LLVM 18 + mesa desde fuente). Sin GPU real. Cerrado 2026-07-20 tras resolver 5 bugs estructurales + 2 de cursor (ver [[kde-metal-qemu-desktop]] en memoria y git log del frente kde/qemu:). Este runbook es sólo para relanzar y verificar, no para rediagnosticar.

Relanzar (caso normal — la imagen ya existe)

cd ~/hammer
# la ventana gtk necesita el X del laptop (Xwayland de mirada):
DISPLAY=:0 GDK_BACKEND=x11 TIMEOUT=1800 DISP=gtk bash scripts/kde/run-qemu-desktop.sh

Verificar sin mirar la ventana (oráculo screendump)

La ventana gtk se congela si mirada reinicia su Xwayland (QEMU sigue vivo por dentro). Para ver el scanout REAL del guest, independiente de la ventana:

cd ~/hammer
printf 'screendump %s/shot.ppm\n' "$PWD" | socat - unix-connect:work/qemu-monitor.sock
magick shot.ppm /tmp/shot.png        # y abrir /tmp/shot.png ; luego: rm shot.ppm

Salud por el serial (no necesita la ventana):

grep -a 'STATUS +' work/qemu-desktop-serial.log | tail -3   # kwin=1 plasmashell=1 = vivo
grep -ac 'código 139' work/qemu-desktop-serial.log          # crashes de kwin (÷3: cada línea sale x3)

Matar / cerrar

pkill -KILL -f 'qemu-sys[t]em-x86_64 -machine q35'          # el [t] evita auto-matar el propio comando

Reconstruir la imagen (si se tocó una receta KDE, mesa/llvm, o plasma-start)

cd ~/hammer
bash scripts/kde/qemu-desktop-image.sh      # funde base+kde-rootfs, inyecta llvmpipe/musl, hornea plasma-start
# necesita en store/: *-mesa-llvmpipe, *-llvm18, y los rootfs work/{metal-rootfs,kde-metal-rootfs}

Rebuild ~40s (host-side, hardlinks + artefactos ya sellados; no compila nada). Luego relanzar.

Los 7 fixes que lo hacen andar (por si algo regresa)

Todos en plasma-start-qemu.sh salvo -vga none (en run-qemu-desktop.sh):

FixSin él
GBM_ALWAYS_SOFTWARE=1segfault al init (virtio sin 3D tratado como HW → vtable NULL)
KWIN_DRM_USE_MODIFIERS=0negro total (virtio rechaza AddFB2WithModifiers con EINVAL)
KWIN_DRM_DEVICES=<card virtio>doble output (efifb+virtio) rompe buffers (redundante con -vga none)
KWIN_COMPOSE=Q (QPainter)kwin segfaltea en el rasterizador llvmpipe (lp_rast_clear_color)
-vga nonepantalla clavada en TianoCore (VGA-std por defecto + simpledrm roban el scanout)
XCURSOR_THEME=breeze_cursors + kcminputrcFailed to load cursor theme "default" (cursor invisible)
KWIN_FORCE_SW_CURSOR=1cursor aparece/desaparece (plano HW de virtio no se presenta)

Gotchas de operación

Prerrequisitos

Relacionado: memoria [[kde-metal-qemu-desktop]], [[frente-escritorio-kde]], [[arranque-grafo-mirada]].

2026-09-03 — verificar el escritorio SIN humano delante (gioser, TCG, sin socat)

Este runbook asumía el laptop: DISP=gtk para ver la ventana y socat para el monitor. En gioser no hay ninguna de las dos cosas —es un vServer sin /dev/kvm y sin socat— y aun así se puede verificar todo, incluido hacer clic. Las tres piezas:

# 1. la imagen y el rootfs viven en el VOLUMEN (/mnt/vvv está al 98%), y el STAGE también:
#    sin STAGE= el install-image-efi hardlinkea de /mnt/cosecha a work/ y muere con EXDEV.
E=/mnt/cosecha/escritorios
BASE=$E/base-rootfs KDE=$E/kde-rootfs MERGED=$E/kde-qemu-rootfs \
IMG=$E/hammer-kde-qemu.img STAGE=$E/.stage-kde bash scripts/kde/qemu-desktop-image.sh

# 2. arrancar headless (cae solo a TCG: gioser no tiene KVM; Plasma pinta en ~2 min)
IMG=$E/hammer-kde-qemu.img SERIAL=work/kde-qemu-serial.log MON=work/kde-monitor.sock \
  VARS=work/kde-OVMF_VARS.fd TIMEOUT=1200 DISP=none bash scripts/kde/run-qemu-desktop.sh &
  1. el monitor de QEMU por socket unix desde python, que reemplaza a socat:
import socket, time
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM); s.connect('work/kde-monitor.sock')
time.sleep(.5); s.recv(65536)
def cmd(c, p=.6):
    s.sendall((c+'\n').encode()); time.sleep(p)
    try: s.recv(200000)
    except: pass
cmd('screendump /mnt/cosecha/escritorios/shot.ppm', 4)   # el scanout REAL del guest

Hacer CLIC sin ventana — y por qué el ratón es relativo

info mice dice QEMU PS/2 Mouse: movimiento RELATIVO, así que no hay «ir a (x,y)». La maniobra que sí funciona es fijar contra una esquina y moverse desde ahí:

cmd('mouse_move -3000 3000', 2)   # clava el puntero en la esquina INFERIOR IZQUIERDA
cmd('mouse_move 10 -8', 1)        # y desde la esquina, al lanzador del panel
cmd('mouse_button 1', .5); cmd('mouse_button 0', 8)

sendkey también anda (sendkey alt-f2, sendkey k, …) y la combinación arranca krunner —se ve en el log de kwin— pero la ventana de krunner no llegó a pintar en dos intentos. Queda anotado como pendiente propio, separado del bug de abajo.

Lo que estas dos herramientas destaparon el 2026-09-03

  1. El panel salía con el reloj y nada más, y no era el panel: eran los ICONOS. Los .so de todos los applets estaban instalados; lo que faltaba era breeze-icons. Ver el commit «escritorios: KDE y GNOME corrían SIN tema de iconos». Evidencia: ../evidencia/plasma6-qemu-2026-09-03-panel-con-iconos.png — kickoff, gestor de tareas, bandeja (notificaciones, volumen, teclado, red), reloj y «mostrar escritorio», todos pintando.

  2. El lanzador de aplicaciones NO ABRE, y el diálogo de error lo dice entero:

    qrc:/qt/qml/plasma/applet/org/kde/plasma/kickoff/main.qml:191:25: Type FullRepresentation unavailable
    .../Header.qml:18:1: module "org.kde.coreaddons" is not installed
    

    recipes/incoming-kde/kcoreaddons.toml pasa -DKCOREADDONS_USE_QML=OFF (la cabecera lo dice: «QML bindings / python / docs apagados»), así que el módulo QML org.kde.coreaddons no se construye. Evidencia: ../evidencia/plasma6-qemu-2026-09-03-kickoff-sin-coreaddons.png. yupana radio kcoreaddons = 71, o sea que prenderlo es una campaña de granja, no un ticket.

Regla que sale de las dos: una captura donde el escritorio «pinta» NO prueba que el escritorio funcione. El barrido barato que sí lo prueba es cruzar los import de los .qml instalados contra los módulos QML con qmldir que hay en el rootfs; así salió org.kde.coreaddons y, de yapa, org.kde.kscreenlocker y org.kde.newstuff.core, que también faltan.

El arreglo, verificado con UN build (2026-09-03)

-DKCOREADDONS_USE_QML=ON + un solo takana build kcoreaddons (56 s) instala usr/lib/qt6/qml/org/kde/coreaddons/{libkcoreaddonsplugin.so,qmldir,…}. Hidratado ESE artefacto en el rootfs y rehecha la imagen, el menú abre: usuario, buscador, Favoritos / Todas las aplicaciones, y las pestañas Aplicaciones / Lugares / Sesión (../evidencia/plasma6-qemu-2026-09-03-menu-abre.png). Escribiendo konsole en el buscador y Enter, la terminal arranca y corre — uname -a da el kernel 6.16.12 de takana y konsole --version da 25.04.3 (../evidencia/plasma6-qemu-2026-09-03-konsole-uname.png).

Es la cadena completa del escritorio por primera vez: panel → menú → búsqueda → app → shell.

Se probó con UN build a propósito: la cascada de 71 es de granja y no hacía falta pagarla para saber si el arreglo era el correcto. Las 71 quedan como deuda declarada —escritorio-kde 192/263— y la imagen de hoy corre con un kcoreaddons más nuevo que aquel contra el que enlazaron sus consumidores. Eso es legítimo porque lo que cruza es un SONAME (misma versión, misma ABI, sólo se suma un módulo QML); es la misma regla que decidió la promoción de pipewire. Lo que NO se puede es hidratar dos artefactos distintos en la misma ruta.

⚠ El aviso rojo Could not find '', starting '/bin/sh' instead de konsole era real y NO venía de /etc/passwd (que dice /bin/sh): konsole lee $SHELL, y este getty no es un login shell. Arreglado exportándolo en plasma-start-qemu.sh.