diff options
author | Douwe Maan <douwe@gitlab.com> | 2017-03-13 15:54:38 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2017-03-13 15:54:38 +0000 |
commit | 1b1e64d5400acca5eeaa79a249a1b4f124ec6f41 (patch) | |
tree | 465374bc461d43481d84168a8c9ad5d2c3d32856 /db | |
parent | a6f9913f71a61399fd2b7b6af94551ea6aeeb71f (diff) | |
parent | cd4db7b4171a090d25391f4cf0425ece3692fa9f (diff) | |
download | gitlab-ce-1b1e64d5400acca5eeaa79a249a1b4f124ec6f41.tar.gz |
Merge branch 'dz-blacklist--names' into 'master'
Blacklist nested groups and project names that can cause ambiguous routing for HA
Closes #29324
See merge request !9898
Diffstat (limited to 'db')
-rw-r--r-- | db/post_migrate/20170313133418_rename_more_reserved_project_names.rb | 101 | ||||
-rw-r--r-- | db/schema.rb | 2 |
2 files changed, 102 insertions, 1 deletions
diff --git a/db/post_migrate/20170313133418_rename_more_reserved_project_names.rb b/db/post_migrate/20170313133418_rename_more_reserved_project_names.rb new file mode 100644 index 00000000000..9dfe77bedb7 --- /dev/null +++ b/db/post_migrate/20170313133418_rename_more_reserved_project_names.rb @@ -0,0 +1,101 @@ +require 'thread' + +class RenameMoreReservedProjectNames < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + include Gitlab::ShellAdapter + + DOWNTIME = false + + THREAD_COUNT = 8 + + KNOWN_PATHS = %w(artifacts graphs refs badges).freeze + + def up + queues = Array.new(THREAD_COUNT) { Queue.new } + start = false + + threads = Array.new(THREAD_COUNT) do |index| + Thread.new do + queue = queues[index] + + # Wait until we have input to process. + until start; end + + rename_projects(queue.pop) until queue.empty? + end + end + + enum = queues.each + + reserved_projects.each_slice(100) do |slice| + begin + queue = enum.next + rescue StopIteration + enum.rewind + retry + end + + queue << slice + end + + start = true + + threads.each(&:join) + end + + def down + # nothing to do here + end + + private + + def reserved_projects + Project.unscoped. + includes(:namespace). + where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)'). + where('projects.path' => KNOWN_PATHS) + end + + def route_exists?(full_path) + quoted_path = ActiveRecord::Base.connection.quote_string(full_path) + + ActiveRecord::Base.connection. + select_all("SELECT id, path FROM routes WHERE path = '#{quoted_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 |project| + id = project.id + path_was = project.path + namespace_path = project.namespace.path + path = rename_path(namespace_path, path_was) + + 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 + project.rename_repo if rename_project_row(project, path) + rescue Exception => e # rubocop: disable Lint/RescueException + Rails.logger.error "Exception when renaming project #{id}: #{e.message}" + end + end + end + + def rename_project_row(project, path) + project.respond_to?(:update_attributes) && + project.update_attributes(path: path) && + project.respond_to?(:rename_repo) + end +end diff --git a/db/schema.rb b/db/schema.rb index 3ec5461f600..ca88198079f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170306170512) do +ActiveRecord::Schema.define(version: 20170313133418) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" |