Commit f35ff1ea authored by Toon Claes's avatar Toon Claes

Ensure all Routables have a parent

Or otherwise do not try to write repo config.
parent de0cc8e4
...@@ -7,6 +7,8 @@ module Gitlab ...@@ -7,6 +7,8 @@ module Gitlab
# Storing the full project path in the git config allows admins to # Storing the full project path in the git config allows admins to
# easily identify a project when it is using hashed storage. # easily identify a project when it is using hashed storage.
module BackfillProjectFullpathInRepoConfig module BackfillProjectFullpathInRepoConfig
OrphanedNamespaceError = Class.new(StandardError)
module Storage module Storage
# Class that returns the disk path for a project using hashed storage # Class that returns the disk path for a project using hashed storage
class HashedProject class HashedProject
...@@ -51,11 +53,15 @@ module Gitlab ...@@ -51,11 +53,15 @@ module Gitlab
end end
def build_full_path def build_full_path
if parent && path return path unless has_parent?
raise OrphanedNamespaceError if parent.nil?
parent.full_path + '/' + path parent.full_path + '/' + path
else
path
end end
def has_parent?
read_attribute(association(:parent).reflection.foreign_key)
end end
end end
...@@ -81,7 +87,9 @@ module Gitlab ...@@ -81,7 +87,9 @@ module Gitlab
include Routable include Routable
belongs_to :parent, class_name: "Namespace" belongs_to :parent, class_name: 'Namespace', inverse_of: 'namespaces'
has_many :projects, inverse_of: :parent
has_many :namespaces, inverse_of: :parent
end end
# Project is where the repository (etc.) is stored # Project is where the repository (etc.) is stored
...@@ -93,9 +101,8 @@ module Gitlab ...@@ -93,9 +101,8 @@ module Gitlab
FULLPATH_CONFIG_KEY = 'gitlab.fullpath' FULLPATH_CONFIG_KEY = 'gitlab.fullpath'
belongs_to :namespace belongs_to :parent, class_name: 'Namespace', foreign_key: :namespace_id, inverse_of: 'projects'
delegate :disk_path, to: :storage delegate :disk_path, to: :storage
alias_method :parent, :namespace
def add_fullpath_config def add_fullpath_config
entries = { FULLPATH_CONFIG_KEY => full_path } entries = { FULLPATH_CONFIG_KEY => full_path }
...@@ -150,14 +157,14 @@ module Gitlab ...@@ -150,14 +157,14 @@ module Gitlab
end end
def perform(start_id, end_id) def perform(start_id, end_id)
Project.where(id: start_id..end_id).each do |project| Project.includes(:parent).where(id: start_id..end_id).each do |project|
safe_perform_one(project) safe_perform_one(project)
end end
end end
def safe_perform_one(project, retry_count = 0) def safe_perform_one(project, retry_count = 0)
perform_one(project) perform_one(project)
rescue GRPC::NotFound, GRPC::InvalidArgument rescue GRPC::NotFound, GRPC::InvalidArgument, OrphanedNamespaceError
nil nil
rescue GRPC::BadStatus rescue GRPC::BadStatus
schedule_retry(project, retry_count + 1) if retry_count < MAX_RETRIES schedule_retry(project, retry_count + 1) if retry_count < MAX_RETRIES
......
...@@ -34,6 +34,12 @@ describe Gitlab::BackgroundMigration::BackfillProjectFullpathInRepoConfig, :migr ...@@ -34,6 +34,12 @@ describe Gitlab::BackgroundMigration::BackfillProjectFullpathInRepoConfig, :migr
it 'returns path containing all parent namespaces' do it 'returns path containing all parent namespaces' do
expect(project.full_path).to eq('foo/bar/baz') expect(project.full_path).to eq('foo/bar/baz')
end end
it 'raises OrphanedNamespaceError when any parent namespace does not exist' do
subgroup.update_attribute(:parent_id, namespaces.maximum(:id).succ)
expect { project.full_path }.to raise_error(Gitlab::BackgroundMigration::BackfillProjectFullpathInRepoConfig::OrphanedNamespaceError)
end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment