cbcf122422
Haiku ops agent + 3 tools (nbshell expect+PTY admin-shell driver, nbapi read-only HTTP client, nb-substituters guarded cache manager) + 2 skills (nixbuild-settings, nixbuild-usage). Encodes the two-control-surface model and the path-style-substituter-URL gotcha.
92 lines
2.4 KiB
Bash
Executable File
92 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# nbapi — read-only client for nixbuild.net's HTTP API (https://api.nixbuild.net).
|
|
#
|
|
# This API is monitoring/reporting only: usage, builds, build summary. It does
|
|
# NOT expose account administration (settings/ssh-keys/tokens) — for those use
|
|
# `nbshell`. The account is metered ("no free build time left" once the monthly
|
|
# tier is spent), so usage/storage visibility is the point of this tool.
|
|
#
|
|
# Auth: Bearer token from $NIXBUILD_API_TOKEN, else `pass show <entry>`
|
|
# (entry from $NIXBUILD_API_TOKEN_PASS_ENTRY or default infra/nixbuild/api-token).
|
|
#
|
|
# Usage:
|
|
# nbapi usage [--from YYYY-MM-DD] [--to YYYY-MM-DD] # billable CPU-seconds + count
|
|
# nbapi summary # aggregated build metrics
|
|
# nbapi builds [--limit N] # recent build history
|
|
# nbapi raw <path> # GET any API path verbatim
|
|
#
|
|
# Output is JSON (pretty-printed via jq when available).
|
|
|
|
set -euo pipefail
|
|
|
|
BASE="https://api.nixbuild.net"
|
|
PASS_ENTRY="${NIXBUILD_API_TOKEN_PASS_ENTRY:-infra/nixbuild/api-token}"
|
|
|
|
token() {
|
|
if [ -n "${NIXBUILD_API_TOKEN:-}" ]; then
|
|
printf '%s' "$NIXBUILD_API_TOKEN"
|
|
elif command -v pass >/dev/null 2>&1; then
|
|
pass show "$PASS_ENTRY" 2>/dev/null | head -n1
|
|
else
|
|
echo "nbapi: no token (set NIXBUILD_API_TOKEN or install pass with $PASS_ENTRY)" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
get() {
|
|
local path="$1" tok
|
|
tok="$(token)" || exit 1
|
|
local out
|
|
out="$(curl -fsS -H "Authorization: Bearer ${tok}" "${BASE}${path}")" || {
|
|
echo "nbapi: request failed: GET ${path}" >&2
|
|
exit 1
|
|
}
|
|
if command -v jq >/dev/null 2>&1; then
|
|
printf '%s' "$out" | jq .
|
|
else
|
|
printf '%s\n' "$out"
|
|
fi
|
|
}
|
|
|
|
cmd="${1:-}"; shift || true
|
|
case "$cmd" in
|
|
usage)
|
|
from=""; to=""
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
--from) from="$2"; shift 2 ;;
|
|
--to) to="$2"; shift 2 ;;
|
|
*) echo "nbapi usage: unknown arg $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
q=""
|
|
[ -n "$from" ] && q="from=${from}"
|
|
[ -n "$to" ] && q="${q:+$q&}to=${to}"
|
|
get "/usage${q:+?$q}"
|
|
;;
|
|
summary)
|
|
get "/builds/summary"
|
|
;;
|
|
builds)
|
|
limit="20"
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
--limit) limit="$2"; shift 2 ;;
|
|
*) echo "nbapi builds: unknown arg $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
get "/builds?limit=${limit}"
|
|
;;
|
|
raw)
|
|
[ -n "${1:-}" ] || { echo "nbapi raw: need a path" >&2; exit 2; }
|
|
get "$1"
|
|
;;
|
|
""|-h|--help|help)
|
|
sed -n '2,20p' "$0"
|
|
;;
|
|
*)
|
|
echo "nbapi: unknown command '$cmd' (try: usage, summary, builds, raw)" >&2
|
|
exit 2
|
|
;;
|
|
esac
|