Commit 2e8cc27
benchmarks-website: systemd-based v3 deploy + admin endpoints
Replaces the ad-hoc SSH-and-`nohup` deploy of the v3 benchmarks site
with a systemd timer that polls origin/develop every 60s, builds and
atomically swaps the binary, and verifies /health. Adds an hourly
gzipped-snapshot timer and two server-side admin endpoints so backups
and ad-hoc reads no longer need to stop the server.
Two new routes mounted only when ADMIN_BEARER_TOKEN is set:
- POST /api/admin/snapshot?ts=<id>: runs `EXPORT DATABASE … (FORMAT
csv)` against the live DuckDB connection, into a fresh subdirectory
under AppState::snapshot_dir. ts must match [A-Za-z0-9_-]{1,64}.
CSV is the only EXPORT format that ships with libduckdb-sys's
`bundled` feature; flipping to parquet or a Vortex layout later is
a one-line change.
- POST /api/admin/sql {sql, ?format=json|table}: runs read-only SQL
(SELECT/WITH/PRAGMA/SHOW/DESCRIBE/EXPLAIN, anything else 403) and
renders either JSON or a duckdb-cli-style ASCII table. Uses the
same connection mutex as ingest, so a slow SELECT briefly delays
writes.
Auth is independent of the ingest token (separate ADMIN_BEARER_TOKEN
env var) so the two rotate separately. Both use constant-time eq.
Everything an EC2 host needs lives under benchmarks-website/ops/:
- install.sh: idempotent one-time bootstrap (state dirs under
/var/lib/vortex-bench, sudoers fragment, env-file template, systemd
units, enable + start the timers). Recommended first-time path is
"wait for the deploy timer to build, then run migrate.sh"; preserving
an existing $HOME/bench.duckdb is documented as a side note.
- deploy.sh: called by vortex-bench-deploy.timer every 60s. Cheap fast
path (sha == stamp → exit 0). Path filter on benchmarks-website/{server,
migrate}, Cargo.toml, Cargo.lock — vortex-array PRs fast-forward the
working tree but skip the rebuild. Atomic versioned-binary symlink
swap, sudo systemctl restart, /health verification with rollback to
previous binary on failure, stamp updated only on success so failures
retry on next tick. Keeps last KEEP_BINARIES (default 3) versions.
- migrate.sh: stops server, snapshots current DB to bench.prev-<ts>.duckdb,
passes args through to `cargo run -p vortex-bench-migrate --`, restarts.
- backup.sh: hourly. Calls /api/admin/snapshot, `tar czf`s the CSV
directory into <ts>.tar.gz (gzip reclaims ~5–7× on this shape since
most data lands in BIGINT[] runtime arrays serialised as text), uploads
with `aws s3 cp` to s3://vortex-ci-benchmark-results/v3-backups/, and
cleans up both local copies. Logs the compression ratio so a future
regression shows up in `journalctl -u vortex-bench-backup`.
- inspect.sh: thin wrapper around /api/admin/sql, no server stop.
- systemd/ units: server (Type=simple, Restart=on-failure, hardening
via ProtectSystem=strict), deploy oneshot + 60s timer, backup
oneshot + hourly timer (Persistent=true so a missed hour catches up
after reboot).
A symlink at /var/lib/vortex-bench/ops -> .../benchmarks-website/ops
keeps the systemd ExecStart paths stable as the repo location changes.
- ops/README.md: full operator runbook — first-time install, day-to-day
ops (push to develop → live in 60s, monitor a deploy, force a deploy,
re-run migration, ad-hoc SQL, backup/restore, token rotation), and
failure modes (deploy retry loop, /health stuck, disk filling up,
backup not running, host migration). Targeted at a fresh admin who
has never seen the system before.
- benchmarks-website/README.md, benchmarks-website/AGENTS.md: updated
to point at ops/ and to reflect the systemd-based deploy.
- server/src/{lib.rs, app.rs, main.rs, admin.rs}: module map, route
table, env-var list, and admin module doc all updated.
The previous v3 docker artifacts are removed:
- benchmarks-website/ec2-init.txt: replaced by ops/README.md.
- benchmarks-website/server/Dockerfile: v3 isn't containerised any more.
- benchmarks-website/server/scripts/backup.sh: replaced by ops/backup.sh.
The v2 React/Vite stack is untouched. docker-compose.yml is left in
place; its v3 service entry is now orphaned but harmless and the v2
service is unaffected.
server/tests/admin.rs (9 tests):
- SQL round-trip (JSON + ASCII table format)
- Read-only allow-list (DELETE/UPDATE/DROP/INSERT/CREATE/ATTACH → 403)
- Allowed verbs (PRAGMA/SHOW/DESCRIBE/EXPLAIN/WITH)
- Bearer enforcement: missing/wrong/ingest-token-on-admin → 401
- Admin router not mounted when ADMIN_BEARER_TOKEN unset → 404
- Snapshot creates the export dir + schema.sql
- Snapshot of an existing dir → 409
- ts validation: empty / "../oops" / "with space" / 65 chars → 400
cargo test -p vortex-bench-server passes (admin: 9, rest: 18 pre-existing).
cargo clippy -p vortex-bench-server --all-targets --all-features clean.
Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>1 parent 919e31e commit 2e8cc27
22 files changed
Lines changed: 2189 additions & 188 deletions
File tree
- benchmarks-website
- ops
- config
- systemd
- server
- scripts
- src
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
18 | | - | |
| 17 | + | |
19 | 18 | | |
20 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
21 | 23 | | |
22 | 24 | | |
23 | 25 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
13 | | - | |
14 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | | - | |
| 20 | + | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
89 | 99 | | |
90 | 100 | | |
91 | 101 | | |
| |||
97 | 107 | | |
98 | 108 | | |
99 | 109 | | |
100 | | - | |
101 | | - | |
| 110 | + | |
| 111 | + | |
102 | 112 | | |
103 | 113 | | |
104 | 114 | | |
105 | 115 | | |
106 | 116 | | |
107 | | - | |
108 | | - | |
109 | | - | |
| 117 | + | |
| 118 | + | |
This file was deleted.
0 commit comments