Files
arje/docs/gnome-boot-test.md
2026-05-06 20:40:47 +00:00

5.3 KiB

Boot test: GNOME bajo Ente #0 (sin systemd)

Procedimiento para verificar que GNOME 45+ arranca con ente-zero como PID 1 y los 8 D-Bus shims (logind, hostnamed, timedated, localed, journald, resolved, polkit, machined) cubren las llamadas que el escritorio realiza durante la sesión.

Qué se prueba

  1. PID 1 boot: el kernel arranca, mounta initramfs, transfiere control a /init que es ente-zero con la Card Semilla.
  2. Genesis spawning: ente-zero encarna el bus D-Bus (dbus-daemon), los 8 compat-shims, NetworkManager, y gdm/sddm (display manager).
  3. D-Bus interception: los compat-shims toman los nombres org.freedesktop.{logind,hostname1,timedate1,locale1,resolve1, PolicyKit1,machine1} antes que cualquier sondeo de systemd.
  4. GNOME session: gdm autenticación → GNOME shell → settings panels funcionan (Region & Language, Date & Time, About, Network).

Prerequisitos

  • QEMU (qemu-system-x86_64) con KVM.
  • Imagen base con kernel + GNOME instalados — sugerencia: una Arch Linux o Fedora minimal modificada (más abajo). NixOS también es razonable.
  • ~10 GiB libre.

Esqueleto del rootfs

scripts/build-rootfs.sh genera un overlay sobre una imagen base que:

  1. Compila el workspace en modo release (cargo build --workspace --release)
  2. Copia los binarios a <rootfs>/usr/local/bin/:
    • ente-zero
    • ente-{logind,hostnamed,timedated,localed,journald,resolved,polkit,machined}-compat
    • ente-echo, brainctl, busctl, ente-journalctl
  3. Renombra el /init original a /sbin/init.systemd (backup)
  4. Symlink /init/usr/local/bin/ente-zero
  5. Coloca la Card Semilla en /ente/seed.card.json
  6. Desinstala los services systemd que ahora son shims (logind, etc) o los enmascara con systemctl mask (en la imagen base, antes de reescribir /init)

Card Semilla para el boot test

/ente/seed.card.json debe declarar como genesis los Entes esenciales:

  • D-Bus daemon (/usr/bin/dbus-daemon --system)
  • Los 8 compat-shims
  • NetworkManager
  • udev daemon (kernel events ya manejados por nuestro Netlink stream; udev añade reglas de userspace — opcional)
  • gdm o sddm

El shape es la serialización serde de EntityCard (ver crates/ente-card/src/lib.rs). Para el primer arranque sin GNOME hay un ejemplo defensivo en docs/seed-vps-min.json (PID 1 + un sleep infinity supervisado). Extiéndelo añadiendo entradas a genesis[] con payload de forma {"Native": {"exec": "...", "argv": [...], "envp": []}} y supervision {"Restart": {"initial": 100, "max": 30000}} para los daemons que sí queremos restart-supervisados.

Boot

scripts/run-vm.sh /path/to/base.qcow2 /path/to/built-rootfs.iso

QEMU arranca con:

  • -kernel el kernel de la imagen base
  • -initrd (opcional) si la imagen no es bootable directa
  • -append "init=/usr/local/bin/ente-zero rd.break=initqueue" para redirigir PID 1 desde el initramfs.
  • -display gtk,gl=on para ver la sesión gráfica.

Verificaciones

Console

  • ente-zero arranca como PID 1 (/proc/1/comm == ente-zero).
  • Genesis instancia los 8 shims: logs Ente encarnado label=compat-X.
  • D-Bus daemon responde: busctl list muestra los nombres tomados por los shims (deberían aparecer como org.freedesktop.X1).

gdm

  • Llega al greeter — significa que polkit, logind, hostnamed responden.
  • Login funciona — verifica que Inhibit, CreateSession, ListSessions no bloquean la pila de PAM.

GNOME shell

  • Settings → About: hostname y OS info pobladas (hostnamed properties).
  • Settings → Date & Time: timezone correcta (timedated).
  • Settings → Region & Language: locale actual visible (localed).
  • Settings → Network: NetworkManager opera, los DNS lookups funcionan (resolved).
  • "Restart" en menú: invoca org.freedesktop.login1.Reboot → llega a nuestro stub → log en journal.

Journal

  • ente-journalctl --tail 100 muestra mensajes capturados durante el boot.
  • Filtros --unit gdm.service y --source syslog funcionan.

Limitaciones conocidas

  • systemd-units: GNOME no usa systemd unit files directamente, pero algunas apps los crean dinámicamente (e.g., gnome-terminal con systemd-run --user). Esas calls fallarán con NotSupported y la app caerá a un fallback no-systemd.
  • sd_notify: services que usan Type=notify para anunciar readiness fallan silenciosamente (NOTIFY_SOCKET no se setea). Reemplazables con Type=simple y nuestro Supervision::Restart.
  • systemd-tmpfiles: tmpfiles.d no se procesa. Aplicar manualmente o portar el comportamiento a un Ente.
  • systemd journal binary export: nuestro journal usa CAS por hash, no el formato .journal binario. Apps que llamen journalctl --output=export no son compatibles. ente-journalctl cubre los casos típicos.

Plan de regresión

Hacer boot test en CI tras cada cambio en los compat-shims:

  1. cargo build --workspace --release
  2. scripts/build-rootfs.sh (overlay sobre imagen base inmutable)
  3. scripts/run-vm.sh --headless --timeout 120 con script de comprobación automatizado (xdotool o similar, o screen-shotting).
  4. Capturar dmesg + ente-journalctl outputs como artefactos.

Output esperado en stdout del test:

PASS: ente-zero como PID 1
PASS: 8 compat-shims encarnados
PASS: gdm greeter mostrado
PASS: settings panels operativos