|
All checks were successful
PR build (required check) / changes (pull_request) Successful in 16s
secrets-guard / encrypted (pull_request) Successful in 15s
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / build-backend (pull_request) Successful in 1m2s
PR build (required check) / gate (pull_request) Successful in 3s
Handoff for the Iceberg worker: the contract iceberg.sh must satisfy (same interface shape as dbq.sh, read-only enforced by the system, no new network endpoints, call-time container resolution), the environment constraints that will otherwise bite -- prod's Swarm overlay is unroutable from its own host so tunnels are impossible, Contabo object storage requires path-style addressing, the backups/ prefix is live, and beta's /etc/thermograph.env is unreadable by the deploy user -- plus the decisions to report back, acceptance criteria with a demonstrated refused write, and anti-goals. |
||
|---|---|---|
| .. | ||
| dbq.sh | ||
| ICEBERG-HANDOFF.md | ||
| README.md | ||
ops/ — operator + agent query tooling
Read-only query access to Thermograph data, uniform across environments.
dbq.sh — Postgres, any environment
infra/ops/dbq.sh dev "select count(*) from climate_history"
infra/ops/dbq.sh prod -tA -c "select max(date) from climate_history"
infra/ops/dbq.sh beta -c '\dt'
echo "select 1" | infra/ops/dbq.sh prod -f -
Environments: dev (LAN compose stack on the dev machine), beta
(75.119.132.91), prod (169.58.46.181). Extra args pass straight through to
psql (-tA, -x, --csv, -f, …); stdin is forwarded.
Why it execs into the container instead of using a connection string
None of the databases are exposed over TCP — each listens only on its private
docker network. Prod's is a Swarm overlay (10.0.2.0/24) that the host
cannot route to, so ssh -L works for beta but is impossible for prod;
publishing 5432 would mean new ufw rules plus a Swarm endpoint change on
production. Running psql inside the db container works identically in all
three environments with no ports, no tunnels, and no infra changes.
The prod container name is a Swarm task name that changes on every redeploy, so
it is resolved at call time via docker ps --filter name=…, never hardcoded.
Safety
Queries connect as thermograph_ro — a NOSUPERUSER role granted only
pg_read_all_data. Read-only is enforced by Postgres, not by convention:
$ infra/ops/dbq.sh prod -c "create table t(i int)"
ERROR: permission denied for schema public
The app's own thermograph role is a superuser and is deliberately not used
by this tool. If the role is ever missing (fresh database), recreate it with:
CREATE ROLE thermograph_ro LOGIN;
GRANT CONNECT ON DATABASE thermograph TO thermograph_ro;
GRANT pg_read_all_data TO thermograph_ro;
Iceberg (planned)
Implementation spec: ICEBERG-HANDOFF.md — the
contract, environment constraints, acceptance criteria and anti-goals for the
Iceberg worker.
Iceberg lands as a sibling in this directory following the same three conventions, so the query surface stays uniform:
- Env-keyed dispatch —
iceberg.sh <dev|beta|prod> "<sql>", same argument shape asdbq.sh. - Run the engine where the data is reachable — the catalog/warehouse dictates it (a Trino/DuckDB/pyiceberg invocation, containerised the same way), rather than exposing new network endpoints.
- A dedicated read-only identity — the Iceberg equivalent of
thermograph_ro, so the same "read-only enforced by the system, not by convention" property holds.