Files
takana/scripts/farm/takana-farm.service
T
Sergio aacee245d6 takana: el worker pasa a /opt/takana y takana-farm.service
Renombrado el directorio del worker y la unit, con las tres units del repo
(farm, deadman service y timer). Todas las rutas /opt/hammer del hub pasan a
/opt/takana: eran defaults REMOTE= y HAMMER_DIR=, mas los systemctl/journalctl
que nombraban la unit sin el sufijo .service, que el primer sed no casaba.

Orden, para que no quedara partido: el hub siembra por rsync a una ruta fija,
asi que se saco el cron ANTES de mover. Si se movia el worker con el hub
apuntando a la ruta vieja, la siguiente cosecha recreaba /opt/hammer y quedaban
dos arboles.

Verificado de punta a punta:
- el worker cerro un ciclo de build REAL desde /opt/takana (dunst sellado, 1/1)
- una cosecha completa del hub contra la ruta nueva: siembra, manifiesto, los
  nueve grafos, static-audit (691 estaticos, MIENTEN 0) y estado pusheado
- la unit vieja quedo deshabilitada y borrada; /opt tiene una sola entrada

NO se tocan dos referencias a /opt/hammer que siguen siendo CORRECTAS:
docs/23-plan-rehasheo.md describe rutas EMBEBIDAS en artefactos ya construidos
—que literalmente dicen /opt/hammer/work en sus secciones .debug— y el HANDOFF
de la noche de KDE es registro. Cambiarlas haria que los documentos mientan.
2026-09-09 20:20:16 +00:00

47 lines
2.6 KiB
Desktop File

[Unit]
Description=takana build farm worker (loop autónomo)
After=network-online.target
Wants=network-online.target
# ── FRENO AL CRASHLOOP (2026-08-31) ──────────────────────────────────────────────────────────────
# Sin esto, `Restart=always` + una receta que no entra en RAM = bucle infinito. Medido en el LXC
# dev.gioser.net: `clang18` disparó el OOM killer, systemd relanzó a los 30 s, el loop volvió a la
# misma receta (build-farm recorre la cola por glob alfabético y clang18 sale primera), OOM otra vez.
# **30 HORAS así**: la caja quedó con presión de I/O `full avg300=43` —todo bloqueado en disco casi
# la mitad del tiempo— y sshd sin poder ni completar el banner, o sea imposible de diagnosticar
# desde fuera. Dos `oom-kill` en el journal fue todo lo que quedó como rastro.
#
# 3 arranques en 1 h ⇒ systemd se rinde y deja la unidad en `failed`, VISIBLE en `systemctl status`.
# Un worker parado y diagnosticable vale más que uno que se reinicia para siempre: el hub ya tolera
# workers ausentes (cosecha-cron avisa "siembra falló" y sigue), así que rendirse no pierde nada.
StartLimitIntervalSec=3600
StartLimitBurst=3
[Service]
Type=simple
WorkingDirectory=/opt/takana
Environment=HOME=/root
# ADR 0016: se fijan LAS DOS mientras dure el renombre. Los scripts leen
# ${TAKANA_DIR:-${HAMMER_DIR:-…}}, pero un script VIEJO —o una copia del repo
# que todavía no sincronizó— sólo mira HAMMER_DIR. Medido el 2026-09-09: esta
# unit era el ÚNICO sitio fuera del repo que traía una variable vieja puesta, y
# es lo que hoy impide retirar la caída. Cuando el worker corra con TAKANA_DIR
# y el resto de la flota también, se borra la segunda línea y recién ahí se
# puede retirar la caída del código (etapa 6).
Environment=TAKANA_DIR=/opt/takana
Environment=HAMMER_DIR=/opt/takana
# JOBS no se fija: el loop usa nproc por defecto (cada build usa 1 core por codegen-units=1).
# Así, al REPOTENCIAR la caja (CCX13→CCX23/33), el worker auto-escala los slots sin tocar config.
# La línea CCX da ~4GB RAM/core ⇒ nproc slots quedan con margen para builds Rust + swap.
ExecStart=/opt/takana/scripts/farm/farm-worker-loop.sh
Restart=always
RestartSec=30
# El OOM del worker NO se reintenta como si fuera un fallo transitorio: si la receta no entra en la
# caja, no va a entrar en 30 segundos. `stop` deja la unidad detenida y contable por StartLimitBurst.
OOMPolicy=stop
# deja respirar al sistema en una caja chica
Nice=10
IOSchedulingClass=idle
[Install]
WantedBy=multi-user.target