|
| 1 | +#!/usr/bin/env bash |
| 2 | +# SPDX-License-Identifier: Apache-2.0 |
| 3 | +# Gateway manifest: Busbar (main, unreleased). |
| 4 | +# |
| 5 | +# The current development head of Busbar, built from source on the box - a PREVIEW entrant so the |
| 6 | +# field always shows where the next release lands next to the shipped image. Same config and launch |
| 7 | +# as the released busbar manifest; only the provenance differs (git main vs Docker image). |
| 8 | +GW_KIND=native |
| 9 | +GW_DISPLAY="Busbar (main)" |
| 10 | +GW_CLASS="Control plane" |
| 11 | +GW_LANG=Rust |
| 12 | +GW_REPO=https://github.com/GetBusbar/busbar |
| 13 | +GW_PORT=8080 |
| 14 | +GW_ANTHROPIC_PATH=/v1/messages |
| 15 | +GW_PATH=/v1/chat/completions |
| 16 | +GW_MODEL=gpt-4o-mini |
| 17 | +GW_AUTH=bench-token |
| 18 | + |
| 19 | +gw_build() { |
| 20 | + if [ -z "${BUSBAR_BIN:-}" ]; then |
| 21 | + command -v cargo >/dev/null || { echo "[busbar-main] need a rust toolchain"; return 1; } |
| 22 | + if [ ! -d "$GW_DIR/src-main" ]; then |
| 23 | + git clone --depth 1 https://github.com/GetBusbar/busbar "$GW_DIR/src-main" >/dev/null 2>&1 \ |
| 24 | + || { echo "[busbar-main] clone failed"; return 1; } |
| 25 | + fi |
| 26 | + (cd "$GW_DIR/src-main" && cargo build --release -p busbar >/dev/null 2>&1) \ |
| 27 | + || { echo "[busbar-main] build failed"; return 1; } |
| 28 | + BUSBAR_BIN="$GW_DIR/src-main/target/release/busbar" |
| 29 | + fi |
| 30 | +} |
| 31 | +gw_version() { local v; v="$("$BUSBAR_BIN" --version 2>/dev/null | head -1)"; echo "${v:-main} (git main)"; } |
| 32 | + |
| 33 | +gw_launch() { |
| 34 | + cat > "$GW_DIR/config.gen.yaml" <<YAML |
| 35 | +listen: "127.0.0.1:$GW_PORT" |
| 36 | +observability: |
| 37 | + emit_server_timing: true |
| 38 | +auth: |
| 39 | + chain: [tokens] |
| 40 | + upstream_credentials: own |
| 41 | + client_tokens: |
| 42 | + - "bench-token" |
| 43 | +providers: |
| 44 | + mock: |
| 45 | + api_key_env: BENCH_MOCK_KEY |
| 46 | +models: |
| 47 | + gpt-4o-mini: |
| 48 | + # max_concurrent is a REQUIRED field in busbar's model config (no default; see the config schema), |
| 49 | + # so it must be set. 8000 is above the sweep's winning concurrency band so it's a ceiling, not the |
| 50 | + # limiter — the equivalent of running every other gateway on its defaults (unbounded), not a tuned |
| 51 | + # advantage. max_requests: -1 = unmetered. |
| 52 | + provider: mock |
| 53 | + max_concurrent: 8000 |
| 54 | + max_requests: -1 |
| 55 | +pools: |
| 56 | + bench-pool: |
| 57 | + members: |
| 58 | + - target: gpt-4o-mini |
| 59 | +YAML |
| 60 | + cat > "$GW_DIR/providers.gen.yaml" <<YAML |
| 61 | +mock: |
| 62 | + protocol: openai |
| 63 | + base_url: http://127.0.0.1:$MOCK_PORT |
| 64 | + error_map: {} |
| 65 | +YAML |
| 66 | + pkill -x busbar 2>/dev/null; sleep 1 |
| 67 | + setsid taskset -c "$CORES" env \ |
| 68 | + BUSBAR_WORKER_THREADS="$(( ${CORES##*-} + 1 ))" \ |
| 69 | + BUSBAR_PROVIDERS="$GW_DIR/providers.gen.yaml" \ |
| 70 | + BUSBAR_CONFIG="$GW_DIR/config.gen.yaml" \ |
| 71 | + BENCH_MOCK_KEY=x \ |
| 72 | + "$BUSBAR_BIN" </dev/null >/tmp/busbar.bench.log 2>&1 & |
| 73 | +} |
| 74 | + |
| 75 | +gw_rss() { awk '/VmRSS/{printf "%.1f", $2/1024}' "/proc/$(pgrep -x busbar)/status" 2>/dev/null; } |
| 76 | +gw_stop() { pkill -x busbar 2>/dev/null; } |
| 77 | + |
| 78 | +# ── governed lane (governed/run.sh) ──────────────────────────────────────────────────────────────── |
| 79 | +# Busbar's governance layer is always compiled in but INERT until governance.admin_token is set. |
| 80 | +# Setting it activates enforcement: static auth tokens are superseded and EVERY inference request |
| 81 | +# must resolve to a busbar-minted virtual key (per-request key resolution + RPM/TPM accounting + |
| 82 | +# an atomic budget check-and-charge on the hot path). gw_governed_launch writes the same config as |
| 83 | +# gw_launch plus the governance block, boots busbar, then mints one virtual key over the admin API |
| 84 | +# (POST /api/v1/admin/keys, x-admin-token auth). The key is minted with NO rpm/tpm/budget caps |
| 85 | +# (absent = unlimited) and no pool ACL (empty allowed_pools = all pools): at 40k+ rps nothing can |
| 86 | +# ever trip, so the lane measures the cost of the CHECK, not a limit. Store: memory (the default), |
| 87 | +# so per-run keys never leak into a durable store. |
| 88 | +BUSBAR_ADMIN_TOKEN="${BUSBAR_ADMIN_TOKEN:-bench-admin-token}" |
| 89 | +BUSBAR_VKEY="" |
| 90 | + |
| 91 | +gw_governed_launch() { |
| 92 | + # The admin plane always runs on its OWN listener (admin_listen, default loopback :8081), never |
| 93 | + # on the data listener — pin it explicitly so the mint below can't drift from a default change. |
| 94 | + BUSBAR_ADMIN_PORT=$(( GW_PORT + 1 )) |
| 95 | + cat > "$GW_DIR/config.gen.yaml" <<YAML |
| 96 | +listen: "127.0.0.1:$GW_PORT" |
| 97 | +admin_listen: "127.0.0.1:$BUSBAR_ADMIN_PORT" |
| 98 | +observability: |
| 99 | + emit_server_timing: true |
| 100 | +auth: |
| 101 | + chain: [tokens] |
| 102 | + upstream_credentials: own |
| 103 | + client_tokens: |
| 104 | + - "bench-token" |
| 105 | +governance: |
| 106 | + # store: memory is the default (ephemeral). admin_token ACTIVATES enforcement: |
| 107 | + # every request below must carry a minted virtual key, checked per request. |
| 108 | + admin_token: "$BUSBAR_ADMIN_TOKEN" |
| 109 | +providers: |
| 110 | + mock: |
| 111 | + api_key_env: BENCH_MOCK_KEY |
| 112 | +models: |
| 113 | + gpt-4o-mini: |
| 114 | + # Same rationale as gw_launch: max_concurrent is a required field; 8000 sits above the sweep's |
| 115 | + # winning band so it is a ceiling, not the limiter. max_requests: -1 = unmetered. |
| 116 | + provider: mock |
| 117 | + max_concurrent: 8000 |
| 118 | + max_requests: -1 |
| 119 | +pools: |
| 120 | + bench-pool: |
| 121 | + members: |
| 122 | + - target: gpt-4o-mini |
| 123 | +YAML |
| 124 | + cat > "$GW_DIR/providers.gen.yaml" <<YAML |
| 125 | +mock: |
| 126 | + protocol: openai |
| 127 | + base_url: http://127.0.0.1:$MOCK_PORT |
| 128 | + error_map: {} |
| 129 | +YAML |
| 130 | + pkill -x busbar 2>/dev/null; sleep 1 |
| 131 | + setsid taskset -c "$CORES" env \ |
| 132 | + BUSBAR_WORKER_THREADS="$(( ${CORES##*-} + 1 ))" \ |
| 133 | + BUSBAR_PROVIDERS="$GW_DIR/providers.gen.yaml" \ |
| 134 | + BUSBAR_CONFIG="$GW_DIR/config.gen.yaml" \ |
| 135 | + BENCH_MOCK_KEY=x \ |
| 136 | + "$BUSBAR_BIN" </dev/null >/tmp/busbar.governed.log 2>&1 & |
| 137 | + # Wait for the admin plane, then mint the run's virtual key. The secret (sk-bb-<32 hex>) is |
| 138 | + # returned exactly once in the 201 body; it becomes the bench bearer token. |
| 139 | + local i resp |
| 140 | + for i in $(seq 1 60); do |
| 141 | + resp="$(curl -s -m3 -X POST "http://127.0.0.1:$BUSBAR_ADMIN_PORT/api/v1/admin/keys" \ |
| 142 | + -H "x-admin-token: $BUSBAR_ADMIN_TOKEN" -H "content-type: application/json" \ |
| 143 | + -d '{"name":"governed-bench"}' 2>/dev/null)" |
| 144 | + BUSBAR_VKEY="$(printf '%s' "$resp" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("secret",""))' 2>/dev/null)" |
| 145 | + [ -n "$BUSBAR_VKEY" ] && return 0 |
| 146 | + sleep 1 |
| 147 | + done |
| 148 | + echo "[busbar] governed: never minted a key; last admin response: $(printf '%s' "${resp:-}" | head -c 300)" >&2 |
| 149 | + return 1 |
| 150 | +} |
| 151 | + |
| 152 | +gw_governed_token() { echo "$BUSBAR_VKEY"; } |
0 commit comments