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:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-18 13:50:51 +0300
commitdb384e6b19af03b4c3c82a5760d83a3fd79f7982 (patch)
tree34beaef37df5f47ccbcf5729d7583aae093cffa0 /lib/gitlab/checks
parent54fd7b1bad233e3944434da91d257fa7f63c3996 (diff)
Add latest changes from gitlab-org/gitlab@16-3-stable-eev16.3.0-rc42
Diffstat (limited to 'lib/gitlab/checks')
-rw-r--r--lib/gitlab/checks/branch_check.rb2
-rw-r--r--lib/gitlab/checks/diff_check.rb28
-rw-r--r--lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb38
-rw-r--r--lib/gitlab/checks/file_size_check/hook_environment_aware_any_oversized_blobs.rb54
-rw-r--r--lib/gitlab/checks/global_file_size_check.rb30
5 files changed, 103 insertions, 49 deletions
diff --git a/lib/gitlab/checks/branch_check.rb b/lib/gitlab/checks/branch_check.rb
index aa89c2711f9..b675eca826a 100644
--- a/lib/gitlab/checks/branch_check.rb
+++ b/lib/gitlab/checks/branch_check.rb
@@ -43,7 +43,7 @@ module Gitlab
def prohibited_branch_checks
return if deletion?
- if branch_name =~ %r{\A\h{40}(-/|/|\z)}
+ if %r{\A#{Gitlab::Git::Commit::RAW_FULL_SHA_PATTERN}(-/|/|\z)}o.match?(branch_name)
raise GitAccess::ForbiddenError, ERROR_MESSAGES[:prohibited_hex_branch_name]
end
diff --git a/lib/gitlab/checks/diff_check.rb b/lib/gitlab/checks/diff_check.rb
index bce4f969284..15b38188f13 100644
--- a/lib/gitlab/checks/diff_check.rb
+++ b/lib/gitlab/checks/diff_check.rb
@@ -18,10 +18,7 @@ module Gitlab
return unless should_run_validations?
return if commits.empty?
- paths = project.repository.find_changed_paths(
- commits.map(&:sha), merge_commit_diff_mode: :all_parents
- )
-
+ paths = project.repository.find_changed_paths(treeish_objects, merge_commit_diff_mode: :all_parents)
paths.each do |path|
validate_path(path)
end
@@ -31,6 +28,29 @@ module Gitlab
private
+ def treeish_objects
+ objects = commits
+
+ return objects unless project.repository.empty? &&
+ Feature.enabled?(:verify_push_rules_for_first_commit, project)
+
+ # It's a special case for the push to the empty repository
+ #
+ # Git doesn't display a diff of the initial commit of the repository
+ # if we just provide a commit sha.
+ #
+ # To fix that we can use TreeRequest to check the difference
+ # between empty tree sha and the tree sha of the initial commit
+ #
+ # `commits` are sorted in reverse order, the initial commit is the last one.
+ init_commit = objects.last
+
+ diff_tree = Gitlab::Git::DiffTree.from_commit(init_commit)
+ return [diff_tree] + objects if diff_tree
+
+ objects
+ end
+
def validate_lfs_file_locks?
strong_memoize(:validate_lfs_file_locks) do
project.lfs_enabled? && project.any_lfs_file_locks?
diff --git a/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb b/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb
deleted file mode 100644
index 78f1716274e..00000000000
--- a/lib/gitlab/checks/file_size_check/allow_existing_oversized_blobs.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Checks
- module FileSizeCheck
- class AllowExistingOversizedBlobs
- def initialize(project:, changes:, file_size_limit_megabytes:)
- @project = project
- @changes = changes
- @oldrevs = changes.pluck(:oldrev).compact # rubocop:disable CodeReuse/ActiveRecord just plucking from an array
- @file_size_limit_megabytes = file_size_limit_megabytes
- end
-
- def find(timeout: nil)
- oversize_blobs = any_oversize_blobs.find(timeout: timeout)
-
- return oversize_blobs unless oldrevs.present?
-
- revs_paths = oldrevs.product(oversize_blobs.map(&:path))
- existing_blobs = project.repository.blobs_at(revs_paths, blob_size_limit: 1)
- map_existing_path_to_size = existing_blobs.group_by(&:path).transform_values { |blobs| blobs.map(&:size).max }
-
- # return blobs that are going to be over the limit that were previously within the limit
- oversize_blobs.select { |blob| map_existing_path_to_size.fetch(blob.path, 0) <= file_size_limit_megabytes }
- end
-
- private
-
- attr_reader :project, :changes, :newrevs, :oldrevs, :file_size_limit_megabytes
-
- def any_oversize_blobs
- AnyOversizedBlobs.new(project: project, changes: changes,
- file_size_limit_megabytes: file_size_limit_megabytes)
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/checks/file_size_check/hook_environment_aware_any_oversized_blobs.rb b/lib/gitlab/checks/file_size_check/hook_environment_aware_any_oversized_blobs.rb
new file mode 100644
index 00000000000..952def83658
--- /dev/null
+++ b/lib/gitlab/checks/file_size_check/hook_environment_aware_any_oversized_blobs.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Checks
+ module FileSizeCheck
+ class HookEnvironmentAwareAnyOversizedBlobs
+ def initialize(project:, changes:, file_size_limit_megabytes:)
+ @project = project
+ @repository = project.repository
+ @changes = changes
+ @file_size_limit_megabytes = file_size_limit_megabytes
+ end
+
+ def find(timeout: nil)
+ if ignore_alternate_directories?
+ blobs = repository.list_all_blobs(bytes_limit: 0, dynamic_timeout: timeout,
+ ignore_alternate_object_directories: true).to_a
+
+ blobs.select! do |blob|
+ ::Gitlab::Utils.bytes_to_megabytes(blob.size) > file_size_limit_megabytes
+ end
+ filter_existing(blobs)
+ else
+ any_oversize_blobs.find(timeout: timeout)
+ end
+ end
+
+ private
+
+ attr_reader :project, :repository, :changes, :file_size_limit_megabytes
+
+ def filter_existing(blobs)
+ gitaly_repo = repository.gitaly_repository.dup.tap { |repo| repo.git_object_directory = "" }
+
+ map_blob_id_to_existence = repository.gitaly_commit_client.object_existence_map(blobs.map(&:id),
+ gitaly_repo: gitaly_repo)
+
+ blobs.reject { |blob| map_blob_id_to_existence[blob.id].present? }
+ end
+
+ def ignore_alternate_directories?
+ git_env = ::Gitlab::Git::HookEnv.all(repository.gl_repository)
+
+ git_env['GIT_OBJECT_DIRECTORY_RELATIVE'].present?
+ end
+
+ def any_oversize_blobs
+ AnyOversizedBlobs.new(project: project, changes: changes,
+ file_size_limit_megabytes: file_size_limit_megabytes)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/checks/global_file_size_check.rb b/lib/gitlab/checks/global_file_size_check.rb
index 418d2d32b57..62facf52239 100644
--- a/lib/gitlab/checks/global_file_size_check.rb
+++ b/lib/gitlab/checks/global_file_size_check.rb
@@ -3,7 +3,6 @@
module Gitlab
module Checks
class GlobalFileSizeCheck < BaseBulkChecker
- MAX_FILE_SIZE_MB = 100
LOG_MESSAGE = 'Checking for blobs over the file size limit'
def validate!
@@ -11,19 +10,38 @@ module Gitlab
Gitlab::AppJsonLogger.info(LOG_MESSAGE)
logger.log_timed(LOG_MESSAGE) do
- Gitlab::Checks::FileSizeCheck::AllowExistingOversizedBlobs.new(
+ oversized_blobs = Gitlab::Checks::FileSizeCheck::HookEnvironmentAwareAnyOversizedBlobs.new(
project: project,
changes: changes,
- file_size_limit_megabytes: MAX_FILE_SIZE_MB
+ file_size_limit_megabytes: file_size_limit
).find
- # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/393535
- # - set limit per plan tier
- # - raise an error if large blobs are found
+ if oversized_blobs.present?
+ Gitlab::AppJsonLogger.info(
+ message: 'Found blob over global limit',
+ blob_sizes: oversized_blobs.map(&:size)
+ )
+
+ if enforce_global_file_size_limit?
+ raise ::Gitlab::GitAccess::ForbiddenError,
+ "Changes include a file that is larger than the allowed size of #{file_size_limit} MiB. " \
+ "Use Git LFS to manage this file.)"
+ end
+ end
end
true
end
+
+ private
+
+ def file_size_limit
+ project.actual_limits.file_size_limit_mb
+ end
+
+ def enforce_global_file_size_limit?
+ Feature.enabled?(:enforce_global_file_size_limit, project)
+ end
end
end
end