sergio/takana
> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…
Etapa G: fixes del kit de granja distribuida (validados en VPS Hetzner real)
1#!/usr/bin/env bash
2# vps-setup.sh — provisiona un WORKER de granja hammer en un VPS Debian/Ubuntu fresco.
3#
4# Modelo hub-and-spoke: el LAPTOP es el hub (tiene la clave de firma + gitea). El worker
5# NO toca gitea ni firma nada — sólo construye la cola `recipes/incoming/` y sella al store
6# local (PROMOTE=0). El hub le rsync-ea código+cola y le baja el store con `farm-sync.sh`.
7#
8# El hub corre esto por SSH tras rsync-ear el repo a $HAMMER_DIR. Idempotente (re-correr
9# actualiza in-place). Necesita root (apt + sysctl + swap + systemd).
10#
11# Uso (en el VPS, como root): HAMMER_DIR=/opt/hammer ./scripts/farm/vps-setup.sh
12set -euo pipefail
13
14HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
15cd "$HAMMER_DIR"
16
17echo "==> 1. deps del sistema (apt)"
18export DEBIAN_FRONTEND=noninteractive
19apt-get update -q
20apt-get install -y -q git build-essential curl pkg-config libssl-dev \
21 bubblewrap rsync ca-certificates uidmap xz-utils
22
23echo "==> 2. user namespaces para bwrap (Debian/Ubuntu los capan por defecto)"
24sysctl -w kernel.unprivileged_userns_clone=1 2>/dev/null || true
25sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 2>/dev/null || true
26cat > /etc/sysctl.d/99-hammer-userns.conf <<'EOF'
27kernel.unprivileged_userns_clone=1
28kernel.apparmor_restrict_unprivileged_userns=0
29EOF
30sysctl --system >/dev/null 2>&1 || true
31
32echo "==> 2b. bubblewrap con soporte overlay (el de la distro suele ser viejo/sin overlayfs)"
33# El sandbox del lab usa `bwrap --overlay-src --tmp-overlay`; bubblewrap <0.10 (p.ej. el 0.9.0 de
34# Ubuntu 24.04) responde "Unknown option --overlay-src". Compilamos 0.11.2 a /usr/local/bin (gana
35# el PATH de systemd) si el instalado no lo soporta.
36if ! bwrap --help 2>&1 | grep -q overlay-src; then
37 apt-get install -y -q meson ninja-build libcap-dev
38 BWV=0.11.2
39 curl -sL "https://github.com/containers/bubblewrap/releases/download/v${BWV}/bubblewrap-${BWV}.tar.xz" -o /tmp/bwrap.tar.xz
40 ( cd /tmp && rm -rf "bubblewrap-${BWV}" && tar xf bwrap.tar.xz && cd "bubblewrap-${BWV}" \
41 && meson setup _build --prefix=/usr/local -Dman=disabled -Dtests=false >/dev/null \
42 && ninja -C _build >/dev/null && ninja -C _build install >/dev/null )
43 hash -r
44 echo " bwrap actualizado: $(/usr/local/bin/bwrap --version)"
45fi
46
47echo "==> 3. swap 16G (8GB de RAM es justo para builds Rust con JOBS=2)"
48if ! swapon --show 2>/dev/null | grep -q /swapfile; then
49 fallocate -l 16G /swapfile 2>/dev/null || dd if=/dev/zero of=/swapfile bs=1M count=16384 status=none
50 chmod 600 /swapfile; mkswap /swapfile >/dev/null; swapon /swapfile
51 grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' >> /etc/fstab
52fi
53
54echo "==> 4. rust host toolchain (para buildear el binario hammer)"
55if ! command -v cargo >/dev/null 2>&1; then
56 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
57 sh -s -- -y --profile minimal --default-toolchain stable
58fi
59. "$HOME/.cargo/env"
60
61echo "==> 5. build hammer (target/release/hammer)"
62cargo build --release --bin hammer
63
64echo "==> 6. rootfs Alpine edge + zig (bootstrap reproducible; varios min la 1ra vez)"
65./scripts/bootstrap-devfs.sh
66
67echo "==> 7. systemd unit del loop"
68cp scripts/farm/hammer-farm.service /etc/systemd/system/hammer-farm.service
69systemctl daemon-reload
70
71echo "✓ worker provisionado."
72echo " arrancar: systemctl enable --now hammer-farm"
73echo " logs: journalctl -u hammer-farm -f"