summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2018-11-29 16:08:14 +0000
committerNick Thomas <nick@gitlab.com>2018-11-29 16:08:14 +0000
commitb09a447f734de0ef23b15c879628640f0af62d87 (patch)
tree82c4d1926bd246fb857bb5ad9adaf68c45982dd5
parent6775dafa3816239f6fa1b12428df42572be5a158 (diff)
parent198fdc54789dcb24efb0622a23e6931d83e1faa6 (diff)
downloadgitlab-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.rb18
-rw-r--r--app/models/pool_repository.rb11
-rw-r--r--app/models/project.rb8
-rw-r--r--app/models/project_repository.rb13
-rw-r--r--app/services/projects/create_service.rb2
-rw-r--r--app/services/projects/hashed_storage/migrate_repository_service.rb1
-rw-r--r--changelogs/unreleased/tc-repo-full-path-in-db.yml5
-rw-r--r--db/migrate/20181122160027_create_project_repositories.rb18
-rw-r--r--db/schema.rb11
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/models/pool_repository_spec.rb2
-rw-r--r--spec/models/project_repository_spec.rb23
-rw-r--r--spec/models/project_spec.rb25
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 }