SDD 30 4c: GNOME con los demonios supervisados por arje — y el control arregló colord
Los demonios de sistema pasan de lanzarse con `&` desde un script de 500 líneas a ser Cards del `genesis`. El bloqueo que este frente daba por corpus se levantó solo: otro agente selló evolution-data-server y gnome-shell mientras esto se escribía, y escritorio-gnome quedó 309/309. SE CORRIÓ UN CONTROL PRIMERO, y es lo único que hace interpretable el resultado: colord control: `MURIÓ al arrancar` cards: `ya vive (pid 175)` ColorManager control: `NO apareció en 40s` cards: `OK` login1/Accounts/UPower OK en los dos compositor wayland-0 y shell vivo en los dos El fallo del control DESAPARECIÓ, y no lo buscaba: colord moría arrancado por el script y vive arrancado por arje, con el bus ya listo porque la espera está dentro de su argv. Sin el control, «ColorManager OK» sería un dato suelto en vez de una diferencia. Los PIDs lo confirman: polkit=119, colord=175, upowerd=178, accounts=180 — de antes de que el lanzador de sesión existiera. QUÉ NO SE COMPROBÓ: no hay screendump; QEMU salió por timeout y el control tampoco lo tuvo. La comparación es serial contra serial y lo que se afirma es sobre los DEMONIOS, no sobre el pintado. Las piezas donde corresponde: `takana service-cards` (UNA sola implementación de receta→Card; el formato es contrato con card_core::Card), `targets.py --service-paths` (une qué-es con si-arranca), y un inyector en FICHERO APARTE porque anidar dos heredocs de python falló en vivo — el terminador del interno cerró el externo y media cosa corrió como shell. La espera del bus va DENTRO del argv de las 5 recetas de sistema: sin ella un daemon arranca antes de que dbus escuche y queda en modo idle sin registrar su nombre — un fallo que no se ve, porque el proceso vive y el bus no lo tiene. Los 5 hashes intactos. Y el guardia de gnome-start es por «¿está corriendo?», no por una perilla: así es correcto venga de donde venga el proceso y la misma copia sirve donde no se inyectaron cards.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
# scripts/targets.py --json # todo el manifiesto expandido
|
||||
# scripts/targets.py --services cli # los servicios que ESA imagen arranca, resueltos
|
||||
# scripts/targets.py --selftest # roturas a propósito + un control que TIENE que pasar
|
||||
# scripts/targets.py --service-paths gnome # rutas de receta de los servicios de SISTEMA
|
||||
#
|
||||
# ⚠ La FLAG va en inglés (regla 4 del CLAUDE.md: la superficie de CLI es contrato) aunque `--lista`
|
||||
# sea deuda vieja del mismo fichero. La CLAVE del TOML sí es `servicios`, en castellano, porque ahí
|
||||
@@ -110,6 +111,19 @@ GRAFOS = ["build-state.json", "build-state-gnome.json", "build-state-kde.json",
|
||||
"build-state-cosmic.json", "build-state-wlr.json"]
|
||||
|
||||
|
||||
def _ruta_de(nombre, recipes_dir=None):
|
||||
"""La ruta de la receta que se llama `nombre`. Se busca por el campo `name`, no por el nombre de
|
||||
fichero: son casi siempre iguales, pero el que manda es el campo."""
|
||||
recipes_dir = Path(recipes_dir) if recipes_dir else ROOT / "recipes"
|
||||
for f in sorted(recipes_dir.rglob("*.toml")):
|
||||
try:
|
||||
if tomllib.load(open(f, "rb")).get("name") == nombre:
|
||||
return str(f.relative_to(ROOT))
|
||||
except tomllib.TOMLDecodeError:
|
||||
continue
|
||||
return None
|
||||
|
||||
|
||||
def _membresia():
|
||||
"""{receta: [perfiles]} fusionando TODOS los grafos de estado. `{}` si no hay ninguno (no es
|
||||
fatal: degrada a no poder comprobar la pertenencia, y se dice)."""
|
||||
@@ -268,6 +282,29 @@ def main():
|
||||
return 0
|
||||
if args[0] == "--selftest":
|
||||
return 0 if autotest() else 1
|
||||
if args[0] == "--service-paths":
|
||||
# Las RUTAS de receta de los servicios de SISTEMA habilitados, para que el ensamblado de la
|
||||
# imagen se las pase a `takana service cards`. Sólo `system`: una Card de sesión en el
|
||||
# `genesis` arrancaría antes de que exista XDG_RUNTIME_DIR o un usuario (SDD 30 §4c).
|
||||
if len(args) < 2 or args[1] not in perfiles:
|
||||
print(f"uso: targets.py --service-paths <perfil>", file=sys.stderr)
|
||||
return 1
|
||||
decl = declaraciones()
|
||||
memb = _membresia()
|
||||
raices = set(perfiles[args[1]]["raices"])
|
||||
vistas = []
|
||||
for lbl in perfiles[args[1]]["servicios_exp"]:
|
||||
for receta, svc in decl.get(lbl, []):
|
||||
if svc.get("scope", "system") != "system":
|
||||
continue
|
||||
if not (receta in raices or args[1] in memb.get(receta, [])):
|
||||
continue
|
||||
ruta = _ruta_de(receta)
|
||||
if ruta and ruta not in vistas:
|
||||
vistas.append(ruta)
|
||||
for r in vistas:
|
||||
print(r)
|
||||
return 0
|
||||
if args[0] in ("--services", "-s"):
|
||||
if len(args) < 2 or args[1] not in perfiles:
|
||||
print(f"uso: targets.py --services <perfil> (hay: {', '.join(sorted(perfiles))})",
|
||||
|
||||
Reference in New Issue
Block a user