diff --git a/docs/evidencia/cosmic-store-busqueda-qemu-2026-08-05.png b/docs/evidencia/cosmic-store-busqueda-qemu-2026-08-05.png new file mode 100644 index 00000000..32ef6805 Binary files /dev/null and b/docs/evidencia/cosmic-store-busqueda-qemu-2026-08-05.png differ diff --git a/docs/evidencia/cosmic-store-qemu-2026-08-05.png b/docs/evidencia/cosmic-store-qemu-2026-08-05.png new file mode 100644 index 00000000..e5b5c93a Binary files /dev/null and b/docs/evidencia/cosmic-store-qemu-2026-08-05.png differ diff --git a/docs/runbooks/cosmic-desktop.md b/docs/runbooks/cosmic-desktop.md index e16ad223..1538c4c5 100644 --- a/docs/runbooks/cosmic-desktop.md +++ b/docs/runbooks/cosmic-desktop.md @@ -696,9 +696,52 @@ la feature `gvfs`, que se apaga. El lock dice el universo; las features dicen el no declara ninguna glib y su binario enlaza **sólo `libxkbcommon.so.0` y `libc.so`**: dos NEEDED, el mínimo de la suite. +## 🛍 LA QUINTA: cosmic-store, y el catálogo que hubo que fabricar (2026-08-05) + +`docs/evidencia/cosmic-store-qemu-2026-08-05.png` — la tienda abierta con *Popular apps* poblada +(App Library, Files, Launcher, Settings) y *Recently updated*; y `…-busqueda-…png` con la búsqueda +`text` devolviendo *COSMIC Text Editor*. Sellada en `b3:a06437f7`, NEEDED = `libxkbcommon` + `libc`. + +**Es la primera aplicación de la suite que choca con que hammer es OTRA distro.** Una tienda es la +cara de un gestor de paquetes. De sus cuatro backends (`src/backend/`, todos tras `#[cfg(feature)]`): +`flatpak` pide `libflatpak` (GObject ⇒ glib compartida + ostree/libsoup/gpgme: la torre de C que esta +campaña evita); `packagekit` es Rust puro pero necesita el DEMONIO en el bus; `rpm-ostree` es +irrelevante; **`pkgar` es el único que arranca** — ni demonio ni enlace. + +**ALCANCE: navega, no instala.** Nada está cableado al `.swm` (Etapa F). El camino barato para +arreglarlo quedó identificado: servir `org.freedesktop.PackageKit` sobre `.swm` y encender la feature +`packagekit`. Es un shim de D-Bus, mismo patrón que `arje-logind-compat`, y **no cuesta un solo `.so` +de C**. + +### El catálogo AppStream: dos trampas encadenadas + +**1. `pkgar` NO lee `/usr/share/metainfo/`.** Lee el CATÁLOGO — +`{/usr/share,/var/lib,/var/cache}/{swcatalog,app-info}/{xml,yaml}/` — que en una distro normal genera +`appstreamcli compose` agregando los metainfo en un ``. Sin ese +fichero la tienda **abre perfecta y no lista NADA**. Lo genera ahora `qemu-desktop-image.sh` con doce +líneas de python; no hace falta AppStream ni glib. + +**2. Hay que SACAR el ``.** Los metainfo que genera `xdgen` lo escriben con los envoltorios +``/``, y el crate `appstream` espera los hijos planos del esquema de catálogo. +Con el envoltorio muere con `The tag provide doesn't have a value` y **descarta el componente entero, +callado**: listaba 2 de 7, justo los dos sin `` (App Library y Launcher). + +**Cómo se diagnosticó, que es lo reutilizable:** desde el lanzador la salida del proceso NO llega al +log de la sesión. Hay que abrir `cosmic-term` DENTRO de la VM y correr +`rm -rf ~/.cache/cosmic-store; RUST_LOG=info cosmic-store 2>/tmp/s.log` — el `rm` no es opcional, la +tienda cachea el parseo en `~/.cache/cosmic-store/*.bitcode` y si no se borra vuelve a mostrar el +resultado viejo. Que la imagen tenga terminal deja de ser una comodidad y pasa a ser instrumental. + +### Y el deadline del panel es una CARRERA, no un umbral + +Con el anfitrión ocioso y `-smp 8`, un arranque de esta tanda salió igual mutilado (130 colores) con +33 procesos vivos y el `deadline has elapsed` en el log. O sea: 8 vCPU + anfitrión quieto **sube +mucho la probabilidad pero no garantiza**. Si sale mutilado y la carga estaba baja, **rearrancá antes +de buscar la causa en tu cambio**. + ## Lo que falta, en orden -1. **Más aplicaciones**: `cosmic-store`, `cosmic-screenshot`. +1. **Más aplicaciones**: `cosmic-screenshot`. 2. **La cadena glib COMPARTIDA** (`glib` + `pcre2` + `libffi` + `zlib` con `.so`), que destrabaría `gvfs` en cosmic-files y su applet del panel. Es una campaña propia y hay que decidir antes si la imagen puede tener una sola glib. diff --git a/scripts/cosmic/qemu-desktop-image.sh b/scripts/cosmic/qemu-desktop-image.sh index 80dde71d..8cfc159b 100755 --- a/scripts/cosmic/qemu-desktop-image.sh +++ b/scripts/cosmic/qemu-desktop-image.sh @@ -150,6 +150,48 @@ ln -sfn /run "$MERGED/var/run" mkdir -p "$MERGED/root/.config" "$MERGED/root/.cache" "$MERGED/run/user/0" "$MERGED/tmp" chmod 1777 "$MERGED/tmp" +# ── CATÁLOGO APPSTREAM, o por qué cosmic-store salía VACÍO ───────────────────────────────────── +# El backend `pkgar` de la tienda NO lee `/usr/share/metainfo/*.metainfo.xml` —los ficheros que cada +# receta instala, uno por aplicación—. Lee el **CATÁLOGO**: los ficheros de +# `{/usr/share,/var/lib,/var/cache}/{swcatalog,app-info}/{xml,yaml}/`, que en una distro normal +# genera `appstreamcli compose` agregando todos los metainfo en un solo documento +# ``. Sin ese fichero la tienda abre perfecta y no lista NADA +# —«No results for …»— porque su catálogo está vacío, no porque le falte nada del sistema. +# +# hammer no tiene appstreamcli (sería AppStream + glib, o sea la torre de C que esta campaña evita), +# pero el formato es XML plano y la agregación es exactamente eso: envolver los `` de cada +# metainfo en una raíz. Doce líneas de python valen la librería entera. +echo "==> catálogo AppStream para cosmic-store (agrega los metainfo del rootfs)" +# +# ⚠ Y hay que SACAR el bloque ``. Los metainfo que genera `xdgen` —los de cosmic-edit, +# files, settings, store y term— lo escriben con los envoltorios ``/``, y el +# parser de la tienda (el crate `appstream`) espera los hijos PLANOS del esquema de catálogo +# (``, ``). Con el envoltorio muere con +# failed to parse … in "/usr/share/swcatalog/xml/hammer.xml": The tag provide doesn't have a value +# y —esto es lo caro— **descarta el componente entero, callado para el usuario**: la tienda abría +# perfecta y listaba sólo 2 de 7, justamente los dos que NO tienen `` (App Library y +# Launcher). Se descubrió corriendo `RUST_LOG=info cosmic-store` desde cosmic-term DENTRO de la VM; +# desde el lanzador la salida del proceso no llega al log de la sesión. +python3 - "$MERGED" <<'PY' +import glob, os, re, sys +merged = sys.argv[1] +comps = [] +for p in sorted(glob.glob(os.path.join(merged, "usr/share/metainfo/*.xml"))): + x = open(p, encoding="utf-8").read() + # Quedarse con el elemento raíz , sin cabecera XML ni comentarios. + m = re.search(r"].*", x, re.S) + if m: + comps.append(re.sub(r"\s*.*?", "", m.group(0), flags=re.S)) +out = os.path.join(merged, "usr/share/swcatalog/xml") +os.makedirs(out, exist_ok=True) +with open(os.path.join(out, "hammer.xml"), "w", encoding="utf-8") as f: + f.write('\n') + f.write('\n') + f.write("\n".join(comps)) + f.write("\n\n") +print(" %d componentes → /usr/share/swcatalog/xml/hammer.xml" % len(comps)) +PY + echo "==> rootfs fundido: $(du -sh "$MERGED" | cut -f1)" need_mb=$(du -sm "$MERGED" | cut -f1) ROOT_SIZE="${ROOT_SIZE:-$(( need_mb + 1536 ))}"