Call dependency proxy cleanup workers in purge

🔎 What does this MR do and why?

In !76696 (merged), we updated the Dependency Proxy purge cache API to use the newer background jobs to handle deletion of Dependency Proxy records in a more scalable and performant way.

The problem is, once records are marked as expired, the DependencyProxy::CleanupManifestWorker and DependencyProxy::CleanupBlobWorker need to be run to actually do the cleanup. It is possible these workers might already be running if the GitLab instance has Dependency Proxy cleanup policies in place, however, there is no guarantee.

Since these two workers are limited capacity workers, we'd like to avoid calling them in multiple places. This MR adds a new centralized worker that queues them twice daily if there are expired records to be cleaned up.

💿 Database

Query generated by DependencyProxy::Manifest.expired.any?

SELECT 1 AS one FROM "dependency_proxy_manifests" WHERE "dependency_proxy_manifests"."status" = 1 LIMIT 1;

Explain: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/7759/commands/27611

Query generated by DependencyProxy::Blob.expired.any?

SELECT 1 AS one FROM "dependency_proxy_blobs" WHERE "dependency_proxy_blobs"."status" = 1 LIMIT 1;

Explain: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/7759/commands/27610

🎥 Screenshots or screen recordings

API request:

→ curl --request DELETE -H "PRIVATE-TOKEN: <token>" "http://gdk.test:3001/api/v4/groups/181/dependency_proxy/cache"
202

After:

[78] pry(main)> Group.find(181).dependency_proxy_manifests.size
=> 0
[79] pry(main)> Group.find(181).dependency_proxy_blobs.size
=> 0

🖥 How to set up and validate locally

  1. Create a group
  2. Log into the dependency proxy (you can use your username/password for credentials, or username/personal_access_token).
    docker login gdk.test:3001
  3. Use the Dependency Proxy to pull a number of images through the group:
    docker pull gdk.test:3001/<group_full_path>/dependency_proxy/containers/nginx:latest
    docker pull gdk.test:3001/<group_full_path>/dependency_proxy/containers/node:latest
  4. Navigate to the group dependency proxy page to view the pulled images group -> Packages & Registries -> Dependency Proxy. You can also view the records in the rails console:
    Group.last.dependency_proxy_manifests
    Group.last.dependency_proxy_blobs
  5. Make a request to the purge API:
    curl --request DELETE -H "Private-Token: <personal_access_token>" "http://gdk.test:3001/api/v4/groups/<group_id>/dependency_proxy/cache"
  6. (optional) check that the records are now expired:
    Group.last.dependency_proxy_manifests.map(&:status)
    Group.last.dependency_proxy_blobs.map(&:status)
  7. Kick off the new centralized cleanup job
    DependencyProxy::CleanupDependencyProxyWorker.perform_at(1.second)
  8. Check that the records get deleted. They should no longer be visible in the UI, and you can check in the rails console:
    Group.last.dependency_proxy_blobs.size
    Group.last.dependency_proxy_manifests.size

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #348176

Edited by Steve Abrams

Merge request reports

Loading