diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-20 11:10:13 +0000 |
commit | 0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch) | |
tree | 7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /app/services/repositories | |
parent | 72123183a20411a36d607d70b12d57c484394c8e (diff) | |
download | gitlab-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.rb | 12 | ||||
-rw-r--r-- | app/services/repositories/changelog_service.rb | 32 | ||||
-rw-r--r-- | app/services/repositories/destroy_rollback_service.rb | 25 | ||||
-rw-r--r-- | app/services/repositories/destroy_service.rb | 36 | ||||
-rw-r--r-- | app/services/repositories/shell_destroy_service.rb | 15 |
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 |