Disallow tag deletion when container repository is importing
🦋 Context
We are preparing for Phase 2 of the Container Registry migration which involves importing all existing container repositories to the new platform (Phase 1 involved routing all new container repositories to the new platform). See &7316 (closed) for full details of how the import will work.
When a container repository is importing, it becomes read only and is locked for pushing and deletion. If a user tries to delete a repository tag while it is locked, the registry will throw an error. Currently, we have a guard in place when users make requests to push or delete a new tag using their docker client, but we also allow tag deletion using the API and through cleanup policies. We need to guard those deletions, which is what this MR is all about.
🔎 What does this MR do and why?
Container registry tag deletion is handled by Projects::ContainerRepository::DeleteTagsService
. We add a guard here to reject the deletion if the repository is currently importing.
Screenshots or screen recordings
See below.
🖥 How to set up and validate locally
-
Push an image with a few tags to one of your projects (this example is using a project
asdf
in theroot
user namespace):# this retags alpine:latest and push it multiple times docker pull alpine:latest docker tag alpine:latest gdk.test:5000/root/asdf:latest docker tag alpine:latest gdk.test:5000/root/asdf:foo docker tag alpine:latest gdk.test:5000/root/asdf:bar docker push gdk.test:5000/root/asdf:latest docker push gdk.test:5000/root/asdf:foo docker push gdk.test:5000/root/asdf:bar
-
In the rails console, get the container repository id and project id:
c = ContainerRepository.last c.id c.project.id
-
Delete a tag with the API
$ curl --request DELETE --header "PRIVATE-TOKEN: <personal_access_token>" \ "http://gdk.test:3001/api/v4/projects/<project_id>/registry/repositories/<container_repository_id>/tags/foo" 200
The request should succeed and you can verify the tag is gone in the UI or rails console.
-
In the rails console, change the container repository
migraiton_state
toimporting
:c.update_columns(migration_state: 'importing', migration_import_started_at: Time.zone.now)
-
Try to delete another tag
$ curl --request DELETE --header "PRIVATE-TOKEN: <personal_access_token>" \ "http://gdk.test:3001/api/v4/projects/<project_id>/registry/repositories/<container_repository_id>/tags/bar" 400
The request should fail and you can verify the tag remains in the UI or rails console.
🛂 MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #349747 (closed)