Files
brahman/docs/arje-replace-systemd.md
T
sergio b83d40a833 refactor(naming): A1 — ente→arje, vista→revista, pluma→fana
Rename batch de la Fase A del PLAN_MACRO:
- 25 crates ente-* → arje-* (protocol/init/runtime/compat). El linaje
  arje (init Linux) queda con prefijo coherente.
- vista → revista (revista-core + revista-web).
- pluma → fana (fana-md + fana-md-reader-web). fana absorbe el linaje
  markdown de pluma; será el writer DAG editor (prioridad alta).

Cambios:
- git mv de 29 crate dirs + 2 SDDs
- package/lib/bin names + path refs + imports .rs reescritos
- workspace Cargo.toml + comentarios de sección
- SDDs de init/runtime/compat/protocol actualizados a arje-
- SDD de revista + SDD de fana (reescrito: writer DAG editor)
- docs/STATUS.md, ROADMAP.md, PLAN_MACRO.md, arje-boot.md,
  arje-replace-systemd.md actualizados
- docs/changelog/akasha.md → chasqui.md

scripts/rename-fase-a.py idempotente (--dry-run soportado).
cargo check --workspace verde.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 00:10:14 +00:00

222 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Reemplazar systemd con arje en una máquina real
> **Importante**: este flujo deja **systemd intacto** y agrega arje como
> entrada GRUB alternativa. No es "destruir y reemplazar"; es "convivir
> hasta confiar". Booteás arje cuando querés, volvés a systemd si rompe.
## 1. Estrategia
| componente | qué hacemos |
| --------------------- | -------------------------------------------------------- |
| `/sbin/init` | NO se toca (sigue siendo systemd). |
| `/lib/systemd/*` | NO se toca. |
| `kernel + initramfs` | reusamos los del host (firmware, módulos, root FS). |
| `init=` en GRUB | nueva entrada apunta a `/sbin/arje-zero`. |
| `GRUB_DEFAULT` | NO se cambia. Sigue arrancando systemd por default. |
| `/ente/seed.card.json`| nueva — define qué arranca arje. |
| `/usr/sbin/arje-*` | binarios musl-static del fractal. |
Booteo del kernel → initramfs nativo hace su trabajo (mountea root,
carga módulos) → cuando llega el `switch_root`, en lugar de exec
`/lib/systemd/systemd`, exec `/sbin/arje-zero`. Esto deja firmware y
udev fuera del scope de arje (todavía).
## 2. Instalación
```bash
# 1. (opcional) revisá la seed default que se va a copiar a /ente/
$EDITOR seeds/arje-host.card.json
# 2. instalar
sudo scripts/install-arje-as-init.sh
# 3. (opcional) bootear arje SÓLO en el próximo reboot (no cambia default)
sudo grub-reboot "arje (init=/sbin/arje-zero) — kernel $(uname -r)"
sudo reboot
```
Si algo rompe en arje: reset/poweroff → en el menú GRUB elegir la
entrada default (systemd) → volvés a un sistema funcional. `arje` no
toca configuración de systemd, así que el rollback es instantáneo.
Para **desinstalar**:
```bash
sudo scripts/uninstall-arje.sh
```
## 3. Filosofía vs systemd — y por qué arje no acapara
systemd arranca, por default, **todo lo que tiene un `.service` con
`WantedBy=multi-user.target`**, recursivamente vía dependencias. Eso es
opaco y crece con cada paquete instalado.
arje no tiene generadores, ni `WantedBy`, ni `Wants`, ni target trees.
**Arranca exactamente lo declarado en `genesis: [...]` de la
`seed.card.json`**, en el orden declarativo, con la `supervision` que
declarás vos. Si no lo declaraste, no corre. Punto.
### 3a. Servicios que systemd arranca y arje NO debería migrar
Estos son los sospechosos típicos en Debian/Ubuntu/Arch. **No agregues
ninguno a tu seed** salvo que sepas que lo usás:
| systemd unit | por qué saltearlo |
| ------------------------------------ | ---------------------------------------- |
| `ModemManager.service` | no tenés módem 3G/4G. |
| `bluetooth.service` | si no usás bluetooth. |
| `cups.service`, `cups-browsed` | si no imprimís. |
| `avahi-daemon.service` | mDNS local. Ruido si no lo necesitás. |
| `snapd.service` | si no usás snaps. |
| `apt-daily.service`, `apt-daily-upgrade` | autoupdates — no son init. |
| `unattended-upgrades.service` | corre tras boot, no init. |
| `accounts-daemon.service` | UI helpers GNOME; no init. |
| `colord.service` | calibración de color. No init. |
| `geoclue.service` | localización. No init. |
| `gdm.service`, `lightdm.service` | DM gráfico — agregalo SÓLO si querés GUI.|
| `NetworkManager-wait-online.service` | espera red. arje no necesita "esperar". |
| `systemd-timesyncd.service` | reemplaza con cron-like + ntpd one-shot. |
| `systemd-machined.service` | reemplazado por `arje-machined-compat`. |
| `systemd-logind.service` | reemplazado por `arje-logind-compat`. |
| `systemd-resolved.service` | reemplazado por `arje-resolved-compat`. |
| `systemd-hostnamed.service` | reemplazado por `arje-hostnamed-compat`. |
| `systemd-timedated.service` | reemplazado por `arje-timedated-compat`. |
| `systemd-localed.service` | reemplazado por `arje-localed-compat`. |
| `systemd-journald.service` | reemplazado por `arje-journald-compat`. |
| `systemd-tmpfiles-*.service` | reemplazado por `arje-tmpfiles-compat`. |
| `systemd-binfmt.service` | reemplazado por `arje-binfmt-compat`. |
| `polkitd.service` | reemplazado por `arje-polkit-compat`. |
Las últimas 12 ya están como Cards en `seeds/arje-host.card.json`. Las
de la mitad de arriba **no** — no las agregues.
### 3b. Servicios que SÍ necesitás declarar (y que ya están en `arje-host.card.json`)
| Card label | reemplaza | binario |
| ------------------ | -------------------------- | -------------------------------------------- |
| `tmpfiles-boot` | `systemd-tmpfiles-setup` | `/usr/sbin/arje-tmpfiles-compat --boot` |
| `mount-fstab` | `local-fs.target` | `/bin/mount -a` (one-shot) |
| `swap-on` | `swap.target` | `/sbin/swapon -a` (one-shot) |
| `dbus-system` | `dbus.service` | `/usr/bin/dbus-daemon --system --nofork` |
| `compat-*` (×11) | shims D-Bus de systemd | `/usr/sbin/arje-*-compat` |
| `network-dhcpcd` | `NetworkManager` / `networkd` | `/usr/sbin/dhcpcd -B` |
| `sshd` | `ssh.service` | `/usr/sbin/sshd -D` |
| `getty-tty1` | `getty@tty1.service` | `/sbin/agetty --noclear tty1 linux` |
15 entes. Compará: una instalación Debian fresh con GNOME desktop tiene
**>180 unidades activas** tras `systemctl list-units --state=running`.
### 3c. Cómo agregar un servicio que falta
1. Encontrá el binario y los argumentos. Mirá el `.service` original:
```
systemctl cat <unit>
```
Mirá `ExecStart=` y reproducí.
2. Agregá una Card al `genesis` de `/ente/seed.card.json`:
```json
{
"schema_version": 1,
"id": "<ULID nuevo, Crockford base32, no I L O U>",
"label": "mi-servicio",
"provides": [], "requires": [],
"permissions": { "networking": "outbound", "filesystem": "read-write", "ipc": { "allow": [] }, "processes": true },
"soma": { ... idéntico al patrón de los otros ... },
"payload": { "Native": { "exec": "/usr/sbin/mi-bin", "argv": ["--foreground"], "envp": [] } },
"supervision": { "Restart": { "initial": 500, "max": 30000 } },
"lifecycle": "daemon",
"priority": "normal",
"flow": { "input": [], "output": [] },
"genesis": []
}
```
**Importante**: `argv` tiene que tener el equivalente a `--foreground` o
`-D` o `--no-fork`. Si el binario se daemoniza solo (fork+exit), arje
no lo puede supervisar y caerá en loop de restart.
3. Validar:
```bash
seeds/validate.sh /ente/seed.card.json
```
4. Reboot a arje. Verificar:
```sh
arje# brahman-status
```
## 4. Diferencias de UX con systemd
| acción | systemd | arje |
| ---------------------------- | ------------------------------------ | ------------------------------------------------------- |
| Ver servicios activos | `systemctl list-units --state=running` | `brahman-status` + `busctl list-entes` |
| Ver logs | `journalctl -u foo` | `arje-journalctl` (TODO en CLI; por ahora `dmesg`) |
| Restart un servicio | `systemctl restart foo` | matar el PID (`brain` lo reanuda por `Supervision`) |
| Habilitar/Deshabilitar | `systemctl enable/disable` | editar `/ente/seed.card.json` + reboot |
| Ver dependencias | `systemctl list-dependencies foo` | `brahman-status` muestra references y flow matches |
| Detectar fallas reincidentes | `systemctl status foo` → "failed" | `brainctl crystals` muestra patrones `EnteDied → …` |
| socket activation | `.socket` unit | (no implementado todavía; ver flow + broker matching) |
| user services | `--user` | (no implementado; arje es system-wide por ahora) |
## 5. Cosas que arje todavía NO hace que sí hace systemd
- **udev / hotplug**: arje captura uevents (vía `spawn_uevent_stream`),
pero no hay reglas declarativas todavía. Para boot inicial, el
initramfs nativo ya hizo el cold-plug, así que no es bloqueante.
- **Timers** (cron-like): `arje-timer-compat` existe pero no está en la
seed host por default. Agregalo si querés `*.timer` units migradas.
- **Service generators**: no hay equivalente a `systemd-fstab-generator`
ni `systemd-getty-generator`. Tu seed los declara explícitamente.
- **Socket activation**: parcialmente — el broker matchea flow
consumer↔producer, pero no hay aún listen-on-fd-handoff como
`sd_listen_fds()`.
- **User instances**: no hay todavía `arje --user`. Los procesos de
usuario los lanza un getty/login estándar.
## 6. Checklist pre-primer-boot
- [ ] `seeds/arje-host.card.json` ajustada a tu hardware/red/users.
- [ ] `seeds/validate.sh` → OK.
- [ ] `/usr/bin/dbus-daemon` existe (de lo contrario los shims no se
anuncian — `apt install dbus`).
- [ ] `/usr/sbin/dhcpcd` o tu network stack preferido está instalado.
- [ ] `/usr/sbin/sshd` instalado y `/etc/ssh/sshd_config` ok si querés
poder entrar remoto si la consola falla.
- [ ] `/sbin/agetty` instalado (`util-linux`) para tty1.
- [ ] `sudo scripts/install-arje-as-init.sh` ejecutado.
- [ ] `grub-reboot` apuntado a la entrada arje **sólo para el próximo
boot** — no `grub-set-default`.
- [ ] Listo para revertir vía menú GRUB si algo falla.
## 7. Cuando arje sea estable: hacerlo default
Cuando ya hayas booteado arje N veces sin problemas y querés que sea
default:
```bash
# Listar entradas
sudo grep -E "^\s*menuentry " /boot/grub/grub.cfg | nl
# Ponerlo como default (usa el índice del menú o el title exacto)
sudo grub-set-default "arje (init=/sbin/arje-zero) — kernel $(uname -r)"
```
Mantené la entrada systemd como rescue. Si querés acortar la lista de
units que systemd arrancaría si bootea de nuevo: `systemctl disable
ModemManager bluetooth cups …` — los nombres de §3a son una guía.
## Apéndice — depurar el primer boot fallido
Si arje no levanta el primer boot:
1. Volver a GRUB → entrada systemd → bootea normal.
2. `journalctl --boot=-1` (logs del intento previo).
3. Buscar `arje-zero` o `Tarjeta Semilla`. Si nada → el ejecutable no
se lanzó (kernel panic temprano, falta `init=` correcto, etc.).
4. Si arrancó pero falló alguna Card: la próxima vez, antes de reboot:
```bash
sudo sed -i 's/console=tty1/console=tty1 ente.log=trace/' /etc/grub.d/40_custom
sudo update-grub
```
y revisá `dmesg` desde systemd tras el reintento.