107 lines
4.6 KiB
SQL
107 lines
4.6 KiB
SQL
-- +goose Up
|
|
-- Initial Runtime Manager PostgreSQL schema.
|
|
--
|
|
-- Three tables cover the durable surface of the service:
|
|
-- * runtime_records — one row per game with the latest known runtime
|
|
-- status and Docker container binding;
|
|
-- * operation_log — append-only audit of every start/stop/restart/
|
|
-- patch/cleanup/reconcile_* operation RTM performed;
|
|
-- * health_snapshots — latest technical health observation per game.
|
|
--
|
|
-- Schema and the matching `rtmanagerservice` role are provisioned
|
|
-- outside this script (in tests via cmd/jetgen/main.go::provisionRoleAndSchema;
|
|
-- in production via an ops init script). This migration runs as the
|
|
-- schema owner with `search_path=rtmanager` and only contains DDL for the
|
|
-- service-owned tables and indexes. ARCHITECTURE.md §Database topology
|
|
-- mandates that the per-service role's grants stay restricted to its own
|
|
-- schema; consequently this file deliberately deviates from PLAN.md
|
|
-- Stage 09's literal `CREATE SCHEMA IF NOT EXISTS rtmanager;` instruction.
|
|
|
|
-- runtime_records holds one durable record per game with the latest
|
|
-- known runtime status and Docker container binding. The status enum
|
|
-- (running | stopped | removed) is enforced by a CHECK so domain code
|
|
-- can rely on it without reading every callsite. The (status, last_op_at)
|
|
-- index drives the periodic container-cleanup worker that scans
|
|
-- `status='stopped' AND last_op_at < now() - retention`.
|
|
CREATE TABLE runtime_records (
|
|
game_id text PRIMARY KEY,
|
|
status text NOT NULL,
|
|
current_container_id text,
|
|
current_image_ref text,
|
|
engine_endpoint text NOT NULL,
|
|
state_path text NOT NULL,
|
|
docker_network text NOT NULL,
|
|
started_at timestamptz,
|
|
stopped_at timestamptz,
|
|
removed_at timestamptz,
|
|
last_op_at timestamptz NOT NULL,
|
|
created_at timestamptz NOT NULL,
|
|
CONSTRAINT runtime_records_status_chk
|
|
CHECK (status IN ('running', 'stopped', 'removed'))
|
|
);
|
|
|
|
CREATE INDEX runtime_records_status_last_op_idx
|
|
ON runtime_records (status, last_op_at);
|
|
|
|
-- operation_log is an append-only audit of every operation Runtime
|
|
-- Manager performed against a game's runtime. The (game_id, started_at
|
|
-- DESC) index drives audit reads from the GM/Admin REST surface;
|
|
-- finished_at is nullable for in-flight rows even though Stage 13+
|
|
-- always finalises the row in the same transaction. The op_kind /
|
|
-- op_source / outcome enums are enforced by CHECK constraints to keep
|
|
-- the audit schema honest without a separate Go validator.
|
|
CREATE TABLE operation_log (
|
|
id bigserial PRIMARY KEY,
|
|
game_id text NOT NULL,
|
|
op_kind text NOT NULL,
|
|
op_source text NOT NULL,
|
|
source_ref text NOT NULL DEFAULT '',
|
|
image_ref text NOT NULL DEFAULT '',
|
|
container_id text NOT NULL DEFAULT '',
|
|
outcome text NOT NULL,
|
|
error_code text NOT NULL DEFAULT '',
|
|
error_message text NOT NULL DEFAULT '',
|
|
started_at timestamptz NOT NULL,
|
|
finished_at timestamptz,
|
|
CONSTRAINT operation_log_op_kind_chk
|
|
CHECK (op_kind IN (
|
|
'start', 'stop', 'restart', 'patch',
|
|
'cleanup_container', 'reconcile_adopt', 'reconcile_dispose'
|
|
)),
|
|
CONSTRAINT operation_log_op_source_chk
|
|
CHECK (op_source IN (
|
|
'lobby_stream', 'gm_rest', 'admin_rest',
|
|
'auto_ttl', 'auto_reconcile'
|
|
)),
|
|
CONSTRAINT operation_log_outcome_chk
|
|
CHECK (outcome IN ('success', 'failure'))
|
|
);
|
|
|
|
CREATE INDEX operation_log_game_started_idx
|
|
ON operation_log (game_id, started_at DESC);
|
|
|
|
-- health_snapshots stores the latest technical health observation per
|
|
-- game. One row per game; later observations overwrite. The status enum
|
|
-- mirrors the `event_type` vocabulary on `runtime:health_events`
|
|
-- (collapsed to a flat status column for the latest-observation view).
|
|
CREATE TABLE health_snapshots (
|
|
game_id text PRIMARY KEY,
|
|
container_id text NOT NULL DEFAULT '',
|
|
status text NOT NULL,
|
|
source text NOT NULL,
|
|
details jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
observed_at timestamptz NOT NULL,
|
|
CONSTRAINT health_snapshots_status_chk
|
|
CHECK (status IN (
|
|
'healthy', 'probe_failed', 'exited',
|
|
'oom', 'inspect_unhealthy', 'container_disappeared'
|
|
)),
|
|
CONSTRAINT health_snapshots_source_chk
|
|
CHECK (source IN ('docker_event', 'inspect', 'probe'))
|
|
);
|
|
|
|
-- +goose Down
|
|
DROP TABLE IF EXISTS health_snapshots;
|
|
DROP TABLE IF EXISTS operation_log;
|
|
DROP TABLE IF EXISTS runtime_records;
|