summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/projects/registry/tags_controller.rb15
-rw-r--r--config/routes/project.rb6
-rw-r--r--spec/controllers/projects/registry/tags_controller_spec.rb33
3 files changed, 53 insertions, 1 deletions
diff --git a/app/controllers/projects/registry/tags_controller.rb b/app/controllers/projects/registry/tags_controller.rb
index bf1d8d8b5fc..22c87dfe1c0 100644
--- a/app/controllers/projects/registry/tags_controller.rb
+++ b/app/controllers/projects/registry/tags_controller.rb
@@ -28,6 +28,21 @@ module Projects
end
end
+ def bulk_destroy
+ @tags = (params[:ids] || []).map { |tag_name| image.tag(tag_name) }
+
+ success_count = 0
+ @tags.each do |tag|
+ if tag.delete
+ success_count += 1
+ end
+ end
+
+ respond_to do |format|
+ format.json { head(success_count == @tags.size ? :no_content : :bad_request) }
+ end
+ end
+
private
def tags
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 1f632765317..4bb0bce2965 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -474,7 +474,11 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
# in JSON format, or a request for tag named `latest.json`.
scope format: false do
resources :tags, only: [:index, :destroy],
- constraints: { id: Gitlab::Regex.container_registry_tag_regex }
+ constraints: { id: Gitlab::Regex.container_registry_tag_regex } do
+ collection do
+ delete :bulk_destroy
+ end
+ end
end
end
end
diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb
index ff35139ae2e..c6e063d8229 100644
--- a/spec/controllers/projects/registry/tags_controller_spec.rb
+++ b/spec/controllers/projects/registry/tags_controller_spec.rb
@@ -113,4 +113,37 @@ describe Projects::Registry::TagsController do
format: :json
end
end
+
+ describe 'POST bulk_destroy' do
+ context 'when user has access to registry' do
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when there is matching tag present' do
+ before do
+ stub_container_registry_tags(repository: repository.path, tags: %w[rc1 test.])
+ end
+
+ it 'makes it possible to delete tags in bulk' do
+ allow_any_instance_of(ContainerRegistry::Tag).to receive(:delete) { |*args| ContainerRegistry::Tag.delete(*args) }
+ expect(ContainerRegistry::Tag).to receive(:delete).exactly(2).times
+
+ bulk_destroy_tags(['rc1', 'test.'])
+ end
+ end
+ end
+
+ private
+
+ def bulk_destroy_tags(names)
+ post :bulk_destroy, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ repository_id: repository,
+ ids: names
+ },
+ format: :json
+ end
+ end
end