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 module Geo
class RepositoryDestroyService 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 @id = id
@name = name @name = name
@path_with_namespace = path @full_path = full_path
@storage_name = storage_name
end end
def async_execute 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 end
end end
...@@ -3,29 +3,7 @@ class GeoRepositoryDestroyWorker ...@@ -3,29 +3,7 @@ class GeoRepositoryDestroyWorker
include GeoQueue include GeoQueue
include Gitlab::ShellAdapter include Gitlab::ShellAdapter
def perform(id, name, full_path) def perform(id, name, full_path, storage_name)
repository_storage = probe_repository_storage(full_path) Geo::RepositoryDestroyService.new(id, name, full_path, storage_name).execute
# 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
end end
end end
...@@ -128,14 +128,13 @@ module Gitlab ...@@ -128,14 +128,13 @@ module Gitlab
def handle_repository_delete(event) def handle_repository_delete(event)
deleted_event = event.repository_deleted_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, full_path = File.join(deleted_event.repository_storage_path,
deleted_event.deleted_path) deleted_event.deleted_path)
job_id = ::Geo::RepositoryDestroyService job_id = ::Geo::RepositoryDestroyService
.new(deleted_event.project_id, .new(deleted_event.project_id,
deleted_event.deleted_project_name, deleted_event.deleted_project_name,
full_path) full_path,
deleted_event.repository_storage_name)
.async_execute .async_execute
log_event_info(event.created_at, log_event_info(event.created_at,
message: "Deleted project", message: "Deleted project",
......
...@@ -76,7 +76,7 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do ...@@ -76,7 +76,7 @@ describe Gitlab::Geo::LogCursor::Daemon, :postgresql do
repository_deleted_event.deleted_path) repository_deleted_event.deleted_path)
expect(::GeoRepositoryDestroyWorker).to receive(:perform_async) 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! subject.run!
end 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' require 'spec_helper'
describe GeoRepositoryDestroyWorker do describe GeoRepositoryDestroyWorker do
let!(:project) { create :project_empty_repo } let(:project) { create(:project) }
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) }
it 'delegates project removal to Projects::DestroyService' do it 'delegates project removal to Geo::RepositoryDestroyService' do
expect_any_instance_of(EE::Projects::DestroyService).to receive(:geo_replicate) expect_any_instance_of(Geo::RepositoryDestroyService).to receive(:execute)
perform! described_class.new.perform(project.id, project.name, project.path, 'default')
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
end end
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