gnome: el bus de sistema COMPLETO — faltaba polkit, y lo dijo la lista de nombres

bus: org.freedesktop.login1      OK
  bus: org.freedesktop.PolicyKit1  OK
  bus: org.freedesktop.Accounts    OK
  bus: org.freedesktop.UPower      OK

accounts-daemon y upowerd arrancaban, seguían vivos, y NUNCA adquirían su nombre: los
dos se bloquean en `polkit_authority_get_sync()` al iniciar, y `org.freedesktop.PolicyKit1`
no lo servía nadie —nuestra receta polkit es libs-only a propósito, porque el demonio lo
pone arje—. gnome-shell esperaba después 25s por cada uno.

**El dato que lo resolvió no salió del log de los daemons sino de la LISTA DE NOMBRES DEL
BUS**: ahí estaban como conexiones anónimas `:1.0`, `:1.1`, sin nombre bien conocido. Eso
distingue tres cosas que en el log del cliente se ven igual — «no arrancó», «arrancó y no
llegó a pedir el nombre» y «lo pidió y se lo negaron». Era la segunda. `gnome-start` ahora
espera cada nombre con NameHasOwner y, si no aparece, vuelca el log del daemon y la lista.

Receta nueva `arje-polkit-compat` (b3:03e0a86f), tercer shim de este tipo tras
arje-logind-compat y arje-sdlogin-compat. Su propio autor ya había escrito el diagnóstico
en el crate: «apps que usan polkit bloquean en CheckAuthorization si no responde nadie».
⚠ AUTORIZA TODO — es la postura de sistema confiado que arje ya tenía tomada, no algo que
esta receta introduzca; queda explícito en su comentario.

Dos gotchas del empaquetado:
- **La política de polkit ya existe y NO alcanza**: permite `own` sólo al usuario polkitd
  y el shim corre como root. Se agrega un `zz-arje-polkit-compat.conf` en vez de reescribir
  la de upstream — dbus lee system.d en orden alfabético y las posteriores ganan.
- **Los ficheros del rootfs fundido son hardlinks de SÓLO LECTURA del store** (0444). Un
  `cat >` encima falla con Permission denied y rompió un build. Regla: nunca sobrescribir
  un fichero que venga de un artefacto; agregar al lado.

