Commit daf0a766 authored by Gabriel Mazetto's avatar Gabriel Mazetto

Make Hashed Storage migration resilient to exceptions

parent 88a60d6b
...@@ -26,11 +26,27 @@ module Projects ...@@ -26,11 +26,27 @@ module Projects
project.set_repository_writable! project.set_repository_writable!
end end
if result && block_given?
yield
end
result result
rescue Gitlab::Git::CommandError => e
logger.error("Repository #{project.full_path} failed to upgrade (PROJECT_ID=#{project.id}). Git operation failed: #{e.inspect}")
rollback_migration!
false
rescue OpenSSL::Cipher::CipherError => e
logger.error("Repository #{project.full_path} failed to upgrade (PROJECT_ID=#{project.id}). There is a problem with encrypted attributes: #{e.inspect}")
rollback_migration!
false
end
private
def rollback_migration!
rollback_folder_move
project.storage_version = nil
project.set_repository_writable!
end end
end end
end end
......
...@@ -8,7 +8,9 @@ module EE ...@@ -8,7 +8,9 @@ module EE
override :execute override :execute
def execute def execute
super do result = super
if result
::Geo::HashedStorageMigratedEventStore.new( ::Geo::HashedStorageMigratedEventStore.new(
project, project,
old_storage_version: old_storage_version, old_storage_version: old_storage_version,
...@@ -17,6 +19,8 @@ module EE ...@@ -17,6 +19,8 @@ module EE
old_design_disk_path: old_design_disk_path old_design_disk_path: old_design_disk_path
).create! ).create!
end end
result
end end
end end
end end
......
...@@ -77,6 +77,42 @@ RSpec.describe Projects::HashedStorage::MigrateRepositoryService do ...@@ -77,6 +77,42 @@ RSpec.describe Projects::HashedStorage::MigrateRepositoryService do
end end
end end
context 'when exception happens' do
it 'handles OpenSSL::Cipher::CipherError' do
expect(project).to receive(:ensure_runners_token).and_raise(OpenSSL::Cipher::CipherError)
expect { service.execute }.not_to raise_exception
end
it 'ensures rollback when OpenSSL::Cipher::CipherError' do
expect(project).to receive(:ensure_runners_token).and_raise(OpenSSL::Cipher::CipherError)
expect(service).to receive(:rollback_folder_move).and_call_original
service.execute
project.reload
expect(project.legacy_storage?).to be_truthy
expect(project.repository_read_only?).to be_falsey
end
it 'handles Gitlab::Git::CommandError' do
expect(project).to receive(:write_repository_config).and_raise(Gitlab::Git::CommandError)
expect { service.execute }.not_to raise_exception
end
it 'ensures rollback when Gitlab::Git::CommandError' do
expect(project).to receive(:write_repository_config).and_raise(Gitlab::Git::CommandError)
expect(service).to receive(:rollback_folder_move).and_call_original
service.execute
project.reload
expect(project.legacy_storage?).to be_truthy
expect(project.repository_read_only?).to be_falsey
end
end
context 'when one move fails' do context 'when one move fails' do
it 'rollsback repositories to original name' do it 'rollsback repositories to original name' do
allow(service).to receive(:move_repository).and_call_original allow(service).to receive(:move_repository).and_call_original
......
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