diff options
author | Nick Thomas <nick@gitlab.com> | 2018-11-29 16:08:14 +0000 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2018-11-29 16:08:14 +0000 |
commit | b09a447f734de0ef23b15c879628640f0af62d87 (patch) | |
tree | 82c4d1926bd246fb857bb5ad9adaf68c45982dd5 | |
parent | 6775dafa3816239f6fa1b12428df42572be5a158 (diff) | |
parent | 198fdc54789dcb24efb0622a23e6931d83e1faa6 (diff) | |
download | gitlab-ce-b09a447f734de0ef23b15c879628640f0af62d87.tar.gz |
Merge branch 'tc-repo-full-path-in-db' into 'master'
Store hashed storage paths in the database
See merge request gitlab-org/gitlab-ce!23143
-rw-r--r-- | app/models/concerns/shardable.rb | 18 | ||||
-rw-r--r-- | app/models/pool_repository.rb | 11 | ||||
-rw-r--r-- | app/models/project.rb | 8 | ||||
-rw-r--r-- | app/models/project_repository.rb | 13 | ||||
-rw-r--r-- | app/services/projects/create_service.rb | 2 | ||||
-rw-r--r-- | app/services/projects/hashed_storage/migrate_repository_service.rb | 1 | ||||
-rw-r--r-- | changelogs/unreleased/tc-repo-full-path-in-db.yml | 5 | ||||
-rw-r--r-- | db/migrate/20181122160027_create_project_repositories.rb | 18 | ||||
-rw-r--r-- | db/schema.rb | 11 | ||||
-rw-r--r-- | spec/lib/gitlab/import_export/all_models.yml | 1 | ||||
-rw-r--r-- | spec/models/pool_repository_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/project_repository_spec.rb | 23 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 25 |
13 files changed, 128 insertions, 10 deletions
diff --git a/app/models/concerns/shardable.rb b/app/models/concerns/shardable.rb new file mode 100644 index 00000000000..57cd77b44b4 --- /dev/null +++ b/app/models/concerns/shardable.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Shardable + extend ActiveSupport::Concern + + included do + belongs_to :shard + validates :shard, presence: true + end + + def shard_name + shard&.name + end + + def shard_name=(name) + self.shard = Shard.by_name(name) + end +end diff --git a/app/models/pool_repository.rb b/app/models/pool_repository.rb index 7351674201e..bad0e30ceb5 100644 --- a/app/models/pool_repository.rb +++ b/app/models/pool_repository.rb @@ -1,21 +1,12 @@ # frozen_string_literal: true class PoolRepository < ActiveRecord::Base - belongs_to :shard - validates :shard, presence: true + include Shardable has_many :member_projects, class_name: 'Project' after_create :correct_disk_path - def shard_name - shard&.name - end - - def shard_name=(name) - self.shard = Shard.by_name(name) - end - private def correct_disk_path diff --git a/app/models/project.rb b/app/models/project.rb index 185fd76cbbc..ade20cc8948 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -186,6 +186,7 @@ class Project < ActiveRecord::Base has_one :import_state, autosave: true, class_name: 'ProjectImportState', inverse_of: :project has_one :import_export_upload, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_one :project_repository, inverse_of: :project # Merge Requests for target project should be removed with it has_many :merge_requests, foreign_key: 'target_project_id', inverse_of: :target_project @@ -1206,6 +1207,13 @@ class Project < ActiveRecord::Base false end + def track_project_repository + return unless hashed_storage?(:repository) + + project_repo = project_repository || build_project_repository + project_repo.update!(shard_name: repository_storage, disk_path: disk_path) + end + def create_repository(force: false) # Forked import is handled asynchronously return if forked? && !force diff --git a/app/models/project_repository.rb b/app/models/project_repository.rb new file mode 100644 index 00000000000..38913f3f2f5 --- /dev/null +++ b/app/models/project_repository.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class ProjectRepository < ActiveRecord::Base + include Shardable + + belongs_to :project, inverse_of: :project_repository + + class << self + def find_project(disk_path) + find_by(disk_path: disk_path)&.project + end + end +end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 481de34b977..2458f5b308a 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -86,6 +86,8 @@ module Projects @project.create_wiki unless skip_wiki? end + @project.track_project_repository + event_service.create_project(@project, current_user) system_hook_service.execute_hooks_for(@project, :create) diff --git a/app/services/projects/hashed_storage/migrate_repository_service.rb b/app/services/projects/hashed_storage/migrate_repository_service.rb index 4462d504071..f3e026ba38c 100644 --- a/app/services/projects/hashed_storage/migrate_repository_service.rb +++ b/app/services/projects/hashed_storage/migrate_repository_service.rb @@ -30,6 +30,7 @@ module Projects if result project.write_repository_config + project.track_project_repository else rollback_folder_move project.storage_version = nil diff --git a/changelogs/unreleased/tc-repo-full-path-in-db.yml b/changelogs/unreleased/tc-repo-full-path-in-db.yml new file mode 100644 index 00000000000..ead8feabeb9 --- /dev/null +++ b/changelogs/unreleased/tc-repo-full-path-in-db.yml @@ -0,0 +1,5 @@ +--- +title: Add model and relation to store repo full path in database +merge_request: 23143 +author: +type: added diff --git a/db/migrate/20181122160027_create_project_repositories.rb b/db/migrate/20181122160027_create_project_repositories.rb new file mode 100644 index 00000000000..e42cef9b1c6 --- /dev/null +++ b/db/migrate/20181122160027_create_project_repositories.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class CreateProjectRepositories < ActiveRecord::Migration[5.0] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :project_repositories, id: :bigserial do |t| + t.references :shard, null: false, index: true, foreign_key: { on_delete: :restrict } + t.string :disk_path, null: false, index: { unique: true } + t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4f9588fd86b..995619bdc69 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1601,6 +1601,15 @@ ActiveRecord::Schema.define(version: 20181126153547) do t.index ["status"], name: "index_project_mirror_data_on_status", using: :btree end + create_table "project_repositories", id: :bigserial, force: :cascade do |t| + t.integer "shard_id", null: false + t.string "disk_path", null: false + t.integer "project_id", null: false + t.index ["disk_path"], name: "index_project_repositories_on_disk_path", unique: true, using: :btree + t.index ["project_id"], name: "index_project_repositories_on_project_id", unique: true, using: :btree + t.index ["shard_id"], name: "index_project_repositories_on_shard_id", using: :btree + end + create_table "project_statistics", force: :cascade do |t| t.integer "project_id", null: false t.integer "namespace_id", null: false @@ -2385,6 +2394,8 @@ ActiveRecord::Schema.define(version: 20181126153547) do add_foreign_key "project_group_links", "projects", name: "fk_daa8cee94c", on_delete: :cascade add_foreign_key "project_import_data", "projects", name: "fk_ffb9ee3a10", on_delete: :cascade add_foreign_key "project_mirror_data", "projects", on_delete: :cascade + add_foreign_key "project_repositories", "projects", on_delete: :cascade + add_foreign_key "project_repositories", "shards", on_delete: :restrict add_foreign_key "project_statistics", "projects", on_delete: :cascade add_foreign_key "projects", "pool_repositories", name: "fk_6e5c14658a", on_delete: :nullify add_foreign_key "prometheus_metrics", "projects", on_delete: :cascade diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 1d184375a52..8d2f60d7a8b 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -245,6 +245,7 @@ project: - protected_branches - protected_tags - project_members +- project_repository - users - requesters - deploy_keys_projects diff --git a/spec/models/pool_repository_spec.rb b/spec/models/pool_repository_spec.rb index 6c904710fb5..541e78507e5 100644 --- a/spec/models/pool_repository_spec.rb +++ b/spec/models/pool_repository_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe PoolRepository do diff --git a/spec/models/project_repository_spec.rb b/spec/models/project_repository_spec.rb new file mode 100644 index 00000000000..c966447fedc --- /dev/null +++ b/spec/models/project_repository_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ProjectRepository do + describe 'associations' do + it { is_expected.to belong_to(:shard) } + it { is_expected.to belong_to(:project) } + end + + describe '.find_project' do + it 'finds project by disk path' do + project = create(:project) + project.track_project_repository + + expect(described_class.find_project(project.disk_path)).to eq(project) + end + + it 'returns nil when it does not find the project' do + expect(described_class.find_project('@@unexisting/path/to/project')).to be_nil + end + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index e98c69e636a..af5b0939ca2 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -54,6 +54,7 @@ describe Project do it { is_expected.to have_one(:gitlab_issue_tracker_service) } it { is_expected.to have_one(:external_wiki_service) } it { is_expected.to have_one(:project_feature) } + it { is_expected.to have_one(:project_repository) } it { is_expected.to have_one(:statistics).class_name('ProjectStatistics') } it { is_expected.to have_one(:import_data).class_name('ProjectImportData') } it { is_expected.to have_one(:last_event).class_name('Event') } @@ -1618,6 +1619,30 @@ describe Project do end end + describe '#track_project_repository' do + let(:project) { create(:project, :repository) } + + it 'creates a project_repository' do + project.track_project_repository + + expect(project.reload.project_repository).to be_present + expect(project.project_repository.disk_path).to eq(project.disk_path) + expect(project.project_repository.shard_name).to eq(project.repository_storage) + end + + it 'updates the project_repository' do + project.track_project_repository + + allow(project).to receive(:disk_path).and_return('@fancy/new/path') + + expect do + project.track_project_repository + end.not_to change(ProjectRepository, :count) + + expect(project.reload.project_repository.disk_path).to eq(project.disk_path) + end + end + describe '#create_repository' do let(:project) { create(:project, :repository) } let(:shell) { Gitlab::Shell.new } |