Build server: wait-<pid> file while a build queues for a slot; Caddy serves the dashboard's two JSON files at build.igneum.network
remote-run.sh writes /srv/builds/_locks/wait-<pid> in the slot-file line format while it waits and removes it when the slot is taken or the wait is given up (shown: present during a held slot, gone after). provision.sh installs Caddy with a Caddyfile that serves only /srv/workers/workers.json and headline.json (every other path 404, CORS for dl.igneum.network, no-store, Let's Encrypt only) and opens 80 and 443. Both asked for by the worker-dashboard agent, approved by main. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
aed5ca9bd7
commit
d9e580d3bd
2 changed files with 46 additions and 3 deletions
|
|
@ -32,6 +32,7 @@
|
|||
# chain) listens on the same 26611 (infra/cloud-devnet/config.sh P2P_PORT=26611). RPC ports
|
||||
# (26610, 28610, 26790 and the 268xx set) stay on loopback as on every seed, so they are not opened.
|
||||
# BOX_HOSTNAME igneum-build-1
|
||||
# WORKERS_HOST build.igneum.network Caddy serves /srv/workers/{workers,headline}.json there (read-only, all else 404)
|
||||
# SSH_PUBKEY (unset) a public key line for the build user when root has no authorized_keys (installimage installs it)
|
||||
#
|
||||
# Mirrors: the Mac pushes to them (never a clone from GitHub; the fork vendor/igneum-node exists only on the Mac):
|
||||
|
|
@ -54,6 +55,7 @@ WORKTREES="${WORKTREES:-}"
|
|||
SLOTS="${SLOTS:-1}"
|
||||
P2P_PORTS="${P2P_PORTS:-26611 26811}"
|
||||
BOX_HOSTNAME="${BOX_HOSTNAME:-igneum-build-1}"
|
||||
WORKERS_HOST="${WORKERS_HOST:-build.igneum.network}" # the dashboard feed's HTTPS name (A record in deSEC, 6 Oct 2026)
|
||||
SSH_PUBKEY="${SSH_PUBKEY:-}"
|
||||
BUILD_USER=build
|
||||
BUILD_HOME=/home/$BUILD_USER
|
||||
|
|
@ -122,7 +124,7 @@ step_os_check() {
|
|||
APT_PACKAGES=(
|
||||
build-essential clang lld llvm libclang-dev pkg-config libssl-dev cmake protobuf-compiler
|
||||
gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-x86-64-dev mingw-w64-tools
|
||||
git tmux curl ca-certificates xz-utils zstd unzip rsync jq python3 ufw htop file
|
||||
git tmux curl ca-certificates xz-utils zstd unzip rsync jq python3 ufw htop file caddy
|
||||
)
|
||||
step_apt() {
|
||||
local need=() p
|
||||
|
|
@ -337,17 +339,49 @@ EOF
|
|||
changed sshd "key-only, root prohibit-password"
|
||||
}
|
||||
|
||||
# the worker dashboard's feed (asked for on 6 October 2026, approved by main): Caddy serves exactly two files of /srv/workers
|
||||
# over HTTPS at build.igneum.network (A record in deSEC, set by main), read-only, no directory listing, every other path 404,
|
||||
# CORS for dl.igneum.network, no caching. Nothing under /srv/workers is a secret (workers.json and headline.json are written
|
||||
# by the dashboard collector and remote-run.sh); the Caddyfile refuses every other file name anyway. Issuer pinned to Let's
|
||||
# Encrypt: Ubuntu's Caddy 2.6.2 fails the ZeroSSL fallback (HTTP 422 caddy_legacy_user_removed, 6 Oct 2026) and would retry it for ever.
|
||||
step_caddy() {
|
||||
local f=/etc/caddy/Caddyfile tmp
|
||||
command -v caddy >/dev/null 2>&1 || die "caddy is not installed (apt)"
|
||||
install -d -m 755 -o "$BUILD_USER" -g "$BUILD_USER" /srv/workers
|
||||
tmp=$(mktemp)
|
||||
cat > "$tmp" <<EOF
|
||||
# igneum-build-1 (infra/build-server/provision.sh): the worker dashboard's two JSON files, nothing else
|
||||
$WORKERS_HOST {
|
||||
tls {
|
||||
issuer acme
|
||||
}
|
||||
root * /srv/workers
|
||||
header Access-Control-Allow-Origin https://dl.igneum.network
|
||||
header Cache-Control "no-store"
|
||||
@notjson not path /workers.json /headline.json
|
||||
respond @notjson 404
|
||||
file_server
|
||||
}
|
||||
EOF
|
||||
if [ -f "$f" ] && cmp -s "$tmp" "$f"; then rm -f "$tmp"; systemctl is-active --quiet caddy || systemctl start caddy; ok caddy "$WORKERS_HOST"; return; fi
|
||||
caddy validate --config "$tmp" --adapter caddyfile >/dev/null 2>&1 || { rm -f "$tmp"; die "caddy validate rejected the Caddyfile"; }
|
||||
install -m 644 "$tmp" "$f"; rm -f "$tmp"
|
||||
systemctl enable --quiet caddy 2>/dev/null || true
|
||||
systemctl reload caddy 2>/dev/null || systemctl restart caddy
|
||||
changed caddy "$WORKERS_HOST serving /srv/workers/{workers,headline}.json"
|
||||
}
|
||||
|
||||
step_ufw() {
|
||||
local p want=() any=0 status
|
||||
status=$(ufw status verbose 2>/dev/null || true)
|
||||
grep -q 'Default: deny (incoming), allow (outgoing)' <<<"$status" || { ufw --force default deny incoming >/dev/null; ufw --force default allow outgoing >/dev/null; any=1; }
|
||||
want=(22)
|
||||
want=(22 80 443)
|
||||
for p in $P2P_PORTS; do want+=("$p"); done
|
||||
for p in "${want[@]}"; do
|
||||
grep -qE "^$p/tcp +ALLOW IN +Anywhere *$" <<<"$status" || { ufw allow "$p/tcp" >/dev/null; any=1; }
|
||||
done
|
||||
grep -q '^Status: active' <<<"$status" || { ufw --force enable >/dev/null; any=1; }
|
||||
[ "$any" = 1 ] && changed ufw "22 and ${P2P_PORTS} open, everything else denied" || ok ufw "22 and ${P2P_PORTS}"
|
||||
[ "$any" = 1 ] && changed ufw "22, 80, 443 and ${P2P_PORTS} open, everything else denied" || ok ufw "22, 80, 443 and ${P2P_PORTS}"
|
||||
}
|
||||
|
||||
step_summary() {
|
||||
|
|
@ -364,6 +398,7 @@ step_summary() {
|
|||
printf 'mirrors: /srv/igneum.git (%s) /srv/igneum-node.git (%s)\n' "$(as_build 'git -C /srv/igneum.git branch --list | wc -l') branches" "$(as_build 'git -C /srv/igneum-node.git branch --list | wc -l') branches"
|
||||
printf 'builds: %s worktree dirs under /srv/builds, %s slot(s)\n' "$(worktree_count)" "$(cat /srv/builds/_locks/slots)"
|
||||
printf 'ufw: %s\n' "$(ufw status | grep -E 'ALLOW' | awk '{ print $1 }' | tr '\n' ' ')"
|
||||
printf 'caddy: %s, %s\n' "$(caddy version 2>/dev/null | cut -d' ' -f1)" "$(systemctl is-active caddy 2>/dev/null) at https://$WORKERS_HOST/headline.json"
|
||||
printf 'ssh line: ssh -i ~/.ssh/igneum_ed25519 build@%s\n' "$(hostname -I 2>/dev/null | awk '{ print $1 }')"
|
||||
} | sed 's/^/ /'
|
||||
}
|
||||
|
|
@ -385,6 +420,7 @@ do_provision() {
|
|||
step_profile
|
||||
step_node
|
||||
step_sshd
|
||||
step_caddy
|
||||
step_ufw
|
||||
step_summary
|
||||
log "done"
|
||||
|
|
|
|||
|
|
@ -81,12 +81,19 @@ for k in $(seq 0 $((slots - 1))); do
|
|||
done
|
||||
if [ -z "$got" ]; then
|
||||
echo "build-remote: all $slots slot(s) busy, waiting (up to 2 h) for build-0: $(head -c 160 "$IGNEUM_BUILD_SLOTS_DIR/build-0" 2>/dev/null)" >&2
|
||||
# the queue is visible while it waits (the worker dashboard reads wait-* files; asked for on 6 October 2026): the same line
|
||||
# format as a slot file, removed the moment the slot is taken or the wait is given up
|
||||
waitfile="$IGNEUM_BUILD_SLOTS_DIR/wait-$BR_PID"
|
||||
printf 'pid %s since %sZ waited 0 s: %s\n' "$BR_PID" "$(date -u +%H:%M:%S)" "$BR_LABEL" > "$waitfile"
|
||||
trap 'rm -f "$waitfile"' EXIT
|
||||
exec {fd}>"$IGNEUM_BUILD_SLOTS_DIR/build-0"
|
||||
if ! flock -w 7200 "$fd"; then
|
||||
echo "build-remote: gave up waiting for a slot after 2 h" >&2
|
||||
jsonlog 75 0 $(( $(date +%s) - BR_T0 )) "" "$(date +%s)" "" "" "" "" "" ""
|
||||
rm -f "$waitfile"
|
||||
exit 75
|
||||
fi
|
||||
rm -f "$waitfile"; trap - EXIT
|
||||
got=0
|
||||
fi
|
||||
waited=$(( $(date +%s) - BR_T0 ))
|
||||
|
|
|
|||
Loading…
Reference in a new issue