diff --git a/infra/build-server/forgejo.sh b/infra/build-server/forgejo.sh new file mode 100644 index 00000000..06f7b2be --- /dev/null +++ b/infra/build-server/forgejo.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash +# The git host (main, 7 October 2026 20:29 BST; GitHub suspended): Forgejo 9 under docker on build-1, data under /srv/git (config +# app.ini written once with generated secrets, kept on the box only), ssh on 2222 public, http 3000 on loopback behind Caddy at +# git.igneum.network (ACME), deSEC A record by hand (dns.sh pattern). Then, by hand through the API as the owner user igneum-labs +# (credentials in ~/.config/igneum/forgejo-admin on the Mac): org igneum-network, private repos igneum and spec, the Mac key on the +# owner; registration off, anonymous read off, push-to-create off. Nightly dump to build-2 by /usr/local/bin/forgejo-backup.sh +# (forgejo-backup.timer 03:30 UTC). Runs as root on the box: scp it over and run it. Idempotent. +set -euo pipefail +mkdir -p /srv/git/data /srv/git/config +chown -R 1000:1000 /srv/git +if [ ! -s /srv/git/config/app.ini ]; then +SECRET=$(head -c 48 /dev/urandom | base64 | tr -d '/+=' | head -c 48) +JWT=$(head -c 48 /dev/urandom | base64 | tr -d '/+=' | head -c 48) +LFSJWT=$(head -c 48 /dev/urandom | base64 | tr -d '/+=' | head -c 48) +cat > /srv/git/config/app.ini </dev/null +fi +ufw allow 2222/tcp >/dev/null +if ! grep -q "^git.igneum.network" /etc/caddy/Caddyfile; then +cat >> /etc/caddy/Caddyfile <<'CADDY' + +# the git host (Forgejo in docker, infra/build-server/forgejo.sh): everything proxied, nothing cached +git.igneum.network { + tls { + issuer acme + } + reverse_proxy 127.0.0.1:3000 + request_body { + max_size 2GB + } +} +CADDY +caddy fmt --overwrite /etc/caddy/Caddyfile >/dev/null 2>&1 || true +systemctl reload caddy +fi +for i in $(seq 1 30); do curl -fsS -o /dev/null http://127.0.0.1:3000/ 2>/dev/null && break; sleep 2; done +echo "forgejo container: $(docker ps --format '{{.Names}} {{.Status}}' | grep forgejo)" +echo "http 3000: $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/)" +echo "ssh 2222: $(timeout 5 bash -c 'exec 3<>/dev/tcp/127.0.0.1/2222; head -c 40 <&3' 2>/dev/null | tr -d '\r\n' | cut -c1-40)" diff --git a/infra/build-server/remote-run.sh b/infra/build-server/remote-run.sh index 7cc7ba43..dadb4654 100755 --- a/infra/build-server/remote-run.sh +++ b/infra/build-server/remote-run.sh @@ -480,18 +480,27 @@ BR_RUN_LOG="$RUN_LOG_DIR/$BR_HOST-$BR_T0-$BR_PID.log"; export BR_RUN_LOG # (nice 0, a gate or a release build) is outside the pool and keeps the full set. ncpu=$(nproc); cores_str="0-$((ncpu - 1))" pool_fds=(); pool_cores=() +# the pool's priority classes (lease.sh, main 7 Oct 2026 20:37 BST: release > v5 > measure > adv): a bounded build or suite is class +# release (rank 0) unless its label names a "v5 gate" or "v5 kit" (class v5, rank 1); the wait file carries "class /:" so +# `lease pool` sweeps (class adv) yield to it, and it yields while a higher class waits (nothing outranks release) +pool_class() { case "$BR_LABEL" in *"v5 gate"*|*"v5 kit"*) echo "v5/1" ;; *) echo "release/0" ;; esac; } pool_take() { # : lease up to free pool cores, at least , waiting up to 2 h; sets pool_cores/pool_fds - local want="$1" min="$2" t0 c fd taken + local want="$1" min="$2" t0 c fd taken cls rank higher + cls=$(pool_class); rank=${cls#*/} t0=$(date +%s) while :; do taken=0; pool_fds=(); pool_cores=() - for ((c = ${BR_POOL_RESERVE:-8}; c < ncpu && taken < want; c++)); do - exec {fd}>>"$SLOTS_DIR/core-$c" - if flock -n "$fd"; then pool_fds+=("$fd"); pool_cores+=("$c"); taken=$((taken + 1)); else exec {fd}>&-; fi - done - if [ "$taken" -ge "$min" ]; then return 0; fi - for fd in "${pool_fds[@]}"; do exec {fd}>&-; done; pool_fds=(); pool_cores=() - [ -f "$waitfile" ] || { echo "build-remote: the bounded pool has $taken free core(s) (want $want, at least $min): waiting for the pool" >&2; holder_line "$(( $(date +%s) - BR_T0 ))" > "$waitfile"; } + higher=$(cat "$SLOTS_DIR"/wait-* 2>/dev/null | grep -v "^pid $BR_PID " | sed -n 's/.* class [a-z0-9]*\/\([0-9]\):.*/\1/p' | awk -v r="$rank" '$1 < r' | head -1) + if [ -z "$higher" ]; then + for ((c = ${BR_POOL_RESERVE:-8}; c < ncpu && taken < want; c++)); do + exec {fd}>>"$SLOTS_DIR/core-$c" + if flock -n "$fd"; then pool_fds+=("$fd"); pool_cores+=("$c"); taken=$((taken + 1)); else exec {fd}>&-; fi + done + if [ "$taken" -ge "$min" ]; then return 0; fi + for fd in "${pool_fds[@]}"; do exec {fd}>&-; done; pool_fds=(); pool_cores=() + fi + [ -f "$waitfile" ] || { echo "build-remote: the bounded pool has $taken free core(s) (want $want, at least $min, class ${cls%/*}): waiting for the pool" >&2; } + printf '%s class %s: pool\n' "$(holder_line "$(( $(date +%s) - BR_T0 ))")" "$cls" > "$waitfile" [ $(( $(date +%s) - t0 )) -lt 7200 ] || give_up "the bounded pool" sleep 10 done