arje-botones: el poweroff ya baja los servicios — deuda cerrada
Este shim traía su propia nota pidiendo el arreglo: «El camino bueno es BusRequest::PowerOff por el bus de arje; cuando arje-ctl esté en la imagen, el shim de poweroff debería delegarle en vez de hacer esto». Ya está: `arjectl` existe sellado y expone `poweroff | reboot | suspend | hibernate`, que ES ese BusRequest. Ahora el shim lo INTENTA primero, y por ahí los servicios SÍ reciben su SIGTERM por el cascade de arje — antes iba directo a SysRq y se lo salteaba entero. ⚠ Y cae a SysRq a propósito, no por desconfianza: `arjectl` viaja en `servidor` y `servidor-minimo` y NO en los cinco escritorios (medido en targets.toml). Un shim que dependiera de él fallaría justo donde más se nota — alguien apagando su portátil. El respaldo es el camino de antes, con su aviso de que no hay cascade. Si arjectl vuelve sin error NO se sigue al respaldo: hacerlo cortaría el cascade que se acaba de pedir. `halt` es un enlace a `poweroff`, así que hereda el arreglo. Verificado que el shim generado es POSIX de verdad: `-n` limpio con simi Y con el ash de busybox, los dos.
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
1 archivos · +35 −11
- scripts/servidor/arje-botones.sh +35 −11
diff --git a/scripts/servidor/arje-botones.sh b/scripts/servidor/arje-botones.sh
index 35b8cb20..591a952f 100755
--- a/scripts/servidor/arje-botones.sh
+++ b/scripts/servidor/arje-botones.sh
@@ -26,10 +26,13 @@
# `kernel.ctrl-alt-del = 0`. O sea: el camino existía entero y no estaba
# conectado a ningún botón. Esto lo conecta.
#
-# ⚠ ASIMETRÍA QUE NO SE PUEDE TAPAR: hay señal para REINICIAR y no la hay para
-# APAGAR. Por eso `poweroff` va por SysRq y **se saltea el cascade**. El camino
-# bueno es `BusRequest::PowerOff` por el bus de arje; cuando `arje-ctl` esté en
-# la imagen, el shim de poweroff debería delegarle en vez de hacer esto.
+# ⚠ ASIMETRÍA: hay señal para REINICIAR y no la hay para APAGAR — arje-zero
+# atrapa SIGINT y sólo SIGINT. ✅ **Pero desde el 2026-10-22 ya no se paga
+# entera**: `arjectl` existe sellado y expone `poweroff|reboot|suspend|
+# hibernate`, que ES el `BusRequest::PowerOff` que esta nota pedía. El shim lo
+# INTENTA primero —y ahí los servicios sí reciben su SIGTERM— y cae a SysRq
+# sólo si no está o si el bus no contesta. La caída hace falta: `arjectl` viaja
+# en `servidor` y `servidor-minimo` y NO en los cinco escritorios.
#
# ⚠ EL BOTÓN DEL PANEL DEL PROVEEDOR NO SE ARREGLA ACÁ, y no por falta de
# ganas: en una caja musl `acpid` es el applet de **busybox**, que encuentra su
@@ -77,17 +80,38 @@ SH
cat > "$RFS/usr/local/bin/poweroff" <<'SH'
#!/bin/sh
-# poweroff — apaga de verdad, PERO SIN el cascade de arje: arje-zero instala
-# SIGINT y sólo SIGINT, así que no hay señal de apagado que mandarle. Va directo
-# al kernel por SysRq: 'u' = remount-ro de emergencia (evita el fsck del próximo
-# arranque), 'o' = apagar. Los servicios NO reciben su SIGTERM. El camino bueno
-# es BusRequest::PowerOff por el bus de arje, cuando arje-ctl esté en la imagen.
+# poweroff — DOS caminos, y el primero es el ordenado.
+#
+# ✅ **Deuda cerrada el 2026-10-22.** Este shim decía: «El camino bueno es
+# BusRequest::PowerOff por el bus de arje, cuando arje-ctl esté en la imagen».
+# Ya está: `arjectl` existe sellado y expone `poweroff | reboot | suspend |
+# hibernate`, que es exactamente ese BusRequest. Así que ahora se INTENTA eso
+# primero y los servicios SÍ reciben su SIGTERM por el cascade de arje.
+#
+# ⚠ Y se cae a SysRq a propósito, no por desconfianza: `arjectl` viaja sólo en
+# `servidor` y `servidor-minimo` (medido en targets.toml), así que en los cinco
+# escritorios no está. Un shim que dependiera de él fallaría justo donde más se
+# nota — alguien apagando su portátil. El respaldo es el camino de antes:
+# 'u' = remount-ro de emergencia (evita el fsck del próximo arranque), 'o' =
+# apagar, sin cascade.
[ "$(id -u)" = 0 ] || { echo "poweroff: hace falta root" >&2; exit 1; }
+
+# 1 · el camino ordenado: el bus de arje
+if command -v arjectl >/dev/null 2>&1; then
+ if arjectl poweroff 2>/dev/null; then
+ # arjectl volvió sin error: arje está bajando los entes. No seguimos al
+ # respaldo — hacerlo cortaría el cascade que acabamos de pedir.
+ exit 0
+ fi
+ echo "poweroff: arjectl no pudo (¿bus caído?) — voy por SysRq" >&2
+fi
+
+# 2 · el respaldo: directo al kernel, sin cascade
[ "$(cat /proc/sys/kernel/sysrq 2>/dev/null)" = 0 ] && {
- echo "poweroff: kernel.sysrq está en 0 — no hay por dónde. Ponelo en 1." >&2
+ echo "poweroff: kernel.sysrq está en 0 y arjectl no sirvió — no hay por dónde." >&2
exit 1
}
-echo "poweroff: sin cascade (arje no expone señal de apagado) — sync + SysRq u,o" >&2
+echo "poweroff: SIN cascade (los servicios no reciben SIGTERM) — sync + SysRq u,o" >&2
sync
echo u > /proc/sysrq-trigger
sleep 1