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

  1. Independent Alembic migration chain with an initializer and revision gate.
  2. Transactional replacement of the current inventory with a generation check.
  3. 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.