Commit 755b3acc authored by Toon Claes's avatar Toon Claes

Do not probe for repository storage, but take it from deleted event

Instead of iterating through all the repository storages to find the
one that has the repository, take the information provided by the
deleted event.
parent 82652580
module Geo
class RepositoryDestroyService
attr_reader :id, :name, :path_with_namespace
attr_reader :id, :name, :full_path, :storage_name
def initialize(id, name, path)
def initialize(id, name, full_path, storage_name)
@id = id
@name = name
@path_with_namespace = path
@full_path = full_path
@storage_name = storage_name
end
def async_execute
GeoRepositoryDestroyWorker.perform_async(id, name, path_with_namespace)
GeoRepositoryDestroyWorker.perform_async(id, name, full_path, storage_name)
end
def execute
::Projects::DestroyService.new(deleted_project, nil).geo_replicate
end
private
def deleted_project
# We don't have access to the original model anymore, so we are
# rebuilding only what our service class requires
::Geo::DeletedProject.new(id: id,
name: name,
full_path: full_path,
repository_storage: storage_name)
end
end
end
......@@ -3,29 +3,7 @@ class GeoRepositoryDestroyWorker
include GeoQueue
include Gitlab::ShellAdapter
def perform(id, name, full_path)
repository_storage = probe_repository_storage(full_path)
# We don't have access to the original model anymore, so we are
# rebuilding only what our service class requires
project = ::Geo::DeletedProject.new(id: id, name: name, full_path: full_path, repository_storage: repository_storage)
::Projects::DestroyService.new(project, nil).geo_replicate
end
private
# Detect in which repository_storage the project repository is stored.
#
# As we don't have access to `repository_storage` from the data in the Hook notification
# we need to probe on all existing ones.
#
# if we don't find it means it has already been deleted and we just return
def probe_repository_storage(repo_path)
Gitlab.config.repositories.storages.each do |repository_storage, rs_data|
return repository_storage if gitlab_shell.exists?(rs_data['path'], repo_path + '.git')
end
nil
def perform(id, name, full_path, storage_name)
Geo::RepositoryDestroyService.new(id, name, full_path, storage_name).execute
end
end
......@@ -128,14 +128,13 @@ module Gitlab
def handle_repository_delete(event)
deleted_event = event.repository_deleted_event
# Once we remove system hooks we can refactor
# GeoRepositoryDestroyWorker to avoid doing this
full_path = File.join(deleted_event.repository_storage_path,
deleted_event.deleted_path)
job_id = ::Geo::RepositoryDestroyService
.new(deleted_event.project_id,
deleted_event.deleted_project_name,
full_path)
full_path,
deleted_event.repository_storage_name)
.async_execute
log_event_info(event.created_at,
message: "Deleted project",
......
......@@ -76,7 +76,7 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
repository_deleted_event.deleted_path)
expect(::GeoRepositoryDestroyWorker).to receive(:perform_async)
.with(project_id, project_name, full_path)
.with(project_id, project_name, full_path, project.repository_storage)
subject.run!
end
......
require 'spec_helper'
describe Geo::RepositoryDestroyService do
let(:project) { create(:project_empty_repo) }
subject(:service) { described_class.new(project.id, project.name, project.disk_path, project.repository_storage) }
describe '#async_execute' do
it 'starts the worker' do
expect(GeoRepositoryDestroyWorker).to receive(:perform_async)
subject.async_execute
end
end
describe '#execute' do
it 'delegates project removal to Projects::DestroyService' do
expect_any_instance_of(EE::Projects::DestroyService).to receive(:geo_replicate)
service.execute
end
context 'legacy storage project' do
it 'removes the repository from disk' do
project.delete
expect(project.gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_truthy
service.execute
expect(project.gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_falsey
end
end
context 'hashed storage project' do
let(:project) { create(:project_empty_repo, :hashed) }
it 'removes the repository from disk' do
project.delete
expect(project.gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_truthy
service.execute
expect(project.gitlab_shell.exists?(project.repository_storage_path, "#{project.disk_path}.git")).to be_falsey
end
end
end
end
require 'spec_helper'
describe GeoRepositoryDestroyWorker do
let!(:project) { create :project_empty_repo }
let!(:path) { project.repository.full_path }
let!(:remove_path) { path.sub(/\.git\Z/, "+#{project.id}+deleted.git") }
let(:perform!) { subject.perform(project.id, project.name, path) }
let(:project) { create(:project) }
it 'delegates project removal to Projects::DestroyService' do
expect_any_instance_of(EE::Projects::DestroyService).to receive(:geo_replicate)
it 'delegates project removal to Geo::RepositoryDestroyService' do
expect_any_instance_of(Geo::RepositoryDestroyService).to receive(:execute)
perform!
end
context 'sidekiq execution' do
before do
project.delete
end
it 'removes the repository from disk' do
expect(project.gitlab_shell.exists?(project.repository_storage_path, path + '.git')).to be_truthy
Sidekiq::Testing.inline! { perform! }
expect(project.gitlab_shell.exists?(project.repository_storage_path, path + '.git')).to be_falsey
expect(project.gitlab_shell.exists?(project.repository_storage_path, remove_path + '.git')).to be_falsey
end
end
describe '#probe_repository_storage' do
it 'returns a repository_storage when repository can be found' do
expect(subject.send(:probe_repository_storage, project.full_path)).to eq('default')
end
it 'returns nil when repository cannot be found in any existing repository_storage' do
expect(subject.send(:probe_repository_storage, 'nonexistent/project')).to eq(nil)
end
described_class.new.perform(project.id, project.name, project.path, 'default')
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment