diff --git a/scripts/farm/farm-up.sh b/scripts/farm/farm-up.sh index 7e1ed347..7fd929dc 100755 --- a/scripts/farm/farm-up.sh +++ b/scripts/farm/farm-up.sh @@ -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\"