Files
arje/docs/gnome-boot-test.md
T
Sergio 48e41331a1 journal-query CLI, machined, polkit con grants reales, GNOME boot test
- ente-journalctl: bin nuevo en ente-journald-compat. Lee
  ~/.local/share/ente/journal/index.log, parse timestamp:source:unit:sha,
  filtra --unit/--source/--since/--grep/--tail, restituye blobs desde CAS
  y formatea (pretty | --json). Default extrae MESSAGE de journald native.
- compat-machined: org.freedesktop.machine1.Manager con
  ListMachines/GetMachine/Register/Terminate. Lista vacía + NotFound —
  apps que llaman al boot ya no quedan en timeout.
- compat-polkit: query_policy() consulta el bus interno por el cap
  POLKIT_DECISION_IFACE con blob (pid_be|uid_be|action_id_utf8). Si hay
  proveedor su byte de respuesta gobierna; si no, default-allow.
  Anuncia POLKIT_SERVICE_IFACE (separado para evitar recursión).
- docs/gnome-boot-test.md: procedimiento end-to-end para arrancar GNOME
  con ente-zero como PID 1 en QEMU. scripts/build-rootfs.sh overlaya
  binarios + symlink /init. scripts/run-vm.sh boot QEMU con KVM y GTK.
  docs/seed-gnome-test.k Card Semilla con genesis para 8 shims +
  dbus-daemon + NetworkManager + gdm.

8 compat-shims operativos en paralelo cubriendo: logind, hostnamed,
timedated, localed, journald, resolved, polkit, machined.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 10:13:00 +00:00

5.8 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.k
  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.k 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

Ejemplo mínimo:

import .card

seed = EntityCard {
    schema_version = 1
    id = "01KQ_BOOT_SEED_GNOME_TEST_0"
    label = "boot-gnome-test"
    provides = [
        Capability {kind = "Spawn"}
        Capability {kind = "Journal"}
    ]
    soma = SomaSpec {}
    payload = Payload {kind = "Virtual"}
    supervision = Supervision {kind = "OneShot"}
    genesis = [
        # dbus-daemon — todo lo demás depende de él.
        EntityCard {
            schema_version = 1
            id = "01KQ_BOOT_DBUS_DAEMON__________"
            label = "dbus-daemon"
            soma = SomaSpec {}
            payload = Payload {
                kind = "Native"
                exec = "/usr/bin/dbus-daemon"
                argv = ["--system", "--nofork"]
            }
            supervision = Supervision {
                kind = "Restart"
                initial_ms = 100
                max_ms = 30000
            }
        }
        # Aquí los 8 compat-shims (mismo patrón) ...
        # Aquí gdm o sddm ...
    ]
}

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