RPM Tracker
RPM tracker owns the rpm_tracker schema in the shared events PostgreSQL
database. It stores upstream state and packaged version status for the dashboard
to read. See the system proposal for the collection and UI design.
Features
- Independent Alembic migration chain with an initializer and revision gate.
- Transactional replacement of the current inventory with a generation check.
- Read-only dashboard access to tracker data in the shared database.
Prerequisites
Python 3.11 or newer and access to the shared PostgreSQL events database.
The migration user needs permission to create the rpm_tracker schema.
Installation
cd rpm-tracker
pip install -e .
DATABASE_URL=postgresql://postgres@localhost:5432/events python -m rpm_tracker.init_db
The Alembic chain uses rpm_tracker.alembic_version, separate from other
services’ migration histories and outside public. The migration files are
bundled in the installed rpm_tracker package. The initializer creates the
schema and applies pending migrations on each invocation; it is a no-op at
the current revision. Run it before deploying the dashboard API, and run it as
an init step before the future collector starts. A failed migration must prevent
collection. The dashboard read endpoint returns HTTP 503 until a migrated
schema compatible with its response model is available. Later tracker revisions
remain readable when they preserve the fields used by the dashboard.
Usage
Create a SQLAlchemy engine with rpm_tracker.db.get_engine() for the storage
module, and dispose of it when collection finishes. The tracker-owned ORM
models mirror the Alembic tables; only the initializer migrates them. Call
store.get_generation(engine) before collecting; both it and
store.ingest(engine, request) require the bundled schema revision. Fetch the
complete RPM checkout and every required monitor release page before calling
ingest() with one status per package and the checked checkout SHA. A failed
fetch must not submit a partial inventory. ingest() locks the singleton sync
row, checks the expected generation, and replaces upstream and status rows in
one transaction. A failed write or conflicting generation leaves the previous
inventory unchanged. Stored rollout times are separate from inventory
replacement. The dashboard exposes GET /api/rpm-upstream-state to read the
sync, upstream, status, and rollout tables in one read-only snapshot; it does
not migrate or write tracker tables. The collector and OpenShift CronJob are
subsequent parts of the proposal.
Configuration
| Variable | Description |
|---|---|
DATABASE_URL |
Shared events PostgreSQL connection URL |
POSTGRES_URL |
Connection URL fallback for the initializer |
Development
cd rpm-tracker
pip install -e '.[dev]'
pytest
To run the PostgreSQL migration and atomic replacement tests, set
DATABASE_URL to a disposable PostgreSQL database before running the tracker
and dashboard tests. CI supplies test_events; the database-backed tests are
skipped when DATABASE_URL is unset. The tracker tests refuse to replace an
existing nonempty tracker inventory.
License
This project is licensed under the GNU General Public License v3.0 or later. See the LICENSE.