Does not inherits Geo::DeletedProject from Project

parent 7807f07a
class Geo::DeletedProject < ::Project
after_initialize :readonly!
class Geo::DeletedProject
include Gitlab::CurrentSettings
def initialize(id:, name:, full_path:, repository_storage:)
repository_storage ||= current_application_settings.pick_repository_storage
attr_reader :id, :name, :disk_path
super(id: id, name: name, repository_storage: repository_storage)
@full_path = full_path
def initialize(id:, name:, disk_path:, repository_storage:)
@id = id
@name = name
@disk_path = disk_path
@repository_storage = repository_storage
end
def full_path
@full_path
alias_method :full_path, :disk_path
def repository
@repository ||= Repository.new(disk_path, self)
end
def repository_storage
@repository_storage ||= current_application_settings.pick_repository_storage
end
def repository_storage_path
Gitlab.config.repositories.storages[repository_storage].try(:[], 'path')
end
def wiki
@wiki ||= ProjectWiki.new(self, nil)
end
def wiki_path
wiki.disk_path
end
# When we remove project we move the repository to path+deleted.git then
# outside the transaction we schedule removal of path+deleted with Sidekiq
# through the run_after_commit callback. In a Geo secondary node, we don't
# attempt to remove the repositories inside a transaction because we don't
# have access to the original model anymore, we just need to perform some
# cleanup. This method will run the given block to remove repositories
# immediately otherwise will leave us with stalled repositories on disk.
def run_after_commit(&block)
instance_eval(&block)
end
alias_method :path_with_namespace, :full_path
end
module Geo
class RepositoryDestroyService
attr_reader :id, :name, :disk_path, :storage_name
attr_reader :id, :name, :disk_path, :repository_storage
def initialize(id, name, disk_path, storage_name)
def initialize(id, name, disk_path, repository_storage)
@id = id
@name = name
@disk_path = disk_path
@storage_name = storage_name
@repository_storage = repository_storage
end
def async_execute
GeoRepositoryDestroyWorker.perform_async(id, name, disk_path, storage_name)
GeoRepositoryDestroyWorker.perform_async(id, name, disk_path, repository_storage)
end
def execute
......@@ -24,8 +24,8 @@ module Geo
# rebuilding only what our service class requires
::Geo::DeletedProject.new(id: id,
name: name,
full_path: disk_path,
repository_storage: storage_name)
disk_path: disk_path,
repository_storage: repository_storage)
end
end
end
......@@ -41,38 +41,12 @@ module EE
flush_caches(project)
trash_repositories!
trash_repositories_cleanup!
log_info("Project \"#{project.name}\" was removed")
end
private
# When we remove project we move the repository to path+deleted.git
# then outside the transaction we schedule removal of path+deleted
# with Sidekiq through the after_commit callback. In a Geo secondary
# node we don't have access to the original model anymore then we
# rebuild a Geo::DeletedProject model. Since this model is read-only,
# this callback will not be triggered leaving us with stalled
# repositories on disk.
def trash_repositories_cleanup!
repo_removed_path = removal_path(repo_path)
if gitlab_shell.exists?(repository_storage_path, repo_removed_path + '.git')
GitlabShellWorker.perform_in(5.minutes, :remove_repository, repository_storage_path, repo_removed_path)
end
wiki_removed_path = removal_path(wiki_path)
if gitlab_shell.exists?(repository_storage_path, wiki_removed_path + '.git')
GitlabShellWorker.perform_in(5.minutes, :remove_repository, repository_storage_path, wiki_removed_path)
end
end
def repository_storage_path
project.repository_storage_path
end
def log_audit_event(project)
::AuditEventService.new(
current_user,
......
require 'spec_helper'
RSpec.describe Geo::DeletedProject, type: :model do
subject { described_class.new(id: 1, name: 'sample', full_path: 'root/sample', repository_storage: nil) }
include StubConfiguration
it { expect(subject).to be_kind_of(Project) }
before do
storages = {
'foo' => { 'path' => 'tmp/tests/storage_foo' },
'bar' => { 'path' => 'tmp/tests/storage_bar' }
}
describe '#full_path' do
it 'returns the initialized value' do
expect(subject.full_path).to eq 'root/sample'
end
stub_storage_settings(storages)
end
describe '#path_with_namespace' do
it 'is an alias for full_path' do
full_path = described_class.instance_method(:full_path)
path_with_namespace = described_class.instance_method(:path_with_namespace)
subject { described_class.new(id: 1, name: 'sample', disk_path: 'root/sample', repository_storage: 'foo') }
it { is_expected.to respond_to(:id) }
it { is_expected.to respond_to(:name) }
it { is_expected.to respond_to(:disk_path) }
expect(path_with_namespace).to eq(full_path)
describe '#full_path' do
it 'is an alias for disk_path' do
expect(subject.full_path).to eq 'root/sample'
end
end
describe '#repository' do
it 'returns a valid repository' do
expect(subject.repository).to be_kind_of(Repository)
expect(subject.repository.full_path).to eq('root/sample')
expect(subject.repository.disk_path).to eq('root/sample')
end
end
describe '#repository_storage' do
it 'returns the initialized value when set' do
expect(subject.repository_storage).to eq 'foo'
end
it 'picks storage from ApplicationSetting when value is not initialized' do
allow_any_instance_of(ApplicationSetting).to receive(:pick_repository_storage).and_return('bar')
subject = described_class.new(id: 1, name: 'sample', disk_path: 'root/sample', repository_storage: nil)
expect(subject.repository_storage).to eq('bar')
end
end
describe '#repository_storage_path' do
it 'returns the repository storage path' do
expect(subject.repository_storage_path).to eq('tmp/tests/storage_foo')
end
end
describe '#wiki' do
it 'returns a valid wiki repository' do
expect(subject.wiki).to be_kind_of(ProjectWiki)
expect(subject.wiki.disk_path).to eq('root/sample.wiki')
end
end
describe '#wiki_path' do
it 'returns the wiki repository path on disk' do
expect(subject.wiki_path).to eq('root/sample.wiki')
end
end
describe '#run_after_commit' do
it 'runs the given block changing self to the caller' do
expect(subject).to receive(:repository_storage_path).once
subject.run_after_commit { self.repository_storage_path }
end
end
end
......@@ -43,6 +43,7 @@ describe Geo::RepositoryDestroyService do
expect(::GitlabShellWorker).to receive(:perform_in)
.with(5.minutes, :remove_repository, project.repository_storage_path, "#{project.disk_path}+#{project.id}+deleted")
.and_return(true)
service.execute
end
......@@ -66,6 +67,7 @@ describe Geo::RepositoryDestroyService do
expect(::GitlabShellWorker).to receive(:perform_in)
.with(5.minutes, :remove_repository, project.repository_storage_path, "#{project.disk_path}+#{project.id}+deleted")
.and_return(true)
service.execute
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