fix: prune RPM metadata when a local file is evicted
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful

Evicting or deleting a local RPM removed the local_files row but left its
rpm_metadata behind, so generated repodata kept listing a package that no
longer exists. Deletes now run a provider cleanup hook symmetric to the
existing upload hook.

- add PostDeleteHook and MetadataDeleter provider interfaces, plus a
  DeleteRPMMetadata DB method
- implement AfterDelete in the RPM provider to drop the metadata row
- route both local delete paths (evictLocal and the files handler) through
  a shared deleteLocalFile helper that removes the file then runs the hook
- cover the cleanup with a dockerised test
This commit is contained in:
2026-07-03 14:48:23 +10:00
parent 787de74b3d
commit 808015f6bb
6 changed files with 123 additions and 2 deletions
+23 -1
View File
@@ -185,13 +185,35 @@ func (h *LocalHandler) remove(w http.ResponseWriter, r *http.Request) {
repoName := chi.URLParam(r, "name")
filePath := chi.URLParam(r, "*")
if err := h.db.DeleteLocalFile(r.Context(), repoName, filePath); err != nil {
if err := deleteLocalFile(r.Context(), h.db, repoName, filePath); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
// deleteLocalFile removes a local file and runs the provider's post-delete hook,
// so provider-derived state (e.g. RPM metadata that feeds generated repodata)
// stops referencing a package that no longer exists.
func deleteLocalFile(ctx context.Context, db *database.DB, repoName, filePath string) error {
if err := db.DeleteLocalFile(ctx, repoName, filePath); err != nil {
return err
}
remote, err := db.GetRemote(ctx, repoName)
if err != nil {
return nil // file is gone; no repo left to resolve a cleanup hook from
}
prov, err := provider.Get(remote.PackageType)
if err != nil {
return nil
}
if hook, ok := prov.(provider.PostDeleteHook); ok {
return hook.AfterDelete(ctx, repoName, filePath, db)
}
return nil
}
func (h *LocalHandler) DB() *database.DB {
return h.db
}