提交 cb2ce845 编写于 作者: G Grzegorz Bizon

Remove legacy registry tags when deleting a project

上级 1c91d52a
...@@ -70,4 +70,8 @@ class ContainerRepository < ActiveRecord::Base ...@@ -70,4 +70,8 @@ class ContainerRepository < ActiveRecord::Base
def self.create_from_path!(path) def self.create_from_path!(path)
build_from_path(path).tap(&:save!) build_from_path(path).tap(&:save!)
end end
def self.build_root_repository(project)
self.new(project: project, name: '')
end
end end
...@@ -29,15 +29,20 @@ module Projects ...@@ -29,15 +29,20 @@ module Projects
Project.transaction do Project.transaction do
project.team.truncate project.team.truncate
project.destroy!
unless remove_legacy_registry_tags
raise_error('Failed to remove some tags in project container registry. Please try again or contact administrator.')
end
unless remove_repository(repo_path) unless remove_repository(repo_path)
raise_error('Failed to remove project repository. Please try again or contact administrator') raise_error('Failed to remove project repository. Please try again or contact administrator.')
end end
unless remove_repository(wiki_path) unless remove_repository(wiki_path)
raise_error('Failed to remove wiki repository. Please try again or contact administrator') raise_error('Failed to remove wiki repository. Please try again or contact administrator.')
end end
project.destroy!
end end
log_info("Project \"#{project.path_with_namespace}\" was removed") log_info("Project \"#{project.path_with_namespace}\" was removed")
...@@ -64,6 +69,18 @@ module Projects ...@@ -64,6 +69,18 @@ module Projects
end end
end end
##
# This method makes sure that we correctly remove registry tags
# for legacy image repository (when repository path equals project path).
#
def remove_legacy_registry_tags
return true unless Gitlab.config.registry.enabled
ContainerRepository.build_root_repository(project).tap do |repository|
return repository.delete_tags! if repository.has_tags?
end
end
def raise_error(message) def raise_error(message)
raise DestroyError.new(message) raise DestroyError.new(message)
end end
......
...@@ -195,4 +195,22 @@ describe ContainerRepository do ...@@ -195,4 +195,22 @@ describe ContainerRepository do
end end
end end
end end
describe '.build_root_repository' do
let(:repository) do
described_class.build_root_repository(project)
end
it 'fabricates a root repository object' do
expect(repository).to be_root_repository
end
it 'assignes it to the correct project' do
expect(repository.project).to eq project
end
it 'does not persist it' do
expect(repository).not_to be_persisted
end
end
end end
...@@ -7,6 +7,11 @@ describe Projects::DestroyService, services: true do ...@@ -7,6 +7,11 @@ describe Projects::DestroyService, services: true do
let!(:remove_path) { path.sub(/\.git\Z/, "+#{project.id}+deleted.git") } let!(:remove_path) { path.sub(/\.git\Z/, "+#{project.id}+deleted.git") }
let!(:async) { false } # execute or async_execute let!(:async) { false } # execute or async_execute
before do
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: [])
end
shared_examples 'deleting the project' do shared_examples 'deleting the project' do
it 'deletes the project' do it 'deletes the project' do
expect(Project.unscoped.all).not_to include(project) expect(Project.unscoped.all).not_to include(project)
...@@ -89,37 +94,64 @@ describe Projects::DestroyService, services: true do ...@@ -89,37 +94,64 @@ describe Projects::DestroyService, services: true do
it_behaves_like 'deleting the project with pipeline and build' it_behaves_like 'deleting the project with pipeline and build'
end end
context 'container registry' do describe 'container registry' do
let(:container_repository) { create(:container_repository) } context 'when there are regular container repositories' do
let(:container_repository) { create(:container_repository) }
before do before do
stub_container_registry_config(enabled: true) stub_container_registry_tags(repository: project.full_path + '/image',
stub_container_registry_tags(repository: :any, tags: ['tag']) tags: ['tag'])
project.container_repositories << container_repository project.container_repositories << container_repository
end end
context 'images deletion succeeds' do context 'when image repository deletion succeeds' do
it do it 'removes tags' do
expect_any_instance_of(ContainerRepository) expect_any_instance_of(ContainerRepository)
.to receive(:delete_tags!).and_return(true) .to receive(:delete_tags!).and_return(true)
destroy_project(project, user, {}) destroy_project(project, user)
end
end
context 'when image repository deletion fails' do
it 'raises an exception' do
expect_any_instance_of(ContainerRepository)
.to receive(:delete_tags!).and_return(false)
expect{ destroy_project(project, user) }
.to raise_error(ActiveRecord::RecordNotDestroyed)
end
end end
end end
context 'images deletion fails' do context 'when there are tags for legacy root repository' do
before do before do
expect_any_instance_of(ContainerRepository) stub_container_registry_tags(repository: project.full_path,
.to receive(:delete_tags!).and_return(false) tags: ['tag'])
end
context 'when image repository tags deletion succeeds' do
it 'removes tags' do
expect_any_instance_of(ContainerRepository)
.to receive(:delete_tags!).and_return(true)
destroy_project(project, user)
end
end end
subject { destroy_project(project, user, {}) } context 'when image repository tags deletion fails' do
it 'raises an exception' do
expect_any_instance_of(ContainerRepository)
.to receive(:delete_tags!).and_return(false)
it { expect{subject}.to raise_error(ActiveRecord::RecordNotDestroyed) } expect { destroy_project(project, user) }
.to raise_error(Projects::DestroyService::DestroyError)
end
end
end end
end end
def destroy_project(project, user, params) def destroy_project(project, user, params = {})
if async if async
Projects::DestroyService.new(project, user, params).async_execute Projects::DestroyService.new(project, user, params).async_execute
else else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册