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

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 47bc8cb517
commit cbf45bfee1
6 changed files with 123 additions and 2 deletions
+10
View File
@@ -53,10 +53,20 @@ type PostUploadHook interface {
AfterUpload(ctx context.Context, repoName, storagePath, contentHash string, blobs BlobReader, db MetadataStore)
}
// PostDeleteHook lets a provider clean up derived state (e.g. RPM metadata that
// feeds generated repodata) after a local file is removed.
type PostDeleteHook interface {
AfterDelete(ctx context.Context, repoName, storagePath string, db MetadataDeleter) error
}
type MetadataStore interface {
InsertRPMMetadata(ctx context.Context, meta *RPMMetadata) error
}
type MetadataDeleter interface {
DeleteRPMMetadata(ctx context.Context, repoName, filePath string) error
}
type RPMMetadataReader interface {
ListRPMMetadataEntries(ctx context.Context, repoName string) ([]RPMMetadata, error)
}
+9
View File
@@ -151,6 +151,15 @@ func (p *Provider) AfterUpload(ctx context.Context, repoName, storagePath, conte
slog.Info("rpm metadata: parsed", "repo", repoName, "name", meta.Name, "version", meta.Version, "arch", meta.Arch)
}
func (p *Provider) AfterDelete(ctx context.Context, repoName, storagePath string, db provider.MetadataDeleter) error {
if err := db.DeleteRPMMetadata(ctx, repoName, storagePath); err != nil {
slog.Error("rpm metadata: delete failed", "repo", repoName, "path", storagePath, "error", err)
return err
}
slog.Info("rpm metadata: deleted", "repo", repoName, "path", storagePath)
return nil
}
func rpmDepFromEntry(e rpmlib.Dependency) provider.RPMDep {
dep := provider.RPMDep{Name: e.Name()}
if e.Flags() != 0 {