Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab')
-rw-r--r--lib/gitlab/database/migration_helpers.rb6
-rw-r--r--lib/gitlab/exclusive_lease.rb11
-rw-r--r--lib/gitlab/git/blob.rb4
-rw-r--r--lib/gitlab/git/commit.rb7
-rw-r--r--lib/gitlab/git/index.rb12
-rw-r--r--lib/gitlab/git/repository.rb64
-rw-r--r--lib/gitlab/gitaly_client/remote_service.rb13
-rw-r--r--lib/gitlab/import_export.rb2
-rw-r--r--lib/gitlab/import_export/import_export.yml4
-rw-r--r--lib/gitlab/import_export/relation_factory.rb18
10 files changed, 115 insertions, 26 deletions
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 33171f83692..7b35c24d153 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -842,6 +842,12 @@ into similar problems in the future (e.g. when new tables are created).
def queue_background_migration_jobs_by_range_at_intervals(model_class, job_class_name, delay_interval, batch_size: BACKGROUND_MIGRATION_BATCH_SIZE)
raise "#{model_class} does not have an ID to use for batch ranges" unless model_class.column_names.include?('id')
+ # To not overload the worker too much we enforce a minimum interval both
+ # when scheduling and performing jobs.
+ if delay_interval < BackgroundMigrationWorker::MIN_INTERVAL
+ delay_interval = BackgroundMigrationWorker::MIN_INTERVAL
+ end
+
model_class.each_batch(of: batch_size) do |relation, index|
start_id, end_id = relation.pluck('MIN(id), MAX(id)').first
diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb
index 3f7b42456af..dbb8f317afe 100644
--- a/lib/gitlab/exclusive_lease.rb
+++ b/lib/gitlab/exclusive_lease.rb
@@ -71,5 +71,16 @@ module Gitlab
redis.exists(@redis_shared_state_key)
end
end
+
+ # Returns the TTL of the Redis key.
+ #
+ # This method will return `nil` if no TTL could be obtained.
+ def ttl
+ Gitlab::Redis::SharedState.with do |redis|
+ ttl = redis.ttl(@redis_shared_state_key)
+
+ ttl if ttl.positive?
+ end
+ end
end
end
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
index a1755143abe..031fccba92b 100644
--- a/lib/gitlab/git/blob.rb
+++ b/lib/gitlab/git/blob.rb
@@ -173,8 +173,8 @@ module Gitlab
end
def find_by_rugged(repository, sha, path, limit:)
- commit = repository.lookup(sha)
- root_tree = commit.tree
+ rugged_commit = repository.lookup(sha)
+ root_tree = rugged_commit.tree
blob_entry = find_entry_by_path(repository, root_tree.oid, path)
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
index 145721dea76..016437b2419 100644
--- a/lib/gitlab/git/commit.rb
+++ b/lib/gitlab/git/commit.rb
@@ -15,8 +15,6 @@ module Gitlab
attr_accessor *SERIALIZE_KEYS # rubocop:disable Lint/AmbiguousOperator
- delegate :tree, to: :rugged_commit
-
def ==(other)
return false unless other.is_a?(Gitlab::Git::Commit)
@@ -452,6 +450,11 @@ module Gitlab
)
end
+ # Is this the same as Blob.find_entry_by_path ?
+ def rugged_tree_entry(path)
+ rugged_commit.tree.path(path)
+ end
+
private
def init_from_hash(hash)
diff --git a/lib/gitlab/git/index.rb b/lib/gitlab/git/index.rb
index db532600d1b..d94082a3e30 100644
--- a/lib/gitlab/git/index.rb
+++ b/lib/gitlab/git/index.rb
@@ -10,6 +10,7 @@ module Gitlab
DEFAULT_MODE = 0o100644
ACTIONS = %w(create create_dir update move delete).freeze
+ ACTION_OPTIONS = %i(file_path previous_path content encoding).freeze
attr_reader :repository, :raw_index
@@ -20,6 +21,11 @@ module Gitlab
delegate :read_tree, :get, to: :raw_index
+ def apply(action, options)
+ validate_action!(action)
+ public_send(action, options.slice(*ACTION_OPTIONS)) # rubocop:disable GitlabSecurity/PublicSend
+ end
+
def write_tree
raw_index.write_tree(repository.rugged)
end
@@ -140,6 +146,12 @@ module Gitlab
rescue Rugged::IndexError => e
raise IndexError, e.message
end
+
+ def validate_action!(action)
+ unless ACTIONS.include?(action.to_s)
+ raise ArgumentError, "Unknown action '#{action}'"
+ end
+ end
end
end
end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index e8b1788e140..283134e043e 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -1163,23 +1163,13 @@ module Gitlab
end
def fetch_repository_as_mirror(repository)
- remote_name = "tmp-#{SecureRandom.hex}"
-
- # Notice that this feature flag is not for `fetch_repository_as_mirror`
- # as a whole but for the fetching mechanism (file path or gitaly-ssh).
- url, env = gitaly_migrate(:fetch_internal) do |is_enabled|
+ gitaly_migrate(:remote_fetch_internal_remote) do |is_enabled|
if is_enabled
- repository = RemoteRepository.new(repository) unless repository.is_a?(RemoteRepository)
- [GITALY_INTERNAL_URL, repository.fetch_env]
+ gitaly_remote_client.fetch_internal_remote(repository)
else
- [repository.path, nil]
+ rugged_fetch_repository_as_mirror(repository)
end
end
-
- add_remote(remote_name, url, mirror_refmap: :all_refs)
- fetch_remote(remote_name, env: env)
- ensure
- remove_remote(remote_name)
end
def blob_at(sha, path)
@@ -1187,7 +1177,7 @@ module Gitlab
end
# Items should be of format [[commit_id, path], [commit_id1, path1]]
- def batch_blobs(items, blob_size_limit: nil)
+ def batch_blobs(items, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE)
Gitlab::Git::Blob.batch(self, items, blob_size_limit: blob_size_limit)
end
@@ -1300,6 +1290,42 @@ module Gitlab
success || gitlab_projects_error
end
+ # rubocop:disable Metrics/ParameterLists
+ def multi_action(
+ user, branch_name:, message:, actions:,
+ author_email: nil, author_name: nil,
+ start_branch_name: nil, start_repository: self)
+
+ OperationService.new(user, self).with_branch(
+ branch_name,
+ start_branch_name: start_branch_name,
+ start_repository: start_repository
+ ) do |start_commit|
+ index = Gitlab::Git::Index.new(self)
+ parents = []
+
+ if start_commit
+ index.read_tree(start_commit.rugged_commit.tree)
+ parents = [start_commit.sha]
+ end
+
+ actions.each { |opts| index.apply(opts.delete(:action), opts) }
+
+ committer = user_to_committer(user)
+ author = Gitlab::Git.committer_hash(email: author_email, name: author_name) || committer
+ options = {
+ tree: index.write_tree,
+ message: message,
+ parents: parents,
+ author: author,
+ committer: committer
+ }
+
+ create_commit(options)
+ end
+ end
+ # rubocop:enable Metrics/ParameterLists
+
def gitaly_repository
Gitlab::GitalyClient::Util.repository(@storage, @relative_path, @gl_repository)
end
@@ -2034,6 +2060,16 @@ module Gitlab
false
end
+ def rugged_fetch_repository_as_mirror(repository)
+ remote_name = "tmp-#{SecureRandom.hex}"
+ repository = RemoteRepository.new(repository) unless repository.is_a?(RemoteRepository)
+
+ add_remote(remote_name, GITALY_INTERNAL_URL, mirror_refmap: :all_refs)
+ fetch_remote(remote_name, env: repository.fetch_env)
+ ensure
+ remove_remote(remote_name)
+ end
+
def fetch_remote(remote_name = 'origin', env: nil)
run_git(['fetch', remote_name], env: env).last.zero?
end
diff --git a/lib/gitlab/gitaly_client/remote_service.rb b/lib/gitlab/gitaly_client/remote_service.rb
index 9218f6cfd68..559a901b9a3 100644
--- a/lib/gitlab/gitaly_client/remote_service.rb
+++ b/lib/gitlab/gitaly_client/remote_service.rb
@@ -23,6 +23,19 @@ module Gitlab
response.result
end
+
+ def fetch_internal_remote(repository)
+ request = Gitaly::FetchInternalRemoteRequest.new(
+ repository: @gitaly_repo,
+ remote_repository: repository.gitaly_repository
+ )
+
+ response = GitalyClient.call(@storage, :remote_service,
+ :fetch_internal_remote, request,
+ remote_storage: repository.storage)
+
+ response.result
+ end
end
end
end
diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb
index 2066005dddc..af203ff711d 100644
--- a/lib/gitlab/import_export.rb
+++ b/lib/gitlab/import_export.rb
@@ -3,7 +3,7 @@ module Gitlab
extend self
# For every version update, the version history in import_export.md has to be kept up to date.
- VERSION = '0.2.1'.freeze
+ VERSION = '0.2.2'.freeze
FILENAME_LIMIT = 50
def export_path(relative_path:)
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index f2b193c79cb..2daed10f678 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -49,8 +49,8 @@ project_tree:
- :author
- events:
- :push_event_payload
- - :stages
- - :statuses
+ - stages:
+ - :statuses
- :auto_devops
- :triggers
- :pipeline_schedules
diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb
index d7d1b05e8b9..05dbaf6322c 100644
--- a/lib/gitlab/import_export/relation_factory.rb
+++ b/lib/gitlab/import_export/relation_factory.rb
@@ -62,6 +62,7 @@ module Gitlab
when :notes then setup_note
when :project_label, :project_labels then setup_label
when :milestone, :milestones then setup_milestone
+ when 'Ci::Pipeline' then setup_pipeline
else
@relation_hash['project_id'] = @project.id
end
@@ -112,9 +113,7 @@ module Gitlab
@relation_hash.delete('trace') # old export files have trace
@relation_hash.delete('token')
- imported_object do |object|
- object.commit_id = nil
- end
+ imported_object
elsif @relation_name == :merge_requests
MergeRequestParser.new(@project, @relation_hash.delete('diff_head_sha'), imported_object, @relation_hash).parse!
else
@@ -182,8 +181,9 @@ module Gitlab
end
def imported_object
- yield(existing_or_new_object) if block_given?
- existing_or_new_object.importing = true if existing_or_new_object.respond_to?(:importing)
+ if existing_or_new_object.respond_to?(:importing)
+ existing_or_new_object.importing = true
+ end
existing_or_new_object
rescue ActiveRecord::RecordNotUnique
@@ -211,6 +211,14 @@ module Gitlab
@relation_hash['diff'] = @relation_hash.delete('utf8_diff')
end
+ def setup_pipeline
+ @relation_hash.fetch('stages').each do |stage|
+ stage.statuses.each do |status|
+ status.pipeline = imported_object
+ end
+ end
+ end
+
def existing_or_new_object
# Only find existing records to avoid mapping tables such as milestones
# Otherwise always create the record, skipping the extra SELECT clause.