feat: add local RPM repository with on-demand repodata #53

Merged
benvin merged 1 commits from benvin/local-rpm into master 2026-06-23 23:20:05 +10:00
Owner

Summary

  • Upload RPMs to local repos, metadata parsed async via cavaliergopher/rpm
  • Repodata (repomd.xml, primary/filelists/other.xml.gz) generated on-demand from DB — nothing stored in S3
  • RPM provider implements LocalUploader, PostUploadHook, and LocalIndexer
  • New rpm_metadata table for parsed RPM header data (name, version, deps, etc.)
  • New provider interfaces: PostUploadHook, BlobReader, MetadataStore, RPMMetadataReader

Test plan

  • Upload cowsay RPM from epel → async metadata parse confirmed in logs
  • repomd.xml generated with correct hashes → primary.xml.gz has correct metadata
  • dnf install from local repo: download + install successful
  • Bad file rejection (.txt → 400), overwrite rejection (409)
## Summary - Upload RPMs to local repos, metadata parsed async via cavaliergopher/rpm - Repodata (repomd.xml, primary/filelists/other.xml.gz) generated on-demand from DB — nothing stored in S3 - RPM provider implements LocalUploader, PostUploadHook, and LocalIndexer - New rpm_metadata table for parsed RPM header data (name, version, deps, etc.) - New provider interfaces: PostUploadHook, BlobReader, MetadataStore, RPMMetadataReader ## Test plan - [x] Upload cowsay RPM from epel → async metadata parse confirmed in logs - [x] repomd.xml generated with correct hashes → primary.xml.gz has correct metadata - [x] `dnf install` from local repo: download + install successful - [x] Bad file rejection (.txt → 400), overwrite rejection (409)
unkinben added 1 commit 2026-06-23 23:14:29 +10:00
feat: add local RPM repository with on-demand repodata
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
72a07663e7
Upload RPMs to local repos. Metadata is parsed async after upload
using cavaliergopher/rpm and stored in rpm_metadata table. Repodata
(repomd.xml, primary.xml.gz, filelists.xml.gz, other.xml.gz) is
generated on-demand from the DB — nothing stored in S3.

- RPM provider implements LocalUploader (validates .rpm extension,
  stores under Packages/)
- RPM provider implements PostUploadHook (async goroutine parses RPM
  headers, extracts name/version/arch/deps/etc into rpm_metadata)
- RPM provider implements LocalIndexer (serves repodata/* paths by
  querying rpm_metadata and generating XML on the fly)
- New provider interfaces: PostUploadHook, BlobReader, MetadataStore,
  RPMMetadataReader
- New rpm_metadata table with JSONB columns for requires/provides/
  files/changelogs

Tested e2e: upload cowsay RPM → repodata generated → dnf install
from local repo
unkinben force-pushed benvin/local-rpm from bb172276ba to 72a07663e7 2026-06-23 23:14:29 +10:00 Compare
benvin merged commit 6f8e70c27a into master 2026-06-23 23:20:05 +10:00
benvin deleted branch benvin/local-rpm 2026-06-23 23:20:05 +10:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/artifactapi#53