Queda escrito en el runbook lo que sigue faltando (colord, y que el shell no tiene servidor
de sonido porque pulseaudio se construyó sólo-cliente: el demonio de audio de la distro
sigue sin decidirse) y las dos lecciones de método que costaron una iteración cada una.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-29 19:19:23 -04:00
co-authored by Claude Opus 5
parent 32926dc6df
commit 3d01d5cb04
5 changed files with 184 additions and 9 deletions
+42
View File
@@ -214,6 +214,18 @@ export XDG_SESSION_ID=1
export XDG_SEAT=seat0
export XDG_VTNR=1
# arje-polkit-compat: el PolicyKit1 del fractal. **VA ANTES que accounts-daemon y upowerd**, y el
# orden no es estético: los dos se bloquean en `polkit_authority_get_sync()` al arrancar, así que si
# `org.freedesktop.PolicyKit1` no está en el bus se quedan conectados pero SIN adquirir su nombre —y
# gnome-shell después espera 25 s por cada uno—. Nuestra receta `polkit` es libs-only a propósito
# (el demonio lo pone arje). Ojo: el shim autoriza TODO; ver recipes/arje-polkit-compat.toml.
if [ -x /usr/bin/arje-polkit-compat ]; then
/usr/bin/arje-polkit-compat >/tmp/polkit-compat.log 2>&1 &
say "arje-polkit-compat lanzado (pid $!)"
else
say "!! sin arje-polkit-compat — accounts-daemon y upowerd se van a colgar pidiendo autorización"
fi
# accounts-daemon: el servicio D-Bus de cuentas (org.freedesktop.Accounts). El shell lo consulta
# desde JavaScript vía `imports.gi.AccountsService` para el nombre y el avatar del usuario del menú.
#
@@ -254,6 +266,36 @@ else
say "!! sin upowerd — el shell va a esperar 25s a su activación D-Bus y seguir sin batería"
fi
# ── ESPERAR EL NOMBRE, NO EL PROCESO ────────────────────────────────────────────────────────────
# El paso que faltaba, y es la otra mitad de «un pid no es un servicio»: comprobar que el daemon
# ADQUIRIÓ su nombre en el bus. Se le da tiempo y, si no aparece, se vuelca su log y la lista de
# nombres del bus — que es el dato que dice si el problema es «no arrancó», «arrancó y no pidió el
# nombre» o «lo pidió y se lo negaron».
esperar_nombre() {
n="$1"; log="$2"; i=0
while [ $i -lt 20 ]; do
if dbus-send --system --dest=org.freedesktop.DBus --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.NameHasOwner "string:$n" 2>/dev/null \
| grep -q "boolean true"; then
say "bus: $n OK"
return 0
fi
i=$((i+1)); sleep 0.5
done
say "!! bus: $n NO apareció en 10s"
[ -n "$log" ] && [ -s "$log" ] && dump "$log"
say "nombres en el bus de sistema:"
dbus-send --system --dest=org.freedesktop.DBus --print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames 2>/dev/null \
| tr -d '" ' | grep -v '^\s*$' > /tmp/busnames.log
dump /tmp/busnames.log
return 1
}
esperar_nombre org.freedesktop.login1 /tmp/logind-compat.log
esperar_nombre org.freedesktop.PolicyKit1 /tmp/polkit-compat.log
esperar_nombre org.freedesktop.Accounts /tmp/accounts-daemon.log
esperar_nombre org.freedesktop.UPower /tmp/upowerd.log
if [ "${DIAG:-1}" = 1 ]; then
ulimit -c unlimited 2>/dev/null || true
echo '/core.%e.%p' > /proc/sys/kernel/core_pattern 2>/dev/null || true
+44
View File
@@ -130,6 +130,50 @@ XML
chmod 644 "$MERGED/usr/share/dbus-1/system.d/org.freedesktop.login1.conf"
echo " ✓ org.freedesktop.login1.conf"
echo "==> inyectando arje-polkit-compat (el PolicyKit1 del fractal) + su política"
# EL TERCER ESLABÓN DEL MISMO TIPO, y lo destapó la lista de nombres del bus: accounts-daemon y
# upowerd quedaban CONECTADOS (`:1.0`, `:1.1`) sin adquirir su nombre, porque los dos se bloquean en
# `polkit_authority_get_sync()` esperando a `org.freedesktop.PolicyKit1`. Nuestra receta `polkit` es
# libs-only a propósito (el demonio lo pone arje), así que nadie servía ese nombre y gnome-shell
# esperaba 25 s por cada uno.
# ⚠ El shim autoriza TODO (postura de sistema confiado ya tomada por arje) — ver su receta.
if APC="${APC:-store/$(./target/release/hammer --store store hash recipes/arje-polkit-compat.toml 2>/dev/null | tail -1 | sed 's/^b3://')-arje-polkit-compat}"; [ -d "$APC" ]; then
install -Dm755 "$APC"/usr/bin/arje-polkit-compat "$MERGED"/usr/bin/arje-polkit-compat
echo "$(basename "$APC" | cut -c1-12)"
else
echo " ✗ falta arje-polkit-compat en store/ — accounts-daemon y upowerd no adquirirán su nombre" >&2
exit 1
fi
# A DIFERENCIA de login1, acá el nombre YA tiene política: la trae el artefacto de `polkit`. Pero
# permite `own` sólo al usuario **polkitd**, y nuestro shim corre como root ⇒ dbus se lo niega.
#
# Se agrega un fichero APARTE en vez de reescribir el de polkit, por dos razones:
# 1. dbus lee todo `system.d` en orden alfabético y las reglas posteriores ganan, así que un
# `zz-…` añade el permiso sin descartar el resto de la política de upstream (que además trae las
# reglas de `AuthenticationAgent`).
# 2. **el fichero de polkit es un HARDLINK DE SÓLO LECTURA del store** — el rootfs fundido se arma
# con hardlinks a los artefactos sellados, que están a 0444. Un `cat >` encima falla con
# `Permission denied`, y eso ya rompió un build de esta imagen. Regla para este script: nunca
# sobrescribir un fichero que venga de un artefacto; agregar al lado, o `rm -f` primero para
# romper el enlace (y entonces se está pisando algo sellado, que es una decisión, no un descuido).
cat > "$MERGED/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf" <<'XML'
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<!-- Añade a la política de polkit el permiso que el shim del fractal necesita: la de upstream sólo
deja adueñarse del nombre al usuario `polkitd`, y arje-polkit-compat corre como root. -->
<busconfig>
<policy user="root">
<allow own="org.freedesktop.PolicyKit1"/>
</policy>
<policy context="default">
<allow send_destination="org.freedesktop.PolicyKit1"/>
<allow receive_sender="org.freedesktop.PolicyKit1"/>
</policy>
</busconfig>
XML
chmod 644 "$MERGED/usr/share/dbus-1/system.d/zz-arje-polkit-compat.conf"
echo " ✓ zz-arje-polkit-compat.conf (añade own= para root sobre la política de polkit)"
echo "==> usuario messagebus (el system bus hace setuid a él)"
for f in passwd:messagebus:x:81:81:messagebus:/dev/null:/sbin/nologin group:messagebus:x:81:; do
file="${f%%:*}"; line="${f#*:}"