API reference
A small, pragmatic surface. The management endpoints below sit next to the Galaxy V1 & V3 serving endpoints on the same TCP tree, so one instance is both control plane and one of the best-behaved Galaxy mirrors your playbooks have talked to.
Serving endpoints (the Galaxy half)
Galaxy V1 API โ the surface ansible-galaxy talks to. No client changes needed.
Galaxy V3 API โ collection indexes and artifact downloads, as served by Galaxy.
Point your clients here and requirement installs resolve against the mirror. Theansible.cfg below is the entire client story:
[galaxy]
server_list = orbitron
[galaxy_server.orbitron]
url = https://orbitron.internal/api/
# token = YOUR_ORBITRON_TOKEN # if require_auth_pull is enabledManagement endpoints
Unauthenticated liveness โ 200 when the storage path is writable, 503 when degraded.
Ingest role & collection YAML manifests. Content-addressed by SHA-256, mirrored by parallel workers.
Re-run every stored manifest, or poll progress and a bounded history of finished syncs.
Lists every stored requirements manifest, grouped by type, with the content sha256 used for idempotent ingestion.
Full cached-version inventory. DELETE /storage/{type}/{name}/{version} purges a single cached version.
Access-based cleanup with retention window โ preview with {"dry_run": true}, nothing is deleted.
Token lifecycle: create, list, revoke and rotate admin tokens, with optional per-token TTLs.
Streams the entire cache as a gzip tar archive, with a per-file SHA-256 manifest. Never includes the token store.
Prometheus exposition โ uptime, cache counts, version totals and storage bytes.
Every endpoint above except /healthz requires a Bearer token or HTTP Basic auth.
Examples
curl -i http://127.0.0.1:8080/healthz
HTTP/1.1 200 OKcurl http://127.0.0.1:8080/api/v1/manifests \
-H "Authorization: Bearer $ORBITRON_TOKEN"
{
"roles": [{"file": "roles_x_requirements.yml", "sha256": "737690a6..."}],
"collections": []
}curl http://127.0.0.1:8080/api/v1/storage \
-H "Authorization: Bearer $ORBITRON_TOKEN"
{
"roles": [
{"type": "role", "name": "geerlingguy.nginx",
"versions": [{"version": "1.2.3", "declared": true, "size_bytes": 20480}]}
],
"collections": []
}curl -X POST http://127.0.0.1:8080/api/v1/prune \
-H "Authorization: Bearer $ORBITRON_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dry_run": true, "days": 90}'
{
"items": ["/var/lib/orbitron/storage/roles/geerlingguy.nginx/2.0.1"],
"freed_bytes": 40960,
"executed": false
}curl http://127.0.0.1:8080/api/v1/dump \
-H "Authorization: Bearer $ORBITRON_TOKEN" \
-o orbitron-backup.tar.gz
# ?compress=fast trades compression ratio for CPU time
tar -xzf orbitron-backup.tar.gz -C /var/lib/orbitron/storage --strip-components=1Backing up a whole mirror
/api/v1/dump is the one call for an offline backup. It walks the whole storage directory and streams a gzip tar archive rooted at orbitron/ โ every role directory, every collection .tar.gz, git-sourced collection checkouts, the stored requirements manifests and the access index.
Written as the last entry. Carries the daemon version, a UTC timestamp, the cache inventory, the excluded paths and a SHA-256 per file. Its absence is the signal that a transfer was cut short.
The token store โ both the configured
tokens_filewhen it lives inside the storage path and<storage>/tokens.jsonโ plus temp files and anything that is not a regular file. A content backup never carries credentials into an offline vault.runningoridleat request time. No snapshot lock is taken, so dumping during a sync yields a consistent set of files but not a globally consistent one; the per-file checksums make a torn dump detectable.
There is no Content-Length โ a backup job cannot resume a half-finished download. Every valid token may dump: treat a token as read access to the whole cache.
The same thing from Ansible, where the archive is streamed to the controller and verified:
- name: Back up the Orbitron cache
chrisvanmeer.orbitron.orbitron_dump:
url: http://127.0.0.1:8080
token: "{{ vault_orbitron_admin_token }}"
dest: /var/backups/orbitron/nightly.tar.gz
read_timeout: 1800
register: dump