feat: github_deb metadata-only package type
Add the Debian/apt analog of github_rpm: a metadata-only remote that scans a GitHub repo's releases for .deb assets, derives per-asset control metadata via a ranged prefix fetch (never downloading whole packages), synthesizes a flat apt repository, and redirects .deb downloads to a backend releases_remote. - Add PackageGitHubDeb to the package-type enum + validity map. - Add the github_deb provider (internal/provider/deb/github.go): ServeRemote serves Packages/Packages.gz/Release, 404s the signed index variants (consumed via [trusted=yes]), and 302-redirects *.deb to the releases_remote; deriveAsset ranged-GETs the ar prefix, locates control.tar.*, and parses the control paragraph, doubling the range on truncation; sha256 comes from the asset digest when present, else a one-time full stream. - Add the github_deb background Syncer (internal/provider/deb/syncer.go): its own worker pool, shared rate limiter, deduped queue, and DB-lease-gated scans. - Add github_deb_sync_state table plus ListGitHubDebRemotes/Claim/Release DB helpers (separate from the rpm ones). - Prime github_deb remotes on create and run the deb syncer alongside the rpm one; route prime-on-create by package type. - Reuse the deb apt-index generators and control parser; skip empty hash lines in the Packages index so a SHA256-only metadata entry is valid.
This commit is contained in:
@@ -12,18 +12,20 @@ import (
|
||||
)
|
||||
|
||||
// Primer enqueues a background metadata prime for a newly created remote so the
|
||||
// create call never blocks on a derive. *rpm.Syncer satisfies it.
|
||||
// create call never blocks on a derive. *rpm.Syncer and *deb.Syncer satisfy it.
|
||||
type Primer interface {
|
||||
EnqueuePrime(remote models.Remote)
|
||||
}
|
||||
|
||||
type RemotesHandler struct {
|
||||
db *database.DB
|
||||
primer Primer
|
||||
db *database.DB
|
||||
primers map[models.PackageType]Primer
|
||||
}
|
||||
|
||||
func NewRemotesHandler(db *database.DB, primer Primer) *RemotesHandler {
|
||||
return &RemotesHandler{db: db, primer: primer}
|
||||
// NewRemotesHandler wires the handler to the per-type metadata primers. primers
|
||||
// may be nil; a package type with no registered primer simply skips priming.
|
||||
func NewRemotesHandler(db *database.DB, primers map[models.PackageType]Primer) *RemotesHandler {
|
||||
return &RemotesHandler{db: db, primers: primers}
|
||||
}
|
||||
|
||||
func (h *RemotesHandler) Routes() chi.Router {
|
||||
@@ -84,10 +86,10 @@ func (h *RemotesHandler) create(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// Prime a github_rpm remote's metadata in the background so its first
|
||||
// repodata request is served from cache instead of a cold on-demand derive.
|
||||
if h.primer != nil && remote.PackageType == models.PackageGitHubRPM {
|
||||
h.primer.EnqueuePrime(remote)
|
||||
// Prime a metadata-only remote (github_rpm/github_deb) in the background so
|
||||
// its first index request is served from cache instead of a cold derive.
|
||||
if primer := h.primers[remote.PackageType]; primer != nil {
|
||||
primer.EnqueuePrime(remote)
|
||||
}
|
||||
writeJSON(w, http.StatusCreated, remote)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user