farm-up: DOS bombas de pérdida de datos — una ya explotó y se llevó ~900 artefactos del volumen
Investigando por qué el worker nuevo arrancó con 2 artefactos en vez de ~900, apareció esto.
BOMBA 1 — `rm -rf $REMOTE/store` sin comprobar si es punto de montaje.
La guarda era `[ -d ] && [ ! -L ]`: basta en un server creado desde la golden ORIGINAL, donde
/opt/hammer/store es un directorio normal. Pero al re-snapshotear un worker (ayer, para meterle
Rust y Go) la imagen se llevó también LA CONFIGURACIÓN DE MONTAJE ⇒ el server nuevo monta el
volumen en esa ruta AL ARRANCAR, antes de que corra el «rescate». Entonces el `rm -rf` borra A
TRAVÉS DEL MONTAJE y se lleva el store del volumen entero — justo lo que el volumen existe para
proteger.
Evidencia: el volumen pasó de ~900 artefactos a 2, pero NO se perdió el filesystem (lost+found
de julio, 17 montajes, .dmerge intacto). Se borró el CONTENIDO, no el disco. Ahora hay
`mountpoint -q`: si ya está montado no hay nada que rescatar ni que borrar.
BOMBA 2 — `mount … || { mkfs.ext4 -F …; }`. Formatear ante CUALQUIER fallo de montaje, incluida
la carrera normal entre `volume attach` y la aparición del dispositivo. Un hipo de segundos
destruía el volumen. Ahora sólo formatea si `blkid` dice que NO tiene filesystem; si lo tiene y
no montó, aborta y lo dice.
Las dos comparten la misma forma: un fallback destructivo que asume la causa benigna. `mv -n`
está bien elegido (no pisa), pero el `rm -rf` que lo sigue anulaba esa prudencia.
Y una consecuencia que hay que asumir: re-snapshotear un worker NO conserva el store — los
artefactos viven en el volumen, que no entra en la imagen. La golden aporta toolchain y sistema;
la caché la aporta el volumen. Hoy la imagen decía traer store y no lo trae.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+22
-2
@@ -97,7 +97,16 @@ for k in $(seq 1 "$N"); do
|
||||
hcloud volume attach --server "$name" "$VOL_NAME" >/dev/null 2>&1 || true
|
||||
dev="/dev/disk/by-id/scsi-0HC_Volume_$vid"
|
||||
$SSH root@"$ip" "mkdir -p /mnt/cosecha
|
||||
mount $dev /mnt/cosecha 2>/dev/null || { mkfs.ext4 -q -F $dev && mount $dev /mnt/cosecha; }
|
||||
# ⚠ El `mkfs.ext4 -F` de rescate SÓLO si el dispositivo no tiene filesystem. La versión previa
|
||||
# formateaba ante CUALQUIER fallo de montaje —incluida la carrera normal entre `volume attach`
|
||||
# y la aparición del dispositivo— o sea que un hipo de segundos destruía el volumen entero.
|
||||
# `blkid` distingue «vacío» de «no pude montarlo ahora».
|
||||
if ! mount $dev /mnt/cosecha 2>/dev/null; then
|
||||
if blkid $dev >/dev/null 2>&1; then
|
||||
echo " ✗ el volumen TIENE filesystem y no montó — NO lo formateo. Revisá a mano." >&2; exit 1
|
||||
fi
|
||||
mkfs.ext4 -q -F $dev && mount $dev /mnt/cosecha
|
||||
fi
|
||||
mkdir -p /mnt/cosecha/store /mnt/cosecha/verdicts /mnt/cosecha/logs
|
||||
# el store del worker ES el del volumen: sellar YA es persistir.
|
||||
# PERO antes hay que RESCATAR el store HORNEADO en la golden (2026-07-21): esto hacía
|
||||
@@ -106,7 +115,18 @@ for k in $(seq 1 "$N"); do
|
||||
# deuda contra un store casi vacío y se pone a reconstruir media distro: en la tanda del
|
||||
# 2026-07-21 dio 716 recetas de deuda donde el hub medía 37. Es CAS (nombre = hash) ⇒
|
||||
# fusionar es seguro por construcción: \`mv -n\` no pisa lo que el volumen ya tiene.
|
||||
if [ -d $REMOTE/store ] && [ ! -L $REMOTE/store ]; then
|
||||
# ⚠ `mountpoint -q` NO ES OPCIONAL — sin él este bloque BORRA EL VOLUMEN.
|
||||
# La guarda original sólo comprobaba «es directorio y no es symlink». Eso basta en un server
|
||||
# recién creado desde la golden ORIGINAL, donde /opt/hammer/store es un directorio normal.
|
||||
# Pero al re-snapshotear un worker (2026-08-08) la imagen se llevó también la CONFIGURACIÓN DE
|
||||
# MONTAJE: el server nuevo monta el volumen en /opt/hammer/store al arrancar, ANTES de que
|
||||
# corra este rescate. Entonces `rm -rf $REMOTE/store` borra A TRAVÉS DEL MONTAJE y se lleva el
|
||||
# store del volumen entero — que es justo lo que el volumen existe para proteger.
|
||||
# Medido: el volumen pasó de ~900 artefactos a 2. No se perdió el filesystem (lost+found es de
|
||||
# julio, 17 montajes): se borró el CONTENIDO.
|
||||
# ⇒ Si ya es punto de montaje, no hay nada que rescatar ni que borrar: el store ya está donde
|
||||
# tiene que estar.
|
||||
if [ -d $REMOTE/store ] && [ ! -L $REMOTE/store ] && ! mountpoint -q $REMOTE/store; then
|
||||
n=\$(ls $REMOTE/store 2>/dev/null | wc -l)
|
||||
[ \"\$n\" -gt 0 ] && mv -n $REMOTE/store/* /mnt/cosecha/store/ 2>/dev/null
|
||||
echo \" ✓ rescatados \$n artefactos horneados de la golden al volumen\"
|
||||
|
||||
Reference in New Issue
Block a user