2019-02-15 15:39:39 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-08-17 22:00:37 +05:30
|
|
|
module Gitlab
|
|
|
|
module Database
|
|
|
|
module RenameReservedPathsMigration
|
|
|
|
module V1
|
|
|
|
class RenameNamespaces < RenameBase
|
|
|
|
include Gitlab::ShellAdapter
|
|
|
|
|
|
|
|
def rename_namespaces(type:)
|
|
|
|
namespaces_for_paths(type: type).each do |namespace|
|
|
|
|
rename_namespace(namespace)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def namespaces_for_paths(type:)
|
|
|
|
namespaces = case type
|
|
|
|
when :child
|
|
|
|
MigrationClasses::Namespace.where.not(parent_id: nil)
|
|
|
|
when :top_level
|
|
|
|
MigrationClasses::Namespace.where(parent_id: nil)
|
|
|
|
end
|
2017-09-10 17:25:29 +05:30
|
|
|
with_paths = MigrationClasses::Route.arel_table[:path]
|
|
|
|
.matches_any(path_patterns)
|
2017-08-17 22:00:37 +05:30
|
|
|
namespaces.joins(:route).where(with_paths)
|
|
|
|
end
|
|
|
|
|
|
|
|
def rename_namespace(namespace)
|
|
|
|
old_full_path, new_full_path = rename_path_for_routable(namespace)
|
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
track_rename('namespace', old_full_path, new_full_path)
|
|
|
|
|
|
|
|
rename_namespace_dependencies(namespace, old_full_path, new_full_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def rename_namespace_dependencies(namespace, old_full_path, new_full_path)
|
2017-08-17 22:00:37 +05:30
|
|
|
move_repositories(namespace, old_full_path, new_full_path)
|
|
|
|
move_uploads(old_full_path, new_full_path)
|
|
|
|
move_pages(old_full_path, new_full_path)
|
|
|
|
rename_user(old_full_path, new_full_path) if namespace.kind == 'user'
|
|
|
|
remove_cached_html_for_projects(projects_for_namespace(namespace).map(&:id))
|
|
|
|
end
|
|
|
|
|
2017-09-10 17:25:29 +05:30
|
|
|
def revert_renames
|
|
|
|
reverts_for_type('namespace') do |path_before_rename, current_path|
|
|
|
|
matches_path = MigrationClasses::Route.arel_table[:path].matches(current_path)
|
|
|
|
namespace = MigrationClasses::Namespace.joins(:route)
|
2020-04-22 19:07:51 +05:30
|
|
|
.find_by(matches_path)&.becomes(MigrationClasses::Namespace)
|
2017-09-10 17:25:29 +05:30
|
|
|
|
|
|
|
if namespace
|
|
|
|
perform_rename(namespace, current_path, path_before_rename)
|
|
|
|
|
|
|
|
rename_namespace_dependencies(namespace, current_path, path_before_rename)
|
|
|
|
else
|
|
|
|
say "Couldn't rename namespace from #{current_path} back to #{path_before_rename}, "\
|
|
|
|
"namespace was renamed, or no longer exists at the expected path"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-08-17 22:00:37 +05:30
|
|
|
def rename_user(old_username, new_username)
|
|
|
|
MigrationClasses::User.where(username: old_username)
|
|
|
|
.update_all(username: new_username)
|
|
|
|
end
|
|
|
|
|
|
|
|
def move_repositories(namespace, old_full_path, new_full_path)
|
2018-10-15 14:42:47 +05:30
|
|
|
repo_shards_for_namespace(namespace).each do |repository_storage|
|
2017-08-17 22:00:37 +05:30
|
|
|
# Ensure old directory exists before moving it
|
2019-12-26 22:10:19 +05:30
|
|
|
Gitlab::GitalyClient::NamespaceService.allow do
|
|
|
|
gitlab_shell.add_namespace(repository_storage, old_full_path)
|
2017-08-17 22:00:37 +05:30
|
|
|
|
2019-12-26 22:10:19 +05:30
|
|
|
unless gitlab_shell.mv_namespace(repository_storage, old_full_path, new_full_path)
|
|
|
|
message = "Exception moving on shard #{repository_storage} from #{old_full_path} to #{new_full_path}"
|
|
|
|
Rails.logger.error message # rubocop:disable Gitlab/RailsLogger
|
|
|
|
end
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-10-15 14:42:47 +05:30
|
|
|
def repo_shards_for_namespace(namespace)
|
2017-09-10 17:25:29 +05:30
|
|
|
projects_for_namespace(namespace).distinct.select(:repository_storage)
|
2018-10-15 14:42:47 +05:30
|
|
|
.map(&:repository_storage)
|
2017-08-17 22:00:37 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def projects_for_namespace(namespace)
|
|
|
|
namespace_ids = child_ids_for_parent(namespace, ids: [namespace.id])
|
2017-09-10 17:25:29 +05:30
|
|
|
namespace_or_children = MigrationClasses::Project
|
|
|
|
.arel_table[:namespace_id]
|
|
|
|
.in(namespace_ids)
|
2017-08-17 22:00:37 +05:30
|
|
|
MigrationClasses::Project.where(namespace_or_children)
|
|
|
|
end
|
|
|
|
|
|
|
|
def child_ids_for_parent(namespace, ids: [])
|
|
|
|
namespace.children.each do |child|
|
|
|
|
ids << child.id
|
|
|
|
child_ids_for_parent(child, ids: ids) if child.children.any?
|
|
|
|
end
|
|
|
|
ids
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|