# accountsservice 23.13.9 — el servicio D-Bus de cuentas de usuario (nombre, avatar, idioma, si es # administrador). Lo pide gnome-shell desde JAVASCRIPT, no desde C: por eso no aparecía en el # meson.build de la cima ni en su cierre de build, y sólo se destapó ARRANCANDO la sesión: # # Gjs-CRITICAL: JS ERROR: Requiring AccountsService, version 1.0: # Typelib file for namespace 'AccountsService', version '1.0' not found # Execution of main.js threw exception # # Lección del método: **el cierre de BUILD no es el cierre de RUNTIME**. gnome-shell selló con # 108/108 recetas y aun así le falta esto, porque `imports.gi.AccountsService` se resuelve en tiempo # de ejecución. Toda dep que el shell cargue por typelib desde JS es invisible al build. # # -Delogind=true es la pieza que hace que esto entre gratis: accountsservice pide `libsystemd` por # defecto (meson.build:219) y con esta opción pide `libelogind` (:217), que YA está sellada — # arje-sdlogin-compat, con Version 255 en su .pc, por encima del >= 229.4 que exige. Es la quinta vez # en la campaña que la C-ABI de logind aparece, y la primera que se resuelve sin esquivarla. # # Apagados: # -Dvapi=false → no hay valac en el corpus. # -Ddocbook=false -Dgtk_doc=false → xmlto/gtk-doc. # -Dsystemdsystemunitdir=no → no instala units de systemd; acá PID1 es arje-zero. Ojo: el valor # tiene que ser literalmente `no`, NO la cadena vacía — con vacía el meson # interpreta "averiguá el directorio" y ASERTA pidiendo systemd.pc (:183). # libxcrypt es `required: false` (meson.build:161) ⇒ no hace falta receta: sin ella el servicio no # cambia contraseñas, que no es lo que el shell le pide (le pide el usuario y su avatar). # # `generate-version.sh` se reemplaza por un `echo` de la versión. El script del tarball deriva la # versión del NOMBRE DEL DIRECTORIO (`basename $PWD | sed 's/^accountsservice-\(.*\)$/\1/'`), y en el # sandbox de takana el árbol de fuentes es `/src` ⇒ no matchea y aborta con "Version unknown". Fijarla # además la vuelve DETERMINISTA: la otra rama del script (la de checkout git) calcula la versión con # `date` sobre el último commit, que es exactamente lo que un store direccionable por contenido no # puede tolerar. # # El otro sed borra una ASERCIÓN sobre wtmp (meson.build:107). accountsservice busca el fichero de # histórico de logins probando `WTMPX_FILENAME` y `_PATH_WTMPX`; **musl no define ninguno de los dos** # —no implementa wtmp—, así que cae a la rama final, que exige que `/var/log/utx.log` EXISTA en el # constructor y aborta si no. Se borra sólo la línea del assert: la rama igual deja # `PATH_WTMP='/var/log/utx.log'`, o sea que el servicio vigila esa ruta y, como nunca aparece, no # reporta histórico de sesiones. Lo que el shell le pide —el usuario, su nombre y su avatar— no # depende de wtmp. La alternativa era `touch` ese fichero en el sandbox para que el chequeo pasara, # que es hacer verdadera una premisa falsa; preferible borrar el chequeo y decir por qué. # # Y un tercer sed saca `subdir('tests')` (:235), que accountsservice no expone como opción. No es por # ahorrar tiempo de build: los tests arrastran el subproyecto `mocklibc`, que llama `fgetgrent()` — # una extensión GNU que **musl no implementa**. No hay forma de compilarlo acá, y lo que se pierde es # la suite del upstream, no la librería. # # El sed saca `subdir('po')`. QUINTA vez que el msgfmt de gettext-tiny obliga a esto (iso-codes, gcr, # eds, gnome-shell y ahora ésta). Ya no es un gotcha: es la deuda de autorar el gettext de GNU. # # ISLA DINÁMICA: -Dintrospection=true + shared, porque lo que falta es justamente el TYPELIB. # # ══ LOS DOS HUECOS QUE HUBO QUE TAPAR, Y NINGUNO ERA DE accountsservice ═════════════════════════ # El configure pasaba entero desde el principio; lo que cortaba era el COMPILE, por dos motivos # independientes, los dos de NUESTRA capa de compatibilidad. Se cuentan acá porque el trabajo real # de esta receta está afuera de ella: # # 1. LA C-ABI DE sd-login SE QUEDABA CORTA. `libelogind` (arje-sdlogin-compat) exportaba 14 símbolos # —los que necesitaba mutter— y accountsservice usa OCHO que no estaban: # sd_get_sessions · sd_seat_can_multi_session · sd_session_get_display # sd_login_monitor (el tipo) · sd_login_monitor_new · sd_login_monitor_unref # sd_login_monitor_get_fd · sd_login_monitor_flush # Los cinco de `sd_login_monitor_*` eran la parte con enjundia: no son getters sobre ficheros sino # una API de NOTIFICACIÓN (un fd que se mete en un poll y despierta cuando cambia el estado de # sesiones). Implementados con inotify sobre /run/systemd/{sessions,seats,users}, que es donde # vive ese estado. Ahora libelogind exporta 22. # # 2. `fgetspent_r` NO EXISTE EN musl (extensión de glibc; la usa src/daemon.c:265). Se tapa con # `accountsservice-fgetspent_r-musl.patch`, que la implementa sobre el `fgetspent()` que musl SÍ # tiene, copiando el registro al buffer del llamador. La copia no es adorno: daemon.c GUARDA esos # buffers en un GHashTable, y `fgetspent()` devuelve un struct estático que se reescribe en cada # llamada. El parche sigue el patrón que el propio accountsservice ya usa para /etc/passwd # (`src/fgetpwent.c` incluido bajo `#ifndef HAVE_FGETPWENT`). # # SELLA: b3:0328b0d0. Produce `AccountsService-1.0.typelib`, que es lo que la capa JS del shell pedía. # # CÓMO SE DESTAPÓ, y es la lección de método: gnome-shell selló con su cierre de build COMPLETO # (108/108) y aun así la sesión murió pidiendo este typelib. **El cierre de build no es el cierre de # runtime**: todo lo que el shell carga por `imports.gi.*` desde JavaScript es invisible al grafo de # deps. Se encuentra arrancando, no compilando. name = "accountsservice" version = "23.13.9" license = "GPL-3.0-or-later" [source] tarball = "https://www.freedesktop.org/software/accountsservice/accountsservice-23.13.9.tar.xz" sha256 = "adda4cdeae24fa0992e7df3ffff9effa7090be3ac233a3edfdf69d5a9c9b924f" patches = ["accountsservice-fgetspent_r-musl.patch"] [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "dynamic" [build.phases] configure = "printf '#!/bin/sh\\necho 23.13.9\\n' > generate-version.sh && sed -i \"/^subdir('po')$/d\" meson.build && sed -i '/Do not know which filename to watch for wtmp changes/d' meson.build && sed -i \"/^subdir('tests')$/d\" meson.build && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Delogind=true -Dintrospection=true -Dvapi=false -Ddocbook=false -Dgtk_doc=false -Dsystemdsystemunitdir=no -Dc_args=-Wno-error=date-time" compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output" install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild" [deps] build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "py3-setuptools", "gi-foreign-girs", "gobject-introspection", "glib", "glib-introspected", "polkit", "dbus-shared", "libelogind", "libffi", "pcre2", "zlib-shared", "expat"] # ── EL SERVICIO QUE ESTE PAQUETE TRAE (SDD 30) ────────────────────────────────────────────────── # Se lanza EXPLÍCITO, no por activación de D-Bus, y el motivo está medido en el script de sesión: la # activación por bus funciona, pero deja el arranque esperando el timeout y no deja log donde mirar. # ⚠ EL `argv` ESPERA AL BUS ANTES DEL `exec`, Y NO ES UNA MAÑA DE ESTA RECETA. arje ordena el # arranque por capacidades (orden topológico real), pero eso ordena el SPAWN, no el ESTAR LISTO: no # existe primitiva «esperá a que aparezca este socket» (DE-SYSTEMD-A-ARJE.md §13 lo lista como hueco # abierto). Sin la espera, este daemon puede arrancar antes de que dbus-daemon escuche y quedarse en # modo idle sin registrar nunca su nombre — un fallo que NO se ve: el proceso vive, el bus no lo # tiene. Mientras el hueco siga abierto la espera va DENTRO del card, a la vista en el argv y no # escondida en un wrapper, para que se pueda contar cuántos servicios la están pagando. [[service]] label = "accounts-daemon" id = "01HQAR53D4M2NBV8KZTYXFQA23" exec = "/bin/busybox" argv = ["sh", "-c", "i=0; while [ ! -S /run/dbus/system_bus_socket ] && [ $i -lt 100 ]; do i=$((i+1)); sleep 0.2; done; exec /usr/libexec/accounts-daemon"] restart = { initial_ms = 500, max_ms = 20000 }