#!/bin/bash # Read the harness registry and derive per-harness credentials from it. # # Source it — the whole point is exporting into the caller's environment, which a subshell # would lose: # # HARNESS_SCRIPTS_DIR=/workspace/scripts . /workspace/scripts/lib/harness-credentials.sh # harness_setup_credentials # # Two callers: `harbor-run`, which needs only this, and `setup-harnesses.sh`, which sources # it and adds installs, config writing and launchers on top. # # No -e here — this file is SOURCED, and shell options belong to the caller's shell (both # post-creates run with -e). An unguarded failure below therefore aborts container # creation, which is why every failure site is individually guarded rather than relying on # this line. set -uo pipefail _HARNESS_REGISTRY_DIR="${HARNESS_SCRIPTS_DIR:-/workspace/scripts}" # The registry is read with tomllib (stdlib from 3.11), and `python3` is not always new # enough — macOS ships 3.9, and a container may symlink an older managed interpreter. Pick # the first one that can actually import it rather than assuming. _raccoon_python() { local p for p in "${RACCOON_PYTHON:-}" python3 python3.13 python3.12 python3.11; do [ -n "$p" ] || continue command -v "$p" >/dev/null 2>&1 || continue if "$p" -c "import tomllib" >/dev/null 2>&1; then printf '%s' "$p" return 0 fi done return 1 } _harness_query() { local py py=$(_raccoon_python) || return 1 "$py" "$_HARNESS_REGISTRY_DIR/resolve_harness.py" "$@" } # The proxy root: the worker's ANTHROPIC_BASE_URL minus its provider path. _harness_proxy_root() { local base_url="${ANTHROPIC_BASE_URL:-}" [ -n "$base_url" ] || return 1 base_url="${base_url%"${base_url##*[!/]}"}" # ".../api/llm_proxy/raccoon" -> ".../api/llm_proxy". Requires a path to strip: a base # URL that is a bare host with no path — a provider's own API root rather than the # proxy — would yield "https:/", handed to codex as a base URL and failing obscurely. case "${base_url#*://}" in */*) printf '%s' "${base_url%/*}" ;; *) return 2 ;; esac } harness_setup_credentials() { # `|| rc=$?` and not a bare assignment: this is sourced into a `set -e` shell (see the # note at the top), and a bare failing assignment would exit the caller's post-create # outright — silently, since the failure paths below are what do the explaining. local root rc=0 root="$(_harness_proxy_root)" || rc=$? if [ "$rc" -ne 0 ]; then if [ "$rc" -eq 2 ]; then echo "harness-setup: ANTHROPIC_BASE_URL (${ANTHROPIC_BASE_URL:-}) has no provider" >&2 echo "harness-setup: path, so it is not the proxy URL other harnesses derive their" >&2 echo "harness-setup: credentials from. claude will work; codex will not be" >&2 echo "harness-setup: authenticated. Use the base URL you were given." >&2 else echo "harness-setup: ANTHROPIC_BASE_URL unset — skipping credential derivation" >&2 fi return 0 fi local key="${ANTHROPIC_API_KEY:-}" if [ -z "$key" ]; then echo "harness-setup: ANTHROPIC_API_KEY unset — skipping credential derivation" >&2 return 0 fi local id key_env base_url_env proxy_path while IFS=$'\t' read -r id key_env base_url_env proxy_path; do [ -n "$key_env" ] || continue # ${!name} is an indirect expansion. Only set when empty: an explicit key wins. if [ -z "${!key_env:-}" ]; then export "$key_env=$key" fi if [ -n "$base_url_env" ] && [ -n "$proxy_path" ] && [ -z "${!base_url_env:-}" ]; then export "$base_url_env=$root/$proxy_path" fi echo "harness-setup: $id credentials ready ($key_env, ${base_url_env:-no base url})" >&2 done < <(_harness_query --authoring-credentials 2>/dev/null || true) }