diff options
6 files changed, 201 insertions, 62 deletions
diff --git a/lib/gitlab/database/rename_reserved_paths_migration.rb b/lib/gitlab/database/rename_reserved_paths_migration.rb index 2cfc01ab2f5..5314f933435 100644 --- a/lib/gitlab/database/rename_reserved_paths_migration.rb +++ b/lib/gitlab/database/rename_reserved_paths_migration.rb @@ -8,6 +8,7 @@ module Gitlab def rename_wildcard_paths(one_or_more_paths) paths = Array(one_or_more_paths) rename_namespaces(paths, type: :wildcard) + rename_projects(paths) end def rename_root_paths(paths) @@ -69,6 +70,36 @@ module Gitlab def route_exists?(full_path) MigrationClasses::Route.where(Route.arel_table[:path].matches(full_path)).any? end + + def move_pages(old_path, new_path) + move_folders(pages_dir, old_path, new_path) + end + + def move_uploads(old_path, new_path) + return unless file_storage? + + move_folders(uploads_dir, old_path, new_path) + end + + def move_folders(directory, old_relative_path, new_relative_path) + old_path = File.join(directory, old_relative_path) + return unless File.directory?(old_path) + + new_path = File.join(directory, new_relative_path) + FileUtils.mv(old_path, new_path) + end + + def file_storage? + CarrierWave::Uploader::Base.storage == CarrierWave::Storage::File + end + + def uploads_dir + File.join(CarrierWave.root, "uploads") + end + + def pages_dir + Settings.pages.path + end end end end diff --git a/lib/gitlab/database/rename_reserved_paths_migration/namespaces.rb b/lib/gitlab/database/rename_reserved_paths_migration/namespaces.rb index b4f2a67fd06..2ef2629f4c2 100644 --- a/lib/gitlab/database/rename_reserved_paths_migration/namespaces.rb +++ b/lib/gitlab/database/rename_reserved_paths_migration/namespaces.rb @@ -16,23 +16,17 @@ module Gitlab elsif type == :top_level MigrationClasses::Namespace.where(parent_id: nil) end - namespaces.where('lower(path) in (?)', paths.map(&:downcase)) + with_paths = MigrationClasses::Namespace.arel_table[:path]. + matches_any(paths) + namespaces.where(with_paths) end def rename_namespace(namespace) old_full_path, new_full_path = rename_path_for_routable(namespace) move_repositories(namespace, old_full_path, new_full_path) - move_namespace_folders(uploads_dir, old_full_path, new_full_path) if file_storage? - move_namespace_folders(pages_dir, old_full_path, new_full_path) - end - - def move_namespace_folders(directory, old_relative_path, new_relative_path) - old_path = File.join(directory, old_relative_path) - return unless File.directory?(old_path) - - new_path = File.join(directory, new_relative_path) - FileUtils.mv(old_path, new_path) + move_uploads(old_full_path, new_full_path) + move_pages(old_full_path, new_full_path) end def move_repositories(namespace, old_full_path, new_full_path) @@ -70,18 +64,6 @@ module Gitlab end ids end - - def file_storage? - CarrierWave::Uploader::Base.storage == CarrierWave::Storage::File - end - - def uploads_dir - File.join(CarrierWave.root, "uploads") - end - - def pages_dir - Settings.pages.path - end end end end diff --git a/lib/gitlab/database/rename_reserved_paths_migration/projects.rb b/lib/gitlab/database/rename_reserved_paths_migration/projects.rb new file mode 100644 index 00000000000..a2c9354e430 --- /dev/null +++ b/lib/gitlab/database/rename_reserved_paths_migration/projects.rb @@ -0,0 +1,38 @@ +module Gitlab + module Database + module RenameReservedPathsMigration + module Projects + include Gitlab::ShellAdapter + + def rename_projects(paths) + projects_for_paths(paths).each do |project| + rename_project(project) + end + end + + def rename_project(project) + old_full_path, new_full_path = rename_path_for_routable(project) + + move_repository(project, old_full_path, new_full_path) + move_repository(project, "#{old_full_path}.wiki", "#{new_full_path}.wiki") + move_uploads(old_full_path, new_full_path) + move_pages(old_full_path, new_full_path) + end + + def move_repository(project, old_path, new_path) + unless gitlab_shell.mv_repository(project.repository_storage_path, + old_path, + new_path) + Rails.logger.error "Error moving #{old_path} to #{new_path}" + end + end + + def projects_for_paths(paths) + with_paths = MigrationClasses::Project.arel_table[:path] + .matches_any(paths) + MigrationClasses::Project.where(with_paths) + end + end + end + end +end diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/namespaces_spec.rb index 3e5f981c095..f6d95f04073 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/namespaces_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/namespaces_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe Gitlab::Database::RenameReservedPathsMigration::Namespaces, :truncate do - let(:test_dir) { File.join(Rails.root, 'tmp', 'tests', 'rename_namespaces_test') } - let(:uploads_dir) { File.join(test_dir, 'public', 'uploads') } let(:subject) do ActiveRecord::Migration.new.extend( Gitlab::Database::RenameReservedPathsMigration @@ -10,10 +8,6 @@ describe Gitlab::Database::RenameReservedPathsMigration::Namespaces, :truncate d end before do - FileUtils.remove_dir(test_dir) if File.directory?(test_dir) - FileUtils.mkdir_p(uploads_dir) - FileUtils.remove_dir(TestEnv.repos_path) if File.directory?(TestEnv.repos_path) - allow(subject).to receive(:uploads_dir).and_return(uploads_dir) allow(subject).to receive(:say) end @@ -44,8 +38,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::Namespaces, :truncate d root_namespace = create(:namespace, path: 'the-path') _other_path = create(:namespace, path: 'other') _child_namespace = create(:namespace, - path: 'the-path', - parent: create(:namespace)) + path: 'the-path', + parent: create(:namespace)) found_ids = subject.namespaces_for_paths(['the-path'], type: :top_level). map(&:id) @@ -87,32 +81,6 @@ describe Gitlab::Database::RenameReservedPathsMigration::Namespaces, :truncate d end end - describe '#move_namespace_folders' do - it 'moves a namespace with files' do - source = File.join(uploads_dir, 'parent-group', 'sub-group') - FileUtils.mkdir_p(source) - destination = File.join(uploads_dir, 'parent-group', 'moved-group') - FileUtils.touch(File.join(source, 'test.txt')) - expected_file = File.join(destination, 'test.txt') - - subject.move_namespace_folders(uploads_dir, File.join('parent-group', 'sub-group'), File.join('parent-group', 'moved-group')) - - expect(File.exist?(expected_file)).to be(true) - end - - it 'moves a parent namespace uploads' do - source = File.join(uploads_dir, 'parent-group', 'sub-group') - FileUtils.mkdir_p(source) - destination = File.join(uploads_dir, 'moved-parent', 'sub-group') - FileUtils.touch(File.join(source, 'test.txt')) - expected_file = File.join(destination, 'test.txt') - - subject.move_namespace_folders(uploads_dir, 'parent-group', 'moved-parent') - - expect(File.exist?(expected_file)).to be(true) - end - end - describe "#child_ids_for_parent" do it "collects child ids for all levels" do parent = create(:namespace) @@ -148,15 +116,13 @@ describe Gitlab::Database::RenameReservedPathsMigration::Namespaces, :truncate d end it "moves the uploads for the namespace" do - allow(subject).to receive(:move_namespace_folders).with(Settings.pages.path, "the-path", "the-path0") - expect(subject).to receive(:move_namespace_folders).with(uploads_dir, "the-path", "the-path0") + expect(subject).to receive(:move_uploads).with("the-path", "the-path0") subject.rename_namespace(namespace) end it "moves the pages for the namespace" do - allow(subject).to receive(:move_namespace_folders).with(uploads_dir, "the-path", "the-path0") - expect(subject).to receive(:move_namespace_folders).with(Settings.pages.path, "the-path", "the-path0") + expect(subject).to receive(:move_pages).with("the-path", "the-path0") subject.rename_namespace(namespace) end diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/projects_spec.rb new file mode 100644 index 00000000000..7d3344faa10 --- /dev/null +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/projects_spec.rb @@ -0,0 +1,76 @@ +require 'spec_helper' + +describe Gitlab::Database::RenameReservedPathsMigration::Projects, :truncate do + let(:subject) do + ActiveRecord::Migration.new.extend( + Gitlab::Database::RenameReservedPathsMigration + ) + end + + before do + allow(subject).to receive(:say) + end + + describe '#projects_for_paths' do + it 'includes the correct projects' do + project = create(:empty_project, path: 'THE-path') + _other_project = create(:empty_project) + + result_ids = subject.projects_for_paths(['the-PATH']).map(&:id) + + expect(result_ids).to contain_exactly(project.id) + end + end + + describe '#rename_project' do + let(:project) do + create(:empty_project, + path: 'the-path', + namespace: create(:namespace, path: 'known-parent' )) + end + + it 'renames path & route for the project' do + expect(subject).to receive(:rename_path_for_routable). + with(project). + and_call_original + + subject.rename_project(project) + end + + it 'moves the wiki & the repo' do + expect(subject).to receive(:move_repository). + with(project, 'known-parent/the-path.wiki', 'known-parent/the-path0.wiki') + expect(subject).to receive(:move_repository). + with(project, 'known-parent/the-path', 'known-parent/the-path0') + + subject.rename_project(project) + end + + it 'moves uploads' do + expect(subject).to receive(:move_uploads). + with('known-parent/the-path', 'known-parent/the-path0') + + subject.rename_project(project) + end + + it 'moves pages' do + expect(subject).to receive(:move_pages). + with('known-parent/the-path', 'known-parent/the-path0') + + subject.rename_project(project) + end + end + + describe '#move_repository' do + let(:known_parent) { create(:namespace, path: 'known-parent') } + let(:project) { create(:project, path: 'the-path', namespace: known_parent) } + + it 'moves the repository for a project' do + expected_path = File.join(TestEnv.repos_path, 'known-parent', 'new-repo.git') + + subject.move_repository(project, 'known-parent/the-path', 'known-parent/new-repo') + + expect(File.directory?(expected_path)).to be(true) + end + end +end diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration_spec.rb index 8fc15c8f716..d3021d330be 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration_spec.rb @@ -19,7 +19,11 @@ describe Gitlab::Database::RenameReservedPathsMigration do subject.rename_wildcard_paths(['first-path', 'second-path']) end - it 'should rename projects' + it 'should rename projects' do + expect(subject).to receive(:rename_projects).with(['the-path']) + + subject.rename_wildcard_paths(['the-path']) + end end describe '#rename_root_paths' do @@ -106,4 +110,46 @@ describe Gitlab::Database::RenameReservedPathsMigration do end end end + + describe "#move_uploads" do + let(:test_dir) { File.join(Rails.root, 'tmp', 'tests', 'rename_reserved_paths') } + let(:uploads_dir) { File.join(test_dir, 'public', 'uploads') } + + it 'moves subdirectories in the uploads folder' do + expect(subject).to receive(:uploads_dir).and_return(uploads_dir) + expect(subject).to receive(:move_folders).with(uploads_dir, 'old_path', 'new_path') + + subject.move_uploads('old_path', 'new_path') + end + + it "doesn't move uploads when they are stored in object storage" do + expect(subject).to receive(:file_storage?).and_return(false) + expect(subject).not_to receive(:move_folders) + + subject.move_uploads('old_path', 'new_path') + end + end + + describe '#move_folders' do + let(:test_dir) { File.join(Rails.root, 'tmp', 'tests', 'rename_reserved_paths') } + let(:uploads_dir) { File.join(test_dir, 'public', 'uploads') } + + before do + FileUtils.remove_dir(test_dir) if File.directory?(test_dir) + FileUtils.mkdir_p(uploads_dir) + allow(subject).to receive(:uploads_dir).and_return(uploads_dir) + end + + it 'moves a folder with files' do + source = File.join(uploads_dir, 'parent-group', 'sub-group') + FileUtils.mkdir_p(source) + destination = File.join(uploads_dir, 'parent-group', 'moved-group') + FileUtils.touch(File.join(source, 'test.txt')) + expected_file = File.join(destination, 'test.txt') + + subject.move_folders(uploads_dir, File.join('parent-group', 'sub-group'), File.join('parent-group', 'moved-group')) + + expect(File.exist?(expected_file)).to be(true) + end + end end |