Class: Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces

Inherits:
RenameBase
  • Object
show all
Includes:
ShellAdapter
Defined in:
lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb

Instance Attribute Summary

Attributes inherited from RenameBase

#migration, #paths

Instance Method Summary collapse

Methods included from ShellAdapter

#gitlab_shell

Methods inherited from RenameBase

#file_storage?, #initialize, #join_routable_path, #move_folders, #move_pages, #move_uploads, #pages_dir, #path_patterns, #perform_rename, #redis_key_for_type, #remove_cached_html_for_projects, #remove_last_occurrence, #rename_path, #rename_path_for_routable, #rename_routes, #reverts_for_type, #route_exists?, #track_rename, #uploads_dir

Constructor Details

This class inherits a constructor from Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase

Instance Method Details

#child_ids_for_parent(namespace, ids: []) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 95

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

#move_repositories(namespace, old_full_path, new_full_path) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 68

def move_repositories(namespace, old_full_path, new_full_path)
  repo_shards_for_namespace(namespace).each do |repository_storage|
    # Ensure old directory exists before moving it
    Gitlab::GitalyClient::NamespaceService.allow do
      gitlab_shell.add_namespace(repository_storage, old_full_path)

      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}"
        Gitlab::AppLogger.error message
      end
    end
  end
end

#namespaces_for_paths(type:) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 16

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
  with_paths = MigrationClasses::Route.arel_table[:path]
                 .matches_any(path_patterns)
  namespaces.joins(:route).where(with_paths)
    .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/420046")
end

#projects_for_namespace(namespace) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 87

def projects_for_namespace(namespace)
  namespace_ids = child_ids_for_parent(namespace, ids: [namespace.id])
  namespace_or_children = MigrationClasses::Project
                            .arel_table[:namespace_id]
                            .in(namespace_ids)
  MigrationClasses::Project.where(namespace_or_children)
end

#rename_namespace(namespace) ⇒ Object



29
30
31
32
33
34
35
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 29

def rename_namespace(namespace)
  old_full_path, new_full_path = rename_path_for_routable(namespace)

  track_rename('namespace', old_full_path, new_full_path)

  rename_namespace_dependencies(namespace, old_full_path, new_full_path)
end

#rename_namespace_dependencies(namespace, old_full_path, new_full_path) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 37

def rename_namespace_dependencies(namespace, old_full_path, new_full_path)
  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

#rename_namespaces(type:) ⇒ Object



10
11
12
13
14
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 10

def rename_namespaces(type:)
  namespaces_for_paths(type: type).each do |namespace|
    rename_namespace(namespace)
  end
end

#rename_user(old_username, new_username) ⇒ Object



63
64
65
66
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 63

def rename_user(old_username, new_username)
  MigrationClasses::User.where(username: old_username)
    .update_all(username: new_username)
end

#repo_shards_for_namespace(namespace) ⇒ Object



82
83
84
85
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 82

def repo_shards_for_namespace(namespace)
  projects_for_namespace(namespace).distinct.select(:repository_storage)
    .map(&:repository_storage)
end

#revert_renamesObject



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb', line 45

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)
                  .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/420046")
                  .find_by(matches_path)&.becomes(MigrationClasses::Namespace) # rubocop: disable Cop/AvoidBecomes

    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