summaryrefslogtreecommitdiff
path: root/app/services/repositories
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 11:10:13 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 11:10:13 +0000
commit0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch)
tree7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /app/services/repositories
parent72123183a20411a36d607d70b12d57c484394c8e (diff)
downloadgitlab-ce-0ea3fcec397b69815975647f5e2aa5fe944a8486.tar.gz
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'app/services/repositories')
-rw-r--r--app/services/repositories/base_service.rb12
-rw-r--r--app/services/repositories/changelog_service.rb32
-rw-r--r--app/services/repositories/destroy_rollback_service.rb25
-rw-r--r--app/services/repositories/destroy_service.rb36
-rw-r--r--app/services/repositories/shell_destroy_service.rb15
5 files changed, 47 insertions, 73 deletions
diff --git a/app/services/repositories/base_service.rb b/app/services/repositories/base_service.rb
index 13ad126f8f0..4d7e4ffe267 100644
--- a/app/services/repositories/base_service.rb
+++ b/app/services/repositories/base_service.rb
@@ -3,8 +3,6 @@
class Repositories::BaseService < BaseService
include Gitlab::ShellAdapter
- DELETED_FLAG = '+deleted'
-
attr_reader :repository
delegate :container, :disk_path, :full_path, to: :repository
@@ -21,16 +19,6 @@ class Repositories::BaseService < BaseService
gitlab_shell.mv_repository(repository.shard, from_path, to_path)
end
- # Build a path for removing repositories
- # We use `+` because its not allowed by GitLab so user can not create
- # project with name cookies+119+deleted and capture someone stalled repository
- #
- # gitlab/cookies.git -> gitlab/cookies+119+deleted.git
- #
- def removal_path
- "#{disk_path}+#{container.id}#{DELETED_FLAG}"
- end
-
# If we get a Gitaly error, the repository may be corrupted. We can
# ignore these errors since we're going to trash the repositories
# anyway.
diff --git a/app/services/repositories/changelog_service.rb b/app/services/repositories/changelog_service.rb
index eafd9d7a55e..7a78b323453 100644
--- a/app/services/repositories/changelog_service.rb
+++ b/app/services/repositories/changelog_service.rb
@@ -6,6 +6,19 @@ module Repositories
DEFAULT_TRAILER = 'Changelog'
DEFAULT_FILE = 'CHANGELOG.md'
+ # The maximum number of commits allowed to fetch in `from` and `to` range.
+ #
+ # This value is arbitrarily chosen. Increasing it means more Gitaly calls
+ # and more presure on Gitaly services.
+ #
+ # This number is 3x of the average number of commits per GitLab releases.
+ # Some examples for GitLab's own releases:
+ #
+ # * 13.6.0: 4636 commits
+ # * 13.5.0: 5912 commits
+ # * 13.4.0: 5541 commits
+ COMMITS_LIMIT = 15_000
+
# The `project` specifies the `Project` to generate the changelog section
# for.
#
@@ -75,6 +88,8 @@ module Repositories
commits =
ChangelogCommitsFinder.new(project: @project, from: from, to: @to)
+ verify_commit_range!(from, @to)
+
commits.each_page(@trailer) do |page|
mrs = mrs_finder.execute(page)
@@ -82,6 +97,9 @@ module Repositories
# batch of commits, instead of needing a query for every commit.
page.each(&:lazy_author)
+ # Preload author permissions
+ @project.team.max_member_access_for_user_ids(page.map(&:author).compact.map(&:id))
+
page.each do |commit|
release.add_entry(
title: commit.title,
@@ -117,5 +135,19 @@ module Repositories
'could be found to use instead'
)
end
+
+ def verify_commit_range!(from, to)
+ return unless Feature.enabled?(:changelog_commits_limitation, @project)
+
+ commits = @project.repository.commits_by(oids: [from, to])
+
+ raise Gitlab::Changelog::Error, "Invalid or not found commit value in the given range" unless commits.count == 2
+
+ _, commits_count = @project.repository.diverging_commit_count(from, to)
+
+ if commits_count > COMMITS_LIMIT
+ raise Gitlab::Changelog::Error, "The commits range exceeds #{COMMITS_LIMIT} elements."
+ end
+ end
end
end
diff --git a/app/services/repositories/destroy_rollback_service.rb b/app/services/repositories/destroy_rollback_service.rb
deleted file mode 100644
index a19e305607f..00000000000
--- a/app/services/repositories/destroy_rollback_service.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class Repositories::DestroyRollbackService < Repositories::BaseService
- def execute
- # There is a possibility project does not have repository or wiki
- return success unless repo_exists?(removal_path)
-
- # Flush the cache for both repositories.
- ignore_git_errors { repository.before_delete }
-
- if mv_repository(removal_path, disk_path)
- log_info(%Q{Repository "#{removal_path}" moved to "#{disk_path}" for repository "#{full_path}"})
-
- success
- elsif repo_exists?(removal_path)
- # If the repo does not exist, there is no need to return an
- # error because there was nothing to do.
- move_error(removal_path)
- else
- success
- end
- rescue Gitlab::Git::Repository::NoRepository
- success
- end
-end
diff --git a/app/services/repositories/destroy_service.rb b/app/services/repositories/destroy_service.rb
index c5a0af56066..a87b8d09244 100644
--- a/app/services/repositories/destroy_service.rb
+++ b/app/services/repositories/destroy_service.rb
@@ -10,31 +10,25 @@ class Repositories::DestroyService < Repositories::BaseService
# Git data (e.g. a list of branch names).
ignore_git_errors { repository.before_delete }
- if mv_repository(disk_path, removal_path)
- log_info(%Q{Repository "#{disk_path}" moved to "#{removal_path}" for repository "#{full_path}"})
+ # Use variables that aren't methods on Project, because they are used in a callback
+ current_storage = repository.shard
+ current_path = "#{disk_path}.git"
- current_repository = repository
-
- # Because GitlabShellWorker is inside a run_after_commit callback it will
- # never be triggered on a read-only instance.
- #
- # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/223272
- if Gitlab::Database.read_only?
- Repositories::ShellDestroyService.new(current_repository).execute
- else
- container.run_after_commit do
- Repositories::ShellDestroyService.new(current_repository).execute
- end
+ # Because #remove happens inside a run_after_commit callback it will
+ # never be triggered on a read-only instance.
+ #
+ # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/223272
+ if Gitlab::Database.read_only?
+ Gitlab::Git::Repository.new(current_storage, current_path, nil, nil).remove
+ else
+ container.run_after_commit do
+ Gitlab::Git::Repository.new(current_storage, current_path, nil, nil).remove
end
+ end
- log_info("Repository \"#{full_path}\" was removed")
+ log_info("Repository \"#{full_path}\" was removed")
- success
- elsif repo_exists?(disk_path)
- move_error(disk_path)
- else
- success
- end
+ success
rescue Gitlab::Git::Repository::NoRepository
success
end
diff --git a/app/services/repositories/shell_destroy_service.rb b/app/services/repositories/shell_destroy_service.rb
deleted file mode 100644
index d25cb28c6d7..00000000000
--- a/app/services/repositories/shell_destroy_service.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-class Repositories::ShellDestroyService < Repositories::BaseService
- REPO_REMOVAL_DELAY = 5.minutes.to_i
- STALE_REMOVAL_DELAY = REPO_REMOVAL_DELAY * 2
-
- def execute(delay = REPO_REMOVAL_DELAY)
- return success unless repository
-
- GitlabShellWorker.perform_in(delay,
- :remove_repository,
- repository.shard,
- removal_path)
- end
-end