645 líneas. Los ADR entran porque en este repo SON documentos vivos, no registros inmutables: el 0013 tiene 5 commits, el 0009 dos. Eso se comprobó antes de decidir, no se asumió por convención general. EXCLUIDOS por ser REGISTRO o generado: docs/evidencia/ (6), el HANDOFF de la noche de KDE (1) y docs/state/ (24, se regenera solo). Reescribir un comando dentro de una evidencia la falsifica. Y el ADR 0016 se excluye de todo barrido, con un aviso adentro para el próximo que barra: habla SOBRE el renombre, así que necesita seguir diciendo 'hammer'. El barrido se lo llevó puesto y lo dejó titulado 'Renombre del sistema: takana → takana'; revertido. Congelados, verificados uno por uno con controles: /opt/hammer, /var/lib/hammer, /usr/bin/hammer, /mnt/vvv/hammer, la URL de gitea, hammer-farm.service, hammer-live-install.sh, BRIEFING-hammer.md, hammerd, hammer-recover y HAMMER_LIVE.
9.7 KiB
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
- Abre una ventana gtk con el virtio-gpu. Bootea UEFI → kernel → arje-zero → Plasma pinta solo (~30-45s).
TIMEOUT=1800= auto-kill a los 30 min (omitir para dejarlo indefinido; matarlo a mano con el kill de abajo).DISP=none= headless (sólo serial, para diagnóstico sin ventana ni interferir con mirada).- Toda la config que lo hace funcionar (los 7 fixes) vive en
scripts/kde/plasma-start-qemu.sh, que se hornea en la imagen. No hace falta setear nada a mano.
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):
| Fix | Sin él |
|---|---|
GBM_ALWAYS_SOFTWARE=1 |
segfault al init (virtio sin 3D tratado como HW → vtable NULL) |
KWIN_DRM_USE_MODIFIERS=0 |
negro 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 none |
pantalla clavada en TianoCore (VGA-std por defecto + simpledrm roban el scanout) |
XCURSOR_THEME=breeze_cursors + kcminputrc |
Failed to load cursor theme "default" (cursor invisible) |
KWIN_FORCE_SW_CURSOR=1 |
cursor aparece/desaparece (plano HW de virtio no se presenta) |
Gotchas de operación
- Lectura STALE del serial: no se trunca hasta que el run-script arranca QEMU (tras el rebuild ~40s).
Un
until grep 'escritorio arriba'matchea el run ANTERIOR. Esperá un marcador único del run nuevo:rm -f work/qemu-monitor.sockantes de lanzar yuntil [ -S work/qemu-monitor.sock ]; do sleep 2; done. pkill -f qemu...se auto-mata (el patrón matchea el propio comando) → usar siempreqemu-sys[t]em.- "Se queda en TianoCore" tras varios relanzamientos: el
work/qemu-desktop-OVMF_VARS.fdpersistente acumula boot entries stale →rm -f work/qemu-desktop-OVMF_VARS.fd(el run-script lo recrea limpio). - Serial triplicado: cada línea sale ×3 (
saytee a console+ttyS0). "139: 3" = 1 crash real. - El escritorio queda sólo con wallpaper+panel; sin discos/energía reales (no hay udisksd/upowerd en el rootfs) ni efectos GL pesados (llvmpipe no los soporta). Es esperado, no un fallo.
Prerrequisitos
work/hammer-kde-qemu.img(la imagen; si falta, reconstruir arriba).- OVMF:
/usr/share/edk2/x64/OVMF_CODE.4m.fd+OVMF_VARS.4m.fd. - Herramientas host:
qemu-system-x86_64,socat,magick(ImageMagick) para el screendump. - Para la ventana gtk: sesión gráfica del laptop viva (
DISPLAY=:0). Headless (DISP=none) no la necesita.
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 &
- 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
-
El panel salía con el reloj y nada más, y no era el panel: eran los ICONOS. Los
.sode todos los applets estaban instalados; lo que faltaba erabreeze-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. -
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 installedrecipes/incoming-kde/kcoreaddons.tomlpasa-DKCOREADDONS_USE_QML=OFF(la cabecera lo dice: «QML bindings / python / docs apagados»), así que el módulo QMLorg.kde.coreaddonsno 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.