Paraleliza el build a un/varios VPS sin exponer gitea ni la clave de firma. Modelo: el laptop es el HUB (firma + gitea); el worker sólo construye la cola incoming/ y sella al store local (PROMOTE=0). Reproducibilidad bit-a-bit + content-addressing ⇒ el store del worker es byte-idéntico, se rsync-ea de vuelta y el hash valida solo (no hay que confiar en el VPS). - vps-setup.sh: provisiona Debian/Ubuntu (deps, userns p/bwrap, swap 16G, rustup, build hammer, bootstrap-devfs rootfs Alpine edge, systemd unit). - farm-worker-loop.sh: loop autónomo 24/7, PROMOTE=0, watchdog de disco integrado; muele lo que haya sin esperar al hub. - hammer-farm.service: systemd, JOBS=2 (CCX13 = 2 vCPU dedicado), Nice/idle-io. - farm-sync.sh (hub): rsync código+cola arriba, store sellado abajo, promote+firma+commit+push. Acceso único laptop->VPS por SSH. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
2.4 KiB
Bash
Executable File
59 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# vps-setup.sh — provisiona un WORKER de granja hammer en un VPS Debian/Ubuntu fresco.
|
|
#
|
|
# Modelo hub-and-spoke: el LAPTOP es el hub (tiene la clave de firma + gitea). El worker
|
|
# NO toca gitea ni firma nada — sólo construye la cola `recipes/incoming/` y sella al store
|
|
# local (PROMOTE=0). El hub le rsync-ea código+cola y le baja el store con `farm-sync.sh`.
|
|
#
|
|
# El hub corre esto por SSH tras rsync-ear el repo a $HAMMER_DIR. Idempotente (re-correr
|
|
# actualiza in-place). Necesita root (apt + sysctl + swap + systemd).
|
|
#
|
|
# Uso (en el VPS, como root): HAMMER_DIR=/opt/hammer ./scripts/farm/vps-setup.sh
|
|
set -euo pipefail
|
|
|
|
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
|
|
cd "$HAMMER_DIR"
|
|
|
|
echo "==> 1. deps del sistema (apt)"
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -q
|
|
apt-get install -y -q git build-essential curl pkg-config libssl-dev \
|
|
bubblewrap rsync ca-certificates uidmap xz-utils
|
|
|
|
echo "==> 2. user namespaces para bwrap (Debian/Ubuntu los capan por defecto)"
|
|
sysctl -w kernel.unprivileged_userns_clone=1 2>/dev/null || true
|
|
sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 2>/dev/null || true
|
|
cat > /etc/sysctl.d/99-hammer-userns.conf <<'EOF'
|
|
kernel.unprivileged_userns_clone=1
|
|
kernel.apparmor_restrict_unprivileged_userns=0
|
|
EOF
|
|
sysctl --system >/dev/null 2>&1 || true
|
|
|
|
echo "==> 3. swap 16G (8GB de RAM es justo para builds Rust con JOBS=2)"
|
|
if ! swapon --show 2>/dev/null | grep -q /swapfile; then
|
|
fallocate -l 16G /swapfile 2>/dev/null || dd if=/dev/zero of=/swapfile bs=1M count=16384 status=none
|
|
chmod 600 /swapfile; mkswap /swapfile >/dev/null; swapon /swapfile
|
|
grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' >> /etc/fstab
|
|
fi
|
|
|
|
echo "==> 4. rust host toolchain (para buildear el binario hammer)"
|
|
if ! command -v cargo >/dev/null 2>&1; then
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
|
|
sh -s -- -y --profile minimal --default-toolchain stable
|
|
fi
|
|
. "$HOME/.cargo/env"
|
|
|
|
echo "==> 5. build hammer (target/release/hammer)"
|
|
cargo build --release --bin hammer
|
|
|
|
echo "==> 6. rootfs Alpine edge + zig (bootstrap reproducible; varios min la 1ra vez)"
|
|
./scripts/bootstrap-devfs.sh
|
|
|
|
echo "==> 7. systemd unit del loop"
|
|
cp scripts/farm/hammer-farm.service /etc/systemd/system/hammer-farm.service
|
|
systemctl daemon-reload
|
|
|
|
echo "✓ worker provisionado."
|
|
echo " arrancar: systemctl enable --now hammer-farm"
|
|
echo " logs: journalctl -u hammer-farm -f"
|