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…
kde: pipeline escritorio QEMU (qemu-desktop-image + plasma-start-qemu)
1#!/usr/bin/env bash
2# qemu-desktop-image.sh — imagen de disco EFI KDE para QEMU (virtio-gpu + software GL), auto-lanza Plasma.
3#
4# Igual que metal-desktop-image.sh pero para una VM: parchea swrast (mesa-swrast softpipe, sin LLVM) al
5# rootfs runtime-completo, instala plasma-start-qemu.sh (software GL sobre el DRM de virtio) y lo AUTO-
6# LANZA desde /etc/profile del console-getty. Así la ventana QEMU bootea → arje-zero → Plasma pinta solo.
7#
8# work/metal-rootfs base: arje-zero PID1 + busybox + kernel(EFI-stub) + firmware
9# work/kde-metal-rootfs KDE runtime-completo (206 pkgs) — ya trae fuentes/iconos/kactivitymanagerd/
10# KDEPlasmaPlatformTheme/módulo QML kwindowsystem
11# + store/*-mesa-swrast swrast_dri/kms_swrast (software GL, softpipe)
12# → work/qemu-desktop-rootfs (hardlinks) → work/hammer-kde-qemu.img
13#
14# Uso: scripts/kde/qemu-desktop-image.sh # arma la imagen
15set -euo pipefail
16ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
17
18BASE="${BASE:-work/metal-rootfs}"
19KDE="${KDE:-work/kde-metal-rootfs}"
20SWRAST="${SWRAST:-$(ls -dt store/*-mesa-swrast 2>/dev/null | head -1)}"
21MERGED="${MERGED:-work/qemu-desktop-rootfs}"
22IMG="${IMG:-work/hammer-kde-qemu.img}"
23
24[ -d "$BASE" ] || { echo "falta $BASE" >&2; exit 1; }
25[ -d "$KDE" ] || { echo "falta $KDE" >&2; exit 1; }
26[ -n "$SWRAST" ] && [ -d "$SWRAST" ] || { echo "falta artefacto mesa-swrast en store/" >&2; exit 1; }
27
28echo "==> fundiendo rootfs por hardlinks (base + KDE)"
29rm -rf "$MERGED"
30cp -al "$BASE" "$MERGED"
31cp -al --remove-destination "$KDE"/. "$MERGED"/
32
33echo "==> parcheando swrast (software GL) desde $SWRAST"
34# el artefacto trae usr/lib/{dri/*swrast*,libEGL,libgbm,libglapi,libGLESv2}; copiamos SIN --remove para
35# no pisar sonames del metal salvo lo que falte, pero swrast_dri debe entrar sí o sí.
36cp -a "$SWRAST"/usr/lib/dri/. "$MERGED"/usr/lib/dri/ 2>/dev/null || true
37for so in libglapi libgbm libEGL libGLESv2; do
38 cp -a "$SWRAST"/usr/lib/$so* "$MERGED"/usr/lib/ 2>/dev/null || true
39done
40ls "$MERGED"/usr/lib/dri/*swrast* >/dev/null 2>&1 && echo " ✓ swrast_dri instalado" || { echo " ✗ swrast no entró" >&2; exit 1; }
41
42echo "==> inyectando musl (loader + libc) — los binarios KDE son dinámicos"
43# La base metal es 100% ESTÁTICA (arje-zero+busybox) y el KDE-rootfs no trae libc ⇒ el merge no tiene
44# loader musl. Los binarios KDE piden interp /lib/ld-musl-x86_64.so.1 + NEEDED libc.so (única lib base
45# que falta; el resto del closure Qt/KF6 está). Copiamos el musl soberano del host (mismo que corre la
46# mirada del laptop ⇒ ejecuta binarios hammer-musl dinámicos). En musl el loader ES libc (mismo fichero).
47MUSL="${MUSL:-/usr/lib/musl/lib/libc.so}"
48[ -r "$MUSL" ] || { echo "no encuentro musl libc ($MUSL) — set MUSL=" >&2; exit 1; }
49mkdir -p "$MERGED/usr/lib/musl/lib" "$MERGED/lib"
50cp -a "$MUSL" "$MERGED/usr/lib/musl/lib/libc.so"
51ln -sf /usr/lib/musl/lib/libc.so "$MERGED/lib/ld-musl-x86_64.so.1" # intérprete
52ln -sf /usr/lib/musl/lib/libc.so "$MERGED/usr/lib/libc.so" # NEEDED soname en el search path
53echo " ✓ musl inyectado ($(du -h "$MERGED/usr/lib/musl/lib/libc.so" | cut -f1))"
54
55echo "==> instalando /usr/bin/plasma-start (variante QEMU software-GL)"
56install -Dm755 scripts/kde/plasma-start-qemu.sh "$MERGED/usr/bin/plasma-start"
57
58echo "==> auto-lanzar Plasma: console-getty ejecuta plasma-start (no /bin/sh)"
59# El console-getty es un getty de SERIAL (115200 console=ttyS0) que corría /bin/sh — pero /bin/sh así NO
60# es login shell, no lee /etc/profile. En vez de eso, hacemos que getty ejecute plasma-start DIRECTO
61# (-l /usr/bin/plasma-start). kwin presenta al DRM de virtio-gpu (ventana gráfica), independiente de que
62# la consola de texto viva en el serial. Si Plasma falla, plasma-start hace exec /bin/sh ⇒ shell serie.
63python3 - "$MERGED/ente/seed.card.json" <<'PY'
64import json, sys, os
65p = sys.argv[1]
66c = json.load(open(p))
67for g in c.get("genesis", []):
68 if g.get("label") == "console-getty":
69 argv = g["payload"]["Native"]["argv"]
70 argv[:] = [("/usr/bin/plasma-start" if a == "/bin/sh" else a) for a in argv]
71 print(" console-getty argv →", argv)
72# escribir a temp y reemplazar la ENTRADA de directorio: rompe el hardlink (el seed en MERGED es un
73# hardlink read-only a work/metal-rootfs) sin tocar el inode fuente ni chocar con los permisos.
74tmp = p + ".new"
75with open(tmp, "w") as f:
76 json.dump(c, f, indent=2)
77os.chmod(tmp, 0o644)
78os.replace(tmp, p)
79PY
80
81mkdir -p "$MERGED/root/.config" "$MERGED/root/.cache" "$MERGED/run/user/0" "$MERGED/tmp"
82chmod 1777 "$MERGED/tmp"
83
84echo "==> rootfs fundido: $(du -sh "$MERGED" | cut -f1)"
85need_mb=$(du -sm "$MERGED" | cut -f1)
86ROOT_SIZE="${ROOT_SIZE:-$(( need_mb + 1536 ))}"
87echo "==> ROOT_SIZE=${ROOT_SIZE} MiB"
88
89export ROOTFS="$MERGED" IMG ROOT_SIZE
90export ESP_MB="${ESP_MB:-128}" STORE_SIZE="${STORE_SIZE:-512}" STATE_SIZE="${STATE_SIZE:-768}"
91exec ./scripts/install-image-efi.sh