Ensure all Routables have a parent
Or otherwise do not try to write repo config.
This commit is contained in:
		
							parent
							
								
									de0cc8e46a
								
							
						
					
					
						commit
						f35ff1ea48
					
				|  | @ -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 | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         def build_full_path |         def build_full_path | ||||||
|           if parent && path |           return path unless has_parent? | ||||||
|             parent.full_path + '/' + path | 
 | ||||||
|           else |           raise OrphanedNamespaceError if parent.nil? | ||||||
|             path | 
 | ||||||
|           end |           parent.full_path + '/' + path | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |         def has_parent? | ||||||
|  |           read_attribute(association(:parent).reflection.foreign_key) | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|  | @ -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 | ||||||
| 
 | 
 | ||||||
|         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 | ||||||
|         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 | ||||||
|       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 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue