77 lines
2.3 KiB
Ruby
77 lines
2.3 KiB
Ruby
![]() |
class RenameReservedProjectNames < ActiveRecord::Migration
|
||
|
include Gitlab::Database::MigrationHelpers
|
||
|
include Gitlab::ShellAdapter
|
||
|
|
||
|
DOWNTIME = false
|
||
|
|
||
|
class Project < ActiveRecord::Base; end
|
||
|
|
||
|
def up
|
||
|
threads = reserved_projects.each_slice(100).map do |slice|
|
||
|
Thread.new do
|
||
|
rename_projects(slice)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
threads.each(&:join)
|
||
|
end
|
||
|
|
||
|
def down
|
||
|
# nothing to do here
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def reserved_projects
|
||
|
select_all("SELECT p.id, p.path, p.repository_storage, n.path AS namespace_path, n.id AS namespace_id FROM projects p
|
||
|
INNER JOIN namespaces n ON n.id = p.namespace_id
|
||
|
WHERE p.path IN (
|
||
|
'.well-known', 'all', 'assets', 'files', 'groups', 'hooks', 'issues',
|
||
|
'merge_requests', 'new', 'profile', 'projects', 'public', 'repository',
|
||
|
'robots.txt', 's', 'snippets', 'teams', 'u', 'unsubscribes', 'users',
|
||
|
'tree', 'commits', 'wikis', 'new', 'edit', 'create', 'update', 'logs_tree',
|
||
|
'preview', 'blob', 'blame', 'raw', 'files', 'create_dir', 'find_file')")
|
||
|
end
|
||
|
|
||
|
def route_exists?(full_path)
|
||
|
select_all("SELECT id, path FROM routes WHERE path = '#{quote_string(full_path)}'").present?
|
||
|
end
|
||
|
|
||
|
# Adds number to the end of the path that is not taken by other route
|
||
|
def rename_path(namespace_path, path_was)
|
||
|
counter = 0
|
||
|
path = "#{path_was}#{counter}"
|
||
|
|
||
|
while route_exists?("#{namespace_path}/#{path}")
|
||
|
counter += 1
|
||
|
path = "#{path_was}#{counter}"
|
||
|
end
|
||
|
|
||
|
path
|
||
|
end
|
||
|
|
||
|
def rename_projects(projects)
|
||
|
projects.each do |row|
|
||
|
id = row['id']
|
||
|
path_was = row['path']
|
||
|
namespace_path = row['namespace_path']
|
||
|
path = rename_path(namespace_path, path_was)
|
||
|
project = Project.find_by(id: id)
|
||
|
|
||
|
begin
|
||
|
# Because project path update is quite complex operation we can't safely
|
||
|
# copy-paste all code from GitLab. As exception we use Rails code here
|
||
|
if project &&
|
||
|
project.respond_to?(:update_attributes) &&
|
||
|
project.update_attributes(path: path) &&
|
||
|
project.respond_to?(:rename_repo)
|
||
|
|
||
|
project.rename_repo
|
||
|
end
|
||
|
rescue => e
|
||
|
Rails.logger.error "Exception when rename project #{id}: #{e.message}"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|