El servicio que falla y agota su backoff sólo se podía recuperar reiniciando la máquina entera.
Ya no. Y no hubo que escribir nada: **el cliente existía en tawasuyu y el crate se llama `arje-ctl`**
(el binario, `arjectl`). Buscarlo por `arjectl` no lo encontraba, y de ahí salió mi conclusión falsa
de que había que implementarlo — el protocolo ya traía ListEntes, SpawnCardFromDisk,
StopCardFromDisk, KillEnte y EnteStatus.
`recipes/arjectl.toml` lo construye del MISMO commit que `arje-zero` (98db584f), y no por comodidad:
el bus es un protocolo entre dos binarios y un cliente de otro árbol puede conectar sin entenderse
con el init. Publica sólo `arjectl`; el crate también produce un `systemctl` de camuflaje que acá no
se instala — en una distro sin systemd, ese nombre en el PATH invita a escribir runbooks con el
verbo ajeno.
⚠ EL HUECO QUE SÓLO SE VE USÁNDOLO: el genesis de la seed dice qué arranca AL BOOT, pero
`start`/`restart` usan `SpawnCardFromDisk`, que lee `/etc/arje/cards.d/<label>.json` — y el armado
no lo escribía:
$ arjectl start gitea
Error: arje-zero rechazó: card gitea: No such file or directory
(buscada en /etc/arje/cards.d/gitea.json)
Son dos preguntas distintas —qué arranca solo, y qué se puede encarnar a pedido— y arje las responde
desde sitios distintos. `inyectar-cards.py` escribe ahora los dos árboles, y en `cards.d` escribe
TODAS las cards, no sólo las nuevas: `sshd` viene del product-rootfs y tampoco era relanzable.
Medido con la VM arrancada UNA sola vez: la imagen trae `cards.d/{gitea,sshd}.json` · `list-units`
da PID/CPU/MEM/HILOS/reinicios · poner el `app.ini` + `arjectl start gitea` ⇒ **GET / 200 sin
reiniciar** (uptime 6 min) · `arjectl restart gitea` cambia el PID (118 → 192) y sigue en 200.
⚠ Y un aviso que costó un HTTP intermitente: **`arjectl start` sobre un Ente YA VIVO lo DUPLICA** —
`SpawnCardFromDisk` no deduplica por label y arje le da un ULID nuevo. En gitea el síntoma fue
`unable to lock level db … resource temporarily unavailable` y un `[F]`: dos servidores peleando por
el mismo estado. Para relanzar se usa `restart`, o se mira `list-units` antes. Un `start` idempotente
es trabajo de arje, no de esta imagen.
⚠ Deuda anotada, no barrida: `arjectl` va en `perfil.servidor` porque este frente es el que lo pagó.
TODA imagen de takana corre arje-zero como PID 1 y ninguna se puede operar sin él ⇒ el argumento
para subirlo a `base` es fuerte, y es una línea. Se deja como decisión.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Tf9T4vGzsMoT7eS8YzMFn
41 lines
2.5 KiB
TOML
41 lines
2.5 KiB
TOML
# arjectl — el control en caliente del init. Sin esto, una caja de takana sólo se administra
|
|
# REINICIÁNDOLA, y eso se descubrió del peor modo: la primera imagen del perfil `servidor` levantó
|
|
# gitea, la card falló por falta de config, el backoff de `restart` se agotó y **no había forma de
|
|
# pedirle a PID 1 que volviera a intentarlo**. Hubo que reiniciar la máquina entera para arrancar un
|
|
# servicio (SDD 28 §6.11).
|
|
#
|
|
# ══ NO SE ESCRIBIÓ NADA: YA EXISTÍA, Y SE LLAMA `arje-ctl` ═════════════════════════════════════
|
|
# El protocolo del bus (`arje-bus::BusRequest`) ya trae `ListEntes`, `SpawnCardFromDisk`,
|
|
# `StopCardFromDisk`, `KillEnte` y `EnteStatus`; lo que faltaba en la imagen era el CLIENTE, que vive
|
|
# en `03_ukupacha/arje/runtime/arje-ctl` y da `status`, `list-units`, `start`, `stop` y `restart`.
|
|
# Buscarlo por `arjectl` no lo encontraba —el crate es `arje-ctl`, el binario `arjectl`— y de ahí
|
|
# salió la conclusión falsa de que había que escribirlo.
|
|
#
|
|
# ══ EL COMMIT ES EL MISMO QUE `arje-zero`, Y NO ES POR COMODIDAD ═══════════════════════════════
|
|
# El bus es un PROTOCOLO entre dos binarios: un cliente de otro commit puede hablarle a un init que
|
|
# ya no entiende lo mismo, y el síntoma sería un `arjectl` que conecta y no obtiene respuesta. Que
|
|
# `arje-zero`, `arje-polkit-compat` y éste salgan del mismo árbol es la garantía de que el cliente y
|
|
# el init fueron compilados contra la MISMA definición. De paso reusa el árbol de fuentes ya
|
|
# fetcheado (ADR 0012).
|
|
#
|
|
# ⚠ El crate publica DOS binarios: `arjectl` (soberano) y `systemctl` (drop-in de camuflaje, que
|
|
# reenvía al systemd real si systemd es el init vivo). Acá se publica **sólo `arjectl`**: la distro
|
|
# no tiene systemd y un `systemctl` en el PATH invitaría a escribir runbooks con el verbo ajeno.
|
|
# Ponerlo sería una decisión de compatibilidad, no un efecto colateral de la receta.
|
|
name = "arjectl"
|
|
version = "0.0.1"
|
|
license = "MIT"
|
|
|
|
[source]
|
|
repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git"
|
|
commit = "98db584fd28d9ff2bf34c9cf7d7db2e1de0b3fd0"
|
|
# Este árbol COMMITEA su propio `vendor/` y el `cargo vendor` de takana lo pisaría — igual que en
|
|
# `arje-zero.toml`. Ver [[takana-cargo-vendor-clobbers-project-vendor]].
|
|
cargo_vendor_dir = ".hammer-cargo-vendor"
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
link = "static"
|
|
flags = ["-p", "arje-ctl", "--bin", "arjectl"]
|