# 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 `/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: ```kcl 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 ```bash 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 ```